diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 55e9661..55ef717 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -59,7 +58,8 @@ gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveProgram.offsetVector, -PIXI.offset.x, -PIXI.offset.y); gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 55e9661..55ef717 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -59,7 +58,8 @@ gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveProgram.offsetVector, -PIXI.offset.x, -PIXI.offset.y); gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index a98cdb5..4f5205d 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -23,6 +23,8 @@ this.backgroundColor; this.batchs = []; this.toRemove = []; + + this.filterManager = new PIXI.FilterManager(); } // constructor @@ -56,17 +58,20 @@ * @method render * @param projection {Object} */ -PIXI.WebGLRenderGroup.prototype.render = function(projection) +PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer) { PIXI.WebGLRenderer.updateTextures(); var gl = this.gl; - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // will render all the elements in the group var renderable; + for (var i=0; i < this.batchs.length; i++) { @@ -77,25 +82,8 @@ continue; } - // non sprite batch.. - var worldVisible = renderable.vcount === PIXI.visibleCount; - - if(renderable instanceof PIXI.TilingSprite) - { - if(worldVisible)this.renderTilingSprite(renderable, projection); - } - else if(renderable instanceof PIXI.Strip) - { - if(worldVisible)this.renderStrip(renderable, projection); - } - else if(renderable instanceof PIXI.Graphics) - { - if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix); - } - else if(renderable instanceof PIXI.FilterBlock) - { - this.handleFilterBlock(renderable, projection); - } + // render special + this.renderSpecial(renderable, projection); } } @@ -108,7 +96,7 @@ * @param projection {Object} * @private */ -PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection) +PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer) { PIXI.WebGLRenderer.updateTextures(); @@ -293,41 +281,32 @@ } } -PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection) +PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection) { /* * for now only masks are supported.. */ var gl = PIXI.gl; - - if(renderable.open) + + if(filterBlock.open) { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - var filter = renderable.data[0]; + var filter = filterBlock.data[0]; + //console.log(filter) + this.filterManager.pushFilter(filterBlock);//filter); + // ok so.. - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader - } - - PIXI.pushShader(filter.shader); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { + gl.enable(gl.STENCIL_TEST); gl.colorMask(false, false, false, false); gl.stencilFunc(gl.ALWAYS,1,0xff); gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - PIXI.WebGLGraphics.renderGraphics(renderable.data, projection); + PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection); gl.colorMask(true, true, true, true); gl.stencilFunc(gl.NOTEQUAL,0,0xff); @@ -336,10 +315,11 @@ } else { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - PIXI.popShader(); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + this.filterManager.popFilter(); + // PIXI.popShader(); + // gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 55e9661..55ef717 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -59,7 +58,8 @@ gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveProgram.offsetVector, -PIXI.offset.x, -PIXI.offset.y); gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index a98cdb5..4f5205d 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -23,6 +23,8 @@ this.backgroundColor; this.batchs = []; this.toRemove = []; + + this.filterManager = new PIXI.FilterManager(); } // constructor @@ -56,17 +58,20 @@ * @method render * @param projection {Object} */ -PIXI.WebGLRenderGroup.prototype.render = function(projection) +PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer) { PIXI.WebGLRenderer.updateTextures(); var gl = this.gl; - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // will render all the elements in the group var renderable; + for (var i=0; i < this.batchs.length; i++) { @@ -77,25 +82,8 @@ continue; } - // non sprite batch.. - var worldVisible = renderable.vcount === PIXI.visibleCount; - - if(renderable instanceof PIXI.TilingSprite) - { - if(worldVisible)this.renderTilingSprite(renderable, projection); - } - else if(renderable instanceof PIXI.Strip) - { - if(worldVisible)this.renderStrip(renderable, projection); - } - else if(renderable instanceof PIXI.Graphics) - { - if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix); - } - else if(renderable instanceof PIXI.FilterBlock) - { - this.handleFilterBlock(renderable, projection); - } + // render special + this.renderSpecial(renderable, projection); } } @@ -108,7 +96,7 @@ * @param projection {Object} * @private */ -PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection) +PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer) { PIXI.WebGLRenderer.updateTextures(); @@ -293,41 +281,32 @@ } } -PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection) +PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection) { /* * for now only masks are supported.. */ var gl = PIXI.gl; - - if(renderable.open) + + if(filterBlock.open) { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - var filter = renderable.data[0]; + var filter = filterBlock.data[0]; + //console.log(filter) + this.filterManager.pushFilter(filterBlock);//filter); + // ok so.. - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader - } - - PIXI.pushShader(filter.shader); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { + gl.enable(gl.STENCIL_TEST); gl.colorMask(false, false, false, false); gl.stencilFunc(gl.ALWAYS,1,0xff); gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - PIXI.WebGLGraphics.renderGraphics(renderable.data, projection); + PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection); gl.colorMask(true, true, true, true); gl.stencilFunc(gl.NOTEQUAL,0,0xff); @@ -336,10 +315,11 @@ } else { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - PIXI.popShader(); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + this.filterManager.popFilter(); + // PIXI.popShader(); + // gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index 2c6fca7..4956a57 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -68,6 +68,8 @@ PIXI.initDefaultStripShader(); + + // PIXI.activateDefaultShader(); var gl = this.gl; @@ -81,6 +83,9 @@ gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); + PIXI.offset = new PIXI.Point(0, 0); + + // TODO remove thease globals.. this.resize(this.width, this.height); this.contextLost = false; @@ -178,6 +183,10 @@ // HACK TO TEST this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + this.stageRenderGroup.render(PIXI.projection); // interaction @@ -303,7 +312,10 @@ //var projectionMatrix = this.projectionMatrix; PIXI.projection.x = this.width/2; - PIXI.projection.y = this.height/2; + PIXI.projection.y = -this.height/2; + + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; // projectionMatrix[0] = 2/this.width; // projectionMatrix[5] = -2/this.height; diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 55e9661..55ef717 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -59,7 +58,8 @@ gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveProgram.offsetVector, -PIXI.offset.x, -PIXI.offset.y); gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index a98cdb5..4f5205d 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -23,6 +23,8 @@ this.backgroundColor; this.batchs = []; this.toRemove = []; + + this.filterManager = new PIXI.FilterManager(); } // constructor @@ -56,17 +58,20 @@ * @method render * @param projection {Object} */ -PIXI.WebGLRenderGroup.prototype.render = function(projection) +PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer) { PIXI.WebGLRenderer.updateTextures(); var gl = this.gl; - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // will render all the elements in the group var renderable; + for (var i=0; i < this.batchs.length; i++) { @@ -77,25 +82,8 @@ continue; } - // non sprite batch.. - var worldVisible = renderable.vcount === PIXI.visibleCount; - - if(renderable instanceof PIXI.TilingSprite) - { - if(worldVisible)this.renderTilingSprite(renderable, projection); - } - else if(renderable instanceof PIXI.Strip) - { - if(worldVisible)this.renderStrip(renderable, projection); - } - else if(renderable instanceof PIXI.Graphics) - { - if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix); - } - else if(renderable instanceof PIXI.FilterBlock) - { - this.handleFilterBlock(renderable, projection); - } + // render special + this.renderSpecial(renderable, projection); } } @@ -108,7 +96,7 @@ * @param projection {Object} * @private */ -PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection) +PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer) { PIXI.WebGLRenderer.updateTextures(); @@ -293,41 +281,32 @@ } } -PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection) +PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection) { /* * for now only masks are supported.. */ var gl = PIXI.gl; - - if(renderable.open) + + if(filterBlock.open) { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - var filter = renderable.data[0]; + var filter = filterBlock.data[0]; + //console.log(filter) + this.filterManager.pushFilter(filterBlock);//filter); + // ok so.. - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader - } - - PIXI.pushShader(filter.shader); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { + gl.enable(gl.STENCIL_TEST); gl.colorMask(false, false, false, false); gl.stencilFunc(gl.ALWAYS,1,0xff); gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - PIXI.WebGLGraphics.renderGraphics(renderable.data, projection); + PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection); gl.colorMask(true, true, true, true); gl.stencilFunc(gl.NOTEQUAL,0,0xff); @@ -336,10 +315,11 @@ } else { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - PIXI.popShader(); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + this.filterManager.popFilter(); + // PIXI.popShader(); + // gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index 2c6fca7..4956a57 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -68,6 +68,8 @@ PIXI.initDefaultStripShader(); + + // PIXI.activateDefaultShader(); var gl = this.gl; @@ -81,6 +83,9 @@ gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); + PIXI.offset = new PIXI.Point(0, 0); + + // TODO remove thease globals.. this.resize(this.width, this.height); this.contextLost = false; @@ -178,6 +183,10 @@ // HACK TO TEST this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + this.stageRenderGroup.render(PIXI.projection); // interaction @@ -303,7 +312,10 @@ //var projectionMatrix = this.projectionMatrix; PIXI.projection.x = this.width/2; - PIXI.projection.y = this.height/2; + PIXI.projection.y = -this.height/2; + + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; // projectionMatrix[0] = 2/this.width; // projectionMatrix[5] = -2/this.height; diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js index f14571a..cec80db 100644 --- a/src/pixi/renderers/webgl/WebGLShaders.js +++ b/src/pixi/renderers/webgl/WebGLShaders.js @@ -24,10 +24,14 @@ "attribute float aColor;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "varying vec2 vTextureCoord;", + "varying float vColor;", + //"const vec2 offsetVector = vec2(1000.0, 0.0);", + "const vec2 center = vec2(-1.0, 1.0);", "void main(void) {", - "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", "vTextureCoord = aTextureCoord;", "vColor = aColor;", "}" @@ -83,10 +87,12 @@ "attribute vec4 aColor;", "uniform mat3 translationMatrix;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "uniform float alpha;", "varying vec4 vColor;", "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", + "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);", + "v -= offsetVector.xyx;", "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", "vColor = aColor * alpha;", "}" @@ -106,6 +112,8 @@ shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor"); shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); + shaderProgram.offsetVector = gl.getUniformLocation(shaderProgram, "offsetVector"); + shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix"); @@ -122,14 +130,28 @@ PIXI.initDefaultShader = function() { + PIXI.frameBufferStack = []; + PIXI.frameBufferPool = []; + PIXI.defaultShader = new PIXI.PixiShader(); PIXI.defaultShader.init(); PIXI.pushShader(PIXI.defaultShader); + + // offset.. + + + + // ok and also create 2 spare frame buffers.. +// PIXI.frameBuffer1 = PIXI.generateFrameBuffer(800, 600); +// PIXI.frameBuffer2 = PIXI.generateFrameBuffer(800, 600); +// PIXI.currentFrameBuffer; + /* PIXI.shaderStack.push(PIXI.defaultShader); PIXI.current*/ } + PIXI.initDefaultStripShader = function() { var gl = this.gl; @@ -197,12 +219,19 @@ PIXI.pushShader = function(shader) { - PIXI.shaderStack.push(shader); - var gl = PIXI.gl; + gl.colorMask(true, true, true, true); + gl.viewport(0, 0, this.width, this.height); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + PIXI.shaderStack.push(shader); + var shaderProgram = shader.program; + // flip! the texture.. + // set the texture! // map uniforms.. gl.useProgram(shaderProgram); diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 55e9661..55ef717 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -59,7 +58,8 @@ gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveProgram.offsetVector, -PIXI.offset.x, -PIXI.offset.y); gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index a98cdb5..4f5205d 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -23,6 +23,8 @@ this.backgroundColor; this.batchs = []; this.toRemove = []; + + this.filterManager = new PIXI.FilterManager(); } // constructor @@ -56,17 +58,20 @@ * @method render * @param projection {Object} */ -PIXI.WebGLRenderGroup.prototype.render = function(projection) +PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer) { PIXI.WebGLRenderer.updateTextures(); var gl = this.gl; - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // will render all the elements in the group var renderable; + for (var i=0; i < this.batchs.length; i++) { @@ -77,25 +82,8 @@ continue; } - // non sprite batch.. - var worldVisible = renderable.vcount === PIXI.visibleCount; - - if(renderable instanceof PIXI.TilingSprite) - { - if(worldVisible)this.renderTilingSprite(renderable, projection); - } - else if(renderable instanceof PIXI.Strip) - { - if(worldVisible)this.renderStrip(renderable, projection); - } - else if(renderable instanceof PIXI.Graphics) - { - if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix); - } - else if(renderable instanceof PIXI.FilterBlock) - { - this.handleFilterBlock(renderable, projection); - } + // render special + this.renderSpecial(renderable, projection); } } @@ -108,7 +96,7 @@ * @param projection {Object} * @private */ -PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection) +PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer) { PIXI.WebGLRenderer.updateTextures(); @@ -293,41 +281,32 @@ } } -PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection) +PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection) { /* * for now only masks are supported.. */ var gl = PIXI.gl; - - if(renderable.open) + + if(filterBlock.open) { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - var filter = renderable.data[0]; + var filter = filterBlock.data[0]; + //console.log(filter) + this.filterManager.pushFilter(filterBlock);//filter); + // ok so.. - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader - } - - PIXI.pushShader(filter.shader); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { + gl.enable(gl.STENCIL_TEST); gl.colorMask(false, false, false, false); gl.stencilFunc(gl.ALWAYS,1,0xff); gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - PIXI.WebGLGraphics.renderGraphics(renderable.data, projection); + PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection); gl.colorMask(true, true, true, true); gl.stencilFunc(gl.NOTEQUAL,0,0xff); @@ -336,10 +315,11 @@ } else { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - PIXI.popShader(); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + this.filterManager.popFilter(); + // PIXI.popShader(); + // gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index 2c6fca7..4956a57 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -68,6 +68,8 @@ PIXI.initDefaultStripShader(); + + // PIXI.activateDefaultShader(); var gl = this.gl; @@ -81,6 +83,9 @@ gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); + PIXI.offset = new PIXI.Point(0, 0); + + // TODO remove thease globals.. this.resize(this.width, this.height); this.contextLost = false; @@ -178,6 +183,10 @@ // HACK TO TEST this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + this.stageRenderGroup.render(PIXI.projection); // interaction @@ -303,7 +312,10 @@ //var projectionMatrix = this.projectionMatrix; PIXI.projection.x = this.width/2; - PIXI.projection.y = this.height/2; + PIXI.projection.y = -this.height/2; + + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; // projectionMatrix[0] = 2/this.width; // projectionMatrix[5] = -2/this.height; diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js index f14571a..cec80db 100644 --- a/src/pixi/renderers/webgl/WebGLShaders.js +++ b/src/pixi/renderers/webgl/WebGLShaders.js @@ -24,10 +24,14 @@ "attribute float aColor;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "varying vec2 vTextureCoord;", + "varying float vColor;", + //"const vec2 offsetVector = vec2(1000.0, 0.0);", + "const vec2 center = vec2(-1.0, 1.0);", "void main(void) {", - "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", "vTextureCoord = aTextureCoord;", "vColor = aColor;", "}" @@ -83,10 +87,12 @@ "attribute vec4 aColor;", "uniform mat3 translationMatrix;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "uniform float alpha;", "varying vec4 vColor;", "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", + "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);", + "v -= offsetVector.xyx;", "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", "vColor = aColor * alpha;", "}" @@ -106,6 +112,8 @@ shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor"); shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); + shaderProgram.offsetVector = gl.getUniformLocation(shaderProgram, "offsetVector"); + shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix"); @@ -122,14 +130,28 @@ PIXI.initDefaultShader = function() { + PIXI.frameBufferStack = []; + PIXI.frameBufferPool = []; + PIXI.defaultShader = new PIXI.PixiShader(); PIXI.defaultShader.init(); PIXI.pushShader(PIXI.defaultShader); + + // offset.. + + + + // ok and also create 2 spare frame buffers.. +// PIXI.frameBuffer1 = PIXI.generateFrameBuffer(800, 600); +// PIXI.frameBuffer2 = PIXI.generateFrameBuffer(800, 600); +// PIXI.currentFrameBuffer; + /* PIXI.shaderStack.push(PIXI.defaultShader); PIXI.current*/ } + PIXI.initDefaultStripShader = function() { var gl = this.gl; @@ -197,12 +219,19 @@ PIXI.pushShader = function(shader) { - PIXI.shaderStack.push(shader); - var gl = PIXI.gl; + gl.colorMask(true, true, true, true); + gl.viewport(0, 0, this.width, this.height); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + PIXI.shaderStack.push(shader); + var shaderProgram = shader.program; + // flip! the texture.. + // set the texture! // map uniforms.. gl.useProgram(shaderProgram); diff --git a/src/pixi/renderers/webgl/filters/Filter.js b/src/pixi/renderers/webgl/filters/Filter.js new file mode 100644 index 0000000..2de16c5 --- /dev/null +++ b/src/pixi/renderers/webgl/filters/Filter.js @@ -0,0 +1,145 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.Filter = function() +{ + // build a program + /* + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + + "uniform vec2 projectionVector;", + "uniform vec2 dimensions;", + "uniform vec2 offsetVector;", + + "varying vec2 vTextureCoord;", + "const vec2 center = vec2(-1.0, 1.0);", + + "void main(void) {", + + "vec2 tempVector = aVertexPosition;", + "tempVector *= dimensions;", + + "tempVector.y -= dimensions.y;", + "tempVector += offsetVector;", + + "tempVector /= projectionVector;", + + "tempVector *= 2.0;", + + "tempVector += center;", + + "gl_Position = vec4( tempVector, 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "}" + ];*/ + + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + "attribute float aColor;", + + "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", + "varying vec2 vTextureCoord;", + + "varying float vColor;", + "const vec2 center = vec2(-1.0, 1.0);", + "void main(void) {", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "vColor = aColor;", + "}" + ]; + + this.fragmentSrc = [ + "precision lowp float;", + "varying vec2 vTextureCoord;", + "uniform sampler2D uSampler;", + + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vTextureCoord).grba;", + "}" + ]; + + + // build program + this.program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); + + var gl = PIXI.gl; + + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(this.program, "uSampler"); + this.projectionVector = gl.getUniformLocation(this.program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(this.program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(this.program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(this.program, "aTextureCoord"); + +} + +PIXI.Filter.prototype.begin = function() +{ + var gl = PIXI.gl; + + gl.bindTexture(gl.TEXTURE_2D, this.texture); + + var filterArea = this.target.filterArea; + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer); + + // set view port + gl.viewport(0, 0, filterArea.width, filterArea.height); + + // update projection + gl.uniform2f(PIXI.currentShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.currentShader.offsetVector, -filterArea.x, -filterArea.y); + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); +} + + +PIXI.Filter.prototype.end = function(x, y, offsetX, offsetY) +{ + var gl = PIXI.gl; + + // set the filter proram.. + gl.useProgram(this.program); + + var filterArea = this.target.filterArea; + + // set the uniforms.. + gl.uniform2f(this.projectionVector, x, y) + gl.uniform2f(this.offsetVector, filterArea.x - offsetX, -(filterArea.y-offsetY)) + gl.uniform2f(this.dimensions, filterArea.width, filterArea.height); + + // bind the buffers.. + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.vertexAttribPointer(this.aTextureCoord, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + + // draw the filter... + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); + + gl.useProgram(PIXI.defaultShader.program); +} + + + +// API diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 55e9661..55ef717 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -59,7 +58,8 @@ gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveProgram.offsetVector, -PIXI.offset.x, -PIXI.offset.y); gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index a98cdb5..4f5205d 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -23,6 +23,8 @@ this.backgroundColor; this.batchs = []; this.toRemove = []; + + this.filterManager = new PIXI.FilterManager(); } // constructor @@ -56,17 +58,20 @@ * @method render * @param projection {Object} */ -PIXI.WebGLRenderGroup.prototype.render = function(projection) +PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer) { PIXI.WebGLRenderer.updateTextures(); var gl = this.gl; - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // will render all the elements in the group var renderable; + for (var i=0; i < this.batchs.length; i++) { @@ -77,25 +82,8 @@ continue; } - // non sprite batch.. - var worldVisible = renderable.vcount === PIXI.visibleCount; - - if(renderable instanceof PIXI.TilingSprite) - { - if(worldVisible)this.renderTilingSprite(renderable, projection); - } - else if(renderable instanceof PIXI.Strip) - { - if(worldVisible)this.renderStrip(renderable, projection); - } - else if(renderable instanceof PIXI.Graphics) - { - if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix); - } - else if(renderable instanceof PIXI.FilterBlock) - { - this.handleFilterBlock(renderable, projection); - } + // render special + this.renderSpecial(renderable, projection); } } @@ -108,7 +96,7 @@ * @param projection {Object} * @private */ -PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection) +PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer) { PIXI.WebGLRenderer.updateTextures(); @@ -293,41 +281,32 @@ } } -PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection) +PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection) { /* * for now only masks are supported.. */ var gl = PIXI.gl; - - if(renderable.open) + + if(filterBlock.open) { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - var filter = renderable.data[0]; + var filter = filterBlock.data[0]; + //console.log(filter) + this.filterManager.pushFilter(filterBlock);//filter); + // ok so.. - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader - } - - PIXI.pushShader(filter.shader); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { + gl.enable(gl.STENCIL_TEST); gl.colorMask(false, false, false, false); gl.stencilFunc(gl.ALWAYS,1,0xff); gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - PIXI.WebGLGraphics.renderGraphics(renderable.data, projection); + PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection); gl.colorMask(true, true, true, true); gl.stencilFunc(gl.NOTEQUAL,0,0xff); @@ -336,10 +315,11 @@ } else { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - PIXI.popShader(); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + this.filterManager.popFilter(); + // PIXI.popShader(); + // gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index 2c6fca7..4956a57 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -68,6 +68,8 @@ PIXI.initDefaultStripShader(); + + // PIXI.activateDefaultShader(); var gl = this.gl; @@ -81,6 +83,9 @@ gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); + PIXI.offset = new PIXI.Point(0, 0); + + // TODO remove thease globals.. this.resize(this.width, this.height); this.contextLost = false; @@ -178,6 +183,10 @@ // HACK TO TEST this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + this.stageRenderGroup.render(PIXI.projection); // interaction @@ -303,7 +312,10 @@ //var projectionMatrix = this.projectionMatrix; PIXI.projection.x = this.width/2; - PIXI.projection.y = this.height/2; + PIXI.projection.y = -this.height/2; + + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; // projectionMatrix[0] = 2/this.width; // projectionMatrix[5] = -2/this.height; diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js index f14571a..cec80db 100644 --- a/src/pixi/renderers/webgl/WebGLShaders.js +++ b/src/pixi/renderers/webgl/WebGLShaders.js @@ -24,10 +24,14 @@ "attribute float aColor;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "varying vec2 vTextureCoord;", + "varying float vColor;", + //"const vec2 offsetVector = vec2(1000.0, 0.0);", + "const vec2 center = vec2(-1.0, 1.0);", "void main(void) {", - "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", "vTextureCoord = aTextureCoord;", "vColor = aColor;", "}" @@ -83,10 +87,12 @@ "attribute vec4 aColor;", "uniform mat3 translationMatrix;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "uniform float alpha;", "varying vec4 vColor;", "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", + "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);", + "v -= offsetVector.xyx;", "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", "vColor = aColor * alpha;", "}" @@ -106,6 +112,8 @@ shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor"); shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); + shaderProgram.offsetVector = gl.getUniformLocation(shaderProgram, "offsetVector"); + shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix"); @@ -122,14 +130,28 @@ PIXI.initDefaultShader = function() { + PIXI.frameBufferStack = []; + PIXI.frameBufferPool = []; + PIXI.defaultShader = new PIXI.PixiShader(); PIXI.defaultShader.init(); PIXI.pushShader(PIXI.defaultShader); + + // offset.. + + + + // ok and also create 2 spare frame buffers.. +// PIXI.frameBuffer1 = PIXI.generateFrameBuffer(800, 600); +// PIXI.frameBuffer2 = PIXI.generateFrameBuffer(800, 600); +// PIXI.currentFrameBuffer; + /* PIXI.shaderStack.push(PIXI.defaultShader); PIXI.current*/ } + PIXI.initDefaultStripShader = function() { var gl = this.gl; @@ -197,12 +219,19 @@ PIXI.pushShader = function(shader) { - PIXI.shaderStack.push(shader); - var gl = PIXI.gl; + gl.colorMask(true, true, true, true); + gl.viewport(0, 0, this.width, this.height); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + PIXI.shaderStack.push(shader); + var shaderProgram = shader.program; + // flip! the texture.. + // set the texture! // map uniforms.. gl.useProgram(shaderProgram); diff --git a/src/pixi/renderers/webgl/filters/Filter.js b/src/pixi/renderers/webgl/filters/Filter.js new file mode 100644 index 0000000..2de16c5 --- /dev/null +++ b/src/pixi/renderers/webgl/filters/Filter.js @@ -0,0 +1,145 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.Filter = function() +{ + // build a program + /* + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + + "uniform vec2 projectionVector;", + "uniform vec2 dimensions;", + "uniform vec2 offsetVector;", + + "varying vec2 vTextureCoord;", + "const vec2 center = vec2(-1.0, 1.0);", + + "void main(void) {", + + "vec2 tempVector = aVertexPosition;", + "tempVector *= dimensions;", + + "tempVector.y -= dimensions.y;", + "tempVector += offsetVector;", + + "tempVector /= projectionVector;", + + "tempVector *= 2.0;", + + "tempVector += center;", + + "gl_Position = vec4( tempVector, 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "}" + ];*/ + + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + "attribute float aColor;", + + "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", + "varying vec2 vTextureCoord;", + + "varying float vColor;", + "const vec2 center = vec2(-1.0, 1.0);", + "void main(void) {", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "vColor = aColor;", + "}" + ]; + + this.fragmentSrc = [ + "precision lowp float;", + "varying vec2 vTextureCoord;", + "uniform sampler2D uSampler;", + + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vTextureCoord).grba;", + "}" + ]; + + + // build program + this.program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); + + var gl = PIXI.gl; + + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(this.program, "uSampler"); + this.projectionVector = gl.getUniformLocation(this.program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(this.program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(this.program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(this.program, "aTextureCoord"); + +} + +PIXI.Filter.prototype.begin = function() +{ + var gl = PIXI.gl; + + gl.bindTexture(gl.TEXTURE_2D, this.texture); + + var filterArea = this.target.filterArea; + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer); + + // set view port + gl.viewport(0, 0, filterArea.width, filterArea.height); + + // update projection + gl.uniform2f(PIXI.currentShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.currentShader.offsetVector, -filterArea.x, -filterArea.y); + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); +} + + +PIXI.Filter.prototype.end = function(x, y, offsetX, offsetY) +{ + var gl = PIXI.gl; + + // set the filter proram.. + gl.useProgram(this.program); + + var filterArea = this.target.filterArea; + + // set the uniforms.. + gl.uniform2f(this.projectionVector, x, y) + gl.uniform2f(this.offsetVector, filterArea.x - offsetX, -(filterArea.y-offsetY)) + gl.uniform2f(this.dimensions, filterArea.width, filterArea.height); + + // bind the buffers.. + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.vertexAttribPointer(this.aTextureCoord, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + + // draw the filter... + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); + + gl.useProgram(PIXI.defaultShader.program); +} + + + +// API diff --git a/src/pixi/renderers/webgl/filters/FilterManager.js b/src/pixi/renderers/webgl/filters/FilterManager.js new file mode 100644 index 0000000..0be0164 --- /dev/null +++ b/src/pixi/renderers/webgl/filters/FilterManager.js @@ -0,0 +1,365 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.FilterManager = function() +{ + this.filterStack = []; + this.texturePool = []; + + this.offsetX = 0; + this.offsetY = 0; + + this.initShaderBuffers(); +} + +// API + +PIXI.FilterManager.prototype.begin = function(projection, buffer) +{ + this.width = projection.x * 2; + this.height = -projection.y * 2; + this.buffer = buffer; +} + +PIXI.FilterManager.prototype.pushFilter = function(filterBlock) +{ + + // filter program + var filter = filterBlock.data[0]; + + this.offsetX += filterBlock.target.filterArea.x; + this.offsetY += filterBlock.target.filterArea.y; + + this.filterStack.push(filterBlock); + + var gl = PIXI.gl; + + var texture = this.texturePool.pop(); + if(!texture)texture = new PIXI.FilterTexture(); + + gl.bindTexture(gl.TEXTURE_2D, texture.texture); + + this.getBounds(filterBlock.target); + + var filterArea = filterBlock.target.filterArea; + + 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); + + //PIXI.currentArea = filterArea + + PIXI.projection.x = filterArea.width/2; + PIXI.projection.y = -filterArea.height/2; + + PIXI.offset.x = -filterArea.x; + PIXI.offset.y = -filterArea.y; + + // update projection + gl.uniform2f(PIXI.currentShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.currentShader.offsetVector, -filterArea.x, -filterArea.y); + //PIXI.primitiveProgram + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + //filter.texture = texture; + filterBlock._glFilterTexture = texture; +} + +PIXI.FilterManager.prototype.popFilter = function() +{ + var filterBlock = this.filterStack.pop(); + var filter = filterBlock.data[0]; + + //console.log( this.offsetY); + this.offsetX -= filterBlock.target.filterArea.x; + this.offsetY -= filterBlock.target.filterArea.y; + + var gl = PIXI.gl; + + 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, false); + } + else + { + var currentFilter = this.filterStack[this.filterStack.length-1]; + var filterArea = currentFilter.target.filterArea; + + sizeX = filterArea.width; + sizeY = filterArea.height; + + offsetX = filterArea.x; + offsetY = filterArea.y; + + buffer = currentFilter._glFilterTexture.frameBuffer; + } + + gl.viewport(0, 0, sizeX, sizeY); + gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + + /////// + if(!filter.shader) + { + //filter.shader = new PIXI.Filter(); + + var shader = new PIXI.PixiShader(); + + shader.fragmentSrc = filter.fragmentSrc; + shader.uniforms = filter.uniforms; + shader.init(); + + filter.shader = shader + //filter.shader.target = filter.target; + } + + var shader = filter.shader; + var filterArea = filterBlock.target.filterArea; + + // set the shader + gl.useProgram(shader.program); + // set the uniforms.. + + PIXI.projection.x = sizeX/2; + PIXI.projection.y = -sizeY/2; + + gl.uniform2f(shader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(shader.offsetVector, 0,0) + + shader.syncUniforms(); + + PIXI.offset.x = offsetX; + PIXI.offset.y = offsetY; + + var x = filterArea.x-offsetX; + var y = filterArea.y-offsetY; + + // bind 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.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.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, filterBlock._glFilterTexture.texture); + + // draw the filter... + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); + + // now restore the regular shader.. + gl.useProgram(PIXI.defaultShader.program); + gl.uniform2f(PIXI.currentShader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(PIXI.currentShader.offsetVector, -offsetX, -offsetY); + + // return the texture to the pool + + this.texturePool.push(filterBlock._glFilterTexture); + filterBlock._glFilterTexture = null; + +} + +PIXI.FilterManager.prototype.initShaderBuffers = function() +{ + var gl = PIXI.gl; + + // create some buffers + this.vertexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + // bind and upload the vertexs.. + // keep a refferance 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); + + // 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); +} + +PIXI.FilterManager.prototype.getBounds = function(displayObject) +{ + // time to get the width and height of the object! + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest; + var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4; + + var tempObject = displayObject.first; + var testObject = displayObject.last._iNext; + + var maxX = -Infinity; + var maxY = -Infinity; + + var minX = Infinity; + var minY = Infinity; + + do + { + // TODO can be optimized! - what if there is no scale / rotation? + + if(tempObject instanceof PIXI.Sprite) + { + width = tempObject.texture.frame.width; + height = tempObject.texture.frame.height; + + // TODO trim?? + aX = tempObject.anchor.x; + aY = tempObject.anchor.y; + w0 = width * (1-aX); + w1 = width * -aX; + + h0 = height * (1-aY); + h1 = height * -aY; + + doTest = true; + } + else if(tempObject instanceof PIXI.Graphics) + { + tempObject.updateFilterBounds(); + + var bounds = tempObject.bounds; + + width = bounds.width; + height = bounds.height; + + w0 = bounds.x + w1 = bounds.x + bounds.width; + + h0 = bounds.y + h1 = bounds.y + bounds.height; + + doTest = true; + } + + if(doTest) + { + worldTransform = tempObject.worldTransform; + + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; + + x1 = a * w1 + c * h1 + tx; + y1 = d * h1 + b * w1 + ty; + + x2 = a * w0 + c * h1 + tx; + y2 = d * h1 + b * w0 + ty; + + x3 = a * w0 + c * h0 + tx; + y3 = d * h0 + b * w0 + ty; + + x4 = a * w1 + c * h0 + tx; + y4 = d * h0 + b * w1 + ty; + + minX = x1 < minX ? x1 : minX; + minX = x2 < minX ? x2 : minX; + minX = x3 < minX ? x3 : minX; + minX = x4 < minX ? x4 : minX; + + minY = y1 < minY ? y1 : minY; + minY = y2 < minY ? y2 : minY; + minY = y3 < minY ? y3 : minY; + minY = y4 < minY ? y4 : minY; + + maxX = x1 > maxX ? x1 : maxX; + maxX = x2 > maxX ? x2 : maxX; + maxX = x3 > maxX ? x3 : maxX; + maxX = x4 > maxX ? x4 : maxX; + + maxY = y1 > maxY ? y1 : maxY; + maxY = y2 > maxY ? y2 : maxY; + maxY = y3 > maxY ? y3 : maxY; + maxY = y4 > maxY ? y4 : maxY; + } + + doTest = false; + tempObject = tempObject._iNext; + } + while(tempObject != testObject) + + displayObject.filterArea.x = minX; + displayObject.filterArea.y = minY; + displayObject.filterArea.width = maxX - minX; + displayObject.filterArea.height = maxY - minY; +} + +PIXI.FilterTexture = function() +{ + var gl = PIXI.gl; + + // next time to create a frame buffer and texture + this.frameBuffer = gl.createFramebuffer(); + this.texture = gl.createTexture(); + + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); +} diff --git a/Gruntfile.js b/Gruntfile.js index 5f7fba8..77b347e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,6 +39,8 @@ '<%= dirs.src %>/renderers/webgl/WebGLRenderer.js', '<%= dirs.src %>/renderers/webgl/WebGLBatch.js', '<%= dirs.src %>/renderers/webgl/WebGLRenderGroup.js', + '<%= dirs.src %>/renderers/webgl/filters/FilterManager.js', + '<%= dirs.src %>/renderers/webgl/filters/Filter.js', '<%= dirs.src %>/renderers/canvas/CanvasRenderer.js', '<%= dirs.src %>/renderers/canvas/CanvasGraphics.js', '<%= dirs.src %>/primitives/Graphics.js', diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 455284d..49f1737 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -164,6 +164,9 @@ this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -353,6 +356,7 @@ { //if(this.filter)return; //this.filter = true; +// data[0].target = this; // insert a filter block.. // TODO Onject pool thease bad boys.. @@ -370,6 +374,8 @@ start.open = true; + start.target = this; + /* * insert start */ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index c4c6154..414dad4 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -22,7 +22,7 @@ "uniform sampler2D uSampler;", "uniform vec2 scale;", "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - "const vec2 textureDimensions = vec2(245.0, 263.0);", + "const vec2 textureDimensions = vec2(800.0, 600.0);", "void main(void) {", diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ff26361..913683a 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -6,7 +6,7 @@ { // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0.5}, + invert: {type: 'f', value: 0}, }; this.fragmentSrc = [ diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index f718178..8e8c3dd 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -221,6 +221,81 @@ this.dirty = true; this.clearDirty = true; this.graphicsData = []; + + this.bounds = null//new PIXI.Rectangle(); +} + + +PIXI.Graphics.prototype.updateFilterBounds = function() +{ + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; + + var minY = Infinity; + var maxY = -Infinity; + + var points, x, y; + + for (var i = 0; i < this.graphicsData.length; i++) { + + + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; + + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 76d9a24..e532938 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -28,6 +28,16 @@ gl.useProgram(program); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // get the default shader bits! program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition"); program.colorAttribute = gl.getAttribLocation(program, "aColor"); @@ -35,6 +45,7 @@ program.projectionVector = gl.getUniformLocation(program, "projectionVector"); program.samplerUniform = gl.getUniformLocation(program, "uSampler"); + program.offsetVector = gl.getUniformLocation(program, "offsetVector"); // add those custom shaders! for (var key in this.uniforms) @@ -78,7 +89,6 @@ gl.uniform1i(this.program[key], 1); - // activate texture.. // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 55e9661..55ef717 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -59,7 +58,8 @@ gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveProgram.offsetVector, -PIXI.offset.x, -PIXI.offset.y); gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index a98cdb5..4f5205d 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -23,6 +23,8 @@ this.backgroundColor; this.batchs = []; this.toRemove = []; + + this.filterManager = new PIXI.FilterManager(); } // constructor @@ -56,17 +58,20 @@ * @method render * @param projection {Object} */ -PIXI.WebGLRenderGroup.prototype.render = function(projection) +PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer) { PIXI.WebGLRenderer.updateTextures(); var gl = this.gl; - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // will render all the elements in the group var renderable; + for (var i=0; i < this.batchs.length; i++) { @@ -77,25 +82,8 @@ continue; } - // non sprite batch.. - var worldVisible = renderable.vcount === PIXI.visibleCount; - - if(renderable instanceof PIXI.TilingSprite) - { - if(worldVisible)this.renderTilingSprite(renderable, projection); - } - else if(renderable instanceof PIXI.Strip) - { - if(worldVisible)this.renderStrip(renderable, projection); - } - else if(renderable instanceof PIXI.Graphics) - { - if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix); - } - else if(renderable instanceof PIXI.FilterBlock) - { - this.handleFilterBlock(renderable, projection); - } + // render special + this.renderSpecial(renderable, projection); } } @@ -108,7 +96,7 @@ * @param projection {Object} * @private */ -PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection) +PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer) { PIXI.WebGLRenderer.updateTextures(); @@ -293,41 +281,32 @@ } } -PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection) +PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection) { /* * for now only masks are supported.. */ var gl = PIXI.gl; - - if(renderable.open) + + if(filterBlock.open) { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - var filter = renderable.data[0]; + var filter = filterBlock.data[0]; + //console.log(filter) + this.filterManager.pushFilter(filterBlock);//filter); + // ok so.. - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader - } - - PIXI.pushShader(filter.shader); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { + gl.enable(gl.STENCIL_TEST); gl.colorMask(false, false, false, false); gl.stencilFunc(gl.ALWAYS,1,0xff); gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - PIXI.WebGLGraphics.renderGraphics(renderable.data, projection); + PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection); gl.colorMask(true, true, true, true); gl.stencilFunc(gl.NOTEQUAL,0,0xff); @@ -336,10 +315,11 @@ } else { - if(renderable.data instanceof Array) + if(filterBlock.data instanceof Array) { - PIXI.popShader(); - gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); + this.filterManager.popFilter(); + // PIXI.popShader(); + // gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y); } else { diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index 2c6fca7..4956a57 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -68,6 +68,8 @@ PIXI.initDefaultStripShader(); + + // PIXI.activateDefaultShader(); var gl = this.gl; @@ -81,6 +83,9 @@ gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); + PIXI.offset = new PIXI.Point(0, 0); + + // TODO remove thease globals.. this.resize(this.width, this.height); this.contextLost = false; @@ -178,6 +183,10 @@ // HACK TO TEST this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + this.stageRenderGroup.render(PIXI.projection); // interaction @@ -303,7 +312,10 @@ //var projectionMatrix = this.projectionMatrix; PIXI.projection.x = this.width/2; - PIXI.projection.y = this.height/2; + PIXI.projection.y = -this.height/2; + + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; // projectionMatrix[0] = 2/this.width; // projectionMatrix[5] = -2/this.height; diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js index f14571a..cec80db 100644 --- a/src/pixi/renderers/webgl/WebGLShaders.js +++ b/src/pixi/renderers/webgl/WebGLShaders.js @@ -24,10 +24,14 @@ "attribute float aColor;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "varying vec2 vTextureCoord;", + "varying float vColor;", + //"const vec2 offsetVector = vec2(1000.0, 0.0);", + "const vec2 center = vec2(-1.0, 1.0);", "void main(void) {", - "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", "vTextureCoord = aTextureCoord;", "vColor = aColor;", "}" @@ -83,10 +87,12 @@ "attribute vec4 aColor;", "uniform mat3 translationMatrix;", "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", "uniform float alpha;", "varying vec4 vColor;", "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", + "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);", + "v -= offsetVector.xyx;", "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", "vColor = aColor * alpha;", "}" @@ -106,6 +112,8 @@ shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor"); shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); + shaderProgram.offsetVector = gl.getUniformLocation(shaderProgram, "offsetVector"); + shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix"); @@ -122,14 +130,28 @@ PIXI.initDefaultShader = function() { + PIXI.frameBufferStack = []; + PIXI.frameBufferPool = []; + PIXI.defaultShader = new PIXI.PixiShader(); PIXI.defaultShader.init(); PIXI.pushShader(PIXI.defaultShader); + + // offset.. + + + + // ok and also create 2 spare frame buffers.. +// PIXI.frameBuffer1 = PIXI.generateFrameBuffer(800, 600); +// PIXI.frameBuffer2 = PIXI.generateFrameBuffer(800, 600); +// PIXI.currentFrameBuffer; + /* PIXI.shaderStack.push(PIXI.defaultShader); PIXI.current*/ } + PIXI.initDefaultStripShader = function() { var gl = this.gl; @@ -197,12 +219,19 @@ PIXI.pushShader = function(shader) { - PIXI.shaderStack.push(shader); - var gl = PIXI.gl; + gl.colorMask(true, true, true, true); + gl.viewport(0, 0, this.width, this.height); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + PIXI.shaderStack.push(shader); + var shaderProgram = shader.program; + // flip! the texture.. + // set the texture! // map uniforms.. gl.useProgram(shaderProgram); diff --git a/src/pixi/renderers/webgl/filters/Filter.js b/src/pixi/renderers/webgl/filters/Filter.js new file mode 100644 index 0000000..2de16c5 --- /dev/null +++ b/src/pixi/renderers/webgl/filters/Filter.js @@ -0,0 +1,145 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.Filter = function() +{ + // build a program + /* + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + + "uniform vec2 projectionVector;", + "uniform vec2 dimensions;", + "uniform vec2 offsetVector;", + + "varying vec2 vTextureCoord;", + "const vec2 center = vec2(-1.0, 1.0);", + + "void main(void) {", + + "vec2 tempVector = aVertexPosition;", + "tempVector *= dimensions;", + + "tempVector.y -= dimensions.y;", + "tempVector += offsetVector;", + + "tempVector /= projectionVector;", + + "tempVector *= 2.0;", + + "tempVector += center;", + + "gl_Position = vec4( tempVector, 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "}" + ];*/ + + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + "attribute float aColor;", + + "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", + "varying vec2 vTextureCoord;", + + "varying float vColor;", + "const vec2 center = vec2(-1.0, 1.0);", + "void main(void) {", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "vColor = aColor;", + "}" + ]; + + this.fragmentSrc = [ + "precision lowp float;", + "varying vec2 vTextureCoord;", + "uniform sampler2D uSampler;", + + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vTextureCoord).grba;", + "}" + ]; + + + // build program + this.program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); + + var gl = PIXI.gl; + + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(this.program, "uSampler"); + this.projectionVector = gl.getUniformLocation(this.program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(this.program, "offsetVector"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(this.program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(this.program, "aTextureCoord"); + +} + +PIXI.Filter.prototype.begin = function() +{ + var gl = PIXI.gl; + + gl.bindTexture(gl.TEXTURE_2D, this.texture); + + var filterArea = this.target.filterArea; + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer); + + // set view port + gl.viewport(0, 0, filterArea.width, filterArea.height); + + // update projection + gl.uniform2f(PIXI.currentShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.currentShader.offsetVector, -filterArea.x, -filterArea.y); + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); +} + + +PIXI.Filter.prototype.end = function(x, y, offsetX, offsetY) +{ + var gl = PIXI.gl; + + // set the filter proram.. + gl.useProgram(this.program); + + var filterArea = this.target.filterArea; + + // set the uniforms.. + gl.uniform2f(this.projectionVector, x, y) + gl.uniform2f(this.offsetVector, filterArea.x - offsetX, -(filterArea.y-offsetY)) + gl.uniform2f(this.dimensions, filterArea.width, filterArea.height); + + // bind the buffers.. + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.vertexAttribPointer(this.aTextureCoord, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + + // draw the filter... + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); + + gl.useProgram(PIXI.defaultShader.program); +} + + + +// API diff --git a/src/pixi/renderers/webgl/filters/FilterManager.js b/src/pixi/renderers/webgl/filters/FilterManager.js new file mode 100644 index 0000000..0be0164 --- /dev/null +++ b/src/pixi/renderers/webgl/filters/FilterManager.js @@ -0,0 +1,365 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.FilterManager = function() +{ + this.filterStack = []; + this.texturePool = []; + + this.offsetX = 0; + this.offsetY = 0; + + this.initShaderBuffers(); +} + +// API + +PIXI.FilterManager.prototype.begin = function(projection, buffer) +{ + this.width = projection.x * 2; + this.height = -projection.y * 2; + this.buffer = buffer; +} + +PIXI.FilterManager.prototype.pushFilter = function(filterBlock) +{ + + // filter program + var filter = filterBlock.data[0]; + + this.offsetX += filterBlock.target.filterArea.x; + this.offsetY += filterBlock.target.filterArea.y; + + this.filterStack.push(filterBlock); + + var gl = PIXI.gl; + + var texture = this.texturePool.pop(); + if(!texture)texture = new PIXI.FilterTexture(); + + gl.bindTexture(gl.TEXTURE_2D, texture.texture); + + this.getBounds(filterBlock.target); + + var filterArea = filterBlock.target.filterArea; + + 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); + + //PIXI.currentArea = filterArea + + PIXI.projection.x = filterArea.width/2; + PIXI.projection.y = -filterArea.height/2; + + PIXI.offset.x = -filterArea.x; + PIXI.offset.y = -filterArea.y; + + // update projection + gl.uniform2f(PIXI.currentShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.currentShader.offsetVector, -filterArea.x, -filterArea.y); + //PIXI.primitiveProgram + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + //filter.texture = texture; + filterBlock._glFilterTexture = texture; +} + +PIXI.FilterManager.prototype.popFilter = function() +{ + var filterBlock = this.filterStack.pop(); + var filter = filterBlock.data[0]; + + //console.log( this.offsetY); + this.offsetX -= filterBlock.target.filterArea.x; + this.offsetY -= filterBlock.target.filterArea.y; + + var gl = PIXI.gl; + + 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, false); + } + else + { + var currentFilter = this.filterStack[this.filterStack.length-1]; + var filterArea = currentFilter.target.filterArea; + + sizeX = filterArea.width; + sizeY = filterArea.height; + + offsetX = filterArea.x; + offsetY = filterArea.y; + + buffer = currentFilter._glFilterTexture.frameBuffer; + } + + gl.viewport(0, 0, sizeX, sizeY); + gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + + /////// + if(!filter.shader) + { + //filter.shader = new PIXI.Filter(); + + var shader = new PIXI.PixiShader(); + + shader.fragmentSrc = filter.fragmentSrc; + shader.uniforms = filter.uniforms; + shader.init(); + + filter.shader = shader + //filter.shader.target = filter.target; + } + + var shader = filter.shader; + var filterArea = filterBlock.target.filterArea; + + // set the shader + gl.useProgram(shader.program); + // set the uniforms.. + + PIXI.projection.x = sizeX/2; + PIXI.projection.y = -sizeY/2; + + gl.uniform2f(shader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(shader.offsetVector, 0,0) + + shader.syncUniforms(); + + PIXI.offset.x = offsetX; + PIXI.offset.y = offsetY; + + var x = filterArea.x-offsetX; + var y = filterArea.y-offsetY; + + // bind 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.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.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, filterBlock._glFilterTexture.texture); + + // draw the filter... + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); + + // now restore the regular shader.. + gl.useProgram(PIXI.defaultShader.program); + gl.uniform2f(PIXI.currentShader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(PIXI.currentShader.offsetVector, -offsetX, -offsetY); + + // return the texture to the pool + + this.texturePool.push(filterBlock._glFilterTexture); + filterBlock._glFilterTexture = null; + +} + +PIXI.FilterManager.prototype.initShaderBuffers = function() +{ + var gl = PIXI.gl; + + // create some buffers + this.vertexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + // bind and upload the vertexs.. + // keep a refferance 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); + + // 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); +} + +PIXI.FilterManager.prototype.getBounds = function(displayObject) +{ + // time to get the width and height of the object! + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest; + var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4; + + var tempObject = displayObject.first; + var testObject = displayObject.last._iNext; + + var maxX = -Infinity; + var maxY = -Infinity; + + var minX = Infinity; + var minY = Infinity; + + do + { + // TODO can be optimized! - what if there is no scale / rotation? + + if(tempObject instanceof PIXI.Sprite) + { + width = tempObject.texture.frame.width; + height = tempObject.texture.frame.height; + + // TODO trim?? + aX = tempObject.anchor.x; + aY = tempObject.anchor.y; + w0 = width * (1-aX); + w1 = width * -aX; + + h0 = height * (1-aY); + h1 = height * -aY; + + doTest = true; + } + else if(tempObject instanceof PIXI.Graphics) + { + tempObject.updateFilterBounds(); + + var bounds = tempObject.bounds; + + width = bounds.width; + height = bounds.height; + + w0 = bounds.x + w1 = bounds.x + bounds.width; + + h0 = bounds.y + h1 = bounds.y + bounds.height; + + doTest = true; + } + + if(doTest) + { + worldTransform = tempObject.worldTransform; + + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; + + x1 = a * w1 + c * h1 + tx; + y1 = d * h1 + b * w1 + ty; + + x2 = a * w0 + c * h1 + tx; + y2 = d * h1 + b * w0 + ty; + + x3 = a * w0 + c * h0 + tx; + y3 = d * h0 + b * w0 + ty; + + x4 = a * w1 + c * h0 + tx; + y4 = d * h0 + b * w1 + ty; + + minX = x1 < minX ? x1 : minX; + minX = x2 < minX ? x2 : minX; + minX = x3 < minX ? x3 : minX; + minX = x4 < minX ? x4 : minX; + + minY = y1 < minY ? y1 : minY; + minY = y2 < minY ? y2 : minY; + minY = y3 < minY ? y3 : minY; + minY = y4 < minY ? y4 : minY; + + maxX = x1 > maxX ? x1 : maxX; + maxX = x2 > maxX ? x2 : maxX; + maxX = x3 > maxX ? x3 : maxX; + maxX = x4 > maxX ? x4 : maxX; + + maxY = y1 > maxY ? y1 : maxY; + maxY = y2 > maxY ? y2 : maxY; + maxY = y3 > maxY ? y3 : maxY; + maxY = y4 > maxY ? y4 : maxY; + } + + doTest = false; + tempObject = tempObject._iNext; + } + while(tempObject != testObject) + + displayObject.filterArea.x = minX; + displayObject.filterArea.y = minY; + displayObject.filterArea.width = maxX - minX; + displayObject.filterArea.height = maxY - minY; +} + +PIXI.FilterTexture = function() +{ + var gl = PIXI.gl; + + // next time to create a frame buffer and texture + this.frameBuffer = gl.createFramebuffer(); + this.texture = gl.createTexture(); + + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); +} diff --git a/src/pixi/textures/RenderTexture.js b/src/pixi/textures/RenderTexture.js index 738c1d7..ec35c18 100644 --- a/src/pixi/textures/RenderTexture.js +++ b/src/pixi/textures/RenderTexture.js @@ -91,12 +91,10 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.baseTexture._glTexture, 0); // create a projection matrix.. - this.projection = new PIXI.Point(this.width/2 , this.height/2); + this.projection = new PIXI.Point(this.width/2 , -this.height/2); // set the correct render function.. this.render = this.renderWebGL; - - } @@ -109,7 +107,7 @@ if(PIXI.gl) { this.projection.x = this.width/2 - this.projection.y = this.height/2; + this.projection.y = -this.height/2; var gl = PIXI.gl; gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); @@ -173,9 +171,8 @@ displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix; // modify to flip... displayObject.worldTransform[4] = -1; - displayObject.worldTransform[5] = this.projection.y * 2; + displayObject.worldTransform[5] = this.projection.y * -2; - if(position) { displayObject.worldTransform[2] = position.x; @@ -196,18 +193,18 @@ { if(displayObject == renderGroup.root) { - renderGroup.render(this.projection); + renderGroup.render(this.projection, this.glFramebuffer); } else { - renderGroup.renderSpecific(displayObject, this.projection); + renderGroup.renderSpecific(displayObject, this.projection, this.glFramebuffer); } } else { if(!this.renderGroup)this.renderGroup = new PIXI.WebGLRenderGroup(gl); this.renderGroup.setRenderable(displayObject); - this.renderGroup.render(this.projection); + this.renderGroup.render(this.projection, this.glFramebuffer); } displayObject.worldTransform = originalWorldTransform;