Changeset 19728


Ignore:
Timestamp:
11/17/15 00:41:57 (9 years ago)
Author:
dlcheng
Message:

CHG: Implementing basic webgl plot_unit functionality for test101.html

Location:
issm/trunk-jpl
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/m/plot/plot_unit.js

    r19727 r19728  
    1 function plot_unit(x,y,z,elements,data,is2d,isplanet,datatype,options){
     1function plot_unit(x,y,z,elements,data,is2d,isplanet,datatype,options) {
    22        //PLOT_UNIT - unit plot, display data
    33        //
     
    1313        var canvas=document.getElementById(options.getfieldvalue('canvasid'));
    1414
    15         //Initialize the GL context:
     15        // Initialize the GL context:
    1616        var gl=initWebGL(canvas);
    1717
     
    1919
    2020        if (gl) {
    21                 // Set clear color to black, fully opaque
    22                 gl.clearColor(0.0, 0.0, 0.0, 1.0);
    23                 // Enable depth testing
    24                 gl.enable(gl.DEPTH_TEST);
    25                 // Near things obscure far things
    26                 gl.depthFunc(gl.LEQUAL);
    27                 // Clear the color as well as the depth buffer.
    28                 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
     21                loadShaders(gl);
     22                var node=loadModel(gl,x,y,z,elements,data);
     23                drawSceneGraphNode(gl,node);
    2924        }
    3025
  • issm/trunk-jpl/src/m/plot/webgl.js

    r19727 r19728  
    11/*This is where we have all our webgl relevant functionality for the plotting routines: */
     2var shaders = {};
     3//{{{ GL Initialization
    24function initWebGL(canvas) { //{{{
    35        gl = null;
     
    1517        }
    1618
     19
     20        // Set clear color to black, fully opaque
     21        gl.clearColor(0.0, 0.0, 0.0, 1.0);
     22        // Enable depth testing
     23        gl.enable(gl.DEPTH_TEST);
     24        // Near things obscure far things
     25        gl.depthFunc(gl.LEQUAL);
     26        // Clear the color as well as the depth buffer.
     27        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
     28
     29        // Allocate arrays equal to maximium number of attributes used by any one shader
     30        gl.enableVertexAttribArray(0);
     31        gl.enableVertexAttribArray(1);
     32
     33        // Add context state variables
     34        //gl.zoomFactor = 1.0;
     35        //gl.cameraMatrix = mat4.create();
     36
     37        // Add event listeners for canvas
     38        if (canvas.addEventListener) {
     39                // IE9, Chrome, Safari, Opera
     40                canvas.addEventListener("mousewheel", function (e) {MouseWheelHandler(e,gl)}, false);
     41                // Firefox
     42                canvas.addEventListener("DOMMouseScroll", function (e) {MouseWheelHandler(e,gl)}, false);
     43                // Mobile
     44                //canvas.addEventListener("gesturechange", MousePinchHandler, false);
     45        }
     46
    1747        return gl;
    1848} //}}}
     49function loadModel(gl,x,y,z,elements,data){ //{{{
     50        colorbar=colorbars["rainbow"];
     51        model={"x":x,"y":y,"z":z,"elements":elements}; 
     52        sceneGraph={};
     53        sceneGraph["model"] = sceneGraphNode(gl);
     54        sceneGraph["model"]["shaderName"] = "colored";
     55        sceneGraph["model"]["shader"] = shaders["colored"]["program"];
     56        sceneGraph["model"]["useIndexBuffer"] = true;
     57       
     58        var meshVertices = [];
     59        var meshColors = [];
     60        var meshNormals = [];
     61        var color = [];
     62
     63        var qmin = Math.min.apply(null,data);
     64        var qmax = Math.max.apply(null,data);
     65        var xmin = Math.min.apply(null,model["x"]);
     66        var xmax = Math.max.apply(null,model["x"]);
     67        var ymin = Math.min.apply(null,model["y"]);
     68        var ymax = Math.max.apply(null,model["y"]);
     69        var zmin = Math.min.apply(null,[0]);
     70        var zmax = Math.max.apply(null,[0]);
     71       
     72        var scale = 1 / (xmax - xmin);
     73        sceneGraph["model"]["scale"] = [scale, scale, scale];
     74        sceneGraph["model"]["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (-2 / scale)];
     75        sceneGraph["model"]["modelMatrix"] = recalculateModelMatrix(sceneGraph["model"]);
     76
     77        for(var i = 0; i < model["x"].length; i++){
     78                meshVertices[meshVertices.length] = model["x"][i];
     79                meshVertices[meshVertices.length] = model["y"][i];
     80                meshVertices[meshVertices.length] = 0.0;
     81               
     82                //initialize vertex normals
     83                meshNormals[meshNormals.length] = 0.0;
     84                meshNormals[meshNormals.length] = 0.0;
     85                meshNormals[meshNormals.length] = 0.0;
     86               
     87                //handle mesh/qinterest size mismatch
     88                color = rgb(data[i], qmin, qmax);
     89                meshColors[meshColors.length] = color[0];
     90                meshColors[meshColors.length] = color[1];
     91                meshColors[meshColors.length] = color[2];
     92                meshColors[meshColors.length] = 1.0;
     93        }
     94
     95        var indices = [];
     96        indices = indices.concat.apply(indices, model["elements"]);
     97
     98        for (var i = 0; i < indices.length; i += 3){
     99                indices[i] -= 1;
     100                indices[i + 1] -= 1;
     101                indices[i + 2] -= 1;
     102        }
     103
     104        meshVertices.itemSize = 3;
     105        meshColors.itemSize = 4;
     106        indices.itemSize = 1;
     107
     108        sceneGraph["model"]["buffers"] = initBuffers(gl,[meshVertices, meshColors, indices]);
     109        return sceneGraph["model"];
     110} //}}}
     111function initBuffers(gl,arrays) { //{{{
     112        var bufferArray = [];
     113        for (var i = 0; i < arrays.length; i++) {
     114                bufferArray[i] = gl.createBuffer();     
     115                bufferArray[i].itemSize = arrays[i].itemSize;
     116                bufferArray[i].numItems = arrays[i].length/bufferArray[i].itemSize;
     117               
     118                if (bufferArray[i].itemSize > 1) {
     119                        gl.bindBuffer(gl.ARRAY_BUFFER, bufferArray[i]);
     120                        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(arrays[i]), gl.STATIC_DRAW);
     121                }
     122                else {
     123                        //TODO: identify index buffers uniquely (by name)
     124                        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferArray[i]);
     125                        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(arrays[i]), gl.STATIC_DRAW);
     126                }
     127        }       
     128        return bufferArray;
     129} //}}}
     130function sceneGraphNode(gl) { //{{{
     131        //Primary object for storing common rendering information.
     132        return {buffers:[],
     133                shader:null,
     134                draw:null,
     135                hideOcean:false,
     136                level:0,
     137                useIndexBuffer:false,
     138                useOrthographic:false,
     139                transparency:1.0,
     140                disableDepthTest:false,
     141                enableCullFace:false,
     142                cullFace:gl.FRONT,
     143                drawMode:gl.TRIANGLES,
     144                texture:null,
     145                translation:vec3.create(),
     146                rotation:vec3.create(),
     147                scale:vec3.fromValues(1, 1, 1),
     148                modelMatrix:mat4.create()};
     149} //}}}
     150function recalculateModelMatrix(node) { //{{{
     151        var modelMatrix = mat4.create();
     152
     153        var scaleMatrix = mat4.create();
     154        mat4.scale(scaleMatrix, scaleMatrix, node["scale"]);
     155        mat4.multiply(modelMatrix, scaleMatrix, modelMatrix);
     156
     157        var zRotationMatrix = mat4.create();   
     158        mat4.rotate(zRotationMatrix, zRotationMatrix, node["rotation"][2] * Math.PI/180.0, [0.0, 0.0, 1.0]);
     159        mat4.multiply(modelMatrix, zRotationMatrix, modelMatrix);
     160        var yRotationMatrix = mat4.create();   
     161        mat4.rotate(yRotationMatrix, yRotationMatrix, node["rotation"][1] * Math.PI/180.0, [0.0, 1.0, 0.0]);
     162        mat4.multiply(modelMatrix, yRotationMatrix, modelMatrix);
     163        var xRotationMatrix = mat4.create();   
     164        mat4.rotate(xRotationMatrix, xRotationMatrix, node["rotation"][0] * Math.PI/180.0, [1.0, 0.0, 0.0]);
     165        mat4.multiply(modelMatrix, xRotationMatrix, modelMatrix);
     166
     167        var translationMatrix = mat4.create();
     168        mat4.translate(translationMatrix, translationMatrix, node["translation"]); //relative translation
     169        mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
     170
     171        return modelMatrix;
     172} //}}}
     173function rgb(value, min, max) { //{{{
     174        value = clamp(value, min + 1.0, max);
     175        var use_log_scale = true;
     176        if (use_log_scale == true) {
     177                var normalizedValue = Math.log(value - min) / Math.log(max - min);
     178        }
     179        else {
     180                var normalizedValue = (value - min) / (max - min);
     181        }
     182        var index = clamp(Math.round(normalizedValue * colorbar.length), 0, colorbar.length - 1);
     183        return colorbar[index];
     184} //}}}
     185function clamp(value, min, max) { //{{{
     186        return Math.max(min, Math.min(value, max));
     187} //}}}
     188//}}}
     189//{{{ Shader Loading
     190function loadShaders(gl) { //{{{
     191        var shader_name_array = ["colored"];
     192        //var shaders = {};
     193        for (var i = 0; i < shader_name_array.length; i++) {
     194                loadShader(gl,shader_name_array[i]);
     195        }
     196        //return shaders;
     197} //}}}
     198function loadShader(gl,shaderName) { //{{{
     199        //var shader = {loaded:false, vsh:{}, fsh:{}};
     200        shaders[shaderName] = {loaded:false, vsh:{}, fsh:{}};
     201        $.ajax({
     202                url: "webgl/shaders/" + shaderName + ".vsh",
     203                async: false,
     204                dataType: "script"
     205        });
     206        $.ajax({
     207                url: "webgl/shaders/" + shaderName + ".fsh",
     208                async: false,
     209                dataType: "script"
     210        });
     211
     212        shaders[shaderName]["vsh"]["shader"] = getShaderByString(gl, shaders[shaderName]["vsh"]["string"], "vsh");
     213        shaders[shaderName]["fsh"]["shader"] = getShaderByString(gl, shaders[shaderName]["fsh"]["string"], "fsh");
     214
     215        shaders[shaderName]["program"] = gl.createProgram();
     216        gl.attachShader(shaders[shaderName]["program"], shaders[shaderName]["vsh"]["shader"]);
     217        gl.attachShader(shaders[shaderName]["program"], shaders[shaderName]["fsh"]["shader"]);
     218        gl.linkProgram(shaders[shaderName]["program"]);
     219
     220        if (!gl.getProgramParameter(shaders[shaderName]["program"], gl.LINK_STATUS)) {
     221                alert("Could not initialise shaders");
     222        }
     223
     224        var vshStringArray = shaders[shaderName]["vsh"]["string"].split("\n");
     225        var fshStringArray = shaders[shaderName]["fsh"]["string"].split("\n");
     226        var line = "";
     227        var property = "";
     228        for (var i = 0; i < vshStringArray.length; i++) {
     229                line = vshStringArray[i];
     230                if (line.search("attribute") != -1) {
     231                        property = nameFromLine(line);
     232                        shaders[shaderName]["program"][property] = gl.getAttribLocation(shaders[shaderName]["program"], property);
     233                }
     234                else if (line.search("uniform") != -1) {
     235                        property = nameFromLine(line);
     236                        shaders[shaderName]["program"][property] = gl.getUniformLocation(shaders[shaderName]["program"], property);
     237                }
     238                else if (line.search("void main") != -1) {
     239                        break;
     240                }
     241        }
     242        for (var i = 0; i < fshStringArray.length; i++) {
     243                line = fshStringArray[i];
     244                if (line.search("uniform") != -1) {
     245                        property = nameFromLine(line);
     246                        shaders[shaderName]["program"][property] = gl.getUniformLocation(shaders[shaderName]["program"], property);
     247                }
     248                else if (line.search("void main") != -1) {
     249                        break;
     250                }
     251        }
     252        shaders[shaderName]["loaded"] = true;
     253        //return shader;
     254} //}}}
     255function getShaderByString(gl,str,type) { //{{{
     256        var shader;
     257        if (type == "fsh") {
     258                shader = gl.createShader(gl.FRAGMENT_SHADER);
     259        }
     260        else if (type == "vsh") {
     261                shader = gl.createShader(gl.VERTEX_SHADER);
     262        }
     263        else {
     264                return null;
     265        }
     266       
     267        gl.shaderSource(shader, str);
     268        gl.compileShader(shader);
     269
     270        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {       
     271                alert(gl.getShaderInfoLog(shader));
     272                return null;
     273        }
     274
     275        return shader;
     276} //}}}
     277function functionToString(functionVariable) { //{{{
     278        //Workaround for loading text files - store as multiline comment in function, then strip string from function once loaded
     279        return functionVariable.toString().replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, '');
     280} //}}}
     281function nameFromLine(line) { //{{{
     282        //returns lowerCamelCase property name from shader line
     283        var fullName = line.split(" ")[2];
     284        return fullName.slice(0, fullName.search(";"));
     285} //}}}
     286//}}}
     287//{{{ Interface Functions
     288function MouseWheelHandler(e,gl) { //{{{
     289        // prevent scrolling when over canvas
     290        e.preventDefault();
     291        var delta = clamp((e.wheelDelta || -e.detail), -1, 1);
     292        //gl.zoomFactor = gl.zoomFactor + delta;
     293        updateCameraMatrix(gl);
     294} //}}}
     295//}}}
     296//{{{ Drawing Functions
     297function updateCameraMatrix(gl) { //{{{
     298        //Update view matrix and multiply with projection matrix to get the view-projection (camera) matrix.
     299        var vMatrix = mat4.create();
     300        var pMatrix = mat4.create();
     301
     302        mat4.perspective(pMatrix, 45 * Math.PI / 180, gl.canvas.width / gl.canvas.height, 0.001, 10000.0);
     303
     304        var scaleMatrix= mat4.create();
     305        mat4.scale(scaleMatrix, scaleMatrix, [1/100000000000000, 1/100000000000000, 1/100000000000000]);       
     306        mat4.multiply(vMatrix, scaleMatrix, vMatrix);
     307
     308        //Apply screenspace relative translation
     309        var translateMatrix = mat4.create();
     310        mat4.translate(translateMatrix, translateMatrix, [0.0, 0.0, gl.zoomFactor]);
     311        mat4.multiply(vMatrix, translateMatrix, vMatrix);
     312
     313        //Apply projection matrix to get camera matrix
     314        mat4.multiply(gl.cameraMatrix, pMatrix, vMatrix);
     315}//}}}
     316function drawSceneGraphNode(gl,node) { //{{{
     317        bindAttributes(gl, node["shader"], node["buffers"]);
     318        var mvpMatrix = mat4.create();
     319        var cameraMatrix = mat4.create();
     320        //var cameraMatrix = gl.cameraMatrix;
     321        if (node["useOrthographic"] == true) {
     322                mat4.ortho(mvpMatrix, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
     323        }
     324        else {
     325                mat4.multiply(mvpMatrix, cameraMatrix, node["modelMatrix"]);
     326        }
     327        gl.uniformMatrix4fv(node["shader"]["uMVPMatrix"], false, mvpMatrix);
     328        gl.uniform1f(node["shader"]["uAlpha"], node["transparency"]);
     329        if  (node["useIndexBuffer"]) {
     330                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, node["buffers"][node["buffers"].length - 1]);
     331                gl.drawElements(node["drawMode"], node["buffers"][node["buffers"].length - 1].numItems, gl.UNSIGNED_SHORT, 0);
     332        }
     333        else {
     334                gl.drawArrays(node["drawMode"], 0, node["buffers"][0].numItems);
     335        }       
     336        gl.enable(gl.DEPTH_TEST);
     337        gl.disable(gl.CULL_FACE);
     338} //}}}
     339function bindAttributes(gl,shaderProgram,bufferArray) { //{{{
     340        gl.useProgram(shaderProgram);
     341        var arrayNumber = 0;
     342        for (var propertyName in shaderProgram) {
     343                if (propertyName[0] == "a") {
     344                        if (bufferArray[arrayNumber].itemSize > 1) {
     345                                gl.bindBuffer(gl.ARRAY_BUFFER, bufferArray[arrayNumber]);
     346                                gl.vertexAttribPointer(shaderProgram[propertyName], bufferArray[arrayNumber].itemSize, gl.FLOAT, false, 0, 0);
     347                                arrayNumber++;
     348                        }
     349                }
     350        }
     351} //}}}
     352//}}}
  • issm/trunk-jpl/test/NightlyRun/test101.html

    r19726 r19728  
    44<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    55<!-- Includes {{{-->
     6<script type="text/javascript" src="webgl/jquery-1.11.1.js"></script>
     7<script type="text/javascript" src="webgl/gl-matrix-2.2.0.js"></script>
     8<script type="text/javascript" src="webgl/colorbars.js"></script>
     9<script type="text/javascript" src="./IssmModule.js"></script>
     10<script type="text/javascript" src="./sprintf.js"></script>
    611<script type="text/javascript" src="../Exp/Square.js"></script>
    712<script type="text/javascript" src="../../src/m/miscellaneous/fielddisplay.js"></script>
     
    2732<script type="text/javascript" src="../../src/wrappers/NodeConnectivity/NodeConnectivity.js"></script>
    2833<script type="text/javascript" src="../../src/wrappers/ElementConnectivity/ElementConnectivity.js"></script>
    29 <script type="text/javascript" src="../../build-js/src/wrappers/javascript/IssmModule.js"></script>
    30 <script type="text/javascript" src="../../externalpackages/javascript/src/sprintf.js"></script>
    3134<!-- Includes }}}-->
    3235</head>
     
    3639        <canvas id="figure2" width="640" height="480">
    3740        </canvas>
    38 
    3941
    4042        <script type="text/javascript" async><!--}}}-->
     
    4749       
    4850</script> <!--{{{-->
     51<canvas id="ISSM-canvas"></canvas>
    4952</body>
    5053</html><!--}}}-->
Note: See TracChangeset for help on using the changeset viewer.