diff --git a/src/core/math/shapes/Rectangle.js b/src/core/math/shapes/Rectangle.js index 2b2a553..6fa9306 100644 --- a/src/core/math/shapes/Rectangle.js +++ b/src/core/math/shapes/Rectangle.js @@ -66,6 +66,16 @@ return new Rectangle(this.x, this.y, this.width, this.height); }; +Rectangle.prototype.copy = function (rectangle) +{ + this.x = rectangle.x; + this.x = rectangle.y; + this.width = rectangle.width; + this.height = rectangle.height; + + return this; +}; + /** * Checks whether the x and y coordinates given are contained within this Rectangle * @@ -103,7 +113,6 @@ this.height += paddingY * 2; } - Rectangle.prototype.fit = function (rectangle) { if (this.x < rectangle.x) diff --git a/src/core/math/shapes/Rectangle.js b/src/core/math/shapes/Rectangle.js index 2b2a553..6fa9306 100644 --- a/src/core/math/shapes/Rectangle.js +++ b/src/core/math/shapes/Rectangle.js @@ -66,6 +66,16 @@ return new Rectangle(this.x, this.y, this.width, this.height); }; +Rectangle.prototype.copy = function (rectangle) +{ + this.x = rectangle.x; + this.x = rectangle.y; + this.width = rectangle.width; + this.height = rectangle.height; + + return this; +}; + /** * Checks whether the x and y coordinates given are contained within this Rectangle * @@ -103,7 +113,6 @@ this.height += paddingY * 2; } - Rectangle.prototype.fit = function (rectangle) { if (this.x < rectangle.x) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f112b5e..4cc9774 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -113,11 +113,11 @@ * * @member {PIXI.FilterManager} */ - this.filterManager = new FilterManager(this); + this._initContext(); - + this.filterManager = new FilterManager(this); // map some webGL blend and drawmodes.. this.blendModes = mapWebGLBlendModesToPixi(gl); this.drawModes = mapWebGLDrawModesToPixi(gl) @@ -255,7 +255,6 @@ { SystemRenderer.prototype.resize.call(this, width, height); - this.filterManager.resize(width, height); this.rootRenderTarget.resize(width, height); diff --git a/src/core/math/shapes/Rectangle.js b/src/core/math/shapes/Rectangle.js index 2b2a553..6fa9306 100644 --- a/src/core/math/shapes/Rectangle.js +++ b/src/core/math/shapes/Rectangle.js @@ -66,6 +66,16 @@ return new Rectangle(this.x, this.y, this.width, this.height); }; +Rectangle.prototype.copy = function (rectangle) +{ + this.x = rectangle.x; + this.x = rectangle.y; + this.width = rectangle.width; + this.height = rectangle.height; + + return this; +}; + /** * Checks whether the x and y coordinates given are contained within this Rectangle * @@ -103,7 +113,6 @@ this.height += paddingY * 2; } - Rectangle.prototype.fit = function (rectangle) { if (this.x < rectangle.x) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f112b5e..4cc9774 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -113,11 +113,11 @@ * * @member {PIXI.FilterManager} */ - this.filterManager = new FilterManager(this); + this._initContext(); - + this.filterManager = new FilterManager(this); // map some webGL blend and drawmodes.. this.blendModes = mapWebGLBlendModesToPixi(gl); this.drawModes = mapWebGLDrawModesToPixi(gl) @@ -255,7 +255,6 @@ { SystemRenderer.prototype.resize.call(this, width, height); - this.filterManager.resize(width, height); this.rootRenderTarget.resize(width, height); diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js index 765e993..7dd8745 100644 --- a/src/core/renderers/webgl/filters/Filter.js +++ b/src/core/renderers/webgl/filters/Filter.js @@ -42,10 +42,9 @@ // this.uniforms = // this is where we store shader references.. // TODO we could cache this! - this.glShaders = []; - this.resolution = 1; + this.glShaders = []; - //this.canBeUsedDirectl + this.resolution = 1; } // constructor diff --git a/src/core/math/shapes/Rectangle.js b/src/core/math/shapes/Rectangle.js index 2b2a553..6fa9306 100644 --- a/src/core/math/shapes/Rectangle.js +++ b/src/core/math/shapes/Rectangle.js @@ -66,6 +66,16 @@ return new Rectangle(this.x, this.y, this.width, this.height); }; +Rectangle.prototype.copy = function (rectangle) +{ + this.x = rectangle.x; + this.x = rectangle.y; + this.width = rectangle.width; + this.height = rectangle.height; + + return this; +}; + /** * Checks whether the x and y coordinates given are contained within this Rectangle * @@ -103,7 +113,6 @@ this.height += paddingY * 2; } - Rectangle.prototype.fit = function (rectangle) { if (this.x < rectangle.x) diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index f112b5e..4cc9774 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -113,11 +113,11 @@ * * @member {PIXI.FilterManager} */ - this.filterManager = new FilterManager(this); + this._initContext(); - + this.filterManager = new FilterManager(this); // map some webGL blend and drawmodes.. this.blendModes = mapWebGLBlendModesToPixi(gl); this.drawModes = mapWebGLDrawModesToPixi(gl) @@ -255,7 +255,6 @@ { SystemRenderer.prototype.resize.call(this, width, height); - this.filterManager.resize(width, height); this.rootRenderTarget.resize(width, height); diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js index 765e993..7dd8745 100644 --- a/src/core/renderers/webgl/filters/Filter.js +++ b/src/core/renderers/webgl/filters/Filter.js @@ -42,10 +42,9 @@ // this.uniforms = // this is where we store shader references.. // TODO we could cache this! - this.glShaders = []; - this.resolution = 1; + this.glShaders = []; - //this.canBeUsedDirectl + this.resolution = 1; } // constructor diff --git a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js index 0281a38..4d0221a 100644 --- a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js +++ b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js @@ -26,8 +26,15 @@ // know about sprites! this.quad = new Quad(gl, this.filterShader); - this.stack = []; - this.stackIndex = -1; + this.stack = [{ + target:null, + bounds:new PIXI.Rectangle(0,0,800,600), + destination:new PIXI.Rectangle(0,0,800,600), + filters:[], + renderTarget:renderer.rootRenderTarget + }]; + + this.stackIndex = 0; // todo add default! } @@ -37,60 +44,62 @@ FilterManager.prototype.pushFilter = function(target, filters) { + var renderer = this.renderer; + + // get the current filter state.. + var currentState = this.stack[++this.stackIndex]; + if(!currentState) + { + currentState = this.stack[this.stackIndex] = new FilterState(); + } + + // for now we go off the filter of the first resolution.. var resolution = filters[0].resolution; - var bounds = target.getBounds().clone(); + var targetBounds = target.getBounds() ; + var sourceFrame = currentState.sourceFrame; + var destinationFrame = currentState.destinationFrame; //TODO - should this be rounded to reoultion? not 1? - bounds.x = bounds.x | 0; - bounds.y = bounds.y | 0; - bounds.width = bounds.width | 0; - bounds.height = bounds.height | 0; - bounds.pad(4 / resolution); - bounds.fit(new PIXI.Rectangle(0,0,800, 800)) //TODO - output.size? + sourceFrame.x = targetBounds.x | 0; + sourceFrame.y = targetBounds.y | 0; + sourceFrame.width = targetBounds.width | 0; + sourceFrame.height = targetBounds.height | 0; + sourceFrame.pad(4 / resolution); + sourceFrame.fit(new PIXI.Rectangle(0,0,800, 800)); - var renderTarget = FilterManager.getPotRenderTarget(this.renderer.gl, bounds.width, bounds.height, resolution); + destinationFrame.width = sourceFrame.width; + destinationFrame.height = sourceFrame.height; - this.stackIndex++; + var renderTarget = FilterManager.getPotRenderTarget(renderer.gl, sourceFrame.width, sourceFrame.height, resolution); - if(!this.stack[this.stackIndex]) - { - this.stack[this.stackIndex] = { - target:target, - bounds:bounds, - filters:filters, - renderTarget:renderTarget - } - } - else - { - var currentState = this.stack[this.stackIndex]; - currentState.target = target; - currentState.bounds = bounds; - currentState.filters = filters; - currentState.renderTarget = renderTarget; - } + currentState.target = target; + currentState.filters = filters; + currentState.renderTarget = renderTarget; // bind the render taget to draw the shape in the top corner.. - tempRect.width = bounds.width; - tempRect.height = bounds.height; - - this.renderer.bindRenderTarget(renderTarget, tempRect, bounds) - this.renderer.clear(); + // bind the render target + renderer.bindRenderTarget(renderTarget, destinationFrame, sourceFrame); + + // clear the renderTarget + renderer.clear(); } FilterManager.prototype.popFilter = function() { var gl = this.renderer.gl; + var currentState = this.stack[this.stackIndex]; - this.quad.map(currentState.renderTarget.size, currentState.bounds).upload(); + this.quad.map(currentState.renderTarget.size, currentState.sourceFrame).upload(); var filter = currentState.filters[0]; - filter.apply(this, currentState.renderTarget, this.renderer.rootRenderTarget, false); + // lets get the last state as that contains the renderTarget we need to render too + var lastState = this.stack[this.stackIndex-1]; + filter.apply(this, currentState.renderTarget, lastState.renderTarget, false); // return the texture.. FilterManager.freePotRenderTarget(currentState.renderTarget); @@ -100,30 +109,30 @@ FilterManager.prototype.applyFilter = function (filter, input, output, clear) { + var renderer = this.renderer; + var lastState = this.stack[this.stackIndex-1]; + var shader = filter.glShaders[gl.id]; if(!shader) { shader = filter.glShaders[gl.id] = new Shader(gl, filter.vertexSrc, filter.fragmentSrc); } - this.renderer.bindRenderTarget(output); + renderer.bindRenderTarget(output, lastState.destinationFrame, lastState.sourceFrame); if(clear) { - this.renderer.clear(); + renderer.clear(); } - this.renderer.bindShader(shader); + renderer.bindShader(shader); + // this syncs the pixi filters uniforms with glsl uniforms this.syncUniforms(shader, filter); - // console.log(shader.uniforms.filterMatrix); - // bind th einput texture.. - input.texture.bind(0); - - // stack shaders.. - var currentState = this.stack[this.stackIndex]; - + // bind the input texture.. + input.texture.bind(0); + this.quad.draw(); } @@ -187,20 +196,19 @@ */ // TODO playing around here.. this is temporary - (will end up in the shader) // thia returns a matrix that will normalise map filter cords in the filter to screen space -FilterManager.prototype.calculateScreenSpaceMatrix = function (outputMatrix, filterArea, textureSize) +FilterManager.prototype.calculateScreenSpaceMatrix = function (outputMatrix) { var currentState = this.stack[this.stackIndex]; - var screenSize = new math.Rectangle(0,0, this.renderer.width, this.renderer.height); - - return filterTransforms.calculateScreenSpaceMatrix(outputMatrix, filterArea, textureSize); + return filterTransforms.calculateScreenSpaceMatrix(outputMatrix, currentState.bounds, currentState.renderTarget.size); } FilterManager.prototype.calculateNormalisedScreenSpaceMatrix = function (outputMatrix) { var currentState = this.stack[this.stackIndex]; - var screenSize = new math.Rectangle(0,0, this.renderer.width, this.renderer.height); + tempRect.x = this.renderer.width; + tempRect.y = this.renderer.height; - return filterTransforms.calculateNormalisedScreenSpaceMatrix(outputMatrix, currentState.bounds, currentState.renderTarget.size, screenSize); + return filterTransforms.calculateNormalisedScreenSpaceMatrix(outputMatrix, currentState.bounds, currentState.renderTarget.size, tempRect); } // this will map the filter coord so that a texture can be used based on the transform of a sprite @@ -210,17 +218,13 @@ return filterTransforms.calculateSpriteMatrix(outputMatrix, currentState.bounds, currentState.renderTarget.size, sprite); }; -FilterManager.prototype.resize = function(width, height) -{ - //TODO remove! no longer required :D -} - FilterManager.prototype.destroy = function() { } //TODO move to a seperate class could be on renderer? +//also - could cause issue with multiple contexts? FilterManager.getPotRenderTarget = function(gl, minWidth, minHeight, resolution) { //TODO you coud return a bigger texture if there is not one in the pool? @@ -252,5 +256,15 @@ FilterManager.pool[key].push(renderTarget) } +var FilterState = function() +{ + this.renderTarget = null; + this.bounds = new math.Rectangle(); + this.sourceFrame = new math.Rectangle(); + this.destinationFrame = new math.Rectangle(); + this.filters = []; + this.target = null; +} + FilterManager.pool = {}