From 191cb96b3b4e1e5aa805211e5ab8dbd6aa075881 Mon Sep 17 00:00:00 2001 From: Nivesh Rajbhandari Date: Thu, 9 Feb 2012 10:09:13 -0800 Subject: Merging WebGL changes that allow users to modify different shape instances. Also, merging in changes that improve rendering performance by not updating static materials. Signed-off-by: Nivesh Rajbhandari --- js/helper-classes/RDGE/GLCircle.js | 13 +- js/helper-classes/RDGE/GLGeomObj.js | 3 + js/helper-classes/RDGE/GLLine.js | 3 + js/helper-classes/RDGE/GLMaterial.js | 40 ++++ js/helper-classes/RDGE/GLRectangle.js | 171 +++++++++++++-- js/helper-classes/RDGE/GLWorld.js | 238 ++++++++++++++++++--- js/helper-classes/RDGE/rdge-compiled.js | 147 ++++++------- js/helper-classes/RDGE/src/core/script/engine.js | 18 +- .../RDGE/src/core/script/init_state.js | 7 +- js/helper-classes/RDGE/src/core/script/jshader.js | 6 +- js/helper-classes/RDGE/src/core/script/renderer.js | 32 ++- .../RDGE/src/core/script/run_state.js | 10 +- js/helper-classes/RDGE/src/core/script/runtime.js | 2 +- 13 files changed, 548 insertions(+), 142 deletions(-) (limited to 'js') diff --git a/js/helper-classes/RDGE/GLCircle.js b/js/helper-classes/RDGE/GLCircle.js index e6bcba89..08057778 100644 --- a/js/helper-classes/RDGE/GLCircle.js +++ b/js/helper-classes/RDGE/GLCircle.js @@ -55,14 +55,16 @@ function GLCircle() this.m_world = world; + if(strokeMaterial) - { this._strokeMaterial = strokeMaterial; - } + else + this._strokeMaterial = new FlatMaterial(); + if(fillMaterial) - { this._fillMaterial = fillMaterial; - } + else + this._fillMaterial = new FlatMaterial(); } /////////////////////////////////////////////////////////////////////// @@ -131,6 +133,9 @@ function GLCircle() if (!world) throw( "null world in buildBuffers" ); if (!world._useWebGL) return; + + // make sure RDGE has the correct context + g_Engine.setContext( world.getCanvas().uuid ); // create the gl buffer var gl = world.getGLContext(); diff --git a/js/helper-classes/RDGE/GLGeomObj.js b/js/helper-classes/RDGE/GLGeomObj.js index 62fbf562..5d7497ad 100644 --- a/js/helper-classes/RDGE/GLGeomObj.js +++ b/js/helper-classes/RDGE/GLGeomObj.js @@ -103,6 +103,9 @@ function GLGeomObj() } } } + + var world = this.getWorld(); + if (world) world.restartRenderLoop(); } this.setFillColor = function(c) { this.setMaterialColor(c, "fill"); } diff --git a/js/helper-classes/RDGE/GLLine.js b/js/helper-classes/RDGE/GLLine.js index bd3cbc26..f01e1610 100644 --- a/js/helper-classes/RDGE/GLLine.js +++ b/js/helper-classes/RDGE/GLLine.js @@ -109,6 +109,9 @@ function GLLine( world, xOffset, yOffset, width, height, slope, strokeSize, stro var world = this.getWorld(); if (!world) throw( "null world in buildBuffers" ); if (!world._useWebGL) return; + + // make sure RDGE has the correct context + g_Engine.setContext( world.getCanvas().uuid ); // create the gl buffer var gl = world.getGLContext(); diff --git a/js/helper-classes/RDGE/GLMaterial.js b/js/helper-classes/RDGE/GLMaterial.js index e1a68abd..642fab05 100644 --- a/js/helper-classes/RDGE/GLMaterial.js +++ b/js/helper-classes/RDGE/GLMaterial.js @@ -31,6 +31,11 @@ function GLMaterial( world ) this._texture; + // vertex deformation variables + this._hasVertexDeformation = false; + this._vertexDeformationRange = [0, 0, 1, 1]; // (xMin, yMin, xMax, yMax) + this._vertexDeformationTolerance = 0.1; + // RDGE variables this._shader; this._materialNode; @@ -62,6 +67,16 @@ function GLMaterial( world ) this.getShader = function() { return this._shader; } this.getMaterialNode = function() { return this._materialNode; } + // a material can be animated or not. default is not. + // Any material needing continuous rendering should override this method + this.isAnimated = function() { return false; } + + // the vertex shader can apply deformations requiring refinement in + // certain areas. + this.hasVertexDeformation = function() { return this._hasVertexDeformation; } + this.getVertexDeformationRange = function() { return this._vertexDeformationRange.slice(); } + this.getVertexDeformationTolerance = function() { return this._vertexDeformationTolerance; } + /////////////////////////////////////////////////////////////////////// // Common Material Methods @@ -174,6 +189,31 @@ function GLMaterial( world ) // animated materials should implement the update method } + this.registerTexture = function( texture ) + { + // the world needs to know about the texture map + var world = this.getWorld(); + if (!world) + console.log( "**** world not defined for registering texture map: " + texture.lookUpName ); + else + world.textureToLoad( texture ); + } + + this.loadTexture = function( texMapName, wrap, mips ) + { + var tex; + var world = this.getWorld(); + if (!world) + console.log( "world not defined for material with texture map" ); + else + { + var renderer = world.getRenderer(); + tex = renderer.getTextureByName(texMapName, wrap, mips ); + this.registerTexture( tex ); + } + return tex; + } + this.export = function() { // this function should be overridden by subclasses diff --git a/js/helper-classes/RDGE/GLRectangle.js b/js/helper-classes/RDGE/GLRectangle.js index b88ecc71..e34532d2 100644 --- a/js/helper-classes/RDGE/GLRectangle.js +++ b/js/helper-classes/RDGE/GLRectangle.js @@ -72,13 +72,14 @@ function GLRectangle() this._materialSpecular = [0.4, 0.4, 0.4, 1.0]; if(strokeMaterial) - { this._strokeMaterial = strokeMaterial; - } + else + this._strokeMaterial = new FlatMaterial(); + if(fillMaterial) - { this._fillMaterial = fillMaterial; - } + else + this._fillMaterial = new FlatMaterial(); } /////////////////////////////////////////////////////////////////////// @@ -209,8 +210,11 @@ function GLRectangle() // get the world var world = this.getWorld(); if (!world) throw( "null world in buildBuffers" ); - + //console.log( "GLRectangle.buildBuffers " + world._worldCount ); if (!world._useWebGL) return; + + // make sure RDGE has the correct context + g_Engine.setContext( world.getCanvas().uuid ); // create the gl buffer var gl = world.getGLContext(); @@ -283,6 +287,7 @@ function GLRectangle() xFill -= strokeSize; yFill -= strokeSize; var fillMaterial = this.makeFillMaterial(); + //console.log( "fillMaterial: " + fillMaterial.getName() ); var fillPrim = this.createFill([x,y], 2*xFill, 2*yFill, tlRadius, blRadius, brRadius, trRadius, fillMaterial); this._primArray.push( fillPrim ); this._materialNodeArray.push( fillMaterial.getMaterialNode() ); @@ -430,7 +435,7 @@ function GLRectangle() this.createStroke = function(ctr, width, height, strokeWidth, tlRad, blRad, brRad, trRad, material) { // create the geometry - var prim = RectangleStroke.create( ctr, width, height, strokeWidth, tlRad, blRad, brRad, trRad) + var prim = RectangleStroke.create( ctr, width, height, strokeWidth, tlRad, blRad, brRad, trRad, material) return prim; } @@ -440,9 +445,9 @@ function GLRectangle() // special the (common) case of no rounded corners var prim if ((tlRad <= 0) && (blRad <= 0) && (brRad <= 0) && (trRad <= 0)) - prim = RectangleGeometry.create( ctr, width, height ); + prim = RectangleGeometry.create( ctr, width, height, material ); else - prim = RectangleFill.create( ctr, width, height, tlRad, blRad, brRad, trRad); + prim = RectangleFill.create( ctr, width, height, tlRad, blRad, brRad, trRad, material); return prim; } @@ -691,7 +696,7 @@ function GLRectangle() } RectangleFill = {}; -RectangleFill.create = function( rectCtr, width, height, tlRad, blRad, brRad, trRad) +RectangleFill.create = function( rectCtr, width, height, tlRad, blRad, brRad, trRad, material) { var x = rectCtr[0], y = rectCtr[1], z = 0.0; var hw = 0.5*width, hh = 0.5*height; @@ -778,6 +783,17 @@ RectangleFill.create = function( rectCtr, width, height, tlRad, blRad, brRad, j++; } + //refine the mesh for vertex deformations + if (material) + { + if (material.hasVertexDeformation()) + { + var paramRange = material.getVertexDeformationRange(); + var tolerance = material.getVertexDeformationTolerance(); + nVertices = ShapePrimitive.refineMesh( this.vertices, this.normals, this.uvs, this.indices, nVertices, paramRange, tolerance ); + } + } + // create the RDGE primitive var prim = ShapePrimitive.create(this.vertices, this.normals, this.uvs, this.indices, g_Engine.getContext().renderer.TRIANGLES, nVertices); return prim; @@ -850,7 +866,7 @@ RectangleFill.getRoundedCorner = function(ctr, startPt, vertices) RectangleStroke = {}; -RectangleStroke.create = function( rectCtr, width, height, strokeWidth, tlRad, blRad, brRad, trRad) +RectangleStroke.create = function( rectCtr, width, height, strokeWidth, tlRad, blRad, brRad, trRad, material) { var x = rectCtr[0], y = rectCtr[1], z = 0.0; var hw = 0.5*width, hh = 0.5*height, sw = strokeWidth; @@ -1041,8 +1057,20 @@ RectangleStroke.create = function( rectCtr, width, height, strokeWidth, tlRad, k++; } + //refine the mesh for vertex deformations + if (material) + { + if (material.hasVertexDeformation()) + { + var paramRange = material.getVertexDeformationRange(); + var tolerance = material.getVertexDeformationTolerance(); + nVertices = ShapePrimitive.refineMesh( this.vertices, this.normals, this.uvs, this.indices, nVertices, paramRange, tolerance ); + } + } + // create the RDGE primitive var prim = ShapePrimitive.create(this.vertices, this.normals, this.uvs, this.indices, g_Engine.getContext().renderer.TRIANGLES, nVertices); + //var prim = ShapePrimitive.create(this.vertices, this.normals, this.uvs, this.indices, g_Engine.getContext().renderer.LINES, nVertices); return prim; } @@ -1085,7 +1113,7 @@ RectangleStroke.getUV = RectangleFill.getUV; // Helper function for generating Three.js geometry RectangleGeometry = {}; -RectangleGeometry.create = function( ctr, width, height ) +RectangleGeometry.create = function( ctr, width, height, material ) { var x = ctr[0], y = ctr[1], z = 0.0; var hw = 0.5*width, hh = 0.5*height; @@ -1123,8 +1151,20 @@ RectangleGeometry.create = function( ctr, width, height ) RectangleGeometry.pushIndices( 2, 1, 0 ); RectangleGeometry.pushIndices( 0, 3, 2 ); + //refine the mesh for vertex deformations + if (material) + { + if (material.hasVertexDeformation()) + { + var paramRange = material.getVertexDeformationRange(); + var tolerance = material.getVertexDeformationTolerance(); + nVertices = ShapePrimitive.refineMesh( this.vertices, this.normals, this.uvs, this.indices, nVertices, paramRange, tolerance ); + } + } + // create the RDGE primitive var prim = ShapePrimitive.create(this.vertices, this.normals, this.uvs, this.indices, g_Engine.getContext().renderer.TRIANGLES, nVertices); + //var prim = ShapePrimitive.create(this.vertices, this.normals, this.uvs, this.indices, g_Engine.getContext().renderer.LINES, nVertices); return prim; } @@ -1193,4 +1233,111 @@ ShapePrimitive.create = function(coords, normals, uvs, indices, primType, ver renderer.createPrimitive(prim, vertexCount); return prim; -} \ No newline at end of file +} + + +ShapePrimitive.refineMesh = function( verts, norms, uvs, indices, nVertices, paramRange, tolerance ) +{ + // get the param range + var pUMin = paramRange[0], pVMin = paramRange[1], + pUMax = paramRange[2], pVMax = paramRange[3]; + var iTriangle = 0; + var nTriangles = indices.length/3; + var index = 0; + while (iTriangle < nTriangles) + { + // get the indices of the 3 vertices + var i0 = indices[index], + i1 = indices[index+1], + i2 = indices[index+2]; + + // get the uv values + //var vrtIndex = 3*iTriangle; + var iuv0 = 2 * i0, + iuv1 = 2 * i1, + iuv2 = 2 * i2; + var u0 = uvs[iuv0], v0 = uvs[iuv0+1], + u1 = uvs[iuv1], v1 = uvs[iuv1+1], + u2 = uvs[iuv2], v2 = uvs[iuv2+1]; + + // find the u and v range + var uMin = u0, vMin = v0; + if (u1 < uMin) uMin = u1; if (v1 < vMin) vMin = v1; + if (u2 < uMin) uMin = u2; if (v2 < vMin) vMin = v2; + var uMax = u0, vMax = v0; + if (u1 > uMax) uMax = u1; if (v1 > vMax) vMax = v1; + if (u2 > uMax) uMax = u2; if (v2 > vMax) vMax = v2; + + // if the parameter range of the triangle is outside the + // desired parameter range, advance to the next polygon and continue + if ((uMin > pUMax) || (uMax < pUMin) || (vMin > pVMax) || (vMax < pVMin)) + { + // go to the next triangle + iTriangle++; + index += 3; + } + else + { + // check thesize of the triangle in uv space. If small enough, advance + // to the next triangle. If not small enough, split the triangle into 3; + var du = uMax - uMin, dv = vMax - vMin; + if ((du < tolerance) && (dv < tolerance)) + { + iTriangle++; + index += 3; + } + else // split the triangle into 4 parts + { + //calculate the position of the new vertex + var iPt0 = 3 * i0, + iPt1 = 3 * i1, + iPt2 = 3 * i2; + var x0 = verts[iPt0], y0 = verts[iPt0+1], z0 = verts[iPt0+2], + x1 = verts[iPt1], y1 = verts[iPt1+1], z1 = verts[iPt1+2], + x2 = verts[iPt2], y2 = verts[iPt2+1], z2 = verts[iPt2+2]; + + // calculate the midpoints of the edges + var xA = (x0 + x1)/2.0, yA = (y0 + y1)/2.0, zA = (z0 + z1)/2.0, + xB = (x1 + x2)/2.0, yB = (y1 + y2)/2.0, zB = (z1 + z2)/2.0, + xC = (x2 + x0)/2.0, yC = (y2 + y0)/2.0, zC = (z2 + z0)/2.0; + + // calculate the uv values of the new coordinates + var uA = (u0 + u1)/2.0, vA = (v0 + v1)/2.0, + uB = (u1 + u2)/2.0, vB = (v1 + v2)/2.0, + uC = (u2 + u0)/2.0, vC = (v2 + v0)/2.0; + + // calculate the normals for the new points + var nx0 = norms[iPt0], ny0 = norms[iPt0+1], nz0 = norms[iPt0+2], + nx1 = norms[iPt1], ny1 = norms[iPt1+1], nz1 = norms[iPt1+2], + nx2 = norms[iPt2], ny2 = norms[iPt2+1], nz2 = norms[iPt2+2]; + var nxA = (nx0 + nx1), nyA = (ny0 + ny1), nzA = (nz0 + nz1); var nrmA = VecUtils.vecNormalize(3, [nxA, nyA, nzA], 1.0 ), + nxB = (nx1 + nx2), nyB = (ny1 + ny2), nzB = (nz1 + nz2); var nrmB = VecUtils.vecNormalize(3, [nxB, nyB, nzB], 1.0 ), + nxC = (nx2 + nx0), nyC = (ny2 + ny0), nzC = (nz2 + nz0); var nrmC = VecUtils.vecNormalize(3, [nxC, nyC, nzC], 1.0 ); + + // push everything + verts.push(xA); verts.push(yA); verts.push(zA); + verts.push(xB); verts.push(yB); verts.push(zB); + verts.push(xC); verts.push(yC); verts.push(zC); + uvs.push(uA), uvs.push(vA); + uvs.push(uB), uvs.push(vB); + uvs.push(uC), uvs.push(vC); + norms.push(nrmA[0]); norms.push(nrmA[1]); norms.push(nrmA[2]); + norms.push(nrmB[0]); norms.push(nrmB[1]); norms.push(nrmB[2]); + norms.push(nrmC[0]); norms.push(nrmC[1]); norms.push(nrmC[2]); + + // split the current triangle into 4 + indices[index+1] = nVertices; indices[index+2] = nVertices+2; + indices.push(nVertices); indices.push(i1); indices.push(nVertices+1); nTriangles++; + indices.push(nVertices+1); indices.push(i2); indices.push(nVertices+2); nTriangles++; + indices.push(nVertices); indices.push(nVertices+1); indices.push(nVertices+2); nTriangles++; + nVertices += 3; + + // by not advancing 'index', we examine the first of the 3 triangles generated above + } + } + } + return nVertices; +} + + + diff --git a/js/helper-classes/RDGE/GLWorld.js b/js/helper-classes/RDGE/GLWorld.js index 59f0bda0..e6e7f466 100644 --- a/js/helper-classes/RDGE/GLWorld.js +++ b/js/helper-classes/RDGE/GLWorld.js @@ -14,6 +14,7 @@ var fragmentShaderSource = ""; var rdgeStarted = false; var nodeCounter = 0; +var worldCounter = 0; /////////////////////////////////////////////////////////////////////// @@ -65,6 +66,14 @@ function GLWorld( canvas, use3D ) this._camera; + // keep a flag indicating whether a render has been completed. + // this allows us to turn off automatic updating if there are + // no animated materials + this._firstRender = true; + + this._worldCount = worldCounter; + worldCounter++; + /////////////////////////////////////////////////////////////////////// // Property accessors /////////////////////////////////////////////////////////////////////// @@ -103,6 +112,8 @@ function GLWorld( canvas, use3D ) this.isWebGL = function() { return this._useWebGL; } + this.getRenderer = function() { return this.renderer; } + //////////////////////////////////////////////////////////////////////////////////// // RDGE // local variables @@ -114,6 +125,10 @@ function GLWorld( canvas, use3D ) this.strokeShader = null; this.renderer = null; + // keep an array of texture maps that need to be loaded + this._texMapsToLoad = []; + this._allMapsLoaded = true; + // this is the node to which objects get hung this._rootNode; @@ -136,6 +151,7 @@ function GLWorld( canvas, use3D ) ctx2 = g_Engine.getContext(); if (ctx1 != ctx2) console.log( "***** different contexts *****" ); this.renderer = ctx1.renderer; + this.renderer._world = this; // create a camera, set its perspective, and then point it at the origin var cam = new camera(); @@ -214,18 +230,160 @@ function GLWorld( canvas, use3D ) { if (this._useWebGL) { + g_Engine.setContext( this._canvas.uuid ); var ctx = g_Engine.getContext(); - //console.log( "RDGE state: " + ctx.ctxStateManager.currentState().name); - + var ctx1 = g_Engine.ctxMan.handleToObject(this._canvas.rdgeCtxHandle); + if (ctx1 != ctx) + console.log( "***** different contexts (2) *****" ); + var aRenderer = ctx1.renderer; var renderer = ctx.renderer; - renderer.disableCulling(); - this.myScene.render(); + if (renderer != aRenderer) + { + console.log( "***** DIFFERENT RENDERERS *****" ); + renderer = aRenderer; + } + + if (renderer.unloadedTextureCount <= 0) + { + renderer.disableCulling(); + //console.log( "GLWorld.draw " + renderer._world._worldCount ); + this.myScene.render(); + + if (this._firstRender) + { + this._firstRender = false; + + if (!this.hasAnimatedMaterials()) + { + //this.myScene.render(); + this._canvas.task.stop(); + //this._renderCount = 10; + } + } + else if (this._renderCount >= 0) + { + this._renderCount--; + if (this._renderCount <= 0) + this._canvas.task.stop(); + } + } } else { this.render(); } } + + this.onRunState = function() + { + console.log( "GLWorld.onRunState" ); + this.restartRenderLoop(); + } + + this.onLoadState = function() + { + console.log( "GLWorld.onLoadState" ); + } + + this.textureToLoad = function( texture ) + { + if (!texture.previouslyReferenced) + { + var name = texture.lookUpName; + texture._world = this; + texture.callback = this.textureMapLoaded; + this._texMapsToLoad[name] = true; + this._allMapsLoaded = false; + + // stop the draw loop until all textures have been loaded + this._canvas.task.stop(); + } + } + + this.textureMapLoaded = function( texture ) + { + var world = texture._world; + if (!world) + { + console.log( "**** loaded texture does not have world defined ****" ); + return; + } + + var name = texture.lookUpName; + if (!world._texMapsToLoad[name]) + { + console.log( "loaded an unregistered texture map: " + name ); + } + else + { + //console.log( "loaded a registered texture map: " + name ); + world._texMapsToLoad[name] = undefined; + } + + // check if all the texture maps are loaded. if so, resume the render loop + world._allMapsLoaded = world.allTextureMapsLoaded(); + if (world._allMapsLoaded) + world._canvas.task.start(); + } + + this.allTextureMapsLoaded = function() + { + for (var name in this._texMapsToLoad) + { + var needsLoad = this._texMapsToLoad[name]; + if (needsLoad) return false; + } + + return true; + } + + this.textureLoadedCallback = function( name ) + { + console.log( "*** material texture loaded: " + name ); + + var world = this._world; + if (!world) + console.log( "**** world not defined for loaded texture map: " + name ); + else + world.textureMapLoaded( name ); + } + + this.hasAnimatedMaterials = function() + { + var root = this.getGeomRoot(); + var rtnVal = false; + if (root) + rtnVal = this.hHasAnimatedMaterials( root ); + + return rtnVal; + } + + this.hHasAnimatedMaterials = function( obj ) + { + if (obj) + { + if (obj.getFillMaterial()) + { + if (obj.getFillMaterial().isAnimated()) return true; + } + + if (obj.getStrokeMaterial()) + { + if (obj.getStrokeMaterial().isAnimated()) return true; + } + + + // do the sibling + var hasAnim = false; + if (obj.getNext()) hasAnim = this.hHasAnimatedMaterials( obj.getNext() ); + if (hasAnim) return true; + if (obj.getChild()) hasAnim = this.hHasAnimatedMaterials( obj.getChild() ); + if (hasAnim) return true; + } + + return false; + } + // END RDGE //////////////////////////////////////////////////////////////////////////////////// @@ -233,23 +391,18 @@ function GLWorld( canvas, use3D ) // start RDGE passing your runtime object, and false to indicate we don't need a an initialization state // in the case of a procedurally built scene an init state is not needed for loading data - //if (this._useWebGL) + if (this._useWebGL) { - if (this._useWebGL) - { - rdgeStarted = true; + rdgeStarted = true; - // TODO - temporary fix for RDGE id's - this._canvas.id = "rdge_" + this._canvas.uuid; + this._canvas.rdgeid = this._canvas.uuid; g_Engine.registerCanvas(this._canvas, this); RDGEStart( this._canvas ); - //this._canvas.fpsTracker = new fpsTracker( '0' ); - //this._canvas.task = new RDGETask(this._canvas, true); - //this._canvas.task.stop() - //this._canvas.task.start() - } + //this._canvas.fpsTracker = new fpsTracker( '0' ); + //this._canvas.task = new RDGETask(this._canvas, false); + this._canvas.task.stop() } } @@ -334,10 +487,6 @@ GLWorld.prototype.addObject = function( obj ) obj.setWorld( this ); - // build the WebGL buffers - if (this._useWebGL) - obj.buildBuffers(); - if (this._geomRoot == null) { this._geomRoot = obj; @@ -349,6 +498,13 @@ GLWorld.prototype.addObject = function( obj ) go.setNext( obj ); obj.setPrev( go ); } + + // build the WebGL buffers + if (this._useWebGL) + { + obj.buildBuffers(); + this.restartRenderLoop(); + } } catch(e) { @@ -356,16 +512,35 @@ GLWorld.prototype.addObject = function( obj ) } } +GLWorld.prototype.restartRenderLoop = function() +{ + //console.log( "restartRenderLoop" ); + + this._firstRender = true; + this._renderCount = -1; + if (this._canvas.task) + { + if (this._allMapsLoaded) + { + //console.log( "starting task" ); + this._canvas.task.start(); + } + else + { + //console.log( "stopping task" ); + this._canvas.task.stop(); + } + } +} + //append to the list of objects if obj doesn't already exist //if obj exists, then don't add to list of objects -GLWorld.prototype.addIfNewObject = function (obj) { +GLWorld.prototype.addIfNewObject = function (obj) +{ if (!obj) return; try { obj.setWorld(this); - // build the WebGL buffers - if (this._useWebGL) - obj.buildBuffers(); if (this._geomRoot == null) { this._geomRoot = obj; @@ -384,8 +559,16 @@ GLWorld.prototype.addIfNewObject = function (obj) { go.setNext(obj); obj.setPrev(go); + } } + + // build the WebGL buffers + if (this._useWebGL) + { + obj.buildBuffers(); + this.restartRenderLoop(); + } } catch (e) { alert("Exception in GLWorld.addIfNewObject " + e); @@ -398,7 +581,7 @@ GLWorld.prototype.clearTree = function() { var root = this._rootNode; root.children = new Array(); - g_Engine.unregisterCanvas( this._canvas.id ) + g_Engine.unregisterCanvas( this._canvas.rdgeid ) this.update( 0 ); this.draw(); @@ -586,7 +769,10 @@ GLWorld.prototype.render = function() } else { - this.draw(); + console.log( "GLWorld.render, " + this._worldCount ); + g_Engine.setContext( this._canvas.uuid ); + //this.draw(); + this.restartRenderLoop(); } } @@ -640,7 +826,7 @@ GLWorld.prototype.getShapeFromPoint = function( offsetX, offsetY ) GLWorld.prototype.export = function() { var exportStr = "GLWorld 1.0\n"; - exportStr += "id: " + this._canvas.id + "\n"; + exportStr += "id: " + this._canvas.rdgeid + "\n"; exportStr += "fov: " + this._fov + "\n"; exportStr += "zNear: " + this._zNear + "\n"; exportStr += "zFar: " + this._zFar + "\n"; diff --git a/js/helper-classes/RDGE/rdge-compiled.js b/js/helper-classes/RDGE/rdge-compiled.js index 4b74aa17..4301200f 100644 --- a/js/helper-classes/RDGE/rdge-compiled.js +++ b/js/helper-classes/RDGE/rdge-compiled.js @@ -1,10 +1,4 @@ -/* -This file contains proprietary software owned by Motorola Mobility, Inc.
-No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
-(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. -
*/ -vec2 = { string: function (a) { return "{ " + a[0] + ", " + a[1] + " }" }, verify: function (a) { return a == void 0 || a.length == void 0 || a.length < 2 ? !1 : typeof a[0] != "number" || typeof a[1] != "number" ? !1 : !0 }, copy: function (a) { return a.length == void 0 ? [a, a] : [a[0], a[1]] }, inplace_copy: function (a, b) { a[0] = b[0]; a[1] = b[1] }, zero: function () { return [0, 0] }, up: function () { return [0, 1] }, right: function () { return [1, 0] }, add: function (a, b) { return [a[0] + b[0], a[1] + b[1]] }, sub: function (a, b) { return [a[0] - b[0], a[1] - b[1]] }, mul: function (a, b) { - return [a[0] * b[0], +vec2={string:function(a){return"{ "+a[0]+", "+a[1]+" }"},verify:function(a){return a==void 0||a.length==void 0||a.length<2?!1:typeof a[0]!="number"||typeof a[1]!="number"?!1:!0},copy:function(a){return a.length==void 0?[a,a]:[a[0],a[1]]},inplace_copy:function(a,b){a[0]=b[0];a[1]=b[1]},zero:function(){return[0,0]},up:function(){return[0,1]},right:function(){return[1,0]},add:function(a,b){return[a[0]+b[0],a[1]+b[1]]},sub:function(a,b){return[a[0]-b[0],a[1]-b[1]]},mul:function(a,b){return[a[0]*b[0], a[1]*b[1]]},addMul:function(a,b,f){return f.length!=void 0&&f.length>=2?[a[0]+b[0]*f[0],a[1]+b[1]*f[1]]:[a[0]+b[0]*f,a[1]+b[1]*f]},scale:function(a,b){return b.length!=void 0&&b.length>=2?[a[0]*b[0],a[1]*b[1]]:[a[0]*b,a[1]*b]},negate:function(a){return[-a[0],-a[1]]},normalize:function(a){var b=Math.sqrt(a[0]*a[0],a[1]*a[1]);return Math.abs(1-b)>1.0E-4?(b=1/b,[a[0]*b,a[1]*b]):a},dot:function(a,b){return a[0]*b[0]+a[1]*b[1]},perp:function(a){return[a[1],-a[0]]},lengthSq:function(a){return a[0]*a[0]+ a[1]*a[1]},length:function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1])},min:function(a,b){return[Math.min(a[0],b[0]),Math.min(a[1],b[1])]},max:function(a,b){return[Math.max(a[0],b[0]),Math.max(a[1],b[1])]}};vec2.clamp=function(a,b,f){return vec2.min(f,vec2.max(a,b))};vec3={string:function(a){return"{ "+a[0]+", "+a[1]+", "+a[2]+" }"},verify:function(a){return a==void 0||a.length==void 0||a.length<3?!1:typeof a[0]!="number"||typeof a[1]!="number"||typeof a[2]!="number"?!1:!0},inplace_copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2]},copy:function(a){return a.length==void 0?[a,a,a]:[a[0],a[1],a[2]]},translation:function(a){return[a[12],a[13],a[14]]},basisX:function(a){return[a[0],a[1],a[2]]},basisY:function(a){return[a[4],a[5],a[6]]},basisZ:function(a){return[a[8], a[9],a[10]]},zero:function(){return[0,0,0]},up:function(){return[0,1,0]},forward:function(){return[0,0,1]},right:function(){return[1,0,0]},random:function(a,b){return[a[0]+(b[0]-a[0])*Math.random(),a[1]+(b[1]-a[1])*Math.random(),a[2]+(b[2]-a[2])*Math.random()]},xy:function(a){return[a[0],a[1]]},xz:function(a){return[a[0],a[2]]},add:function(a,b){return[a[0]+b[0],a[1]+b[1],a[2]+b[2]]},plusEqual:function(a,b){a[0]+=b[0];a[1]+=b[1];a[2]+=b[2]},sub:function(a,b){return[a[0]-b[0],a[1]-b[1],a[2]-b[2]]}, @@ -19,14 +13,14 @@ vec4.equal=function(a,b,f){f||(f=0.0010);return vec4.distanceSq(a,b)=4?b[3]:1;return[a[0]*f+a[4]*g+a[8]*h+a[12]*l,a[1]*f+a[5]*g+a[9]*h+a[13]*l,a[2]*f+a[6]*g+a[10]*h+a[14]*l,a[3]*f+a[7]*g+a[11]*h+a[15]*l]};mat4.transformVector=function(a,b){var a=mat4.inverse(a),f=b[0],g=b[1],h=b[2],l=b.length>=4?b[3]:0;return[a[0]*f+a[1]*g+a[2]*h+a[3]*l,a[4]*f+a[5]*g+a[6]*h+a[7]*l,a[8]*f+a[9]*g+a[10]*h+a[11]*l,a[12]*f+a[13]*g+a[14]*h+a[15]*l]}; mat4.transformPoint4x3=function(a,b){var f=b[0],g=b[1],h=b[2];return[a[0]*f+a[4]*g+a[8]*h+a[12],a[1]*f+a[5]*g+a[9]*h+a[13],a[2]*f+a[6]*g+a[10]*h+a[14],1]};mat4.transformVector4x3=function(a,b){var a=mat4.inverse(a),f=b[0],g=b[1],h=b[2];return[a[0]*f+a[1]*g+a[2]*h,a[4]*f+a[5]*g+a[6]*h,a[8]*f+a[9]*g+a[10]*h,0]};mat4.getRow=function(a,b){b*=4;return[a[b],a[b+1],a[b+2],a[b+3]]};mat4.getCol=function(a,b){return[a[b],a[b+4],a[b+8],a[b+12]]}; @@ -36,7 +30,7 @@ mat4.translateY=function(a,b){return mat4.translate(a,[0,b,0])};mat4.translateZ= b[2]-a[2]*b[1],a[3]*b[1]-a[0]*b[2]+a[1]*b[3]+a[2]*b[0],a[3]*b[2]+a[0]*b[1]-a[1]*b[0]+a[2]*b[3]]},addMul:function(a,b,f){return f.length!=void 0&&f.length>=4?[a[0]+b[0]*f[0],a[1]+b[1]*f[1],a[2]+b[2]*f[2],a[3]+b[3]*f[3]]:[a[0]+b[0]*f,a[1]+b[1]*f,a[2]+b[2]*f,a[3]+b[3]*f]},scale:function(a,b){return b.length!=void 0&&b.length>=4?[a[0]*b[0],a[1]*a[1],a[2]*b[2],a[3]*b[3]]:[a[0]*b,a[1]*b,a[2]*b,a[3]*b]},lengthSq:function(a){return a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]},length:function(a){return Math.sqrt(a[0]* a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3])},normalize:function(a){var b=Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]);return Math.abs(1-b)>1.0E-4?(b=1/b,[a[0]*b,a[1]*b,a[2]*b,a[3]*b]):a},inverse:function(a){var b=vec4.lengthSq(a);return b>1.0E-5?(b=1/b,[a[0]*-b,a[1]*-b,a[2]*-b,a[3]]):a},dot:function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}};quat.applyRotation=function(a,b){return mat4.transformPoint(quat.toMatrix(a),b)}; quat.lerp=function(a,b,f){return quat.normalize([a[0]+(b[0]-a[0])*f,a[1]+(b[1]-a[1])*f,a[2]+(b[2]-a[2])*f,a[3]+(b[3]-a[3])*f])};quat.slerp=function(a,b,f){var g=quat.dot(a,b);if(g>=0.9)return quat.lerp(a,b,f);var h=Math.sqrt(Math.abs(1-g*g));if(h<0.0010)return a;var g=g<0?-1:1,l=Math.asin(h),n=1/h,h=Math.sin((1-f)*l)*n,f=Math.sin(f*l)*n*g;quat.scale(a,h);quat.scale(b,f);return quat.normalize(quat.add(a,b))}; -quat.toMatrix=function(a){var b=2*a[0],f=2*a[1],g=2*a[2],h=b*a[3],l=f*a[3],n=g*a[3];b*=a[0];var o=f*a[0],q=g*a[0];f*=a[1];var p=g*a[1],a=g*a[2];return[1-(f+a),o+n,q-l,0,o-n,1-(b+a),p+h,0,q+l,p-h,1-(b+f),0,0,0,0,1]};var stat=function(){pages={};dlgId="";self=function(a,b,f,g,h){h==void 0&&(h=!0);category=!a?"default":a;pages[category]||(pages[category]=[]);pages[category].push(this);this.name=b;this.value=this.defValue=f;this.func=g;this.reset=h;this.reportInterval=500;stat.dirty=!0;stat.find=function(a,b){var f=pages[a];for(i=0;i'+a+"");g+="";for(a in pages)pages[a]&&(g+='
',g+="
");g+="";f.innerHTML=g;$("#stat_tabs").tabs();stat.dirty=!1}for(a in pages)f=document.getElementById(a),stat.report(f,a,b)};stat.report=function(a,b){b||(b="default");var f=pages[b];if(f){outputHTML='';var g=0;for(i=0;i', outputHTML+=f[i].func?f[i].name+" : "+f[i].func(f[i].value):f[i].name+" : "+f[i].value,outputHTML+="",g++>=3&&(outputHTML+="",g=0),f[i].reset)f[i].value=f[i].defValue;outputHTML+="
";a.innerHTML=outputHTML}}};setInterval(function(){self.reportAll("RDGE_STATS")},500);return self}(); dbCanvas=function(a,b){this.front=document.createElement("canvas");this.front.setAttribute("width",a);this.front.setAttribute("height",b);this.front.setAttribute("style","position:absolute; margin: 0.0em; padding: 0.0em;");this.front.ctx=this.front.getContext("2d");this.back=document.createElement("canvas");this.back.setAttribute("width",a);this.back.setAttribute("height",b);this.front.setAttribute("style","position:absolute; margin: 0.0em; padding: 0.0em;");this.back.ctx=this.back.getContext("2d"); @@ -61,14 +55,15 @@ this.ctx.clearColor(1,0,0,1);this.clearColor=[1,0,0,1];this.clearFlags=this.ctx. 5123;this.INT=5124;this.UNSIGNED_INT=5125;this.FLOAT=5126;this.VS_ELEMENT_FLOAT4=4;this.VS_ELEMENT_FLOAT3=this.VS_ELEMENT_NORM=this.VS_ELEMENT_POS=3;this.VS_ELEMENT_UV=this.VS_ELEMENT_FLOAT2=2;this.VS_ELEMENT_FLOAT=1;this.MAX_ELEM_TYPES=7;this.BUFFER_STATIC=35040;this.BUFFER_DYNAMIC=35044;this.BUFFER_STREAM=35048;this.MAX_MATERIAL_LIGHTS=4;this.usedTextureUnits=5;this.vpY=this.vpX=0;this.vpWidth=a.width;this.vpHeight=a.height;this.cameraMan=new cameraManager;this.buffers=[];this.cullBackFace=function(){this.ctx.cullFace(this.ctx.Back)}; this.cullFrontFace=function(){this.ctx.cullFace(this.ctx.FRONT)};this.disableCulling=function(){this.ctx.disable(this.ctx.CULL_FACE)};this.enableCulling=function(){this.ctx.enable(this.ctx.CULL_FACE)};this.enablePolyOffsetFill=function(){this.ctx.enable(this.ctx.POLYGON_OFFSET_FILL)};this.disablePolyOffsetFill=function(){this.ctx.enable(this.ctx.POLYGON_OFFSET_FILL)};this.enablePointSprites=function(){};this.disablePointSprites=function(){};this.setClearColor=function(a){this.clearColor=a.slice(); this.ctx.clearColor(a[0],a[1],a[2],a[3])};this.setClearFlags=function(a){this.clearFlags=a};this._clear=function(){this.ctx.clear(this.clearFlags)};this.clear=function(a){this.ctx.clear(a)};this.flush=function(){this.ctx.flush()};this.setViewPort=function(a,b,h,l){this.vpX=a;this.vpY=b;this.vpWidth=h;this.vpHeight=l;this.ctx.viewport(this.vpX,this.vpY,this.vpWidth,this.vpHeight)};this.cameraManager=function(){return this.cameraMan};this.textureMap=[];this.rttMap=[];this.getTextureByName=function(a, -b,h){var l=a.split(".")[1],n=this.textureMap[a];if(n===void 0)n=this.createTexture(a+(l?"":".png"),b,h),this.textureMap[a]=n,n.lookUpName=a;return n};_texparams=function(a,b){this.wrap=a;this.mips=b};this.createTexture=function(a,b,h){var l=this.ctx.createTexture();b===void 0&&(b="CLAMP");h===void 0&&(h=!0);if(l)l.image=new Image,l.image.src=a,l.image.context=g_Engine.getContext(),l.texparams=new _texparams(b,h),l.image.onload=function(){this.context.ctxStateManager.RDGEInitState.loadTexture(l)}; -return l};this.commitTexture=function(a){this.ctx.bindTexture(this.ctx.TEXTURE_2D,a);this.ctx.texImage2D(this.ctx.TEXTURE_2D,0,this.ctx.RGBA,this.ctx.RGBA,this.ctx.UNSIGNED_BYTE,a.image);a.texparams.mips&&this.ctx.generateMipmap(this.ctx.TEXTURE_2D);this.ctx.texParameteri(this.ctx.TEXTURE_2D,this.ctx.TEXTURE_MAG_FILTER,this.ctx.LINEAR);this.ctx.texParameteri(this.ctx.TEXTURE_2D,this.ctx.TEXTURE_MIN_FILTER,a.texparams.mips?this.ctx.LINEAR_MIPMAP_LINEAR:this.ctx.LINEAR);this.ctx.texParameteri(this.ctx.TEXTURE_2D, -this.ctx.TEXTURE_WRAP_S,a.texparams.wrap==="REPEAT"?this.ctx.REPEAT:this.ctx.CLAMP_TO_EDGE);this.ctx.texParameteri(this.ctx.TEXTURE_2D,this.ctx.TEXTURE_WRAP_T,a.texparams.wrap==="REPEAT"?this.ctx.REPEAT:this.ctx.CLAMP_TO_EDGE);this.ctx.bindTexture(this.ctx.TEXTURE_2D,null)};this.verify=function(a){var b=this.ctx.getError();b!=0&&window.console.log("GLError ( "+a+") : "+b)};this.createRenderTargetTexture=function(a,b,h,l){var n=this.ctx,o=n.createFramebuffer();n.bindFramebuffer(n.FRAMEBUFFER,o);o.width= -b;o.height=h;b=n.createTexture();n.bindTexture(n.TEXTURE_2D,b);try{n.texImage2D(n.TEXTURE_2D,0,n.RGBA,o.width,o.height,0,n.RGBA,n.UNSIGNED_BYTE,null)}catch(q){h=new WebctxUnsignedByteArray(o.width*o.height*4),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,o.width,o.height,0,n.RGBA,n.UNSIGNED_BYTE,h)}n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,l?n.LINEAR_MIPMAP_NEAREST:n.LINEAR);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE);n.texParameteri(n.TEXTURE_2D, -n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE);l&&n.generateMipmap(n.TEXTURE_2D);l=n.createRenderbuffer();n.bindRenderbuffer(n.RENDERBUFFER,l);n.renderbufferStorage(n.RENDERBUFFER,n.DEPTH_COMPONENT16,o.width,o.height);n.getError(n.bindFramebuffer(n.FRAMEBUFFER,o));n.getError(n.bindRenderbuffer(n.RENDERBUFFER,l));n.getError(n.renderbufferStorage(n.RENDERBUFFER,n.DEPTH_COMPONENT16,o.width,o.height));n.bindRenderbuffer(n.RENDERBUFFER,null);n.getError(n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D, -b,0));n.getError(n.framebufferRenderbuffer(n.FRAMEBUFFER,n.DEPTH_ATTACHMENT,n.RENDERBUFFER,l));n.bindFramebuffer(n.FRAMEBUFFER,null);n.bindTexture(n.TEXTURE_2D,null);n.bindRenderbuffer(n.RENDERBUFFER,null);n.bindFramebuffer(n.FRAMEBUFFER,null);b.id="RT_"+nodeIdGen.getId();b.frameBuffer=o;this.textureMap[a]&&window.console.log("Notification: render target: "+a+" has overwritten an existing render target");return this.textureMap[a]=b};this.defaultShaderDefintion={shaders:{defaultVShader:"assets/shaders/test_vshader.glsl", -defaultFShader:"assets/shaders/test_fshader.glsl"},techniques:{defaultTechnique:[{vshader:"defaultVShader",fshader:"defaultFShader",attributes:{vert:{type:"vec3"},normal:{type:"vec3"},texcoord:{type:"vec2"}},params:{},states:{depthEnable:!0,blendEnable:!1,culling:!0,cullFace:"BACK"}}]}}}; -rdgeDefaultShaderDefintion={shaders:{defaultVShader:"assets/shaders/test_vshader.glsl",defaultFShader:"assets/shaders/test_fshader.glsl"},techniques:{defaultTechnique:[{vshader:"defaultVShader",fshader:"defaultFShader",attributes:{vert:{type:"vec3"},normal:{type:"vec3"},texcoord:{type:"vec2"}},params:{},states:{depthEnable:!0,blendEnable:!1,culling:!0,cullFace:"BACK"}}]}}; +b,h){var l=a.split(".")[1],n=this.textureMap[a];n===void 0?(n=this.createTexture(a+(l?"":".png"),b,h),this.textureMap[a]=n,n.lookUpName=a,n.previouslyReferenced=!1):n.previouslyReferenced=!0;return n};this.unloadedTextureCount=0;_texparams=function(a,b){this.wrap=a;this.mips=b};this.createTexture=function(a,b,h){var l=this.ctx.createTexture();this.unloadedTextureCount++;b===void 0&&(b="CLAMP");h===void 0&&(h=!0);if(l)l.image=new Image,l.image.src=a,l.image.context=g_Engine.getContext(),l.texparams= +new _texparams(b,h),l.image.onload=function(){this.context.ctxStateManager.RDGEInitState.loadTexture(l);this.context.renderer.unloadedTextureCount--;l.callback&&l.callback(l);this.context.renderer.unloadedTextureCount<0&&console.log("more textures loaded then created...")},l.image.onerror=function(){this.context.renderer.unloadedTextureCount--;l.callback&&l.callback(l);this.context.renderer.unloadedTextureCount<0&&console.log("more textures loaded then created...")};return l};this.commitTexture=function(a){this.ctx.bindTexture(this.ctx.TEXTURE_2D, +a);this.ctx.texImage2D(this.ctx.TEXTURE_2D,0,this.ctx.RGBA,this.ctx.RGBA,this.ctx.UNSIGNED_BYTE,a.image);a.texparams.mips&&this.ctx.generateMipmap(this.ctx.TEXTURE_2D);this.ctx.texParameteri(this.ctx.TEXTURE_2D,this.ctx.TEXTURE_MAG_FILTER,this.ctx.LINEAR);this.ctx.texParameteri(this.ctx.TEXTURE_2D,this.ctx.TEXTURE_MIN_FILTER,a.texparams.mips?this.ctx.LINEAR_MIPMAP_LINEAR:this.ctx.LINEAR);this.ctx.texParameteri(this.ctx.TEXTURE_2D,this.ctx.TEXTURE_WRAP_S,a.texparams.wrap==="REPEAT"?this.ctx.REPEAT: +this.ctx.CLAMP_TO_EDGE);this.ctx.texParameteri(this.ctx.TEXTURE_2D,this.ctx.TEXTURE_WRAP_T,a.texparams.wrap==="REPEAT"?this.ctx.REPEAT:this.ctx.CLAMP_TO_EDGE);this.ctx.bindTexture(this.ctx.TEXTURE_2D,null)};this.verify=function(a){var b=this.ctx.getError();b!=0&&window.console.log("GLError ( "+a+") : "+b)};this.createRenderTargetTexture=function(a,b,h,l){var n=this.ctx,o=n.createFramebuffer();n.bindFramebuffer(n.FRAMEBUFFER,o);o.width=b;o.height=h;b=n.createTexture();n.bindTexture(n.TEXTURE_2D,b); +try{n.texImage2D(n.TEXTURE_2D,0,n.RGBA,o.width,o.height,0,n.RGBA,n.UNSIGNED_BYTE,null)}catch(p){h=new WebctxUnsignedByteArray(o.width*o.height*4),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,o.width,o.height,0,n.RGBA,n.UNSIGNED_BYTE,h)}n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,l?n.LINEAR_MIPMAP_NEAREST:n.LINEAR);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE);l&& +n.generateMipmap(n.TEXTURE_2D);l=n.createRenderbuffer();n.bindRenderbuffer(n.RENDERBUFFER,l);n.renderbufferStorage(n.RENDERBUFFER,n.DEPTH_COMPONENT16,o.width,o.height);n.getError(n.bindFramebuffer(n.FRAMEBUFFER,o));n.getError(n.bindRenderbuffer(n.RENDERBUFFER,l));n.getError(n.renderbufferStorage(n.RENDERBUFFER,n.DEPTH_COMPONENT16,o.width,o.height));n.bindRenderbuffer(n.RENDERBUFFER,null);n.getError(n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,b,0));n.getError(n.framebufferRenderbuffer(n.FRAMEBUFFER, +n.DEPTH_ATTACHMENT,n.RENDERBUFFER,l));n.bindFramebuffer(n.FRAMEBUFFER,null);n.bindTexture(n.TEXTURE_2D,null);n.bindRenderbuffer(n.RENDERBUFFER,null);n.bindFramebuffer(n.FRAMEBUFFER,null);b.id="RT_"+nodeIdGen.getId();b.frameBuffer=o;this.textureMap[a]&&window.console.log("Notification: render target: "+a+" has overwritten an existing render target");return this.textureMap[a]=b};this.defaultShaderDefintion={shaders:{defaultVShader:"assets/shaders/test_vshader.glsl",defaultFShader:"assets/shaders/test_fshader.glsl"}, +techniques:{defaultTechnique:[{vshader:"defaultVShader",fshader:"defaultFShader",attributes:{vert:{type:"vec3"},normal:{type:"vec3"},texcoord:{type:"vec2"}},params:{},states:{depthEnable:!0,blendEnable:!1,culling:!0,cullFace:"BACK"}}]}}}; +rdgeDefaultShaderDefintion={shaders:{defaultVShader:"assets/shaders/Basic.vert.glsl",defaultFShader:"assets/shaders/Basic.frag.glsl"},techniques:{defaultTechnique:[{vshader:"defaultVShader",fshader:"defaultFShader",attributes:{vert:{type:"vec3"},normal:{type:"vec3"},texcoord:{type:"vec2"}},params:{},states:{depthEnable:!0,blendEnable:!1,culling:!0,cullFace:"BACK"}}]}}; rdgeDepthMapShaderDef={shaders:{depthMapVShader:"assets/shaders/depthMap_vshader.glsl",depthMapFShader:"assets/shaders/depthMap_fshader.glsl"},techniques:{shadowDepthMap:[{vshader:"depthMapVShader",fshader:"depthMapFShader",attributes:{vert:{type:"vec3"},normal:{type:"vec3"},texcoord:{type:"vec2"}},params:{},states:{depthEnable:!0,blendEnable:!1,culling:!0,cullFace:"BACK"}}],depthMap:[{vshader:"depthMapVShader",fshader:"depthMapFShader",attributes:{vert:{type:"vec3"},normal:{type:"vec3"},texcoord:{type:"vec2"}}, params:{},states:{depthEnable:!0,blendEnable:!1,culling:!0,cullFace:"BACK"}}]}};rdgeViewSpaceNormalsShader={shaders:{normalsVShader:"assets/shaders/norm_depth_vshader.glsl",normalsFShader:"assets/shaders/norm_depth_fshader.glsl"},techniques:{depthMapWNormal:[{vshader:"normalsVShader",fshader:"normalsFShader",attributes:{vert:{type:"vec3"},normal:{type:"vec3"}},params:{},states:{depthEnable:!0,blendEnable:!1,culling:!0,cullFace:"BACK"}}]}}; rdgeScreenQuadShaderDef={shaders:{screenQuadVShader:"\t\t\t\tattribute vec3 a_pos;\t\t\t\tattribute vec2 a_uv;\t\t\t\tuniform float u_inv_viewport_width;\t\t\t\tuniform float u_inv_viewport_height;\t\t\t\tvarying vec2 vTexcoord;\t\t\t\tvoid main()\t\t\t\t{\t\t\t\t\tgl_Position = vec4(a_pos.xy, 0.0, 1.0);\t\t\t\t\t\t\t\tvTexcoord.x = 0.5 * (1.0 + a_pos.x + u_inv_viewport_width);\t\t\t\tvTexcoord.y = 0.5 * (1.0 - a_pos.y + u_inv_viewport_height);\t\t\t\t}",screenQuadFShader:"\t\t\t\tprecision highp float;\t\t\t\tuniform sampler2D u_mainRT;\t\t\t\tuniform sampler2D u_glowFinal;\t\t\t\tuniform sampler2D u_ssaoRT;\t\t\t\tuniform sampler2D u_shadowMap;\t\t\t\tvarying vec2 vTexcoord;\t\t\t\tvoid main()\t\t\t\t{\t\t\t\t vec2 tex = vec2(vTexcoord.x, 1.0 - vTexcoord.y);\t\t\t\t vec4 glowTexel = texture2D(u_glowFinal, tex);\t\t\t\t vec4 ssaoTexel = texture2D(u_ssaoRT, tex);\t\t\t\t vec4 smapCoef = texture2D(u_shadowMap, tex);\t\t\t\t ssaoTexel.a = 0.0;\t\t\t\t vec4 texel\t\t= texture2D(u_mainRT, tex);\t\t\t\t gl_FragColor = vec4(texel.r*((1.0 - glowTexel.r)*smapCoef.r), texel.g*((1.0 - glowTexel.g)*smapCoef.g), texel.b*((1.0 - glowTexel.b)*smapCoef.b), texel.a) + glowTexel - ssaoTexel;\t\t\t\t}"}, @@ -91,61 +86,60 @@ g.bufferUsage):(this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER,this.buffers[a.buffers 0,new Float32Array(a.indexBuffer),a.indexUsage)):this.buffers[a.buffersID].indexHandle=this.createIndexBufferUINT16(a.indexBuffer,a.indexUsage):(this.ctx.bindBuffer(this.ctx.ELEMENT_ARRAY_BUFFER,this.buffers[a.buffersID].indexHandle),this.ctx.bufferSubData(this.ctx.ELEMENT_ARRAY_BUFFER,0,new Float32Array(a.indexBuffer),a.indexUsage)),a.indexCount=b,a.triCount=b/3):a.triCount=a.posCount/3}else this.createPrimitive(a)}; _renderer.prototype.deletePrimitive=function(a){var b=this.buffers[a.buffersID];if(b){var f=this;b.forEach(function(a){f.ctx.deleteBuffer(a)});delete this.buffers[a.buffersID]}};_renderer.prototype.getPrimitiveBuffer=function(a,b){return this.buffers[a.buffersID][b]}; _renderer.prototype.drawPrimitive=function(a,b,f){g_renderStats.numDrawCalls.value++;g_renderStats.numTriangles.value+=Math.floor(a.triCount);g_renderStats.numVerts.value+=Math.floor(a.coordCount/3);a.indexCount?this.drawIndexedPrimitive(a,b,f):this.drawNonIndexedPrimitive(a,b,f);a.useDoubleBuffer===!0&&a.flip(this)}; -_renderer.prototype.drawIndexedPrimitive=function(a,b,f){var g=b=0,h=a.buffersID,l="",n=f.length,o=0,q=a.frontBufferIndex*a.doubleBufferOffset;for(g_Engine.getContext();o0;)for(var b=Math.min(this.lineBuffer.length,this.maxLines),f=0;b>0;){var g=this.lineBuffer.shift(),h=f*6,l=f*8;this.posBufferData[h+0]=g[0][0];this.posBufferData[h+1]=g[0][1];this.posBufferData[h+2]=g[0][2];this.posBufferData[h+3]=g[1][0];this.posBufferData[h+4]=g[1][1];this.posBufferData[h+ 5]=g[1][2];this.colorBufferData[l+0]=g[2][0];this.colorBufferData[l+1]=g[2][1];this.colorBufferData[l+2]=g[2][2];this.colorBufferData[l+3]=g[2][3];this.colorBufferData[l+4]=g[3][0];this.colorBufferData[l+5]=g[3][1];this.colorBufferData[l+6]=g[3][2];this.colorBufferData[l+7]=g[3][3];b--;f++;if(b<=0){this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER,this.posBufferObject);this.ctx.bufferSubData(this.ctx.ARRAY_BUFFER,0,null);this.ctx.bufferSubData(this.ctx.ARRAY_BUFFER,0,this.posBufferData);this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.colorBufferObject);this.ctx.bufferSubData(this.ctx.ARRAY_BUFFER,0,null);this.ctx.bufferSubData(this.ctx.ARRAY_BUFFER,0,this.colorBufferData);this.ctx.disable(this.ctx.DEPTH_TEST);this.shader.begin();this.shader.beginPass(0);this.ctx.enableVertexAttribArray(0);this.ctx.enableVertexAttribArray(1);this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER,this.posBufferObject);this.ctx.vertexAttribPointer(0,3,this.ctx.FLOAT,!1,0,0);this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER,this.colorBufferObject);this.ctx.vertexAttribPointer(1, 4,this.ctx.FLOAT,!1,0,0);this.ctx.drawArrays(this.ctx.LINES,0,f*2);this.shader.endPass();this.shader.end();this.ctx.enable(this.ctx.DEPTH_TEST);a++;this.ctx.finish();this.ctx.flush();break}}};renderUtils={createBox:function(){var a=g_Engine.getContext().renderer,b=new rdgePrimitiveDefinition;b.vertexDefinition={vert:{type:rdgeConstants.VS_ELEMENT_POS,bufferIndex:0,bufferUsage:rdgeConstants.BUFFER_STATIC},a_pos:{type:rdgeConstants.VS_ELEMENT_POS,bufferIndex:0,bufferUsage:rdgeConstants.BUFFER_STATIC},normal:{type:rdgeConstants.VS_ELEMENT_FLOAT3,bufferIndex:1,bufferUsage:rdgeConstants.BUFFER_STATIC},a_nrm:{type:rdgeConstants.VS_ELEMENT_FLOAT3,bufferIndex:1,bufferUsage:rdgeConstants.BUFFER_STATIC}, texcoord:{type:rdgeConstants.VS_ELEMENT_FLOAT2,bufferIndex:2,bufferUsage:rdgeConstants.BUFFER_STATIC},a_uv:{type:rdgeConstants.VS_ELEMENT_FLOAT2,bufferIndex:2,bufferUsage:rdgeConstants.BUFFER_STATIC}};b.bufferStreams=[[1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,