Index: /issm/trunk-jpl/src/m/plot/applyoptions.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/applyoptions.js	(revision 19852)
+++ /issm/trunk-jpl/src/m/plot/applyoptions.js	(revision 19853)
@@ -1,3 +1,3 @@
-function applyoptions(md,data,options){
+function applyoptions(md,data,options,canvas,gl,node){
 	//APPLYOPTIONS - apply the options to current plot
 	//
@@ -143,8 +143,8 @@
 			var color;
 			var cheightoffset = options.getfieldvalue('colorbarfontsize',16);
-			var ccontext,ccanvas,ccanvasid;
+			var ccontext,ccanvas,ccanvasid,ccanvashtml;
 			ccanvasid = options.getfieldvalue('colorbarcanvasid',options.getfieldvalue('canvasid')+'_colorbar');
 			ccanvashtml = document.getElementById(ccanvasid);
-			if(ccanvashtml==null){
+			if (ccanvashtml==null) {
 				ccanvas = $('<canvas id="'+ccanvasid+'" width="'+String(cwidth+cheightoffset*4)+'" height="'+String(cheight+cheightoffset)+'"></canvas>').insertAfter('#'+options.getfieldvalue('canvasid'));
 				ccanvas.css({'position':'relative','top':((canvassize-cheight-cheightoffset)/-2).toFixed(2)+'px'});
@@ -159,6 +159,5 @@
 					//get html object instead of jqurey object to modify height/width to accomodate labels
 					ccanvashtml.width = ccanvas.width()+cheightoffset*6;
-					ccanvas.css({'display':'inline-block'});
-					ccanvashtml.height = canvassize;
+					ccanvashtml.height = cheight+cheightoffset;
 					ccanvashtml.cwidth = cwidth;
 					ccanvashtml.cheight = cheight;
@@ -175,11 +174,32 @@
 			}
 			var cgradient = ccontext.createLinearGradient(0,cheightoffset/2,0,cheight);
+			var tgradient = ccontext.createLinearGradient(0,0,0,256);
+			var cmap = options.getfieldvalue('cmap','jet');
+			var colorbar = colorbars[cmap];
 			for (var i = 0; i < colorbar.length; i++) {
 				color = colorbar[colorbar.length-i-1];
 				color = [Math.round(color[0]*255),Math.round(color[1]*255),Math.round(color[2]*255)];	
 				cgradient.addColorStop(i/colorbar.length,'rgba('+color.toString()+',1.0)');
+				tgradient.addColorStop(i/colorbar.length,'rgba('+color.toString()+',1.0)');
 			}
 			ccontext.fillStyle=cgradient;
 			ccontext.fillRect(0,cheightoffset/2,cwidth,cheight);
+			//Make texture canvas
+			var tcontext,tcanvas,tcanvasid,tcanvashtml,tURL;
+			tcanvasid = 'texturecanvas';
+			var tcanvashtml = document.getElementById(tcanvasid);
+			if (tcanvashtml == null) {
+				tcanvas = $('<canvas id="texturecanvas" width="256" height="256"></canvas>').insertAfter(ccanvas);
+				tcanvas.css({'display':'none'});
+				tcanvashtml = document.getElementById(tcanvasid);
+			}
+			else {
+				tcanvas = $('#' + tcanvasid);
+			}
+			tcontext = tcanvashtml.getContext('2d');
+			tcontext.fillStyle = tgradient;
+			tcontext.fillRect(0,0,256,256);
+			tURL = tcanvashtml.toDataURL();
+			node["texture"] = initTexture(gl,tURL);
 			//Draw colorbar border
 			ccontext.beginPath();
Index: /issm/trunk-jpl/src/m/plot/plot_manager.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_manager.js	(revision 19852)
+++ /issm/trunk-jpl/src/m/plot/plot_manager.js	(revision 19853)
@@ -28,4 +28,7 @@
 	}
 	
+	//Initialize the buffer structure: 
+	var node = Node(gl,options);
+	
 	//figure out if this is a special plot
 	if (typeof data === 'string'){
@@ -92,5 +95,5 @@
 			case 'mesh':
 				//plot_mesh(md,options,nlines,ncols,i);
-				plot_mesh(md,options,canvas,gl);
+				plot_mesh(md,options,canvas,gl,node);
 				break;
 			case 'none':
@@ -215,8 +218,11 @@
 	if (typeof data !== 'string'){
 		//plot unit
-		plot_unit(md,data,options,canvas,gl);
+		plot_unit(md,data,options,canvas,gl,node);
 	}
 
 	//applyoptions(md,data2,options); 
-	applyoptions(md,data,options); 
+	applyoptions(md,data,options,canvas,gl,node);
+	
+	/*Draw into the canvas:*/
+	draw(gl,options,canvas,node);
 }
Index: /issm/trunk-jpl/src/m/plot/plot_mesh.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_mesh.js	(revision 19852)
+++ /issm/trunk-jpl/src/m/plot/plot_mesh.js	(revision 19853)
@@ -1,3 +1,3 @@
-function plot_mesh(md,options,canvas,gl) {
+function plot_mesh(md,options,canvas,gl,node) {
 	//   Usage:
 	//      plot_mesh(md,options,canvas,gl);
@@ -6,5 +6,4 @@
 
 	//declare variables:  {{{
-	var node;
 	var vertices = [];
 	var indices = [];
@@ -22,7 +21,4 @@
 	//}}}
 
-	//Initialize the buffer structure: 
-	node = Node(gl,options);
-
 	//Compute coordinates and data range: 
 	xmin = ArrayMin(x);
@@ -35,4 +31,5 @@
 	//Compute scaling: 
 	var scale = 1 / (xmax - xmin);
+	node["shaderName"] = "colored";
 	node["scale"] = [scale, scale, scale];
 	node["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (-2 / scale)];
@@ -107,6 +104,3 @@
 	node["arrays"] = [vertices, colors, indices];
 	node["buffers"] = initBuffers(gl, node["arrays"]);
-	
-	/*Draw into the canvas:*/
-	draw(gl,options,canvas,node);
 }
Index: /issm/trunk-jpl/src/m/plot/plot_unit.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_unit.js	(revision 19852)
+++ /issm/trunk-jpl/src/m/plot/plot_unit.js	(revision 19853)
@@ -1,3 +1,3 @@
-function plot_unit(md,data,options,canvas,gl) {
+function plot_unit(md,data,options,canvas,gl,node) {
 	//PLOT_UNIT - unit plot, display data
 	//
@@ -8,8 +8,7 @@
 
 	//declare variables:  {{{
-	var node;
 	var vertices = [];
 	var indices = [];
-	var colors = [];
+	var texcoords = [];
 	var rgbcolor = [];
 	var xmin,xmax;
@@ -33,8 +32,4 @@
 	//}}}
 
-	//Initialize the buffer structure: 
-	node = Node(gl,options);
-
-
 	//Compute coordinates and data range: 
 	xmin = ArrayMin(x);
@@ -55,5 +50,5 @@
 				
 	//some defaults:
-	colors.itemSize = 4;
+	texcoords.itemSize = 2;
 
 	switch(datatype){
@@ -109,5 +104,5 @@
 				vertices.itemSize = 3;
 				var cmap=options.getfieldvalue('cmap','jet');
-				console.log(z[0]);
+				
 				for(var i = 0; i < x.length; i++){
 					vertices[vertices.length] = x[i];
@@ -115,12 +110,8 @@
 					vertices[vertices.length] = z[i];
 
-					//handle mesh/qinterest size mismatch
-					rgbcolor = rgb(data[i], datamin, datamax,cmap);
-					colors[colors.length] = rgbcolor[0];
-					colors[colors.length] = rgbcolor[1];
-					colors[colors.length] = rgbcolor[2];
-					colors[colors.length] = 1.0;
+					texcoords[texcoords.length] = 0.5;
+					texcoords[texcoords.length] = (data[i] - datamin) / (datamax - datamin);
 				}
-
+				
 				//linearize the elements array: 
 				indices = indices.concat.apply(indices, elements); 
@@ -147,7 +138,4 @@
 	
 	/*Initalize buffers: */
-	node["buffers"] = initBuffers(gl,[vertices, colors, indices]);
-	
-	/*Draw into the canvas:*/
-	draw(gl,options,canvas,node);
+	node["buffers"] = initBuffers(gl,[vertices, texcoords, indices]);
 }
Index: /issm/trunk-jpl/src/m/plot/webgl.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/webgl.js	(revision 19852)
+++ /issm/trunk-jpl/src/m/plot/webgl.js	(revision 19853)
@@ -66,4 +66,36 @@
 	return bufferArray;
 } //}}}
+function createSolidTexture(gl, r, g, b, a) {
+    var data = new Uint8Array([r, g, b, a]);
+    var texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+	gl.bindTexture(gl.TEXTURE_2D, null);
+    return texture;
+}
+function initTexture(gl,imageSource) { //{{{
+	var texture = gl.createTexture();
+	texture.image = new Image();
+	texture.image.onload = function () {
+		handleLoadedTexture(gl,texture);
+	}
+	texture.image.src = imageSource;
+	texture.isLoaded = true;
+	return texture;
+} //}}}
+function handleLoadedTexture(gl,texture) { //{{{
+	gl.activeTexture(gl.TEXTURE0);
+	gl.bindTexture(gl.TEXTURE_2D, texture);
+	gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
+	gl.generateMipmap(gl.TEXTURE_2D);
+	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
+	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+	gl.bindTexture(gl.TEXTURE_2D, null);
+} //}}}
 function Node(gl,options) { //{{{
 	
@@ -71,5 +103,5 @@
 
 	node= {buffers:[],
-		shader:gl.shaders["colored"]["program"],
+		shader:gl.shaders["unlit_textured"]["program"],
 		draw:null,
 		hideOcean:false,
@@ -87,5 +119,5 @@
 		scale:vec3.fromValues(1, 1, 1),
 		modelMatrix:mat4.create(),
-		shaderName:"colored",
+		shaderName:"unlit_textured",
 	};
 	
@@ -120,5 +152,5 @@
 	var normalizedValue;
 					
-	colorbar=colorbars[cmap];
+	var colorbar=colorbars[cmap];
 
 	value = clamp(value, min, max);
@@ -135,8 +167,7 @@
 //{{{ Shader Loading
 function loadShaders(gl) { //{{{
-	// TODO: Subsitute shaders["colored"] with shaderColored
-	shaderName = "colored";
+	var shaderNames = ["colored", "unlit_textured"];
 	shaders = {};
-	shaders[shaderName] = {loaded:false, vsh:{}, fsh:{}};
+	shaders["colored"] = {loaded:false, vsh:{}, fsh:{}};
 	shaders["colored"]["vsh"]["string"] = 
 		['attribute vec3 aVertexPosition;',
@@ -160,46 +191,70 @@
 		'	gl_FragColor = vColor;',
 		'}'].join('\n');
-
-	shaders[shaderName]["vsh"]["shader"] = getShaderByString(gl, shaders[shaderName]["vsh"]["string"], "vsh");
-	shaders[shaderName]["fsh"]["shader"] = getShaderByString(gl, shaders[shaderName]["fsh"]["string"], "fsh");
-
-	shaders[shaderName]["program"] = gl.createProgram();
-	gl.attachShader(shaders[shaderName]["program"], shaders[shaderName]["vsh"]["shader"]);
-	gl.attachShader(shaders[shaderName]["program"], shaders[shaderName]["fsh"]["shader"]);
-	gl.linkProgram(shaders[shaderName]["program"]);
-
-	if (!gl.getProgramParameter(shaders[shaderName]["program"], gl.LINK_STATUS)) {
-		alert("Could not initialise shaders");
-	}
-
-	var vshStringArray = shaders[shaderName]["vsh"]["string"].split("\n");
-	var fshStringArray = shaders[shaderName]["fsh"]["string"].split("\n");
-	var line = "";
-	var property = "";
-	for (var i = 0; i < vshStringArray.length; i++) {
-		line = vshStringArray[i];
-		if (line.search("attribute") != -1) {
-			property = nameFromLine(line);
-			shaders[shaderName]["program"][property] = gl.getAttribLocation(shaders[shaderName]["program"], property);
-		}
-		else if (line.search("uniform") != -1) {
-			property = nameFromLine(line);
-			shaders[shaderName]["program"][property] = gl.getUniformLocation(shaders[shaderName]["program"], property);
-		}
-		else if (line.search("void main") != -1) {
-			break;
-		}
-	}
-	for (var i = 0; i < fshStringArray.length; i++) {
-		line = fshStringArray[i];
-		if (line.search("uniform") != -1) {
-			property = nameFromLine(line);
-			shaders[shaderName]["program"][property] = gl.getUniformLocation(shaders[shaderName]["program"], property);
-		}
-		else if (line.search("void main") != -1) {
-			break;
-		}
-	}
-	shaders[shaderName]["loaded"] = true;
+	shaders["unlit_textured"] = {loaded:false, vsh:{}, fsh:{}};
+	shaders["unlit_textured"]["vsh"]["string"] = 
+		['attribute vec3 aVertexPosition;',
+		'attribute vec2 aTextureCoord;',
+		'',
+		'uniform mat4 uMVPMatrix;',
+		'',
+		'varying vec2 vTextureCoord;',
+		'',
+		'void main(void) {',
+		'	gl_Position = uMVPMatrix * vec4(aVertexPosition.xyz, 1.0);',
+		'	vTextureCoord = aTextureCoord;',
+		'}'].join('\n');
+	shaders["unlit_textured"]["fsh"]["string"] =
+		['precision mediump float;',
+		'',
+		'varying vec2 vTextureCoord;',
+		'',
+		'uniform sampler2D uColorSampler;',
+		'',
+		'void main(void) {',
+		'	gl_FragColor = texture2D(uColorSampler, vec2(vTextureCoord.s, vTextureCoord.t));',
+		'}'].join('\n');
+	shaderNames.forEach(function(shaderName){
+		shaders[shaderName]["vsh"]["shader"] = getShaderByString(gl, shaders[shaderName]["vsh"]["string"], "vsh");
+		shaders[shaderName]["fsh"]["shader"] = getShaderByString(gl, shaders[shaderName]["fsh"]["string"], "fsh");
+
+		shaders[shaderName]["program"] = gl.createProgram();
+		gl.attachShader(shaders[shaderName]["program"], shaders[shaderName]["vsh"]["shader"]);
+		gl.attachShader(shaders[shaderName]["program"], shaders[shaderName]["fsh"]["shader"]);
+		gl.linkProgram(shaders[shaderName]["program"]);
+
+		if (!gl.getProgramParameter(shaders[shaderName]["program"], gl.LINK_STATUS)) {
+			alert("Could not initialise shaders");
+		}
+
+		var vshStringArray = shaders[shaderName]["vsh"]["string"].split("\n");
+		var fshStringArray = shaders[shaderName]["fsh"]["string"].split("\n");
+		var line = "";
+		var property = "";
+		for (var i = 0; i < vshStringArray.length; i++) {
+			line = vshStringArray[i];
+			if (line.search("attribute") != -1) {
+				property = nameFromLine(line);
+				shaders[shaderName]["program"][property] = gl.getAttribLocation(shaders[shaderName]["program"], property);
+			}
+			else if (line.search("uniform") != -1) {
+				property = nameFromLine(line);
+				shaders[shaderName]["program"][property] = gl.getUniformLocation(shaders[shaderName]["program"], property);
+			}
+			else if (line.search("void main") != -1) {
+				break;
+			}
+		}
+		for (var i = 0; i < fshStringArray.length; i++) {
+			line = fshStringArray[i];
+			if (line.search("uniform") != -1) {
+				property = nameFromLine(line);
+				shaders[shaderName]["program"][property] = gl.getUniformLocation(shaders[shaderName]["program"], property);
+			}
+			else if (line.search("void main") != -1) {
+				break;
+			}
+		}
+		shaders[shaderName]["loaded"] = true;
+	});
 	return shaders;
 } //}}}
@@ -269,4 +324,9 @@
 	gl.uniformMatrix4fv(node["shader"]["uMVPMatrix"], false, mvpMatrix);
 	gl.uniform1f(node["shader"]["uAlpha"], node["transparency"]);
+	if (node["texture"]) {
+		gl.activeTexture(gl.TEXTURE0);
+		gl.bindTexture(gl.TEXTURE_2D, node["texture"]);
+		gl.uniform1i(node["shader"]["uColorSampler"], 0);	
+	}
 	if  (node["useIndexBuffer"]) {
 		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, node["buffers"][node["buffers"].length - 1]);
@@ -304,6 +364,6 @@
 	window.requestAnimationFrame(function(time) {draw(gl,options,canvas,node)});
 	updateCameraMatrix(canvas);
+
 	drawSceneGraphNode(gl, canvas, node);
-
 } //}}}
 //}}}
