/** * Create a renderer object working fully in WebGL * Here is a sample set of command to illustrate how to use this renderer * * var renderer = new WebGLRenderer('rendererId','http://localhost:8080/ParaViewWebService') * renderer.init(sessionId, viewId); * renderer.bindToElementId('containerID'); // => Add a WebGL canvas inside a div tag id 'containerID' * renderer.start(); * * renderer.init(otherSessionId, otherViewId); * renderer.view.width = '100'; * renderer.view.height = '400'; * renderer.setSize('100', '400'); * * renderer.unbindToElementId('containerID'); */ // Global object to keep track of WebGL renderers var webglRenderers = new Object(); window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback, /* DOMElement */ element){ window.setTimeout(callback, 1000 / 60); }; })(); function WebGLRenderer(rendererId, coreServiceURL) { this.baseURL = coreServiceURL + "/WebGL"; this.rendererId = rendererId; this.sessionId = ""; this.viewId = ""; this.nbError = 0; this.localTimeStamp = 0; this.offlineMode = false; this.setServerMode(false); this.forceSquareSize = false; this.view = new Object(); this.view.width = 100; this.view.height = 100; this.view.id = rendererId; this.view.alt = "ParaView Renderer"; //Default Shaders this.view.shaderfs = document.createElement("script"); this.view.shaderfs.id = "shader-fs"; this.view.shaderfs.type = "x-shader/x-fragment"; this.view.shaderfs.innerHTML = "\ #ifdef GL_ES\n\ precision highp float;\n\ #endif\n\ uniform bool uIsLine;\ varying vec4 vColor;\ varying vec4 vTransformedNormal;\ varying vec4 vPosition;\ void main(void) {\ float directionalLightWeighting1 = max(dot(normalize(vTransformedNormal.xyz), vec3(0.0, 0.0, 1.0)), 0.0); \ float directionalLightWeighting2 = max(dot(normalize(vTransformedNormal.xyz), vec3(0.0, 0.0, -1.0)), 0.0);\ vec3 lightWeighting = max(vec3(1.0, 1.0, 1.0) * directionalLightWeighting1, vec3(1.0, 1.0, 1.0) * directionalLightWeighting2);\ if (uIsLine == false){\ gl_FragColor = vec4(vColor.rgb * lightWeighting, vColor.a);\ } else {\ gl_FragColor = vColor*vec4(1.0, 1.0, 1.0, 1.0);\ }\ }"; this.view.shadervs = document.createElement("script"); this.view.shadervs.id = "shader-vs"; this.view.shadervs.type = "x-shader/x-vertex"; this.view.shadervs.innerHTML = "\ attribute vec3 aVertexPosition;\ attribute vec4 aVertexColor;\ attribute vec3 aVertexNormal;\ uniform mat4 uMVMatrix;\ uniform mat4 uPMatrix;\ uniform mat4 uNMatrix;\ varying vec4 vColor;\ varying vec4 vPosition;\ varying vec4 vTransformedNormal;\ void main(void) {\ vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);\ gl_Position = uPMatrix * vPosition;\ vTransformedNormal = uNMatrix * vec4(aVertexNormal, 1.0);\ vColor = aVertexColor;\ }"; // Point Shaders this.view.shaderfsPoint = document.createElement("script"); this.view.shaderfsPoint.id = "shader-fs-Point"; this.view.shaderfsPoint.type = "x-shader/x-fragment"; this.view.shaderfsPoint.innerHTML = "\ #ifdef GL_ES\n\ precision highp float;\n\ #endif\n\ varying vec4 vColor;\ void main(void) {\ gl_FragColor = vColor;\ }"; this.view.shadervsPoint = document.createElement("script"); this.view.shadervsPoint.id = "shader-vs-Point"; this.view.shadervsPoint.type = "x-shader/x-vertex"; this.view.shadervsPoint.innerHTML = "\ attribute vec3 aVertexPosition;\ attribute vec4 aVertexColor;\ uniform mat4 uMVMatrix;\ uniform mat4 uPMatrix;\ uniform mat4 uNMatrix;\ uniform float uPointSize;\ varying vec4 vColor;\ void main(void) {\ vec4 pos = uMVMatrix * vec4(aVertexPosition, 1.0);\ gl_Position = uPMatrix * pos;\ vColor = aVertexColor*vec4(1.0, 1.0, 1.0, 1.0);\ gl_PointSize = uPointSize;\ }"; // this.canvasName = "glcanvas" + rendererId; this.view.html = '
Your browser doesn\'t appear to support the HTML5 \ <canvas> element.'; this.view.html += '
'; this.fps = 0; // Register in global var webglRenderers[rendererId] = this; } WebGLRenderer.prototype.bindToElementId = function (elementId) { this.oldInnerHTML = document.getElementById(elementId).innerHTML; document.getElementById(elementId).innerHTML = this.view.html; document.getElementById(elementId).appendChild(this.view.shaderfs); document.getElementById(elementId).appendChild(this.view.shadervs); document.getElementById(elementId).appendChild(this.view.shaderfsPoint); document.getElementById(elementId).appendChild(this.view.shadervsPoint); } WebGLRenderer.prototype.unbindToElementId = function (elementId) { document.getElementById(elementId).innerHTML = this.oldInnerHTML; clearTimeout(this.drawInterval); if (typeof(paraview) != "undefined") paraview.updateConfiguration(true, "JPEG", "NO"); } WebGLRenderer.prototype.setOfflineMode = function (mode) { this.offlineMode = mode; this.requestMetaData(); } WebGLRenderer.prototype.bindToElement = function (element) { this.oldInnerHTML = element.innerHTML; element.innerHTML = this.view.html; element.appendChild(this.view.shaderfs); element.appendChild(this.view.shadervs); element.appendChild(this.view.shaderfsPoint); element.appendChild(this.view.shadervsPoint); } WebGLRenderer.prototype.unbindToElement = function (element) { element.innerHTML = this.oldInnerHTML; clearTimeout(this.drawInterval); if (typeof(paraview) != "undefined") paraview.updateConfiguration(true, "JPEG", "NO"); } WebGLRenderer.prototype.init = function (sessionId, viewId) { this.sessionId = sessionId; this.viewId = viewId; } WebGLRenderer.prototype.start = function(metadata, objects) { if (typeof(renderers) == "undefined"){ renderers = Object(); renderers.current = this; } if (typeof(paraview) != "undefined") paraview.updateConfiguration(true, "JPEG", "WebGL"); canvas = document.getElementById(this.canvasName); canvas.width = this.view.width; canvas.height = this.view.height; this.hasSceneChanged = true; //Scene Graph Has Changed this.oldCamPos = null; //Last Known Camera Position this.sceneJSON = null; //Current Scene Graph this.up = []; this.right = []; this.z_dir = []; this.objects = []; //List of objects this.nbErrors = 0; //Number of Errors this.background = null; //Background object: mesh, normals, colors, render this.interactionRatio = 2; this.requestInterval = 250; //Frequency it request new data from the server this.requestOldInterval = 250; // this.updateInterval = 100; //Frequency the server will be updated this.fps = 0; this.frames = 0; this.lastTime = new Date().getTime(); this.view.aspectRatio = 1; this.lookAt = [0,0,0,0,1,0,0,0,1]; this.offlineMode = !(typeof(metadata)=="undefined" || typeof(objects)=="undefined"); this.cachedObjects = []; //List of Cached Objects this.isCaching = false; //Is Caching or Not this.processQueue = []; //List of process to be executed this.objScale = 1.0; //Scale applied locally in the scene this.translation = [0.0, 0.0, 0.0]; //Translation this.rotMatrix = mat4.create(); //Rotation Matrix mat4.identity(this.rotMatrix); this.rotMatrix2 = mat4.create(this.rotMatrix); this.mouseDown = false; this.lastMouseX = 0; this.lastMouseY = 0; this.mvMatrix = mat4.create(this.rotMatrix); this.pMatrix = mat4.create(this.rotMatrix); // Initialize the GL context this.gl = null; try { this.gl = canvas.getContext("experimental-webgl"); this.gl.viewportWidth = this.view.width; this.gl.viewportHeight = this.view.height; } catch(e) {} if (this.gl) { this.gl.clearColor(0.0, 0.0, 0.0, 1.0); this.gl.clearDepth(1.0); this.gl.enable(this.gl.DEPTH_TEST); this.gl.depthFunc(this.gl.LEQUAL); this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA); this.initShaders(); this.ctx2d = document.getElementById(this.canvasName + "Widget").getContext('2d'); // Set up to draw the scene periodically. this.drawInterval = requestAnimFrame(new Function("webglRenderers['" + this.view.id + "'].drawScene();")); if (!this.offlineMode){ this.requestMetaData(); this.updateCamera(); } else { this.sceneJSON = JSON.parse(metadata); for(aw=0; aw height) height = width; else width = height; } this.view.width = width; this.view.height = height; canvas = document.getElementById(this.canvasName); canvasWidget = document.getElementById(this.canvasName + "Widget"); if (canvas){ canvas.width = this.view.width; canvas.height = this.view.height; canvasWidget.width = this.view.width; canvasWidget.height = this.view.height; if (typeof(this.gl) != "undefined" && this.gl != null){ if (!this.offlineMode) updateRendererSize(this.sessionId, this.viewId, width, height); this.gl.viewportWidth = this.view.width; this.gl.viewportHeight = this.view.height; } left = 0; tt = 0; if (this.forceSquareSize){ left = Math.round((w-this.view.width)/2); tt = Math.round((h-this.view.height)/2); } this.view.left = left; this.view.top = top; if(this.forceSquareSize == true){ canvas.setAttribute("style", "position: absolute; overflow: hidden; left: " + left + "px; top: " + tt + "px; right: 0px; z-index:0;"); canvasWidget.setAttribute("style", "position: absolute; overflow: hidden; left: " + left + "px; top: " + tt + "px; right: 0px; z-index:1;"); } else { canvas.setAttribute("style", "overflow: hidden; left: " + left + "px; top: " + tt + "px; right: 0px; z-index:0;"); canvasWidget.setAttribute("style", "position: absolute; overflow: hidden; left: " + left + "px; top: " + tt + "px; right: 0px; z-index:1;"); } } } WebGLRenderer.prototype.requestMetaData = function() { if (this.mouseDown || renderers.current != this) return; if (this.offlineMode) return; interval = this.requestInterval; if (this.serverMode) interval = interval/2; this.timer = setTimeout("webglRenderers[\'" + this.view.id + "\'].requestMetaData()", interval); var request = new XMLHttpRequest(); request.requester = this; filename = this.baseURL + "?sid=" + this.sessionId + "&vid=" + this.viewId + "&q=meta"; try { request.open("GET", filename, false); request.overrideMimeType('text/plain; charset=x-user-defined'); request.onreadystatechange = function() { if(this.requester.mouseDown) return; if (request.status != 200) this.requester.nbErrors++ else if (request.readyState == 4) { aux = JSON.parse(request.responseText); this.requester.hasSceneChanged = JSON.stringify(aux)!=JSON.stringify(this.requester.sceneJSON); this.requester.sceneJSON = JSON.parse(request.responseText); if (this.requester.hasSceneChanged) this.requester.updateScene(); } } request.send(); } catch (e) { this.nbErrors++; } } WebGLRenderer.prototype.updateScene = function(){ if (typeof(this.sceneJSON) == "undefined" || this.sceneJSON == null) return; c1 = [0,0,0]; c2 = [0,0,0]; for(l=0; l= 50 && this.nbErrors < 5){ this.frames = 0; ko = new Date(); currTime = ko.getTime(); diff = currTime - this.lastTime; this.lastTime = currTime; this.fps = 50000/diff; } this.processObject(); this.gl.viewport(0, 0, this.gl.viewportWidth, this.gl.viewportHeight); this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); mat4.ortho(-1.0, 1.0, -1.0, 1.0, 1.0, 1000000.0, this.pMatrix); mat4.identity(this.mvMatrix); this.gl.disable(this.gl.DEPTH_TEST); this.renderBackground(); this.gl.enable(this.gl.DEPTH_TEST); this.ctx2d.clearRect(0, 0, this.view.width, this.view.height); for(rr=this.sceneJSON.Renderers.length-1; rr>=0 ; rr--){ renderer = this.sceneJSON.Renderers[rr]; width = renderer.size[0]-renderer.origin[0]; height = renderer.size[1]-renderer.origin[1]; width = width*this.view.width; height = height*this.view.height; x = renderer.origin[0]*this.view.width; y = renderer.origin[1]*this.view.height; if (y < 0) y = 0; this.gl.viewport(x, y, width, height); //this.gl.clear(this.gl.DEPTH_BUFFER_BIT); mat4.perspective(renderer.LookAt[0], width/height, 0.1, 1000000.0, this.pMatrix); mat4.identity(this.mvMatrix); mat4.lookAt([renderer.LookAt[7], renderer.LookAt[8], renderer.LookAt[9]], [renderer.LookAt[1], renderer.LookAt[2], renderer.LookAt[3]], [renderer.LookAt[4], renderer.LookAt[5], renderer.LookAt[6]], this.mvMatrix); for(r=0; r