From 648ee61ae84216d0236e0dbc211addc13b2cfa3a Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Fri, 6 Jul 2012 11:52:06 -0700 Subject: Expand tabs --- js/helper-classes/RDGE/src/core/script/jshader.js | 60 +++++++++++------------ 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'js/helper-classes/RDGE/src/core/script/jshader.js') diff --git a/js/helper-classes/RDGE/src/core/script/jshader.js b/js/helper-classes/RDGE/src/core/script/jshader.js index b9170857..f8d79580 100755 --- a/js/helper-classes/RDGE/src/core/script/jshader.js +++ b/js/helper-classes/RDGE/src/core/script/jshader.js @@ -31,46 +31,46 @@ POSSIBILITY OF SUCH DAMAGE. // RDGE namespaces var RDGE = RDGE || {}; -/* +/* this API should be familiar to anyone who has worked with HLSL effect files. */ /* - * A map of types to uniform 'binding' functions + * A map of types to uniform 'binding' functions */ RDGE.bindMap={}; -RDGE.bindMap['int'] = function(ctx, a,b) { ctx.uniform1iv(a,b); }; -RDGE.bindMap['float'] = function(ctx, a,b) { ctx.uniform1fv(a,b); }; -RDGE.bindMap['vec2'] = function(ctx, a,b) { ctx.uniform2fv(a,b); }; -RDGE.bindMap['vec3'] = function(ctx, a,b) { ctx.uniform3fv(a,b); }; -RDGE.bindMap['vec4'] = function(ctx, a,b) { ctx.uniform4fv(a,b); }; -RDGE.bindMap['mat3'] = function(ctx, a,b) { ctx.uniformMatrix3fv(a,false,b); }; -RDGE.bindMap['mat4'] = function(ctx, a,b) +RDGE.bindMap['int'] = function(ctx, a,b) { ctx.uniform1iv(a,b); }; +RDGE.bindMap['float'] = function(ctx, a,b) { ctx.uniform1fv(a,b); }; +RDGE.bindMap['vec2'] = function(ctx, a,b) { ctx.uniform2fv(a,b); }; +RDGE.bindMap['vec3'] = function(ctx, a,b) { ctx.uniform3fv(a,b); }; +RDGE.bindMap['vec4'] = function(ctx, a,b) { ctx.uniform4fv(a,b); }; +RDGE.bindMap['mat3'] = function(ctx, a,b) { ctx.uniformMatrix3fv(a,false,b); }; +RDGE.bindMap['mat4'] = function(ctx, a,b) { - ctx.uniformMatrix4fv(a,false,b); - RDGE.globals.engine.getContext().debug.mat4CallCount++; + ctx.uniformMatrix4fv(a,false,b); + RDGE.globals.engine.getContext().debug.mat4CallCount++; }; -RDGE.bindMap['tex2d'] = function(ctx, a,b) +RDGE.bindMap['tex2d'] = function(ctx, a,b) { - ctx.activeTexture(ctx.TEXTURE0+b[0]); - ctx.bindTexture(ctx.TEXTURE_2D, b[1]); - ctx.uniform1iv(a,[b[0]]); + ctx.activeTexture(ctx.TEXTURE0+b[0]); + ctx.bindTexture(ctx.TEXTURE_2D, b[1]); + ctx.uniform1iv(a,[b[0]]); }; RDGE.bindMap['texCube']=function(ctx, a,b) { - ctx.activeTexture(ctx.TEXTURE0+b[0]); - ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, b[1]); - ctx.uniform1iv(a,[b[0]]); + ctx.activeTexture(ctx.TEXTURE0+b[0]); + ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, b[1]); + ctx.uniform1iv(a,[b[0]]); }; RDGE.lightDataMap = [ - function(ctx, loc, lightNode) { ctx.uniform3fv(loc, lightNode.position); }, - function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightDiffuse); }, - function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightAmbient); }, - function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightSpecular); } + function(ctx, loc, lightNode) { ctx.uniform3fv(loc, lightNode.position); }, + function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightDiffuse); }, + function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightAmbient); }, + function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightSpecular); } ]; RDGE.paramTypeNameMapping = null; @@ -120,7 +120,7 @@ RDGE.jshader = function (addr) { } /* - * private helper functions + * private helper functions */ this.bindParameters = function (pass) { var params = pass.defParamsList; // global parameters to start with @@ -177,7 +177,7 @@ RDGE.jshader = function (addr) { }; /* - * helper function for setting up a texture + * helper function for setting up a texture */ createJShaderTexture = function (ctx, param) { var texHandle = null; @@ -310,9 +310,9 @@ RDGE.jshader = function (addr) { defaultTech = t; var curTechnique = techniques[t]; this[t] = - { - 'passes': [] - }; + { + 'passes': [] + }; var numPasses = curTechnique.length; var i = 0; while (i < numPasses) { @@ -445,7 +445,7 @@ RDGE.jshader = function (addr) { }; /* - * Init a local parameter at any time during the life of the jshader. + * Init a local parameter at any time during the life of the jshader. * This will add the parameter to the list of parameters to be bound * before rendering */ @@ -587,7 +587,7 @@ RDGE.jshader = function (addr) { }; /* - * Set the light nodes used by this jshader + * Set the light nodes used by this jshader * array item 0 corresponds to light 0, item 1 tp light 1 and so on * place null for lights that are not there */ @@ -601,7 +601,7 @@ RDGE.jshader = function (addr) { }; /* - * Called by the system to add material textures settings to the jshader + * Called by the system to add material textures settings to the jshader */ this.setTextureContext = function (textureList) { var passCount = this.technique.passes.length; -- cgit v1.2.3 From 04343eda8c2f870b0da55cfdc8003c99fe1cc4de Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Fri, 6 Jul 2012 11:53:10 -0700 Subject: Remove trailing spaces --- js/helper-classes/RDGE/src/core/script/jshader.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'js/helper-classes/RDGE/src/core/script/jshader.js') diff --git a/js/helper-classes/RDGE/src/core/script/jshader.js b/js/helper-classes/RDGE/src/core/script/jshader.js index f8d79580..123a53e4 100755 --- a/js/helper-classes/RDGE/src/core/script/jshader.js +++ b/js/helper-classes/RDGE/src/core/script/jshader.js @@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. // RDGE namespaces var RDGE = RDGE || {}; -/* +/* this API should be familiar to anyone who has worked with HLSL effect files. */ @@ -45,27 +45,27 @@ RDGE.bindMap['vec2'] = function(ctx, a,b) { ctx.uniform2fv(a,b); }; RDGE.bindMap['vec3'] = function(ctx, a,b) { ctx.uniform3fv(a,b); }; RDGE.bindMap['vec4'] = function(ctx, a,b) { ctx.uniform4fv(a,b); }; RDGE.bindMap['mat3'] = function(ctx, a,b) { ctx.uniformMatrix3fv(a,false,b); }; -RDGE.bindMap['mat4'] = function(ctx, a,b) -{ - ctx.uniformMatrix4fv(a,false,b); +RDGE.bindMap['mat4'] = function(ctx, a,b) +{ + ctx.uniformMatrix4fv(a,false,b); RDGE.globals.engine.getContext().debug.mat4CallCount++; }; -RDGE.bindMap['tex2d'] = function(ctx, a,b) +RDGE.bindMap['tex2d'] = function(ctx, a,b) { ctx.activeTexture(ctx.TEXTURE0+b[0]); ctx.bindTexture(ctx.TEXTURE_2D, b[1]); ctx.uniform1iv(a,[b[0]]); }; -RDGE.bindMap['texCube']=function(ctx, a,b) +RDGE.bindMap['texCube']=function(ctx, a,b) { ctx.activeTexture(ctx.TEXTURE0+b[0]); ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, b[1]); ctx.uniform1iv(a,[b[0]]); }; -RDGE.lightDataMap = +RDGE.lightDataMap = [ function(ctx, loc, lightNode) { ctx.uniform3fv(loc, lightNode.position); }, function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightDiffuse); }, @@ -410,7 +410,7 @@ RDGE.jshader = function (addr) { // link up aliases for (var p in curTechnique[i].params) { if (typeof curTechnique[i].params[p] == 'string') { - // this just redirects to an already existing parameter. + // this just redirects to an already existing parameter. this[t][p] = this[t].passes[i].params[p]; } } @@ -446,7 +446,7 @@ RDGE.jshader = function (addr) { /* * Init a local parameter at any time during the life of the jshader. - * This will add the parameter to the list of parameters to be bound + * This will add the parameter to the list of parameters to be bound * before rendering */ this.initLocalParameter = function (name, param) { @@ -518,7 +518,7 @@ RDGE.jshader = function (addr) { source = vShaderDef; } else { var vshaderRequest = new XMLHttpRequest(); - var urlVertShader = vShaderDef; + var urlVertShader = vShaderDef; vshaderRequest.open("GET", urlVertShader, false); vshaderRequest.send(null); source = vshaderRequest.responseText; -- cgit v1.2.3 From 3644cb6def4f681c99959e5729e78ea353441fad Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Fri, 6 Jul 2012 12:34:53 -0700 Subject: Normalize to unix line terminators --- js/helper-classes/RDGE/src/core/script/jshader.js | 1528 ++++++++++----------- 1 file changed, 764 insertions(+), 764 deletions(-) (limited to 'js/helper-classes/RDGE/src/core/script/jshader.js') diff --git a/js/helper-classes/RDGE/src/core/script/jshader.js b/js/helper-classes/RDGE/src/core/script/jshader.js index 123a53e4..559380e3 100755 --- a/js/helper-classes/RDGE/src/core/script/jshader.js +++ b/js/helper-classes/RDGE/src/core/script/jshader.js @@ -1,764 +1,764 @@ -/* -Copyright (c) 2012, Motorola Mobility, Inc -All Rights Reserved. -BSD License. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of Motorola Mobility nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - */ - -// RDGE namespaces -var RDGE = RDGE || {}; - -/* -this API should be familiar to anyone who has worked with HLSL effect files. -*/ - -/* - * A map of types to uniform 'binding' functions - */ -RDGE.bindMap={}; -RDGE.bindMap['int'] = function(ctx, a,b) { ctx.uniform1iv(a,b); }; -RDGE.bindMap['float'] = function(ctx, a,b) { ctx.uniform1fv(a,b); }; -RDGE.bindMap['vec2'] = function(ctx, a,b) { ctx.uniform2fv(a,b); }; -RDGE.bindMap['vec3'] = function(ctx, a,b) { ctx.uniform3fv(a,b); }; -RDGE.bindMap['vec4'] = function(ctx, a,b) { ctx.uniform4fv(a,b); }; -RDGE.bindMap['mat3'] = function(ctx, a,b) { ctx.uniformMatrix3fv(a,false,b); }; -RDGE.bindMap['mat4'] = function(ctx, a,b) -{ - ctx.uniformMatrix4fv(a,false,b); - RDGE.globals.engine.getContext().debug.mat4CallCount++; -}; - -RDGE.bindMap['tex2d'] = function(ctx, a,b) -{ - ctx.activeTexture(ctx.TEXTURE0+b[0]); - ctx.bindTexture(ctx.TEXTURE_2D, b[1]); - ctx.uniform1iv(a,[b[0]]); -}; - -RDGE.bindMap['texCube']=function(ctx, a,b) -{ - ctx.activeTexture(ctx.TEXTURE0+b[0]); - ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, b[1]); - ctx.uniform1iv(a,[b[0]]); -}; - -RDGE.lightDataMap = -[ - function(ctx, loc, lightNode) { ctx.uniform3fv(loc, lightNode.position); }, - function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightDiffuse); }, - function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightAmbient); }, - function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightSpecular); } -]; - -RDGE.paramTypeNameMapping = null; - -RDGE.jshader = function (addr) { - this.name = addr; - this.def = null; - this.technique = {}; - this.params = {}; - this.compiledShaders = {}; - this.resetRS = false; - this.currentPass = 0; - this.type_jshader = {}; - this.global = {}; - this.renderer = RDGE.globals.engine.getContext().renderer; - this.ctx = this.renderer.ctx; - - // load jshader definition at addr (if provided) - if (addr != undefined && addr != null) { - // a synchronous ajax request - request = new XMLHttpRequest(); - request.open("GET", addr, false); - request.send(null); - this.def = JSON.parse(request.responseText); - } - - if (!RDGE.paramTypeNameMapping) { - var gl = this.ctx; - RDGE.paramTypeNameMapping = {}; - RDGE.paramTypeNameMapping[gl.BOOL] = "bool"; - RDGE.paramTypeNameMapping[gl.INT] = "int"; - RDGE.paramTypeNameMapping[gl.FLOAT] = "float"; - RDGE.paramTypeNameMapping[gl.FLOAT_VEC2] = "vec2"; - RDGE.paramTypeNameMapping[gl.FLOAT_VEC3] = "vec3"; - RDGE.paramTypeNameMapping[gl.FLOAT_VEC4] = "vec4"; - RDGE.paramTypeNameMapping[gl.INT_VEC2] = "vec2"; - RDGE.paramTypeNameMapping[gl.INT_VEC3] = "vec3"; - RDGE.paramTypeNameMapping[gl.INT_VEC4] = "vec4"; - RDGE.paramTypeNameMapping[gl.BOOL_VEC2] = "vec2"; - RDGE.paramTypeNameMapping[gl.BOOL_VEC3] = "vec3"; - RDGE.paramTypeNameMapping[gl.BOOL_VEC4] = "vec4"; - RDGE.paramTypeNameMapping[gl.FLOAT_MAT2] = "mat2"; - RDGE.paramTypeNameMapping[gl.FLOAT_MAT3] = "mat3"; - RDGE.paramTypeNameMapping[gl.FLOAT_MAT4] = "mat4"; - RDGE.paramTypeNameMapping[gl.SAMPLER_2D] = "tex2d"; - RDGE.paramTypeNameMapping[gl.SAMPLER_CUBE] = "texCube"; - } - - /* - * private helper functions - */ - this.bindParameters = function (pass) { - var params = pass.defParamsList; // global parameters to start with - var lightParams = pass.lightParams; - var lightContext = pass.lightContext; - var length = params.length; - var idx = 0; - var texArg = new Array(2) - - // global parameters - var texUnit = 0; - for (idx = 0; idx < length; ++idx) { - if (params[idx].type == 'tex2d' || params[idx].type == 'texCube') { - texArg[0] = texUnit++; - texArg[1] = params[idx].data[0]; - RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, texArg); - } - else { - RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, RDGE.rdgeGlobalParameters[params[idx].name].data); - } - } - - // light settings defined by the material - var len = RDGE.rdgeConstants.MAX_MATERIAL_LIGHTS; - for (var i = 0; i < len; ++i) { - // if there is a context for a light check to see if we have a binding to the light - if (lightContext[i] != null) { - // see if we have parameters to bind to this light - if (lightParams[i]) { - // something is here lets bind it - var numParams = lightParams[i].length; - for (var lp = 0; lp < numParams; ++lp) { - // bind the parameters using the lightDataMap function lookup, dataIndex is the key - RDGE.lightDataMap[lightParams[i][lp].dataIndex](this.ctx, lightParams[i][lp].loc, lightContext[i]); - } - } - } - } - - // let locally defined uniforms stomp globally defined uniforms - texUnit = this.renderer.usedTextureUnits; // start adding texture after the default textures - params = pass.paramsList; - length = params.length; - for (idx = 0; idx < length; ++idx) { - if (params[idx].type == 'tex2d' || params[idx].type == 'texCube') { - texArg[0] = texUnit++; - texArg[1] = params[idx].data[0]; - RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, texArg); - } - else { - RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, params[idx].data); - } - } - }; - - /* - * helper function for setting up a texture - */ - createJShaderTexture = function (ctx, param) { - var texHandle = null; - if (typeof param.data == "string") { - texHandle = ctx.canvas.renderer.getTextureByName(param.data, param.wrap, param.repeat, param.mips); - } - else { - texHandle = ctx.canvas.renderer.getTextureByName(param.data.lookUpName, param.wrap, param.repeat, param.mips); - } - - return [texHandle]; - }; - - paramType = function (ctx, name, def, program, technique) { - var texUnit = 0; - - // Get the uniform location and store it - this.loc = ctx.getUniformLocation(program, name); - - // if the parameter does not exist in the shader cull it from the pass - if (this.loc == null) { - window.console.log("ctx:" + ctx.canvas.rdgeid + ", technique: " + technique + ", uniform: " + name + " was not found, jshader param will have no affect"); - //return; - } - - var param = def[name]; - this.type = param.type; - - // if data was not provided then create default data - if (param.data == undefined) { - switch (param.type) { - case "vec4": this.data = RDGE.vec4.zero(); break; - case "vec3": this.data = RDGE.vec3.zero(); break; - case "vec2": this.data = RDGE.vec2.zero(); break; - case "mat4": this.data = RDGE.mat4.zero(); break; - case "mat3": this.data = new Array(9); break; - case "mat2": this.data = [0, 0, 0, 0]; break; - case "float": this.data = [0]; break; - case "int": this.data = [0]; break; - case "tex2d": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; - case "texCube": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; - } - } - else { - if (param.type == 'tex2d' || param.type == 'texCube') { - this.data = createJShaderTexture(ctx, param); - } - else { - this.data = param.data.slice(); - } - } - - this.get = function () { - return this.data.slice(); - }; - - this.set = function (v) { - if (this.type == 'tex2d' || this.type == 'texCube') { - if (typeof v == "string") { - v = ctx.canvas.renderer.getTextureByName(v); - } - - this.data[0] = v; - } - else { - var len = this.data.length; - for (var i = 0; i < len; ++i) - this.data[i] = v[i]; - } - }; - }; - - globalParam = function (ctx, name, param, program) { - this.type = param.type; - - this.data = param.data; - - // Get the uniform location and store it - this.loc = ctx.getUniformLocation(program, name); - - // if data was not provided then create default data - if (!this.data) { - switch (param.type) { - case "vec4": this.data = RDGE.vec4.zero(); break; - case "vec3": this.data = RDGE.vec3.zero(); break; - case "vec2": this.data = RDGE.vec2.zero(); break; - case "mat4": this.data = RDGE.mat4.zero(); break; - case "mat3": this.data = new Array(9); break; - case "mat2": this.data = [0, 0, 0, 0]; break; - case "float": this.data = [0]; break; - case "int": this.data = [0]; break; - case "tex2d": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; - case "texCube": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; - } - } - else { - if (param.type == 'tex2d' || param.type == 'texCube') { - this.data = createJShaderTexture(ctx, param); - } - else { - this.data = param.data.slice(); - } - } - - this.get = function () { - return this.data.slice(); - }; - - this.set = function (v) { - if (this.type == 'tex2d' || this.type == 'texCube') { - if (typeof v == "string") { - v = ctx.canvas.renderer.getTextureByName(v); - } - - this.data[0] = v; - } - else { - var len = this.data.length; - for (var i = 0; i < len; ++i) - this.data[i] = v[i]; - } - }; - }; - - - this.init = function () { - var techniques = this.def.techniques; - var defaultTech = null; - for (t in techniques) { - defaultTech = t; - var curTechnique = techniques[t]; - this[t] = - { - 'passes': [] - }; - var numPasses = curTechnique.length; - var i = 0; - while (i < numPasses) { - var program = this.buildProgram(curTechnique[i]); - this.ctx.useProgram(program); - - // automatically create a parameter def for every active attribute in the shader. - var numAttribs = this.ctx.getProgramParameter(program, this.ctx.ACTIVE_ATTRIBUTES); - for (j = 0; j < numAttribs; ++j) { - var attribInfo = this.ctx.getActiveAttrib(program, j); - curTechnique[i].attributes[attribInfo.name] = { 'type': RDGE.paramTypeNameMapping[attribInfo.type] }; - } - // automatically create a parameter def for every active uniform in the shader. - var numUniforms = this.ctx.getProgramParameter(program, this.ctx.ACTIVE_UNIFORMS); - for (j = 0; j < numUniforms; ++j) { - var uniformInfo = this.ctx.getActiveUniform(program, j); - if (!RDGE.rdgeGlobalParameters[uniformInfo.name]) { - curTechnique[i].params[uniformInfo.name] = { 'type': RDGE.paramTypeNameMapping[uniformInfo.type] }; - } - } - - program.ctxId = this.ctx.canvas.rdgeid; - if (!program) { - this.renderer.console.log("Build errors found in technique: " + t); - this.def[t] = null; // remove bad technique - break; - } else { - this[t].passes.push({ "program": program, "params": {}, "defParams": {}, "states": curTechnique[i].states, "attributes": curTechnique[i].attribPairs }); - } - - // init default parameters - for (var p in RDGE.rdgeGlobalParameters) { - var gp = new globalParam(this.ctx, p, RDGE.rdgeGlobalParameters[p], program); - - if (gp.loc != null) { - gp.loc.ctxID = this.ctx.canvas.rdgeid; - this[t].passes[i].defParams[p] = gp; - this.global[p] = gp; - } - } - - // attach light parameters and container to light context - this[t].passes[i].lightParams = [null, null, null, null]; - this[t].passes[i].lightContext = [null, null, null, null]; - - // attach a parameter list that will be used to optimize binding attributes - if (!this[t].passes[i].paramsList) - this[t].passes[i].paramsList = []; - - // locate individual light parameters to bind with local context - var totalLights = RDGE.rdgeConstants.MAX_MATERIAL_LIGHTS; - for (var lightIdx = 0; lightIdx < totalLights; ++lightIdx) { - - // clear parameter - this[t].passes[i].lightParams[lightIdx] = null; - - // 0 = pos, 1 = diff, 2 = amb, 3 = spec - // this is order assumed for light parameters - - // the parameter index key - lets us know which piece of data we are getting/setting - var lightDataIndex = 0; - - for (var lp in RDGE.globals.engine.lightManager.lightUniforms[lightIdx]) { - loc = this.ctx.getUniformLocation(program, lp); - - // if item found enable this light param and set parameters to bind and lookup data - if (loc != null) { - if (!this[t].passes[i].lightParams[lightIdx]) - this[t].passes[i].lightParams[lightIdx] = []; - - this[t].passes[i].lightParams[lightIdx].push({ 'loc': loc, 'name': lp, 'dataIndex': lightDataIndex }); - } - - lightDataIndex++; - } - } - - - - // init user defined parameters - for (var p in curTechnique[i].params) { - if (typeof curTechnique[i].params[p] == 'string') { - continue; - } - - var newParam = new paramType(this.ctx, p, curTechnique[i].params, program, t); - - // if(newParam.loc != null) - // { - this[t].passes[i].params[p] = newParam; - this[t][p] = newParam; - // } - } - - // link up aliases - for (var p in curTechnique[i].params) { - if (typeof curTechnique[i].params[p] == 'string') { - // this just redirects to an already existing parameter. - this[t][p] = this[t].passes[i].params[p]; - } - } - - i++; - } - } - - // create linear lists of parameters - optimization - for (t in techniques) { - var numPasses = this[t].passes.length; - - for (var i = 0; i < numPasses; ++i) { - - this[t].passes[i].defParamsList = []; - - for (var p in this[t].passes[i].params) { - var param = this[t].passes[i].params[p]; - param.name = p; - this[t].passes[i].paramsList.push(param); - } - - for (var p in this[t].passes[i].defParams) { - var param = this[t].passes[i].defParams[p]; - param.name = p; - this[t].passes[i].defParamsList.push(param); - } - } - } - - this.setTechnique(defaultTech); - }; - - /* - * Init a local parameter at any time during the life of the jshader. - * This will add the parameter to the list of parameters to be bound - * before rendering - */ - this.initLocalParameter = function (name, param) { - var techniques = this.def.techniques; - for (t in techniques) { - var curTechnique = techniques[t]; - var numPasses = curTechnique.length; - var i = 0; - while (i < numPasses) { - var newParam = new paramType(this.ctx, name, param, curTechnique[i].program, t); - if (newParam) { - curTechnique[i][name] = newParam; - - // this params list is created here because a parameter could be added before the jshader is initialized - if (!curTechnique[i].paramsList) - curTechnique[i].paramsList = []; - - curTechnique[i].paramsList.push(newParam); - } - - i++; - } - } - }; - - this.buildShader = function (shaderType, shaderStr) { - // pre-pend preprocessor settings - var preProcessor = "#define PC\n" - preProcessor += shaderStr; - shaderStr = preProcessor; - - // Create the shader object - var shader = this.ctx.createShader(shaderType); - if (shader == null) { - this.renderer.console.log("*** Error: unable to create shader '" + shaderType + "'"); - return null; - } - - // Load the shader source - this.ctx.shaderSource(shader, shaderStr); - - // Compile the shader - this.ctx.compileShader(shader); - - // Check the compile status - var compiled = this.ctx.getShaderParameter(shader, this.ctx.COMPILE_STATUS); - if (!compiled) { - // compile failed, report error. - var error = this.ctx.getShaderInfoLog(shader); - window.console.error("*** Error compiling shader '" + shaderType + "':" + error); - this.ctx.deleteShader(shader); - return null; - } - - return shader; - }; - - this.buildProgram = function (t) { - window.console.log("building shader pair: <" + t.vshader + ", " + t.fshader + ">"); - var vShaderDef = RDGE.globals.engine.remapAssetFolder(this.def.shaders[t.vshader]); - var fShaderDef = RDGE.globals.engine.remapAssetFolder(this.def.shaders[t.fshader]); - - this.ctx.useProgram(null); - - var vertexShader = null; - var source = null; - - if (vShaderDef.indexOf('{') != -1) { - source = vShaderDef; - } else { - var vshaderRequest = new XMLHttpRequest(); - var urlVertShader = vShaderDef; - vshaderRequest.open("GET", urlVertShader, false); - vshaderRequest.send(null); - source = vshaderRequest.responseText; - } - - vertexShader = this.buildShader(this.ctx.VERTEX_SHADER, source); - - var fragmentShader = null; - var source = null; - if (vShaderDef.indexOf('{') != -1) { - source = fShaderDef; - } else { - var vshaderRequest = new XMLHttpRequest(); - var urlFragShader = fShaderDef; - vshaderRequest.open("GET", urlFragShader, false); - vshaderRequest.send(null); - source = vshaderRequest.responseText; - } - - fragmentShader = this.buildShader(this.ctx.FRAGMENT_SHADER, source); - - if (!vertexShader || !fragmentShader) { - return null; - } - - this.compiledShaders[t.vshader] = vertexShader; - this.compiledShaders[t.fshader] = fragmentShader; - - // Create the program object - var program = this.ctx.createProgram(); - if (!program) { - return null; - } - - // Attach our two shaders to the program - this.ctx.attachShader(program, vertexShader); - this.ctx.attachShader(program, fragmentShader); - - // Bind attributes - var idx = 0; - t.attribPairs = []; - for (var i in t.attributes) { - t.attribPairs.push({ 'loc': idx, 'name': i }); - this.ctx.bindAttribLocation(program, idx++, i); - } - - // Link the program - this.ctx.linkProgram(program); - - // Check the link status - var linked = this.ctx.getProgramParameter(program, this.ctx.LINK_STATUS); - if (!linked) { - // failed to link - var error = this.ctx.getProgramInfoLog(program); - - window.console.log("Error in program linking:" + error); - - this.ctx.deleteProgram(program); - this.ctx.deleteProgram(fragmentShader); - this.ctx.deleteProgram(vertexShader); - - return null; - } - - return program; - }; - - /* - * Set the light nodes used by this jshader - * array item 0 corresponds to light 0, item 1 tp light 1 and so on - * place null for lights that are not there - */ - this.setLightContext = function (lightRefArray) { - for (t in this.technique) { - var len = this.technique.passes.length; - for (var i = 0; i < len; ++i) { - this.technique.passes[i].lightContext = lightRefArray.slice(); - } - } - }; - - /* - * Called by the system to add material textures settings to the jshader - */ - this.setTextureContext = function (textureList) { - var passCount = this.technique.passes.length; - var param = null; - - for (var t = 0, texCount = textureList.length; t < texCount; ++t) { - for (var i = 0; i < passCount; ++i) { - var param = textureList[t]; - - // set the rdge global parameters if the texture is in the list - if (this.technique.passes[i].defParams[param.name]) - this.technique.passes[i].defParams[param.name].set(param.handle); - - // and set the local parameters if the texture is in the list - if (this.technique.passes[i].params[param.name]) - this.technique.passes[i].params[param.name].set(param.data[0]); - } - } - }; - - this.setTechnique = function (name) { - if (this[name] != undefined) { - this.technique = this[name]; - return true; - } - - this.ctx.console.log("Failed to set technique:" + name); - return false; - }; - - this.beginRenderState = function (i) { - var states = this.technique.passes[i].states; - if (states == undefined) { - return; - } - - // depth enabled by default. - var depthEnable = states.depthEnable != undefined ? states.depthEnable : true; - if (!depthEnable) { - this.ctx.disable(this.ctx.DEPTH_TEST); - var depthFunc = states.depthFunc != undefined ? states.depthFunc : "LESS"; - this.ctx.depthFunc(this.ctx[states.depthFunc]); - this.ctx.depthMask(true); - } - else { - - if (states.depthFunc) { - this.ctx.depthFunc(this.ctx[states.depthFunc]); - } - - if (states.offset) { - this.ctx.enable(this.ctx.POLYGON_OFFSET_FILL); - this.ctx.polygonOffset(states.offset[0], states.offset[1]); - } - - // depth write - if (states.depthWrite) { - this.ctx.depthMask(states.depthWrite); - } - - if (states.depthRangeMin) { - this.ctx.depthRange(states.depthRangeMin); - } - - if (states.depthRangeMax) { - this.ctx.depthRange(states.depthRangeMax); - } - } - - // blend enabled by default. - var blendEnabled = states.blendEnable != undefined ? states.blendEnable : false; - if (blendEnabled) { - var srcBlend = states.srcBlend != undefined ? states.srcBlend : "ONE"; // default src blend - var dstBlend = states.dstBlend != undefined ? states.dstBlend : "ZERO"; // default dst blend - this.ctx.enable(this.ctx.BLEND); - this.ctx.blendFunc(this.ctx[srcBlend], this.ctx[dstBlend]); - } - - if (states.culling) { - if (states.culling) - this.ctx.enable(this.ctx.CULL_FACE); - else - this.ctx.disable(this.ctx.CULL_FACE); - - } - - if (states.cullFace) { - this.ctx.cullFace(this.ctx[states.cullFace]); - } - - if (states.pointsprite) { - if (states.pointsprite === true) - this.renderer.enablePointSprites(); - else - this.renderer.disablePointSprites(); - } - - this.resetRS = this.technique.passes[i].states.reset == undefined || this.technique.passes[i].states.reset == true; - }; - - this.endRenderState = function () { - // restore render states to some default state. - var ctx = this.ctx; - if (this.resetRS) { - ctx.enable(this.ctx.DEPTH_TEST); - ctx.disable(this.ctx.BLEND); - ctx.depthFunc(this.ctx.LESS); - ctx.disable(this.ctx.POLYGON_OFFSET_FILL); - ctx.disable(this.ctx.CULL_FACE); - // this.renderer.disablePointSprites(); - //ctx.enable(ctx.CULL_FACE); - //ctx.cullFace(ctx.BACK); - } - }; - - this.begin = function () { - this.currentPass = null; - if (this.def == null || this.technique == null) { - return 0; - } - return this.technique.passes.length; - }; - - this.beginPass = function (i) { - this.currentPass = this.technique.passes[i]; - this.ctx.useProgram(this.currentPass.program); - this.bindParameters(this.currentPass); - this.beginRenderState(i); - return this.currentPass; - }; - - this.endPass = function () { - this.endRenderState(); - this.ctx.useProgram(null); - }; - - this.end = function () { - }; - - this.exportShader = function () { - - for (t in this.def.techniques) { - var numPasses = this[t].passes.length; - - for (var i = 0; i < numPasses; ++i) { - this[t].passes[i].paramsList = []; - this[t].passes[i].defParamsList = []; - - for (var p in this[t].passes[i].params) { - var tech = this.def.techniques[t][i]; - if (tech && this[t].passes[i].params[p].type != "tex2d" && this[t].passes[i].params[p] != "texCube") - tech.params[p].data = this[t].passes[i].params[p].data; - } - } - } - - return JSON.stringify(this.def); - - } -}; +/* +Copyright (c) 2012, Motorola Mobility, Inc +All Rights Reserved. +BSD License. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of Motorola Mobility nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + */ + +// RDGE namespaces +var RDGE = RDGE || {}; + +/* +this API should be familiar to anyone who has worked with HLSL effect files. +*/ + +/* + * A map of types to uniform 'binding' functions + */ +RDGE.bindMap={}; +RDGE.bindMap['int'] = function(ctx, a,b) { ctx.uniform1iv(a,b); }; +RDGE.bindMap['float'] = function(ctx, a,b) { ctx.uniform1fv(a,b); }; +RDGE.bindMap['vec2'] = function(ctx, a,b) { ctx.uniform2fv(a,b); }; +RDGE.bindMap['vec3'] = function(ctx, a,b) { ctx.uniform3fv(a,b); }; +RDGE.bindMap['vec4'] = function(ctx, a,b) { ctx.uniform4fv(a,b); }; +RDGE.bindMap['mat3'] = function(ctx, a,b) { ctx.uniformMatrix3fv(a,false,b); }; +RDGE.bindMap['mat4'] = function(ctx, a,b) +{ + ctx.uniformMatrix4fv(a,false,b); + RDGE.globals.engine.getContext().debug.mat4CallCount++; +}; + +RDGE.bindMap['tex2d'] = function(ctx, a,b) +{ + ctx.activeTexture(ctx.TEXTURE0+b[0]); + ctx.bindTexture(ctx.TEXTURE_2D, b[1]); + ctx.uniform1iv(a,[b[0]]); +}; + +RDGE.bindMap['texCube']=function(ctx, a,b) +{ + ctx.activeTexture(ctx.TEXTURE0+b[0]); + ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, b[1]); + ctx.uniform1iv(a,[b[0]]); +}; + +RDGE.lightDataMap = +[ + function(ctx, loc, lightNode) { ctx.uniform3fv(loc, lightNode.position); }, + function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightDiffuse); }, + function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightAmbient); }, + function(ctx, loc, lightNode) { ctx.uniform4fv(loc, lightNode.lightSpecular); } +]; + +RDGE.paramTypeNameMapping = null; + +RDGE.jshader = function (addr) { + this.name = addr; + this.def = null; + this.technique = {}; + this.params = {}; + this.compiledShaders = {}; + this.resetRS = false; + this.currentPass = 0; + this.type_jshader = {}; + this.global = {}; + this.renderer = RDGE.globals.engine.getContext().renderer; + this.ctx = this.renderer.ctx; + + // load jshader definition at addr (if provided) + if (addr != undefined && addr != null) { + // a synchronous ajax request + request = new XMLHttpRequest(); + request.open("GET", addr, false); + request.send(null); + this.def = JSON.parse(request.responseText); + } + + if (!RDGE.paramTypeNameMapping) { + var gl = this.ctx; + RDGE.paramTypeNameMapping = {}; + RDGE.paramTypeNameMapping[gl.BOOL] = "bool"; + RDGE.paramTypeNameMapping[gl.INT] = "int"; + RDGE.paramTypeNameMapping[gl.FLOAT] = "float"; + RDGE.paramTypeNameMapping[gl.FLOAT_VEC2] = "vec2"; + RDGE.paramTypeNameMapping[gl.FLOAT_VEC3] = "vec3"; + RDGE.paramTypeNameMapping[gl.FLOAT_VEC4] = "vec4"; + RDGE.paramTypeNameMapping[gl.INT_VEC2] = "vec2"; + RDGE.paramTypeNameMapping[gl.INT_VEC3] = "vec3"; + RDGE.paramTypeNameMapping[gl.INT_VEC4] = "vec4"; + RDGE.paramTypeNameMapping[gl.BOOL_VEC2] = "vec2"; + RDGE.paramTypeNameMapping[gl.BOOL_VEC3] = "vec3"; + RDGE.paramTypeNameMapping[gl.BOOL_VEC4] = "vec4"; + RDGE.paramTypeNameMapping[gl.FLOAT_MAT2] = "mat2"; + RDGE.paramTypeNameMapping[gl.FLOAT_MAT3] = "mat3"; + RDGE.paramTypeNameMapping[gl.FLOAT_MAT4] = "mat4"; + RDGE.paramTypeNameMapping[gl.SAMPLER_2D] = "tex2d"; + RDGE.paramTypeNameMapping[gl.SAMPLER_CUBE] = "texCube"; + } + + /* + * private helper functions + */ + this.bindParameters = function (pass) { + var params = pass.defParamsList; // global parameters to start with + var lightParams = pass.lightParams; + var lightContext = pass.lightContext; + var length = params.length; + var idx = 0; + var texArg = new Array(2) + + // global parameters + var texUnit = 0; + for (idx = 0; idx < length; ++idx) { + if (params[idx].type == 'tex2d' || params[idx].type == 'texCube') { + texArg[0] = texUnit++; + texArg[1] = params[idx].data[0]; + RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, texArg); + } + else { + RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, RDGE.rdgeGlobalParameters[params[idx].name].data); + } + } + + // light settings defined by the material + var len = RDGE.rdgeConstants.MAX_MATERIAL_LIGHTS; + for (var i = 0; i < len; ++i) { + // if there is a context for a light check to see if we have a binding to the light + if (lightContext[i] != null) { + // see if we have parameters to bind to this light + if (lightParams[i]) { + // something is here lets bind it + var numParams = lightParams[i].length; + for (var lp = 0; lp < numParams; ++lp) { + // bind the parameters using the lightDataMap function lookup, dataIndex is the key + RDGE.lightDataMap[lightParams[i][lp].dataIndex](this.ctx, lightParams[i][lp].loc, lightContext[i]); + } + } + } + } + + // let locally defined uniforms stomp globally defined uniforms + texUnit = this.renderer.usedTextureUnits; // start adding texture after the default textures + params = pass.paramsList; + length = params.length; + for (idx = 0; idx < length; ++idx) { + if (params[idx].type == 'tex2d' || params[idx].type == 'texCube') { + texArg[0] = texUnit++; + texArg[1] = params[idx].data[0]; + RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, texArg); + } + else { + RDGE.bindMap[params[idx].type](this.ctx, params[idx].loc, params[idx].data); + } + } + }; + + /* + * helper function for setting up a texture + */ + createJShaderTexture = function (ctx, param) { + var texHandle = null; + if (typeof param.data == "string") { + texHandle = ctx.canvas.renderer.getTextureByName(param.data, param.wrap, param.repeat, param.mips); + } + else { + texHandle = ctx.canvas.renderer.getTextureByName(param.data.lookUpName, param.wrap, param.repeat, param.mips); + } + + return [texHandle]; + }; + + paramType = function (ctx, name, def, program, technique) { + var texUnit = 0; + + // Get the uniform location and store it + this.loc = ctx.getUniformLocation(program, name); + + // if the parameter does not exist in the shader cull it from the pass + if (this.loc == null) { + window.console.log("ctx:" + ctx.canvas.rdgeid + ", technique: " + technique + ", uniform: " + name + " was not found, jshader param will have no affect"); + //return; + } + + var param = def[name]; + this.type = param.type; + + // if data was not provided then create default data + if (param.data == undefined) { + switch (param.type) { + case "vec4": this.data = RDGE.vec4.zero(); break; + case "vec3": this.data = RDGE.vec3.zero(); break; + case "vec2": this.data = RDGE.vec2.zero(); break; + case "mat4": this.data = RDGE.mat4.zero(); break; + case "mat3": this.data = new Array(9); break; + case "mat2": this.data = [0, 0, 0, 0]; break; + case "float": this.data = [0]; break; + case "int": this.data = [0]; break; + case "tex2d": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; + case "texCube": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; + } + } + else { + if (param.type == 'tex2d' || param.type == 'texCube') { + this.data = createJShaderTexture(ctx, param); + } + else { + this.data = param.data.slice(); + } + } + + this.get = function () { + return this.data.slice(); + }; + + this.set = function (v) { + if (this.type == 'tex2d' || this.type == 'texCube') { + if (typeof v == "string") { + v = ctx.canvas.renderer.getTextureByName(v); + } + + this.data[0] = v; + } + else { + var len = this.data.length; + for (var i = 0; i < len; ++i) + this.data[i] = v[i]; + } + }; + }; + + globalParam = function (ctx, name, param, program) { + this.type = param.type; + + this.data = param.data; + + // Get the uniform location and store it + this.loc = ctx.getUniformLocation(program, name); + + // if data was not provided then create default data + if (!this.data) { + switch (param.type) { + case "vec4": this.data = RDGE.vec4.zero(); break; + case "vec3": this.data = RDGE.vec3.zero(); break; + case "vec2": this.data = RDGE.vec2.zero(); break; + case "mat4": this.data = RDGE.mat4.zero(); break; + case "mat3": this.data = new Array(9); break; + case "mat2": this.data = [0, 0, 0, 0]; break; + case "float": this.data = [0]; break; + case "int": this.data = [0]; break; + case "tex2d": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; + case "texCube": this.data = [ctx.canvas.renderer.getTextureByName(RDGE.globals.engine._assetPath+"images/white.png")]; break; + } + } + else { + if (param.type == 'tex2d' || param.type == 'texCube') { + this.data = createJShaderTexture(ctx, param); + } + else { + this.data = param.data.slice(); + } + } + + this.get = function () { + return this.data.slice(); + }; + + this.set = function (v) { + if (this.type == 'tex2d' || this.type == 'texCube') { + if (typeof v == "string") { + v = ctx.canvas.renderer.getTextureByName(v); + } + + this.data[0] = v; + } + else { + var len = this.data.length; + for (var i = 0; i < len; ++i) + this.data[i] = v[i]; + } + }; + }; + + + this.init = function () { + var techniques = this.def.techniques; + var defaultTech = null; + for (t in techniques) { + defaultTech = t; + var curTechnique = techniques[t]; + this[t] = + { + 'passes': [] + }; + var numPasses = curTechnique.length; + var i = 0; + while (i < numPasses) { + var program = this.buildProgram(curTechnique[i]); + this.ctx.useProgram(program); + + // automatically create a parameter def for every active attribute in the shader. + var numAttribs = this.ctx.getProgramParameter(program, this.ctx.ACTIVE_ATTRIBUTES); + for (j = 0; j < numAttribs; ++j) { + var attribInfo = this.ctx.getActiveAttrib(program, j); + curTechnique[i].attributes[attribInfo.name] = { 'type': RDGE.paramTypeNameMapping[attribInfo.type] }; + } + // automatically create a parameter def for every active uniform in the shader. + var numUniforms = this.ctx.getProgramParameter(program, this.ctx.ACTIVE_UNIFORMS); + for (j = 0; j < numUniforms; ++j) { + var uniformInfo = this.ctx.getActiveUniform(program, j); + if (!RDGE.rdgeGlobalParameters[uniformInfo.name]) { + curTechnique[i].params[uniformInfo.name] = { 'type': RDGE.paramTypeNameMapping[uniformInfo.type] }; + } + } + + program.ctxId = this.ctx.canvas.rdgeid; + if (!program) { + this.renderer.console.log("Build errors found in technique: " + t); + this.def[t] = null; // remove bad technique + break; + } else { + this[t].passes.push({ "program": program, "params": {}, "defParams": {}, "states": curTechnique[i].states, "attributes": curTechnique[i].attribPairs }); + } + + // init default parameters + for (var p in RDGE.rdgeGlobalParameters) { + var gp = new globalParam(this.ctx, p, RDGE.rdgeGlobalParameters[p], program); + + if (gp.loc != null) { + gp.loc.ctxID = this.ctx.canvas.rdgeid; + this[t].passes[i].defParams[p] = gp; + this.global[p] = gp; + } + } + + // attach light parameters and container to light context + this[t].passes[i].lightParams = [null, null, null, null]; + this[t].passes[i].lightContext = [null, null, null, null]; + + // attach a parameter list that will be used to optimize binding attributes + if (!this[t].passes[i].paramsList) + this[t].passes[i].paramsList = []; + + // locate individual light parameters to bind with local context + var totalLights = RDGE.rdgeConstants.MAX_MATERIAL_LIGHTS; + for (var lightIdx = 0; lightIdx < totalLights; ++lightIdx) { + + // clear parameter + this[t].passes[i].lightParams[lightIdx] = null; + + // 0 = pos, 1 = diff, 2 = amb, 3 = spec + // this is order assumed for light parameters + + // the parameter index key - lets us know which piece of data we are getting/setting + var lightDataIndex = 0; + + for (var lp in RDGE.globals.engine.lightManager.lightUniforms[lightIdx]) { + loc = this.ctx.getUniformLocation(program, lp); + + // if item found enable this light param and set parameters to bind and lookup data + if (loc != null) { + if (!this[t].passes[i].lightParams[lightIdx]) + this[t].passes[i].lightParams[lightIdx] = []; + + this[t].passes[i].lightParams[lightIdx].push({ 'loc': loc, 'name': lp, 'dataIndex': lightDataIndex }); + } + + lightDataIndex++; + } + } + + + + // init user defined parameters + for (var p in curTechnique[i].params) { + if (typeof curTechnique[i].params[p] == 'string') { + continue; + } + + var newParam = new paramType(this.ctx, p, curTechnique[i].params, program, t); + + // if(newParam.loc != null) + // { + this[t].passes[i].params[p] = newParam; + this[t][p] = newParam; + // } + } + + // link up aliases + for (var p in curTechnique[i].params) { + if (typeof curTechnique[i].params[p] == 'string') { + // this just redirects to an already existing parameter. + this[t][p] = this[t].passes[i].params[p]; + } + } + + i++; + } + } + + // create linear lists of parameters - optimization + for (t in techniques) { + var numPasses = this[t].passes.length; + + for (var i = 0; i < numPasses; ++i) { + + this[t].passes[i].defParamsList = []; + + for (var p in this[t].passes[i].params) { + var param = this[t].passes[i].params[p]; + param.name = p; + this[t].passes[i].paramsList.push(param); + } + + for (var p in this[t].passes[i].defParams) { + var param = this[t].passes[i].defParams[p]; + param.name = p; + this[t].passes[i].defParamsList.push(param); + } + } + } + + this.setTechnique(defaultTech); + }; + + /* + * Init a local parameter at any time during the life of the jshader. + * This will add the parameter to the list of parameters to be bound + * before rendering + */ + this.initLocalParameter = function (name, param) { + var techniques = this.def.techniques; + for (t in techniques) { + var curTechnique = techniques[t]; + var numPasses = curTechnique.length; + var i = 0; + while (i < numPasses) { + var newParam = new paramType(this.ctx, name, param, curTechnique[i].program, t); + if (newParam) { + curTechnique[i][name] = newParam; + + // this params list is created here because a parameter could be added before the jshader is initialized + if (!curTechnique[i].paramsList) + curTechnique[i].paramsList = []; + + curTechnique[i].paramsList.push(newParam); + } + + i++; + } + } + }; + + this.buildShader = function (shaderType, shaderStr) { + // pre-pend preprocessor settings + var preProcessor = "#define PC\n" + preProcessor += shaderStr; + shaderStr = preProcessor; + + // Create the shader object + var shader = this.ctx.createShader(shaderType); + if (shader == null) { + this.renderer.console.log("*** Error: unable to create shader '" + shaderType + "'"); + return null; + } + + // Load the shader source + this.ctx.shaderSource(shader, shaderStr); + + // Compile the shader + this.ctx.compileShader(shader); + + // Check the compile status + var compiled = this.ctx.getShaderParameter(shader, this.ctx.COMPILE_STATUS); + if (!compiled) { + // compile failed, report error. + var error = this.ctx.getShaderInfoLog(shader); + window.console.error("*** Error compiling shader '" + shaderType + "':" + error); + this.ctx.deleteShader(shader); + return null; + } + + return shader; + }; + + this.buildProgram = function (t) { + window.console.log("building shader pair: <" + t.vshader + ", " + t.fshader + ">"); + var vShaderDef = RDGE.globals.engine.remapAssetFolder(this.def.shaders[t.vshader]); + var fShaderDef = RDGE.globals.engine.remapAssetFolder(this.def.shaders[t.fshader]); + + this.ctx.useProgram(null); + + var vertexShader = null; + var source = null; + + if (vShaderDef.indexOf('{') != -1) { + source = vShaderDef; + } else { + var vshaderRequest = new XMLHttpRequest(); + var urlVertShader = vShaderDef; + vshaderRequest.open("GET", urlVertShader, false); + vshaderRequest.send(null); + source = vshaderRequest.responseText; + } + + vertexShader = this.buildShader(this.ctx.VERTEX_SHADER, source); + + var fragmentShader = null; + var source = null; + if (vShaderDef.indexOf('{') != -1) { + source = fShaderDef; + } else { + var vshaderRequest = new XMLHttpRequest(); + var urlFragShader = fShaderDef; + vshaderRequest.open("GET", urlFragShader, false); + vshaderRequest.send(null); + source = vshaderRequest.responseText; + } + + fragmentShader = this.buildShader(this.ctx.FRAGMENT_SHADER, source); + + if (!vertexShader || !fragmentShader) { + return null; + } + + this.compiledShaders[t.vshader] = vertexShader; + this.compiledShaders[t.fshader] = fragmentShader; + + // Create the program object + var program = this.ctx.createProgram(); + if (!program) { + return null; + } + + // Attach our two shaders to the program + this.ctx.attachShader(program, vertexShader); + this.ctx.attachShader(program, fragmentShader); + + // Bind attributes + var idx = 0; + t.attribPairs = []; + for (var i in t.attributes) { + t.attribPairs.push({ 'loc': idx, 'name': i }); + this.ctx.bindAttribLocation(program, idx++, i); + } + + // Link the program + this.ctx.linkProgram(program); + + // Check the link status + var linked = this.ctx.getProgramParameter(program, this.ctx.LINK_STATUS); + if (!linked) { + // failed to link + var error = this.ctx.getProgramInfoLog(program); + + window.console.log("Error in program linking:" + error); + + this.ctx.deleteProgram(program); + this.ctx.deleteProgram(fragmentShader); + this.ctx.deleteProgram(vertexShader); + + return null; + } + + return program; + }; + + /* + * Set the light nodes used by this jshader + * array item 0 corresponds to light 0, item 1 tp light 1 and so on + * place null for lights that are not there + */ + this.setLightContext = function (lightRefArray) { + for (t in this.technique) { + var len = this.technique.passes.length; + for (var i = 0; i < len; ++i) { + this.technique.passes[i].lightContext = lightRefArray.slice(); + } + } + }; + + /* + * Called by the system to add material textures settings to the jshader + */ + this.setTextureContext = function (textureList) { + var passCount = this.technique.passes.length; + var param = null; + + for (var t = 0, texCount = textureList.length; t < texCount; ++t) { + for (var i = 0; i < passCount; ++i) { + var param = textureList[t]; + + // set the rdge global parameters if the texture is in the list + if (this.technique.passes[i].defParams[param.name]) + this.technique.passes[i].defParams[param.name].set(param.handle); + + // and set the local parameters if the texture is in the list + if (this.technique.passes[i].params[param.name]) + this.technique.passes[i].params[param.name].set(param.data[0]); + } + } + }; + + this.setTechnique = function (name) { + if (this[name] != undefined) { + this.technique = this[name]; + return true; + } + + this.ctx.console.log("Failed to set technique:" + name); + return false; + }; + + this.beginRenderState = function (i) { + var states = this.technique.passes[i].states; + if (states == undefined) { + return; + } + + // depth enabled by default. + var depthEnable = states.depthEnable != undefined ? states.depthEnable : true; + if (!depthEnable) { + this.ctx.disable(this.ctx.DEPTH_TEST); + var depthFunc = states.depthFunc != undefined ? states.depthFunc : "LESS"; + this.ctx.depthFunc(this.ctx[states