New Filter Structure

Base Filters now working for graphics and sprite
Filters now nestable
This commit is contained in:
Mat Groves 2013-10-29 16:57:39 +00:00
parent e50a6716d8
commit 46ae15a6ce
13 changed files with 684 additions and 63 deletions

View file

@ -39,6 +39,8 @@ module.exports = function(grunt) {
'<%= 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',

View file

@ -164,6 +164,9 @@ PIXI.DisplayObject = function()
this._sr = 0;
this._cr = 1;
this.filterArea = new PIXI.Rectangle(0,0,1,1);
/*
* MOUSE Callbacks
*/
@ -353,6 +356,7 @@ PIXI.DisplayObject.prototype.addFilter = function(data)
{
//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 @@ PIXI.DisplayObject.prototype.addFilter = function(data)
start.open = true;
start.target = this;
/*
* insert start
*/

View file

@ -22,7 +22,7 @@ PIXI.DisplacementFilter = function(texture)
"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) {",

View file

@ -6,7 +6,7 @@ PIXI.InvertFilter = function()
{
// set the uniforms
this.uniforms = {
invert: {type: 'f', value: 0.5},
invert: {type: 'f', value: 0},
};
this.fragmentSrc = [

View file

@ -221,6 +221,81 @@ PIXI.Graphics.prototype.clear = function()
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:

View file

@ -28,6 +28,16 @@ PIXI.PixiShader.prototype.init = function()
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 @@ PIXI.PixiShader.prototype.init = function()
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 @@ PIXI.PixiShader.prototype.syncUniforms = function()
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);

View file

@ -46,7 +46,6 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
PIXI.WebGLGraphics.updateGraphics(graphics);
}
PIXI.activatePrimitiveShader();
// This could be speeded up fo sure!
@ -59,7 +58,8 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
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);

View file

@ -23,6 +23,8 @@ PIXI.WebGLRenderGroup = function(gl)
this.backgroundColor;
this.batchs = [];
this.toRemove = [];
this.filterManager = new PIXI.FilterManager();
}
// constructor
@ -56,17 +58,20 @@ PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
* @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 @@ PIXI.WebGLRenderGroup.prototype.render = function(projection)
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 @@ PIXI.WebGLRenderGroup.prototype.render = function(projection)
* @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.renderSpecial = function(renderable, projection)
}
}
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 @@ PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, project
}
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
{

View file

@ -68,6 +68,8 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
PIXI.initDefaultStripShader();
// PIXI.activateDefaultShader();
var gl = this.gl;
@ -81,6 +83,9 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
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 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
// 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 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height)
//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;

View file

@ -24,10 +24,14 @@ PIXI.shaderVertexSrc = [
"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 @@ PIXI.primitiveShaderVertexSrc = [
"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 @@ PIXI.initPrimitiveShader = function()
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.initPrimitiveShader = function()
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.compileProgram = function(vertexSrc, fragmentSrc)
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);

View file

@ -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

View file

@ -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);
}

View file

@ -91,12 +91,10 @@ PIXI.RenderTexture.prototype.initWebGL = function()
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 @@ PIXI.RenderTexture.prototype.resize = function(width, height)
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 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle
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 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle
{
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;