diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index ccfdf8f..b64a236 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -401,7 +401,6 @@ // both thease only need to be set if they are changing.. // set the projection - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); } } diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index ccfdf8f..b64a236 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -401,7 +401,6 @@ // both thease only need to be set if they are changing.. // set the projection - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); } } diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 9c262ad..bc280bb 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -53,7 +53,7 @@ throw new Error('Unable to create RenderTexture, you must pass a renderer into the constructor.'); } - width = width || 100; + width = width || 100; height = height || 100; resolution = resolution || 1; @@ -132,8 +132,6 @@ */ this.render = null; - - /** * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. * @@ -145,7 +143,7 @@ { var gl = this.renderer.gl; - this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution)//, this.baseTexture.scaleMode); + this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution);//, this.baseTexture.scaleMode); this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; this.render = this.renderWebGL; @@ -153,7 +151,7 @@ } else { - + this.render = this.renderCanvas; this.textureBuffer = new CanvasBuffer(this.width* this.resolution, this.height* this.resolution); this.baseTexture.source = this.textureBuffer.canvas; @@ -301,7 +299,7 @@ // this.renderer.spriteRenderer.dirty = true; - this.renderer.renderDisplayObject(displayObject, this.textureBuffer)//this.projection, this.textureBuffer.frameBuffer); +this.renderer.renderDisplayObject(displayObject, this.textureBuffer);//this.projection, this.textureBuffer.frameBuffer); // this.renderer.spriteRenderer.dirty = true; @@ -335,11 +333,11 @@ return; } - + var tempAlpha, tempTransform; - + var wt = displayObject.worldTransform; wt.identity(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index ccfdf8f..b64a236 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -401,7 +401,6 @@ // both thease only need to be set if they are changing.. // set the projection - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); } } diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 9c262ad..bc280bb 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -53,7 +53,7 @@ throw new Error('Unable to create RenderTexture, you must pass a renderer into the constructor.'); } - width = width || 100; + width = width || 100; height = height || 100; resolution = resolution || 1; @@ -132,8 +132,6 @@ */ this.render = null; - - /** * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. * @@ -145,7 +143,7 @@ { var gl = this.renderer.gl; - this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution)//, this.baseTexture.scaleMode); + this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution);//, this.baseTexture.scaleMode); this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; this.render = this.renderWebGL; @@ -153,7 +151,7 @@ } else { - + this.render = this.renderCanvas; this.textureBuffer = new CanvasBuffer(this.width* this.resolution, this.height* this.resolution); this.baseTexture.source = this.textureBuffer.canvas; @@ -301,7 +299,7 @@ // this.renderer.spriteRenderer.dirty = true; - this.renderer.renderDisplayObject(displayObject, this.textureBuffer)//this.projection, this.textureBuffer.frameBuffer); +this.renderer.renderDisplayObject(displayObject, this.textureBuffer);//this.projection, this.textureBuffer.frameBuffer); // this.renderer.spriteRenderer.dirty = true; @@ -335,11 +333,11 @@ return; } - + var tempAlpha, tempTransform; - + var wt = displayObject.worldTransform; wt.identity(); diff --git a/src/core/utils/pluginTarget.js b/src/core/utils/pluginTarget.js index 011dbc3..7969d02 100644 --- a/src/core/utils/pluginTarget.js +++ b/src/core/utils/pluginTarget.js @@ -9,29 +9,28 @@ * * pluginTarget.mixin(MyObject); */ -function pluginTarget(obj) +function pluginTarget(obj) { obj.__plugins = {}; - obj.registerPlugin = function (pluginName, ctor) + obj.registerPlugin = function (pluginName, ctor) { obj.__plugins[pluginName] = ctor; }; - obj.prototype.initPlugins = function () + obj.prototype.initPlugins = function () { - this.plugins = {}; + this.plugins = this.plugins || {}; - for (var o in obj.__plugins) + for (var o in obj.__plugins) { this.plugins[o] = new (obj.__plugins[o])(this); } }; - obj.prototype.destroyPlugins = function () + obj.prototype.destroyPlugins = function () { - - for (var o in this.plugins) + for (var o in this.plugins) { this.plugins[o].destroy(); this.plugins[o] = null; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index ccfdf8f..b64a236 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -401,7 +401,6 @@ // both thease only need to be set if they are changing.. // set the projection - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); } } diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 9c262ad..bc280bb 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -53,7 +53,7 @@ throw new Error('Unable to create RenderTexture, you must pass a renderer into the constructor.'); } - width = width || 100; + width = width || 100; height = height || 100; resolution = resolution || 1; @@ -132,8 +132,6 @@ */ this.render = null; - - /** * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. * @@ -145,7 +143,7 @@ { var gl = this.renderer.gl; - this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution)//, this.baseTexture.scaleMode); + this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution);//, this.baseTexture.scaleMode); this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; this.render = this.renderWebGL; @@ -153,7 +151,7 @@ } else { - + this.render = this.renderCanvas; this.textureBuffer = new CanvasBuffer(this.width* this.resolution, this.height* this.resolution); this.baseTexture.source = this.textureBuffer.canvas; @@ -301,7 +299,7 @@ // this.renderer.spriteRenderer.dirty = true; - this.renderer.renderDisplayObject(displayObject, this.textureBuffer)//this.projection, this.textureBuffer.frameBuffer); +this.renderer.renderDisplayObject(displayObject, this.textureBuffer);//this.projection, this.textureBuffer.frameBuffer); // this.renderer.spriteRenderer.dirty = true; @@ -335,11 +333,11 @@ return; } - + var tempAlpha, tempTransform; - + var wt = displayObject.worldTransform; wt.identity(); diff --git a/src/core/utils/pluginTarget.js b/src/core/utils/pluginTarget.js index 011dbc3..7969d02 100644 --- a/src/core/utils/pluginTarget.js +++ b/src/core/utils/pluginTarget.js @@ -9,29 +9,28 @@ * * pluginTarget.mixin(MyObject); */ -function pluginTarget(obj) +function pluginTarget(obj) { obj.__plugins = {}; - obj.registerPlugin = function (pluginName, ctor) + obj.registerPlugin = function (pluginName, ctor) { obj.__plugins[pluginName] = ctor; }; - obj.prototype.initPlugins = function () + obj.prototype.initPlugins = function () { - this.plugins = {}; + this.plugins = this.plugins || {}; - for (var o in obj.__plugins) + for (var o in obj.__plugins) { this.plugins[o] = new (obj.__plugins[o])(this); } }; - obj.prototype.destroyPlugins = function () + obj.prototype.destroyPlugins = function () { - - for (var o in this.plugins) + for (var o in this.plugins) { this.plugins[o].destroy(); this.plugins[o] = null; diff --git a/src/extras/StripShader.js b/src/extras/StripShader.js index c7b69b3..bb12757 100644 --- a/src/extras/StripShader.js +++ b/src/extras/StripShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function StripShader(shaderManager) { @@ -53,4 +53,4 @@ StripShader.prototype.constructor = StripShader; module.exports = StripShader; -//core.WebGLShaderManager.registerPlugin('stripShader', StripShader); +//core.ShaderManager.registerPlugin('stripShader', StripShader); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index ccfdf8f..b64a236 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -401,7 +401,6 @@ // both thease only need to be set if they are changing.. // set the projection - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); } } diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 9c262ad..bc280bb 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -53,7 +53,7 @@ throw new Error('Unable to create RenderTexture, you must pass a renderer into the constructor.'); } - width = width || 100; + width = width || 100; height = height || 100; resolution = resolution || 1; @@ -132,8 +132,6 @@ */ this.render = null; - - /** * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. * @@ -145,7 +143,7 @@ { var gl = this.renderer.gl; - this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution)//, this.baseTexture.scaleMode); + this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution);//, this.baseTexture.scaleMode); this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; this.render = this.renderWebGL; @@ -153,7 +151,7 @@ } else { - + this.render = this.renderCanvas; this.textureBuffer = new CanvasBuffer(this.width* this.resolution, this.height* this.resolution); this.baseTexture.source = this.textureBuffer.canvas; @@ -301,7 +299,7 @@ // this.renderer.spriteRenderer.dirty = true; - this.renderer.renderDisplayObject(displayObject, this.textureBuffer)//this.projection, this.textureBuffer.frameBuffer); +this.renderer.renderDisplayObject(displayObject, this.textureBuffer);//this.projection, this.textureBuffer.frameBuffer); // this.renderer.spriteRenderer.dirty = true; @@ -335,11 +333,11 @@ return; } - + var tempAlpha, tempTransform; - + var wt = displayObject.worldTransform; wt.identity(); diff --git a/src/core/utils/pluginTarget.js b/src/core/utils/pluginTarget.js index 011dbc3..7969d02 100644 --- a/src/core/utils/pluginTarget.js +++ b/src/core/utils/pluginTarget.js @@ -9,29 +9,28 @@ * * pluginTarget.mixin(MyObject); */ -function pluginTarget(obj) +function pluginTarget(obj) { obj.__plugins = {}; - obj.registerPlugin = function (pluginName, ctor) + obj.registerPlugin = function (pluginName, ctor) { obj.__plugins[pluginName] = ctor; }; - obj.prototype.initPlugins = function () + obj.prototype.initPlugins = function () { - this.plugins = {}; + this.plugins = this.plugins || {}; - for (var o in obj.__plugins) + for (var o in obj.__plugins) { this.plugins[o] = new (obj.__plugins[o])(this); } }; - obj.prototype.destroyPlugins = function () + obj.prototype.destroyPlugins = function () { - - for (var o in this.plugins) + for (var o in this.plugins) { this.plugins[o].destroy(); this.plugins[o] = null; diff --git a/src/extras/StripShader.js b/src/extras/StripShader.js index c7b69b3..bb12757 100644 --- a/src/extras/StripShader.js +++ b/src/extras/StripShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function StripShader(shaderManager) { @@ -53,4 +53,4 @@ StripShader.prototype.constructor = StripShader; module.exports = StripShader; -//core.WebGLShaderManager.registerPlugin('stripShader', StripShader); +//core.ShaderManager.registerPlugin('stripShader', StripShader); diff --git a/src/loaders/loader.js b/src/loaders/loader.js index b1d9c1d..4c6e1b1 100644 --- a/src/loaders/loader.js +++ b/src/loaders/loader.js @@ -11,6 +11,6 @@ // parse any Image objects into textures .use(textureParser()) // parse any spritesheet data into multiple textures - .use(spritesheetParser()) + .use(spritesheetParser()); module.exports = loader; diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index ccfdf8f..b64a236 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -401,7 +401,6 @@ // both thease only need to be set if they are changing.. // set the projection - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); } } diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 9c262ad..bc280bb 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -53,7 +53,7 @@ throw new Error('Unable to create RenderTexture, you must pass a renderer into the constructor.'); } - width = width || 100; + width = width || 100; height = height || 100; resolution = resolution || 1; @@ -132,8 +132,6 @@ */ this.render = null; - - /** * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. * @@ -145,7 +143,7 @@ { var gl = this.renderer.gl; - this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution)//, this.baseTexture.scaleMode); + this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution);//, this.baseTexture.scaleMode); this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; this.render = this.renderWebGL; @@ -153,7 +151,7 @@ } else { - + this.render = this.renderCanvas; this.textureBuffer = new CanvasBuffer(this.width* this.resolution, this.height* this.resolution); this.baseTexture.source = this.textureBuffer.canvas; @@ -301,7 +299,7 @@ // this.renderer.spriteRenderer.dirty = true; - this.renderer.renderDisplayObject(displayObject, this.textureBuffer)//this.projection, this.textureBuffer.frameBuffer); +this.renderer.renderDisplayObject(displayObject, this.textureBuffer);//this.projection, this.textureBuffer.frameBuffer); // this.renderer.spriteRenderer.dirty = true; @@ -335,11 +333,11 @@ return; } - + var tempAlpha, tempTransform; - + var wt = displayObject.worldTransform; wt.identity(); diff --git a/src/core/utils/pluginTarget.js b/src/core/utils/pluginTarget.js index 011dbc3..7969d02 100644 --- a/src/core/utils/pluginTarget.js +++ b/src/core/utils/pluginTarget.js @@ -9,29 +9,28 @@ * * pluginTarget.mixin(MyObject); */ -function pluginTarget(obj) +function pluginTarget(obj) { obj.__plugins = {}; - obj.registerPlugin = function (pluginName, ctor) + obj.registerPlugin = function (pluginName, ctor) { obj.__plugins[pluginName] = ctor; }; - obj.prototype.initPlugins = function () + obj.prototype.initPlugins = function () { - this.plugins = {}; + this.plugins = this.plugins || {}; - for (var o in obj.__plugins) + for (var o in obj.__plugins) { this.plugins[o] = new (obj.__plugins[o])(this); } }; - obj.prototype.destroyPlugins = function () + obj.prototype.destroyPlugins = function () { - - for (var o in this.plugins) + for (var o in this.plugins) { this.plugins[o].destroy(); this.plugins[o] = null; diff --git a/src/extras/StripShader.js b/src/extras/StripShader.js index c7b69b3..bb12757 100644 --- a/src/extras/StripShader.js +++ b/src/extras/StripShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function StripShader(shaderManager) { @@ -53,4 +53,4 @@ StripShader.prototype.constructor = StripShader; module.exports = StripShader; -//core.WebGLShaderManager.registerPlugin('stripShader', StripShader); +//core.ShaderManager.registerPlugin('stripShader', StripShader); diff --git a/src/loaders/loader.js b/src/loaders/loader.js index b1d9c1d..4c6e1b1 100644 --- a/src/loaders/loader.js +++ b/src/loaders/loader.js @@ -11,6 +11,6 @@ // parse any Image objects into textures .use(textureParser()) // parse any spritesheet data into multiple textures - .use(spritesheetParser()) + .use(spritesheetParser()); module.exports = loader; diff --git a/src/loaders/spritesheetParser.js b/src/loaders/spritesheetParser.js index 22d41e6..934e1d7 100644 --- a/src/loaders/spritesheetParser.js +++ b/src/loaders/spritesheetParser.js @@ -30,7 +30,7 @@ var trim = null; // Check to see if the sprite is trimmed - if (frameData[i].trimmed) + if (frames[i].trimmed) { trim = new core.math.Rectangle( frames[i].spriteSourceSize.x, @@ -40,7 +40,7 @@ ); } - cresource.textures[i] = new core.Texture(resource.texture.baseTexture, size, size.clone(), trim); + resource.textures[i] = new core.Texture(res.texture.baseTexture, size, size.clone(), trim); } } diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index 46121cd..8c6c25c 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -31,8 +31,8 @@ GraphicsRenderer.prototype.onContextChange = function() { - -} + +}; /** * Destroys this renderer. @@ -91,7 +91,7 @@ shader = renderer.shaderManager.primitiveShader; - + renderer.shaderManager.setShader( shader );//activatePrimitiveShader(); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); diff --git a/src/core/index.js b/src/core/index.js index 4fc777d..67b8d4e 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -44,7 +44,7 @@ // renderers - webgl WebGLRenderer: require('./renderers/webgl/WebGLRenderer'), - WebGLShaderManager: require('./renderers/webgl/managers/WebGLShaderManager'), + ShaderManager: require('./renderers/webgl/managers/ShaderManager'), Shader: require('./renderers/webgl/shaders/Shader'), /** diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e66777b..3325b81 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -245,11 +245,11 @@ * @param {Matrix} matrix * @return {Matrix} This matrix. Good for chaining method calls. */ -Matrix.prototype.prepend = function(matrix) +Matrix.prototype.prepend = function(matrix) { var tx1 = this.tx; - if (matrix.a != 1 || matrix.b != 0 || matrix.c != 0 || matrix.d != 1) + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { var a1 = this.a; var c1 = this.c; @@ -258,7 +258,7 @@ this.c = c1*matrix.a+this.d*matrix.c; this.d = c1*matrix.b+this.d*matrix.d; } - + this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx; this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty; @@ -266,7 +266,7 @@ }; -Matrix.prototype.invert = function() +Matrix.prototype.invert = function() { var a1 = this.a; var b1 = this.b; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f5a7203..5a2fac1 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -1,4 +1,4 @@ -var WebGLShaderManager = require('./managers/WebGLShaderManager'), +var ShaderManager = require('./managers/ShaderManager'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), FilterManager = require('./managers/FilterManager'), @@ -174,13 +174,13 @@ // time to create the render managers! each one focuses on managing a state in webGL - + /** * Deals with managing the shader programs and their attribs - * @member {WebGLShaderManager} + * @member {ShaderManager} */ - this.shaderManager = new WebGLShaderManager(this); + this.shaderManager = new ShaderManager(this); /** * Manages the masks using the stencil buffer @@ -205,7 +205,7 @@ this.blendModes = null; - + this._boundUpdateTexture = this.updateTexture.bind(this); this._boundDestroyTexture = this.destroyTexture.bind(this); @@ -355,7 +355,7 @@ this.drawCount = 0; // start the filter manager - this.filterManager.begin()//renderTarget.frameBuffer); + this.filterManager.begin(); // render the scene! displayObject.renderWebGL(this); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 45d6a76..9acd869 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -1,9 +1,9 @@ var WebGLManager = require('./WebGLManager'), FilterTexture = require('../utils/FilterTexture'), RenderTarget = require('../utils/RenderTarget'); - DefaultShader = require('../shaders/DefaultShader'), + DefaultShader = require('../shaders/TextureShader'), - Quad = require('./Quad'), + Quad = require('../utils/Quad'), math = require('../../../math'); /** diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 66c54e9..3e7f4a7 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,6 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../utils/SpriteMaskFilter'), - utils = require('../../../utils'); + AlphaMaskFilter = require('../utils/SpriteMaskFilter'); /** * @class @@ -28,15 +27,9 @@ * @param graphics {Graphics} * @param webGLData {any[]} */ - -MaskManager.prototype.destroy = function () -{ - -}; - MaskManager.prototype.pushMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.pushSpriteMask(target, maskData); } @@ -45,37 +38,38 @@ this.pushStencilMask(target, maskData); } -} +}; MaskManager.prototype.popMask = function (target, maskData) { - if(maskData.texture) + if (maskData.texture) { this.popSpriteMask(target, maskData); } else { this.popStencilMask(target, maskData); - } -} + } +}; MaskManager.prototype.pushSpriteMask = function (target, maskData) { var alphaMaskFilter = this.alphaMaskPool.pop(); - if(!alphaMaskFilter)alphaMaskFilter = [ new AlphaMaskFilter( maskData ) ]; + if (!alphaMaskFilter) + { + alphaMaskFilter = [new AlphaMaskFilter(maskData)]; + } - this.renderer.filterManager.pushFilter(target, alphaMaskFilter) -} + this.renderer.filterManager.pushFilter(target, alphaMaskFilter); +}; /** * Removes the last filter from the filter stack and doesn't return it. * - * @param maskData {any[]} */ -MaskManager.prototype.popSpriteMask = function (maskData) +MaskManager.prototype.popSpriteMask = function () { - var filters = this.renderer.filterManager.popFilter(); this.alphaMaskPool.push(filters); @@ -91,7 +85,7 @@ MaskManager.prototype.pushStencilMask = function (target, maskData) { this.renderer.stencilManager.pushMask(maskData); -} +}; /** * Removes the last filter from the filter stack and doesn't return it. diff --git a/src/core/renderers/webgl/managers/Quad.js b/src/core/renderers/webgl/managers/Quad.js deleted file mode 100644 index b2fae63..0000000 --- a/src/core/renderers/webgl/managers/Quad.js +++ /dev/null @@ -1,107 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function Quad(gl) -{ - this.gl = gl; - -// this.textures = new TextureUvs(); - - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - - var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - - this.colors = new Float32Array([ - white, - white, - white, - white - ]) - - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -Quad.prototype.map = function(rect, rect2) -{ - var x = 0//rect2.x / rect.width; - var y = 0//rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -} - -Quad.prototype.upload = function() -{ - var gl = this.gl; - - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -} - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js new file mode 100644 index 0000000..b01d537 --- /dev/null +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -0,0 +1,148 @@ +var WebGLManager = require('./WebGLManager'), + TextureShader = require('../shaders/TextureShader'), + ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), + PrimitiveShader = require('../shaders/PrimitiveShader'), + utils = require('../../../utils'); + +/** + * @class + * @namespace PIXI + * @param renderer {WebGLRenderer} The renderer this manager works for. + */ +function ShaderManager(renderer) +{ + WebGLManager.call(this, renderer); + + /** + * @member {number} + */ + this.maxAttibs = 10; + + /** + * @member {any[]} + */ + this.attribState = []; + + /** + * @member {any[]} + */ + this.tempAttribState = []; + + for (var i = 0; i < this.maxAttibs; i++) + { + this.attribState[i] = false; + } + + /** + * @member {any[]} + */ + this.stack = []; + + /** + * @member {number} + * @private + */ + this._currentId = -1; + + /** + * @member {Shader} + * @private + */ + this.currentShader = null; + + this.initPlugins(); +} + +ShaderManager.prototype = Object.create(WebGLManager.prototype); +ShaderManager.prototype.constructor = ShaderManager; +utils.pluginTarget.mixin(ShaderManager); + +module.exports = ShaderManager; + +ShaderManager.prototype.onContextChange = function () +{ + this.initPlugins(); + + // TODO - Why are these not plugins? We can't decouple primitives unless they are.... + this.defaultShader = new TextureShader(this); + this.primitiveShader = new PrimitiveShader(this); + this.complexPrimitiveShader = new ComplexPrimitiveShader(this); +}; + +/** + * Takes the attributes given in parameters. + * + * @param attribs {Array} attribs + */ +ShaderManager.prototype.setAttribs = function (attribs) +{ + // reset temp state + var i; + + for (i = 0; i < this.tempAttribState.length; i++) + { + this.tempAttribState[i] = false; + } + + // set the new attribs + for (var a in attribs) + { + this.tempAttribState[attribs[a]] = true; + } + + var gl = this.renderer.gl; + + for (i = 0; i < this.attribState.length; i++) + { + if (this.attribState[i] !== this.tempAttribState[i]) + { + this.attribState[i] = this.tempAttribState[i]; + + if (this.attribState[i]) + { + gl.enableVertexAttribArray(i); + } + else + { + gl.disableVertexAttribArray(i); + } + } + } +}; + +/** + * Sets the current shader. + * + * @param shader {Any} + */ +ShaderManager.prototype.setShader = function (shader) +{ + if (this._currentId === shader.uuid) + { + return false; + } + + this._currentId = shader.uuid; + + this.currentShader = shader; + + this.renderer.gl.useProgram(shader.program); + this.setAttribs(shader.attributes); + + return true; +}; + +/** + * Destroys this object. + * + */ +ShaderManager.prototype.destroy = function () +{ + WebGLManager.prototype.destroy.call(this); + + this.destroyPlugins(); + + this.attribState = null; + + this.tempAttribState = null; +}; diff --git a/src/core/renderers/webgl/managers/StencilManager.js b/src/core/renderers/webgl/managers/StencilManager.js index 56390da..741ca8b 100644 --- a/src/core/renderers/webgl/managers/StencilManager.js +++ b/src/core/renderers/webgl/managers/StencilManager.js @@ -124,9 +124,7 @@ var gl = this.renderer.gl; // bind the graphics object.. - var projection = this.renderer.projection, - offset = this.renderer.offset, - shader; + var shader;// = this.renderer.shaderManager.plugins.primitiveShader; if (webGLData.mode === 1) { @@ -155,12 +153,13 @@ } else { + //this.renderer.shaderManager.activatePrimitiveShader(); shader = this.renderer.shaderManager.primitiveShader; this.renderer.shaderManager.setShader( shader ); gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, graphics.worldTransform.toArray(true)); - + gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); gl.uniform3fv(shader.uniforms.tint._location, utils.hex2rgb(graphics.tint)); @@ -277,7 +276,8 @@ */ WebGLMaskManager.prototype.destroy = function () { - this.renderer = null; + WebGLManager.prototype.destroy.call(this); + this.stencilStack = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js b/src/core/renderers/webgl/managers/WebGLFilterManager copy.js deleted file mode 100644 index 2dac048..0000000 --- a/src/core/renderers/webgl/managers/WebGLFilterManager copy.js +++ /dev/null @@ -1,481 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - FilterTexture = require('../utils/FilterTexture'), - Shader = require('../shaders/Shader'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLFilterManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {any[]} - */ - this.filterStack = []; - - /** - * @member {any[]]} - */ - this.texturePool = []; - - /** - * @member {number} - */ - this.offsetX = 0; - - /** - * @member {number} - */ - this.offsetY = 0; - - // listen for context and update necessary buffers - var self = this; - this.renderer.on('context', function () - { - self.texturePool.length = 0; - self.initShaderBuffers(); - }); -} - -WebGLFilterManager.prototype = Object.create(WebGLManager.prototype); -WebGLFilterManager.prototype.constructor = WebGLFilterManager; -module.exports = WebGLFilterManager; - -/** - * @param renderer {WebGLRenderer} - * @param buffer {ArrayBuffer} - */ -WebGLFilterManager.prototype.begin = function (buffer) -{ - this.defaultShader = this.renderer.shaderManager.defaultShader; - - this.width = this.renderer.projection.x * 2; - this.height = -this.renderer.projection.y * 2; - - this.buffer = buffer; -}; - -/** - * Applies the filter and adds it to the current filter stack. - * - * @param filterBlock {object} the filter that will be pushed to the current filter stack - */ -WebGLFilterManager.prototype.pushFilter = function (filterBlock) -{ - var gl = this.renderer.gl; - - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if (!texture) - { - texture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - var localX = filterArea.x, - localY = filterArea.y; - - if (filterArea.x < 0) - { - filterArea.width += filterArea.x; - filterArea.x = 0; - } - - if (filterArea.y < 0) - { - filterArea.height += filterArea.y; - filterArea.y = 0; - } - - if (localX + filterArea.width > this.width) - { - filterArea.width = this.width - localX; - } - - if (localY + filterArea.height > this.height) - { - filterArea.height = this.height - localY; - } - - if (filterArea.width < 0) - { - filterArea.width = 0; - } - - if (filterArea.height < 0) - { - filterArea.height = 0; - } - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderer.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** - * Removes the last filter from the filter stack and doesn't return it. - * - */ -WebGLFilterManager.prototype.popFilter = function () -{ - var gl = this.renderer.gl; - - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderer.projection; - var offset = this.renderer.offset; - - if (filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if (!outputTexture) - { - outputTexture = new FilterTexture(this.renderer.gl, this.width, this.height); - } - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if (this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderer.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** - * Applies the filter to the specified area. - * - * @param filter {AbstractFilter} the filter that needs to be applied - * @param filterArea {Texture} TODO - might need an update - * @param width {number} the horizontal range of the filter - * @param height {number} the vertical range of the filter - */ -WebGLFilterManager.prototype.applyFilterPass = function (filter, filterArea, width, height) -{ - // use program - var gl = this.renderer.gl; - - var shader = filter.shaders[gl.id]; - - if (!shader) - { - shader = new Shader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderer.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if (filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.aColor, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderer.drawCount++; -}; - -/** - * Initialises the shader buffers. - * - */ -WebGLFilterManager.prototype.initShaderBuffers = function () -{ - var gl = this.renderer.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** - * Destroys the filter and removes it from the filter stack. - * - */ -WebGLFilterManager.prototype.destroy = function () -{ - var gl = this.renderer.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) - { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/managers/WebGLManager.js b/src/core/renderers/webgl/managers/WebGLManager.js index 198f28e..fd544b3 100644 --- a/src/core/renderers/webgl/managers/WebGLManager.js +++ b/src/core/renderers/webgl/managers/WebGLManager.js @@ -13,7 +13,7 @@ this.renderer = renderer; var self = this; - this.renderer.on('context', function(){ + this.renderer.on('context', this._onContextChangeFn = function(){ self.onContextChange(); @@ -26,9 +26,11 @@ WebGLManager.prototype.onContextChange = function () { // do some codes init! -} +}; WebGLManager.prototype.destroy = function () { + this.renderer.off('context', this._onContextChangeFn); + this.renderer = null; }; diff --git a/src/core/renderers/webgl/managers/WebGLShaderManager.js b/src/core/renderers/webgl/managers/WebGLShaderManager.js deleted file mode 100644 index 08585b7..0000000 --- a/src/core/renderers/webgl/managers/WebGLShaderManager.js +++ /dev/null @@ -1,156 +0,0 @@ -var WebGLManager = require('./WebGLManager'), - DefaultShader = require('../shaders/DefaultShader'), - ComplexPrimitiveShader = require('../shaders/ComplexPrimitiveShader'), - PrimitiveShader = require('../shaders/PrimitiveShader'), - utils = require('../../../utils'); - -/** - * @class - * @namespace PIXI - * @param renderer {WebGLRenderer} The renderer this manager works for. - */ -function WebGLShaderManager(renderer) -{ - WebGLManager.call(this, renderer); - - /** - * @member {number} - */ - this.maxAttibs = 10; - - /** - * @member {any[]} - */ - this.attribState = []; - - /** - * @member {any[]} - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @member {any[]} - */ - this.stack = []; - - /** - * @member {number} - * @private - */ - this._currentId = -1; - - /** - * @member {Shader} - * @private - */ - this.currentShader = null; - - this.initPlugins(); - - // listen for context and update necessary shaders - var self = this; - -} - -WebGLShaderManager.prototype = Object.create(WebGLManager.prototype); -WebGLShaderManager.prototype.constructor = WebGLShaderManager; -utils.pluginTarget.mixin(WebGLShaderManager); - -module.exports = WebGLShaderManager; - -WebGLShaderManager.prototype.onContextChange = function () -{ - for (var o in this.plugins) - { - this.plugins[o] = new (this.plugins[o].constructor)(self); - } - - this.defaultShader = new DefaultShader(this); - // init webGL stuff! - this.primitiveShader = new PrimitiveShader(this); - this.complexPrimitiveShader = new ComplexPrimitiveShader(this); -} - - -/** - * Takes the attributes given in parameters. - * - * @param attribs {Array} attribs - */ -WebGLShaderManager.prototype.setAttribs = function (attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (var a in attribs) - { - this.tempAttribState[attribs[a]] = true; - } - - var gl = this.renderer.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if (this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if (this.attribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** - * Sets the current shader. - * - * @param shader {Any} - */ -WebGLShaderManager.prototype.setShader = function (shader) -{ - if (this._currentId === shader.uuid) - { - return false; - } - - this._currentId = shader.uuid; - - this.currentShader = shader; - - this.renderer.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** - * Destroys this object. - * - */ -WebGLShaderManager.prototype.destroy = function () -{ - this.destroyPlugins(); - - this.attribState = null; - - this.tempAttribState = null; - - this.renderer = null; -}; diff --git a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js index 6bb8b2e..e1fb45b 100644 --- a/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/ComplexPrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function ComplexPrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/DefaultShader.js b/src/core/renderers/webgl/shaders/DefaultShader.js deleted file mode 100644 index 77fe02a..0000000 --- a/src/core/renderers/webgl/shaders/DefaultShader.js +++ /dev/null @@ -1,91 +0,0 @@ -var utils = require('../../../utils'), - Shader = require('./Shader'); -/** - * @class - * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. - * @param [vertexSrc] {string} The source of the vertex shader. - * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. - */ -function DefaultShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) -{ - var uniforms = { - - uSampler: { type: 'sampler2D', value: 0 }, - projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, - 0, 1, 0, - 0, 0, 1) }, - }; - - if(customUniforms) - { - for (var u in customUniforms) - { - uniforms[u] = customUniforms[u]; - } - } - - - var attributes = { - aVertexPosition: 0, - aTextureCoord: 0, - aColor: 0 - }; - - if(customAttributes) - { - for (var a in attributes) - { - attributes[a] = customAttributes[a]; - } - } - - /** - * The vertex shader. - * @member {Array} - */ - vertexSrc = vertexSrc || [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform mat3 projectionMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' - ].join('\n'); - - /** - * The fragment shader. - * @member {Array} - */ - fragmentSrc = fragmentSrc || [ - 'precision lowp float;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'uniform sampler2D uSampler;', - - 'void main(void){', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ].join('\n'); - - Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); -} - -// constructor -DefaultShader.prototype = Object.create(Shader.prototype); -DefaultShader.prototype.constructor = DefaultShader; -module.exports = DefaultShader; diff --git a/src/core/renderers/webgl/shaders/PrimitiveShader.js b/src/core/renderers/webgl/shaders/PrimitiveShader.js index cad38fd..89ce005 100644 --- a/src/core/renderers/webgl/shaders/PrimitiveShader.js +++ b/src/core/renderers/webgl/shaders/PrimitiveShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function PrimitiveShader(shaderManager) { diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 35b98d6..f44095b 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -3,11 +3,11 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. * @param [vertexSrc] {string} The source of the vertex shader. * @param [fragmentSrc] {string} The source of the fragment shader. - * @param customUniforms {object} Custom uniforms to use to augment the built-in ones. - * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [uniforms] {object} Uniforms for this shader. + * @param [attributes] {object} Attributes for this shader. */ function Shader(shaderManager, vertexSrc, fragmentSrc, uniforms, attributes) { @@ -30,7 +30,7 @@ */ this.program = null; - this.uniforms = uniforms || {} + this.uniforms = uniforms || {}; this.attributes = attributes || {}; @@ -172,7 +172,7 @@ var uniform = this.uniforms[key]; Object.defineProperty(this, key, { - + get: function () { return uniform.value @@ -423,17 +423,15 @@ default: window.console.warn('Pixi.js Shader Warning: Unknown uniform type: ' + uniform.type); } -} +}; Shader.prototype.syncUniforms = function () { - var gl = this.gl; - this.textureCount = 0; for (var key in this.uniforms) { - this.syncUniform(); + this.syncUniform(this.uniforms[key]); } }; diff --git a/src/core/renderers/webgl/shaders/TextureShader.js b/src/core/renderers/webgl/shaders/TextureShader.js new file mode 100644 index 0000000..9189434 --- /dev/null +++ b/src/core/renderers/webgl/shaders/TextureShader.js @@ -0,0 +1,91 @@ +var Shader = require('./Shader'); + +/** + * @class + * @namespace PIXI + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. + * @param [vertexSrc] {string} The source of the vertex shader. + * @param [fragmentSrc] {string} The source of the fragment shader. + * @param [customUniforms] {object} Custom uniforms to use to augment the built-in ones. + * @param [fragmentSrc] {string} The source of the fragment shader. + */ +function TextureShader(shaderManager, vertexSrc, fragmentSrc, customUniforms, customAttributes) +{ + var uniforms = { + + uSampler: { type: 'sampler2D', value: 0 }, + projectionMatrix: { type: 'mat3', value: new Float32Array(1, 0, 0, + 0, 1, 0, + 0, 0, 1) } + }; + + if(customUniforms) + { + for (var u in customUniforms) + { + uniforms[u] = customUniforms[u]; + } + } + + + var attributes = { + aVertexPosition: 0, + aTextureCoord: 0, + aColor: 0 + }; + + if(customAttributes) + { + for (var a in attributes) + { + attributes[a] = customAttributes[a]; + } + } + + /** + * The vertex shader. + * @member {Array} + */ + vertexSrc = vertexSrc || [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void){', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'); + + /** + * The fragment shader. + * @member {Array} + */ + fragmentSrc = fragmentSrc || [ + 'precision lowp float;', + + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform sampler2D uSampler;', + + 'void main(void){', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + '}' + ].join('\n'); + + Shader.call(this, shaderManager, vertexSrc, fragmentSrc, uniforms, attributes); +} + +// constructor +TextureShader.prototype = Object.create(Shader.prototype); +TextureShader.prototype.constructor = TextureShader; +module.exports = TextureShader; diff --git a/src/core/renderers/webgl/utils/AbstractFilter.js b/src/core/renderers/webgl/utils/AbstractFilter.js index ebbe894..e288d6d 100644 --- a/src/core/renderers/webgl/utils/AbstractFilter.js +++ b/src/core/renderers/webgl/utils/AbstractFilter.js @@ -81,9 +81,9 @@ { for (var i = 0, j = this.shaders.length; i < j; ++i) { - this.shaders[i].syncUniform(uniform) - } -} + this.shaders[i].syncUniform(uniform); + } +}; /* AbstractFilter.prototype.apply = function (frameBuffer) diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js new file mode 100644 index 0000000..249d17b --- /dev/null +++ b/src/core/renderers/webgl/utils/Quad.js @@ -0,0 +1,104 @@ +/** + * @class + * @namespace PIXI + * @param gl {WebGLRenderingContext} The gl context for this quad to use. + */ +function Quad(gl) +{ + this.gl = gl; + +// this.textures = new TextureUvs(); + + this.vertices = new Float32Array([ + 0,0, + 200,0, + 200,200, + 0,200 + ]); + + this.uvs = new Float32Array([ + 0,0, + 1,0, + 1,1, + 0,1 + ]); + + var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); + + this.colors = new Float32Array([ + white, + white, + white, + white + ]); + + this.indices = new Uint16Array([ + 0, 1, 2, 0, 3, 2 + ]); + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 4) * 4, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + + this.upload(); +} + +Quad.prototype.constructor = Quad; + +Quad.prototype.map = function(rect, rect2) +{ + var x = 0; //rect2.x / rect.width; + var y = 0; //rect2.y / rect.height; + + this.uvs[0] = x; + this.uvs[1] = y; + + this.uvs[2] = x + rect2.width / rect.width; + this.uvs[3] = y; + + this.uvs[4] = x + rect2.width / rect.width; + this.uvs[5] = y + rect2.height / rect.height; + + this.uvs[6] = x; + this.uvs[7] = y + rect2.height / rect.height; + + /// ----- + x = rect2.x; + y = rect2.y; + + this.vertices[0] = x; + this.vertices[1] = y; + + this.vertices[2] = x + rect2.width; + this.vertices[3] = y; + + this.vertices[4] = x + rect2.width; + this.vertices[5] = y + rect2.height; + + this.vertices[6] = x; + this.vertices[7] = y + rect2.height; + + this.upload(); +}; + +Quad.prototype.upload = function() +{ + var gl = this.gl; + + gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); + + gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); + + gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); +}; + +module.exports = Quad; + + diff --git a/src/core/sprites/webgl/SpriteBatchRenderer.js b/src/core/sprites/webgl/SpriteBatchRenderer.js index 2e69c97..239f860 100644 --- a/src/core/sprites/webgl/SpriteBatchRenderer.js +++ b/src/core/sprites/webgl/SpriteBatchRenderer.js @@ -1,5 +1,4 @@ var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'), - Shader = require('../../renderers/webgl/shaders/Shader'), WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'), SpriteBatchShader = require('./SpriteBatchShader'); diff --git a/src/core/sprites/webgl/SpriteBatchShader.js b/src/core/sprites/webgl/SpriteBatchShader.js index 1f53252..af28701 100644 --- a/src/core/sprites/webgl/SpriteBatchShader.js +++ b/src/core/sprites/webgl/SpriteBatchShader.js @@ -4,7 +4,7 @@ * @class * @extends Shader * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function SpriteBatchShader(shaderManager) { diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index ccfdf8f..b64a236 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -401,7 +401,6 @@ // both thease only need to be set if they are changing.. // set the projection - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, this.renderer.currentRenderTarget.projectionMatrix.toArray(true)); } } diff --git a/src/core/textures/RenderTexture.js b/src/core/textures/RenderTexture.js index 9c262ad..bc280bb 100644 --- a/src/core/textures/RenderTexture.js +++ b/src/core/textures/RenderTexture.js @@ -53,7 +53,7 @@ throw new Error('Unable to create RenderTexture, you must pass a renderer into the constructor.'); } - width = width || 100; + width = width || 100; height = height || 100; resolution = resolution || 1; @@ -132,8 +132,6 @@ */ this.render = null; - - /** * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. * @@ -145,7 +143,7 @@ { var gl = this.renderer.gl; - this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution)//, this.baseTexture.scaleMode); + this.textureBuffer = new RenderTarget(gl, this.width * this.resolution, this.height * this.resolution);//, this.baseTexture.scaleMode); this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; this.render = this.renderWebGL; @@ -153,7 +151,7 @@ } else { - + this.render = this.renderCanvas; this.textureBuffer = new CanvasBuffer(this.width* this.resolution, this.height* this.resolution); this.baseTexture.source = this.textureBuffer.canvas; @@ -301,7 +299,7 @@ // this.renderer.spriteRenderer.dirty = true; - this.renderer.renderDisplayObject(displayObject, this.textureBuffer)//this.projection, this.textureBuffer.frameBuffer); +this.renderer.renderDisplayObject(displayObject, this.textureBuffer);//this.projection, this.textureBuffer.frameBuffer); // this.renderer.spriteRenderer.dirty = true; @@ -335,11 +333,11 @@ return; } - + var tempAlpha, tempTransform; - + var wt = displayObject.worldTransform; wt.identity(); diff --git a/src/core/utils/pluginTarget.js b/src/core/utils/pluginTarget.js index 011dbc3..7969d02 100644 --- a/src/core/utils/pluginTarget.js +++ b/src/core/utils/pluginTarget.js @@ -9,29 +9,28 @@ * * pluginTarget.mixin(MyObject); */ -function pluginTarget(obj) +function pluginTarget(obj) { obj.__plugins = {}; - obj.registerPlugin = function (pluginName, ctor) + obj.registerPlugin = function (pluginName, ctor) { obj.__plugins[pluginName] = ctor; }; - obj.prototype.initPlugins = function () + obj.prototype.initPlugins = function () { - this.plugins = {}; + this.plugins = this.plugins || {}; - for (var o in obj.__plugins) + for (var o in obj.__plugins) { this.plugins[o] = new (obj.__plugins[o])(this); } }; - obj.prototype.destroyPlugins = function () + obj.prototype.destroyPlugins = function () { - - for (var o in this.plugins) + for (var o in this.plugins) { this.plugins[o].destroy(); this.plugins[o] = null; diff --git a/src/extras/StripShader.js b/src/extras/StripShader.js index c7b69b3..bb12757 100644 --- a/src/extras/StripShader.js +++ b/src/extras/StripShader.js @@ -3,7 +3,7 @@ /** * @class * @namespace PIXI - * @param shaderManager {WebGLShaderManager} The webgl shader manager this shader works for. + * @param shaderManager {ShaderManager} The webgl shader manager this shader works for. */ function StripShader(shaderManager) { @@ -53,4 +53,4 @@ StripShader.prototype.constructor = StripShader; module.exports = StripShader; -//core.WebGLShaderManager.registerPlugin('stripShader', StripShader); +//core.ShaderManager.registerPlugin('stripShader', StripShader); diff --git a/src/loaders/loader.js b/src/loaders/loader.js index b1d9c1d..4c6e1b1 100644 --- a/src/loaders/loader.js +++ b/src/loaders/loader.js @@ -11,6 +11,6 @@ // parse any Image objects into textures .use(textureParser()) // parse any spritesheet data into multiple textures - .use(spritesheetParser()) + .use(spritesheetParser()); module.exports = loader; diff --git a/src/loaders/spritesheetParser.js b/src/loaders/spritesheetParser.js index 22d41e6..934e1d7 100644 --- a/src/loaders/spritesheetParser.js +++ b/src/loaders/spritesheetParser.js @@ -30,7 +30,7 @@ var trim = null; // Check to see if the sprite is trimmed - if (frameData[i].trimmed) + if (frames[i].trimmed) { trim = new core.math.Rectangle( frames[i].spriteSourceSize.x, @@ -40,7 +40,7 @@ ); } - cresource.textures[i] = new core.Texture(resource.texture.baseTexture, size, size.clone(), trim); + resource.textures[i] = new core.Texture(res.texture.baseTexture, size, size.clone(), trim); } } diff --git a/src/loaders/textureParser.js b/src/loaders/textureParser.js index 53d034a..9b3d2d5 100644 --- a/src/loaders/textureParser.js +++ b/src/loaders/textureParser.js @@ -1,5 +1,4 @@ -var Resource = require('asset-loader').Resource, - core = require('../core'); +var core = require('../core'); module.exports = function () {