From 40b4b2dbd060e9157320ef6e39a96f3b076d77c6 Mon Sep 17 00:00:00 2001 From: Felipe Alfonso Date: Thu, 21 Jul 2016 01:57:39 -0400 Subject: [PATCH] added multi texture to WebGLFastSpritebatch and Strip (wip) --- src/pixi/extras/Strip.js | 162 +++++++++--------- .../renderers/webgl/shaders/PixiFastShader.js | 100 +++++++---- .../renderers/webgl/shaders/StripShader.js | 43 ++++- .../webgl/utils/WebGLFastSpriteBatch.js | 31 +++- .../renderers/webgl/utils/WebGLSpriteBatch.js | 10 +- 5 files changed, 220 insertions(+), 126 deletions(-) diff --git a/src/pixi/extras/Strip.js b/src/pixi/extras/Strip.js index 6c021b0a7..5038e721c 100644 --- a/src/pixi/extras/Strip.js +++ b/src/pixi/extras/Strip.js @@ -2,7 +2,7 @@ * @author Mat Groves http://matgroves.com/ */ - /** +/** * * @class Strip * @extends DisplayObjectContainer @@ -12,9 +12,8 @@ * @param height {Number} the height * */ -PIXI.Strip = function(texture) -{ - PIXI.DisplayObjectContainer.call( this ); +PIXI.Strip = function (texture) { + PIXI.DisplayObjectContainer.call(this); /** @@ -27,19 +26,24 @@ PIXI.Strip = function(texture) // set up the main bits.. this.uvs = new PIXI.Float32Array([0, 1, - 1, 1, - 1, 0, - 0, 1]); + 1, 1, + 1, 0, + 0, 1 + ]); this.vertices = new PIXI.Float32Array([0, 0, - 100, 0, - 100, 100, - 0, 100]); + 100, 0, + 100, 100, + 0, 100 + ]); this.colors = new PIXI.Float32Array([1, 1, 1, 1]); this.indices = new PIXI.Uint16Array([0, 1, 2, 3]); + var textureIndex = texture.baseTexture.textureIndex; + this.textureIndices = new PIXI.Float32Array([textureIndex, textureIndex, textureIndex, textureIndex]); + /** * Whether the strip is dirty or not * @@ -73,16 +77,15 @@ PIXI.Strip = function(texture) PIXI.Strip.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); PIXI.Strip.prototype.constructor = PIXI.Strip; -PIXI.Strip.prototype._renderWebGL = function(renderSession) -{ +PIXI.Strip.prototype._renderWebGL = function (renderSession) { // if the sprite is not visible or the alpha is 0 then no need to render this element - if(!this.visible || this.alpha <= 0)return; + if (!this.visible || this.alpha <= 0) return; // render triangle strip.. renderSession.spriteBatch.stop(); // init! init! - if(!this._vertexBuffer)this._initWebGL(renderSession); + if (!this._vertexBuffer) this._initWebGL(renderSession); renderSession.shaderManager.setShader(renderSession.shaderManager.stripShader); @@ -95,8 +98,7 @@ PIXI.Strip.prototype._renderWebGL = function(renderSession) //TODO check culling }; -PIXI.Strip.prototype._initWebGL = function(renderSession) -{ +PIXI.Strip.prototype._initWebGL = function (renderSession) { // build the strip! var gl = renderSession.gl; @@ -104,22 +106,27 @@ PIXI.Strip.prototype._initWebGL = function(renderSession) this._indexBuffer = gl.createBuffer(); this._uvBuffer = gl.createBuffer(); this._colorBuffer = gl.createBuffer(); + this._textureIndex = gl.createBuffer(); + + + gl.bindBuffer(gl.ARRAY_BUFFER, this._textureIndex); + gl.bufferData(gl.ARRAY_BUFFER, this.textureIndices, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); + gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + }; -PIXI.Strip.prototype._renderStrip = function(renderSession) -{ +PIXI.Strip.prototype._renderStrip = function (renderSession) { var gl = renderSession.gl; var projection = renderSession.projection, offset = renderSession.offset, @@ -138,13 +145,16 @@ PIXI.Strip.prototype._renderStrip = function(renderSession) gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); gl.uniform1f(shader.alpha, this.worldAlpha); - if(!this.dirty) - { + if (!this.dirty) { + + gl.bindBuffer(gl.ARRAY_BUFFER, this._textureIndex); + gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); + // update the uvs gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); @@ -152,12 +162,9 @@ PIXI.Strip.prototype._renderStrip = function(renderSession) gl.activeTexture(gl.TEXTURE0); // check if a texture is dirty.. - if(this.texture.baseTexture._dirty[gl.id]) - { + if (this.texture.baseTexture._dirty[gl.id]) { renderSession.renderer.updateTexture(this.texture.baseTexture); - } - else - { + } else { // bind the current texture gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); } @@ -166,9 +173,7 @@ PIXI.Strip.prototype._renderStrip = function(renderSession) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - } - else - { + } else { this.dirty = false; gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); @@ -183,12 +188,9 @@ PIXI.Strip.prototype._renderStrip = function(renderSession) gl.activeTexture(gl.TEXTURE0); // check if a texture is dirty.. - if(this.texture.baseTexture._dirty[gl.id]) - { + if (this.texture.baseTexture._dirty[gl.id]) { renderSession.renderer.updateTexture(this.texture.baseTexture); - } - else - { + } else { gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); } @@ -200,6 +202,7 @@ PIXI.Strip.prototype._renderStrip = function(renderSession) //console.log(gl.TRIANGLE_STRIP) // // + debugger; gl.drawElements(drawMode, this.indices.length, gl.UNSIGNED_SHORT, 0); @@ -207,8 +210,7 @@ PIXI.Strip.prototype._renderStrip = function(renderSession) -PIXI.Strip.prototype._renderCanvas = function(renderSession) -{ +PIXI.Strip.prototype._renderCanvas = function (renderSession) { var context = renderSession.context; var transform = this.worldTransform; @@ -216,27 +218,20 @@ PIXI.Strip.prototype._renderCanvas = function(renderSession) var tx = (transform.tx * renderSession.resolution) + renderSession.shakeX; var ty = (transform.ty * renderSession.resolution) + renderSession.shakeY; - if (renderSession.roundPixels) - { + if (renderSession.roundPixels) { context.setTransform(transform.a, transform.b, transform.c, transform.d, tx | 0, ty | 0); - } - else - { + } else { context.setTransform(transform.a, transform.b, transform.c, transform.d, tx, ty); } - if (this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP) - { + if (this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP) { this._renderCanvasTriangleStrip(context); - } - else - { + } else { this._renderCanvasTriangles(context); } }; -PIXI.Strip.prototype._renderCanvasTriangleStrip = function(context) -{ +PIXI.Strip.prototype._renderCanvasTriangleStrip = function (context) { // draw triangles!! var vertices = this.vertices; var uvs = this.uvs; @@ -251,8 +246,7 @@ PIXI.Strip.prototype._renderCanvasTriangleStrip = function(context) } }; -PIXI.Strip.prototype._renderCanvasTriangles = function(context) -{ +PIXI.Strip.prototype._renderCanvasTriangles = function (context) { // draw triangles!! var vertices = this.vertices; var uvs = this.uvs; @@ -263,22 +257,31 @@ PIXI.Strip.prototype._renderCanvasTriangles = function(context) for (var i = 0; i < length; i += 3) { // draw some triangles! - var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; + var index0 = indices[i] * 2, + index1 = indices[i + 1] * 2, + index2 = indices[i + 2] * 2; this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); } }; -PIXI.Strip.prototype._renderCanvasDrawTriangle = function(context, vertices, uvs, index0, index1, index2) -{ +PIXI.Strip.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2) { var textureSource = this.texture.baseTexture.source; var textureWidth = this.texture.width; var textureHeight = this.texture.height; - var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; - var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; + var x0 = vertices[index0], + x1 = vertices[index1], + x2 = vertices[index2]; + var y0 = vertices[index0 + 1], + y1 = vertices[index1 + 1], + y2 = vertices[index2 + 1]; - var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; - var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; + var u0 = uvs[index0] * textureWidth, + u1 = uvs[index1] * textureWidth, + u2 = uvs[index2] * textureWidth; + var v0 = uvs[index0 + 1] * textureHeight, + v1 = uvs[index1 + 1] * textureHeight, + v2 = uvs[index2 + 1] * textureHeight; if (this.canvasPadding > 0) { var paddingX = this.canvasPadding / this.worldTransform.a; @@ -323,12 +326,12 @@ PIXI.Strip.prototype._renderCanvasDrawTriangle = function(context, vertices, uvs context.clip(); // Compute matrix transform - var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); - var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); - var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); + var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); + var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); + var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); - var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); - var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); + var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); + var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); context.transform(deltaA / delta, deltaD / delta, @@ -348,22 +351,24 @@ PIXI.Strip.prototype._renderCanvasDrawTriangle = function(context, vertices, uvs * @param strip {Strip} The Strip to render * @private */ -PIXI.Strip.prototype.renderStripFlat = function(strip) -{ +PIXI.Strip.prototype.renderStripFlat = function (strip) { var context = this.context; var vertices = strip.vertices; - var length = vertices.length/2; + var length = vertices.length / 2; this.count++; context.beginPath(); - for (var i=1; i < length-2; i++) - { + for (var i = 1; i < length - 2; i++) { // draw some triangles! - var index = i*2; + var index = i * 2; - var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; - var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; + var x0 = vertices[index], + x1 = vertices[index + 2], + x2 = vertices[index + 4]; + var y0 = vertices[index + 1], + y1 = vertices[index + 3], + y2 = vertices[index + 5]; context.moveTo(x0, y0); context.lineTo(x1, y1); @@ -397,8 +402,7 @@ PIXI.Strip.prototype.setTexture = function(texture) * @private */ -PIXI.Strip.prototype.onTextureUpdate = function() -{ +PIXI.Strip.prototype.onTextureUpdate = function () { this.updateFrame = true; }; @@ -409,8 +413,7 @@ PIXI.Strip.prototype.onTextureUpdate = function() * @param matrix {Matrix} the transformation matrix of the sprite * @return {Rectangle} the framing rectangle */ -PIXI.Strip.prototype.getBounds = function(matrix) -{ +PIXI.Strip.prototype.getBounds = function (matrix) { var worldTransform = matrix || this.worldTransform; var a = worldTransform.a; @@ -427,9 +430,9 @@ PIXI.Strip.prototype.getBounds = function(matrix) var minY = Infinity; var vertices = this.vertices; - for (var i = 0, n = vertices.length; i < n; i += 2) - { - var rawX = vertices[i], rawY = vertices[i + 1]; + for (var i = 0, n = vertices.length; i < n; i += 2) { + var rawX = vertices[i], + rawY = vertices[i + 1]; var x = (a * rawX) + (c * rawY) + tx; var y = (d * rawY) + (b * rawX) + ty; @@ -440,8 +443,7 @@ PIXI.Strip.prototype.getBounds = function(matrix) maxY = y > maxY ? y : maxY; } - if (minX === -Infinity || maxY === Infinity) - { + if (minX === -Infinity || maxY === Infinity) { return PIXI.EmptyRectangle; } @@ -469,4 +471,4 @@ PIXI.Strip.prototype.getBounds = function(matrix) PIXI.Strip.DrawModes = { TRIANGLE_STRIP: 0, TRIANGLES: 1 -}; +}; \ No newline at end of file diff --git a/src/pixi/renderers/webgl/shaders/PixiFastShader.js b/src/pixi/renderers/webgl/shaders/PixiFastShader.js index 49bd89b11..d72d809d5 100644 --- a/src/pixi/renderers/webgl/shaders/PixiFastShader.js +++ b/src/pixi/renderers/webgl/shaders/PixiFastShader.js @@ -3,19 +3,18 @@ */ /** -* @class PixiFastShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.PixiFastShader = function(gl) -{ + * @class PixiFastShader + * @constructor + * @param gl {WebGLContext} the current WebGL drawing context + */ +PIXI.PixiFastShader = function (gl) { /** * @property _UID * @type Number * @private */ this._UID = PIXI._UID++; - + /** * @property gl * @type WebGLContext @@ -29,6 +28,16 @@ PIXI.PixiFastShader = function(gl) */ this.program = null; + var gl = this.gl; + this.MAX_TEXTURES = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n' + for (var index = 1; index < this.MAX_TEXTURES; ++index) + { + dynamicIfs += '\telse if (vTextureIndex == ' + + index + '.0) gl_FragColor = texture2D(uSamplerArray[' + + index + '], vTextureCoord) * vColor;\n' + } + /** * The fragment shader. * @property fragmentSrc @@ -39,9 +48,13 @@ PIXI.PixiFastShader = function(gl) 'precision lowp float;', 'varying vec2 vTextureCoord;', 'varying float vColor;', - 'uniform sampler2D uSampler;', + 'varying float vTextureIndex;', + 'uniform sampler2D uSamplerArray[' + this.MAX_TEXTURES + '];', + 'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);', + 'const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0);', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', + dynamicIfs, + 'else gl_FragColor = PINK;', '}' ]; @@ -58,6 +71,7 @@ PIXI.PixiFastShader = function(gl) 'attribute float aRotation;', 'attribute vec2 aTextureCoord;', 'attribute float aColor;', + 'attribute float aTextureIndex;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', @@ -65,6 +79,7 @@ PIXI.PixiFastShader = function(gl) 'varying vec2 vTextureCoord;', 'varying float vColor;', + 'varying float vTextureIndex;', 'const vec2 center = vec2(-1.0, 1.0);', @@ -76,7 +91,8 @@ PIXI.PixiFastShader = function(gl) ' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;', ' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);', ' vTextureCoord = aTextureCoord;', - // ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vTextureIndex = aTextureIndex;', + // ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', ' vColor = aColor;', '}' ]; @@ -87,27 +103,37 @@ PIXI.PixiFastShader = function(gl) * @type Number */ this.textureCount = 0; - + this.init(); }; PIXI.PixiFastShader.prototype.constructor = PIXI.PixiFastShader; /** -* Initialises the shader. -* -* @method init -*/ -PIXI.PixiFastShader.prototype.init = function() -{ - var gl = this.gl; + * Initialises the shader. + * + * @method init + */ +PIXI.PixiFastShader.prototype.init = function () { + var gl = this.gl; var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - + gl.useProgram(program); // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); + this.uSampler = gl.getUniformLocation(program, 'uSamplerArray[0]'); + + var indices = []; + for (var i = 0; i < this.MAX_TEXTURES; ++i) { + indices.push(i); + } + // NOTE:!!! + // If textures are not bound + // then we'll get a bunch of warnings like: + // "WARNING: there is no texture bound to the unit X" + // Don't be scared, everything will be alright. + gl.uniform1iv(this.uSampler, indices); this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); @@ -123,35 +149,43 @@ PIXI.PixiFastShader.prototype.init = function() this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - + + this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex'); + // Begin worst hack eva // // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters? // maybe its somthing to do with the current state of the gl context. // Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel // If theres any webGL people that know why could happen please help :) - if(this.colorAttribute === -1) - { + if (this.colorAttribute === -1) { this.colorAttribute = 2; } - this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute]; - + this.attributes = [ + this.aVertexPosition, + this.aPositionCoord, + this.aScale, + this.aRotation, + this.aTextureCoord, + this.colorAttribute, + this.aTextureIndex + ]; + // End worst hack eva // this.program = program; }; /** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.PixiFastShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); + * Destroys the shader. + * + * @method destroy + */ +PIXI.PixiFastShader.prototype.destroy = function () { + this.gl.deleteProgram(this.program); this.uniforms = null; this.gl = null; this.attributes = null; -}; +}; \ No newline at end of file diff --git a/src/pixi/renderers/webgl/shaders/StripShader.js b/src/pixi/renderers/webgl/shaders/StripShader.js index d61d0080e..0a4542874 100644 --- a/src/pixi/renderers/webgl/shaders/StripShader.js +++ b/src/pixi/renderers/webgl/shaders/StripShader.js @@ -29,6 +29,17 @@ PIXI.StripShader = function(gl) */ this.program = null; + var gl = this.gl; + this.MAX_TEXTURES = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord);\n' + for (var index = 1; index < this.MAX_TEXTURES; ++index) + { + dynamicIfs += '\telse if (vTextureIndex == ' + + index + '.0) gl_FragColor = texture2D(uSamplerArray[' + + index + '], vTextureCoord) ;\n' + } + + /** * The fragment shader. * @property fragmentSrc @@ -38,13 +49,15 @@ PIXI.StripShader = function(gl) '//StripShader Fragment Shader.', 'precision mediump float;', 'varying vec2 vTextureCoord;', + 'varying float vTextureIndex;', // 'varying float vColor;', 'uniform float alpha;', - 'uniform sampler2D uSampler;', - + 'uniform sampler2D uSamplerArray[' + this.MAX_TEXTURES + '];', + 'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);', + 'const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0);', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * alpha;', - // ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);',//gl_FragColor * alpha;', + dynamicIfs, + 'else gl_FragColor = PINK;', '}' ]; @@ -57,12 +70,14 @@ PIXI.StripShader = function(gl) '//StripShader Vertex Shader.', 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', + 'attribute float aTextureIndex;', 'uniform mat3 translationMatrix;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', // 'uniform float alpha;', // 'uniform vec3 tint;', 'varying vec2 vTextureCoord;', + 'varying float vTextureIndex;', // 'varying vec4 vColor;', 'void main(void) {', @@ -70,6 +85,7 @@ PIXI.StripShader = function(gl) ' v -= offsetVector.xyx;', ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);', ' vTextureCoord = aTextureCoord;', + ' vTextureIndex = aTextureIndex;', // ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; @@ -87,22 +103,35 @@ PIXI.StripShader.prototype.constructor = PIXI.StripShader; PIXI.StripShader.prototype.init = function() { var gl = this.gl; - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); gl.useProgram(program); // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, 'uSamplerArray[0]'); + + var indices = []; + for (var i = 0; i < this.MAX_TEXTURES; ++i) { + indices.push(i); + } + // NOTE:!!! + // If textures are not bound + // then we'll get a bunch of warnings like: + // "WARNING: there is no texture bound to the unit X" + // Don't be scared, everything will be alright. + gl.uniform1iv(this.uSampler, indices); + this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex'); //this.dimensions = gl.getUniformLocation(this.program, 'dimensions'); // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - this.attributes = [this.aVertexPosition, this.aTextureCoord]; + this.attributes = [this.aVertexPosition, this.aTextureCoord, this.aTextureIndex]; this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); this.alpha = gl.getUniformLocation(program, 'alpha'); diff --git a/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js b/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js index 179d9e4b0..0b73e2d8b 100644 --- a/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js +++ b/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js @@ -14,11 +14,12 @@ */ PIXI.WebGLFastSpriteBatch = function(gl) { + /** * @property vertSize * @type Number */ - this.vertSize = 10; + this.vertSize = 11; /** * @property maxSize @@ -180,6 +181,7 @@ PIXI.WebGLFastSpriteBatch.prototype.end = function() */ PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch) { + debugger; var children = spriteBatch.children; var sprite = children[0]; @@ -211,6 +213,16 @@ PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch) */ PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite) { + var texture = sprite.texture; + var baseTexture = texture.baseTexture; + var gl = this.gl; + + if (this.textureArray[baseTexture.textureIndex] != baseTexture) { + gl.activeTexture(gl.TEXTURE0 + baseTexture.textureIndex); + gl.bindTexture(gl.TEXTURE_2D, baseTexture._glTextures[gl.id]); + this.textureArray[baseTexture.textureIndex] = baseTexture; + this.flush(); + } //sprite = children[i]; if(!sprite.visible)return; @@ -251,7 +263,7 @@ PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite) } index = this.currentBatchSize * 4 * this.vertSize; - + var textureIndex = sprite.texture.baseTexture.textureIndex; // xy vertices[index++] = w1; vertices[index++] = h1; @@ -271,6 +283,8 @@ PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite) vertices[index++] = uvs.y1; // color vertices[index++] = sprite.alpha; + // texture Index + vertices[index++] = textureIndex; // xy @@ -292,7 +306,8 @@ PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite) vertices[index++] = uvs.y1; // color vertices[index++] = sprite.alpha; - + // texture Index + vertices[index++] = textureIndex; // xy vertices[index++] = w0; @@ -313,7 +328,8 @@ PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite) vertices[index++] = uvs.y2; // color vertices[index++] = sprite.alpha; - + // texture Index + vertices[index++] = textureIndex; @@ -336,6 +352,8 @@ PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite) vertices[index++] = uvs.y3; // color vertices[index++] = sprite.alpha; + // texture Index + vertices[index++] = textureIndex; // increment the batchs this.currentBatchSize++; @@ -351,6 +369,8 @@ PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite) */ PIXI.WebGLFastSpriteBatch.prototype.flush = function() { + debugger; + // If the batch is length 0 then return as there is nothing to draw if (this.currentBatchSize===0)return; @@ -360,7 +380,7 @@ PIXI.WebGLFastSpriteBatch.prototype.flush = function() if(!this.currentBaseTexture._glTextures[gl.id])this.renderSession.renderer.updateTexture(this.currentBaseTexture, gl); - gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]); + //gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]); // upload the verts to the buffer @@ -424,5 +444,6 @@ PIXI.WebGLFastSpriteBatch.prototype.start = function() gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4); gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4); gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4); + gl.vertexAttribPointer(this.shader.aTextureIndex, 1, gl.FLOAT, false, stride, 10 * 4); }; diff --git a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js index 1b0c55f53..76b2ac930 100644 --- a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js +++ b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js @@ -360,7 +360,15 @@ PIXI.WebGLSpriteBatch.prototype.render = function (sprite, matrix) { */ PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function (sprite) { var texture = sprite.tilingTexture; - + var baseTexture = texture.baseTexture; + var gl = this.gl; + + if (this.textureArray[baseTexture.textureIndex] != baseTexture) { + gl.activeTexture(gl.TEXTURE0 + baseTexture.textureIndex); + gl.bindTexture(gl.TEXTURE_2D, baseTexture._glTextures[gl.id]); + this.textureArray[baseTexture.textureIndex] = baseTexture; + this.flush(); + } // check texture.. if (this.currentBatchSize >= this.size) {