diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 93cb171..e9fc053 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -49,10 +49,18 @@ attribMap[i] = shader.attributeData[i].location; } - console.log(attribMap) const glShader = new GLShader(this.gl, shader.vertexSrc, shader.fragmentSrc, PRECISION.DEFAULT, attribMap); + + //TODO should I add this a s a prototype + glShader.dirtyFlags = {}; + for (var i in shader.realUniforms) { + glShader.dirtyFlags[i] = 0; + }; + console.log(glShader.dirtyFlags) + shader.glShaders[renderer.CONTEXT_UID] = glShader; + return glShader } @@ -62,28 +70,34 @@ * @param {GLShader} shader - The underlying gl shader. * @param {PIXI.Filter} filter - The filter we are synchronizing. */ - syncUniforms(shader, filter) + syncUniforms(glShader, shader) { - const uniformData = filter.uniformData; - const uniforms = filter.uniforms; + const uniformData = shader.uniformData; + const realUniforms = shader.realUniforms; + const dirtyFlags = glShader.dirtyFlags; // 0 is reserverd for the pixi texture so we start at 1! let textureCount = 1; - let currentState; - // TODO Cacheing layer.. + // TODO don't need to use the uniform for (const i in uniformData) { - if (uniformData[i].type === 'sampler2D' && uniforms[i] !== 0) + if(dirtyFlags[i] === uniformData[i].dirtyId) { - shader.uniforms[i] = textureCount; + continue; + } - if (uniforms[i].baseTexture) + dirtyFlags[i] = uniformData[i].dirtyId; + + if (uniformData[i].type === 'sampler2D' && uniformData[i].value !== 0) + { + if (uniformData[i].value.baseTexture) { - this.renderer.bindTexture(uniforms[i].baseTexture, textureCount); + glShader.uniforms[i] = this.renderer.bindTexture(uniformData[i].value, textureCount); } else { + glShader.uniforms[i] = textureCount; // TODO // this is helpful as renderTargets can also be set. // Although thinking about it, we could probably @@ -100,41 +114,41 @@ else if (uniformData[i].type === 'mat3') { // check if its pixi matrix.. - if (uniforms[i].a !== undefined) + if (uniformData[i].value.a !== undefined) { - shader.uniforms[i] = uniforms[i].toArray(true); + glShader.uniforms[i] = uniformData[i].value.toArray(true); } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else if (uniformData[i].type === 'vec2') { // check if its a point.. - if (uniforms[i].x !== undefined) + if (uniformData[i].value.x !== undefined) { - const val = shader.uniforms[i] || new Float32Array(2); + const val = glShader.uniforms[i] || new Float32Array(2); - val[0] = uniforms[i].x; - val[1] = uniforms[i].y; - shader.uniforms[i] = val; + val[0] = uniformData[i].value.x; + val[1] = uniformData[i].value.y; + glShader.uniforms[i] = val; } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else if (uniformData[i].type === 'float') { - if (shader.uniforms.data[i].value !== uniformData[i]) + if (glShader.uniforms.data[i].value !== uniformData[i].value) { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } } diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 93cb171..e9fc053 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -49,10 +49,18 @@ attribMap[i] = shader.attributeData[i].location; } - console.log(attribMap) const glShader = new GLShader(this.gl, shader.vertexSrc, shader.fragmentSrc, PRECISION.DEFAULT, attribMap); + + //TODO should I add this a s a prototype + glShader.dirtyFlags = {}; + for (var i in shader.realUniforms) { + glShader.dirtyFlags[i] = 0; + }; + console.log(glShader.dirtyFlags) + shader.glShaders[renderer.CONTEXT_UID] = glShader; + return glShader } @@ -62,28 +70,34 @@ * @param {GLShader} shader - The underlying gl shader. * @param {PIXI.Filter} filter - The filter we are synchronizing. */ - syncUniforms(shader, filter) + syncUniforms(glShader, shader) { - const uniformData = filter.uniformData; - const uniforms = filter.uniforms; + const uniformData = shader.uniformData; + const realUniforms = shader.realUniforms; + const dirtyFlags = glShader.dirtyFlags; // 0 is reserverd for the pixi texture so we start at 1! let textureCount = 1; - let currentState; - // TODO Cacheing layer.. + // TODO don't need to use the uniform for (const i in uniformData) { - if (uniformData[i].type === 'sampler2D' && uniforms[i] !== 0) + if(dirtyFlags[i] === uniformData[i].dirtyId) { - shader.uniforms[i] = textureCount; + continue; + } - if (uniforms[i].baseTexture) + dirtyFlags[i] = uniformData[i].dirtyId; + + if (uniformData[i].type === 'sampler2D' && uniformData[i].value !== 0) + { + if (uniformData[i].value.baseTexture) { - this.renderer.bindTexture(uniforms[i].baseTexture, textureCount); + glShader.uniforms[i] = this.renderer.bindTexture(uniformData[i].value, textureCount); } else { + glShader.uniforms[i] = textureCount; // TODO // this is helpful as renderTargets can also be set. // Although thinking about it, we could probably @@ -100,41 +114,41 @@ else if (uniformData[i].type === 'mat3') { // check if its pixi matrix.. - if (uniforms[i].a !== undefined) + if (uniformData[i].value.a !== undefined) { - shader.uniforms[i] = uniforms[i].toArray(true); + glShader.uniforms[i] = uniformData[i].value.toArray(true); } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else if (uniformData[i].type === 'vec2') { // check if its a point.. - if (uniforms[i].x !== undefined) + if (uniformData[i].value.x !== undefined) { - const val = shader.uniforms[i] || new Float32Array(2); + const val = glShader.uniforms[i] || new Float32Array(2); - val[0] = uniforms[i].x; - val[1] = uniforms[i].y; - shader.uniforms[i] = val; + val[0] = uniformData[i].value.x; + val[1] = uniformData[i].value.y; + glShader.uniforms[i] = val; } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else if (uniformData[i].type === 'float') { - if (shader.uniforms.data[i].value !== uniformData[i]) + if (glShader.uniforms.data[i].value !== uniformData[i].value) { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } } diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index fb0a85a..098507f 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -33,22 +33,40 @@ // pull out the vertex and shader uniforms if they are not specified.. // currently this does not extract structs only default types this.uniformData = uniforms || extractUniformsFromSrc(this.vertexSrc, this.fragmentSrc, 'projectionMatrix|uSampler'); - this.attributeData = extractAttributesFromSrc(this.vertexSrc); - this.uniforms = {}; + // time to build some getters and setters! + // I guess down the line this could sort of generate an instruction list rather than use dirty ids? + // does the trick for now though! for (const i in this.uniformData) { - this.uniforms[i] = this.uniformData[i].value; + var _this = this; + + Object.defineProperty(this.uniforms, i, { + get: function(){ + return _this.uniformData[i].value; + }, + set: function(value){ + + _this.uniformData[i].dirtyId++; + _this.uniformData[i].value = value; + + } + }); } + // this is where we store shader references.. // TODO we could cache this! this.glShaders = {}; + + + } + /** * The default vertex shader source * diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 93cb171..e9fc053 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -49,10 +49,18 @@ attribMap[i] = shader.attributeData[i].location; } - console.log(attribMap) const glShader = new GLShader(this.gl, shader.vertexSrc, shader.fragmentSrc, PRECISION.DEFAULT, attribMap); + + //TODO should I add this a s a prototype + glShader.dirtyFlags = {}; + for (var i in shader.realUniforms) { + glShader.dirtyFlags[i] = 0; + }; + console.log(glShader.dirtyFlags) + shader.glShaders[renderer.CONTEXT_UID] = glShader; + return glShader } @@ -62,28 +70,34 @@ * @param {GLShader} shader - The underlying gl shader. * @param {PIXI.Filter} filter - The filter we are synchronizing. */ - syncUniforms(shader, filter) + syncUniforms(glShader, shader) { - const uniformData = filter.uniformData; - const uniforms = filter.uniforms; + const uniformData = shader.uniformData; + const realUniforms = shader.realUniforms; + const dirtyFlags = glShader.dirtyFlags; // 0 is reserverd for the pixi texture so we start at 1! let textureCount = 1; - let currentState; - // TODO Cacheing layer.. + // TODO don't need to use the uniform for (const i in uniformData) { - if (uniformData[i].type === 'sampler2D' && uniforms[i] !== 0) + if(dirtyFlags[i] === uniformData[i].dirtyId) { - shader.uniforms[i] = textureCount; + continue; + } - if (uniforms[i].baseTexture) + dirtyFlags[i] = uniformData[i].dirtyId; + + if (uniformData[i].type === 'sampler2D' && uniformData[i].value !== 0) + { + if (uniformData[i].value.baseTexture) { - this.renderer.bindTexture(uniforms[i].baseTexture, textureCount); + glShader.uniforms[i] = this.renderer.bindTexture(uniformData[i].value, textureCount); } else { + glShader.uniforms[i] = textureCount; // TODO // this is helpful as renderTargets can also be set. // Although thinking about it, we could probably @@ -100,41 +114,41 @@ else if (uniformData[i].type === 'mat3') { // check if its pixi matrix.. - if (uniforms[i].a !== undefined) + if (uniformData[i].value.a !== undefined) { - shader.uniforms[i] = uniforms[i].toArray(true); + glShader.uniforms[i] = uniformData[i].value.toArray(true); } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else if (uniformData[i].type === 'vec2') { // check if its a point.. - if (uniforms[i].x !== undefined) + if (uniformData[i].value.x !== undefined) { - const val = shader.uniforms[i] || new Float32Array(2); + const val = glShader.uniforms[i] || new Float32Array(2); - val[0] = uniforms[i].x; - val[1] = uniforms[i].y; - shader.uniforms[i] = val; + val[0] = uniformData[i].value.x; + val[1] = uniformData[i].value.y; + glShader.uniforms[i] = val; } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else if (uniformData[i].type === 'float') { - if (shader.uniforms.data[i].value !== uniformData[i]) + if (glShader.uniforms.data[i].value !== uniformData[i].value) { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } else { - shader.uniforms[i] = uniforms[i]; + glShader.uniforms[i] = uniformData[i].value; } } } diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index fb0a85a..098507f 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -33,22 +33,40 @@ // pull out the vertex and shader uniforms if they are not specified.. // currently this does not extract structs only default types this.uniformData = uniforms || extractUniformsFromSrc(this.vertexSrc, this.fragmentSrc, 'projectionMatrix|uSampler'); - this.attributeData = extractAttributesFromSrc(this.vertexSrc); - this.uniforms = {}; + // time to build some getters and setters! + // I guess down the line this could sort of generate an instruction list rather than use dirty ids? + // does the trick for now though! for (const i in this.uniformData) { - this.uniforms[i] = this.uniformData[i].value; + var _this = this; + + Object.defineProperty(this.uniforms, i, { + get: function(){ + return _this.uniformData[i].value; + }, + set: function(value){ + + _this.uniformData[i].dirtyId++; + _this.uniformData[i].value = value; + + } + }); } + // this is where we store shader references.. // TODO we could cache this! this.glShaders = {}; + + + } + /** * The default vertex shader source * diff --git a/src/core/shader/extractUniformsFromSrc.js b/src/core/shader/extractUniformsFromSrc.js index e803c40..bbc0f1f 100644 --- a/src/core/shader/extractUniformsFromSrc.js +++ b/src/core/shader/extractUniformsFromSrc.js @@ -47,6 +47,7 @@ { uniforms[name] = { value: defaultValue(type, size), + dirtyId: 0, name, type, };