diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 01721c0..471f725 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -20,13 +20,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -273,19 +274,22 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 01721c0..471f725 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -20,13 +20,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -273,19 +274,22 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js index b206e79..62383e0 100644 --- a/src/pixi/renderers/webgl/PrimitiveShader.js +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -24,13 +24,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -46,6 +47,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 01721c0..471f725 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -20,13 +20,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -273,19 +274,22 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js index b206e79..62383e0 100644 --- a/src/pixi/renderers/webgl/PrimitiveShader.js +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -24,13 +24,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -46,6 +47,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index e84898b..83c2eac 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -69,6 +69,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -132,7 +140,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -141,6 +149,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 01721c0..471f725 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -20,13 +20,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -273,19 +274,22 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js index b206e79..62383e0 100644 --- a/src/pixi/renderers/webgl/PrimitiveShader.js +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -24,13 +24,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -46,6 +47,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index e84898b..83c2eac 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -69,6 +69,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -132,7 +140,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -141,6 +149,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch diff --git a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js index d834ee2..7fffd67 100644 --- a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js +++ b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js @@ -251,6 +251,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 01721c0..471f725 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -20,13 +20,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -273,19 +274,22 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js index b206e79..62383e0 100644 --- a/src/pixi/renderers/webgl/PrimitiveShader.js +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -24,13 +24,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -46,6 +47,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index e84898b..83c2eac 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -69,6 +69,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -132,7 +140,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -141,6 +149,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch diff --git a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js index d834ee2..7fffd67 100644 --- a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js +++ b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js @@ -251,6 +251,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); diff --git a/src/pixi/renderers/webgl/utils/WebGLGraphics.js b/src/pixi/renderers/webgl/utils/WebGLGraphics.js index bb90529..99877cf 100644 --- a/src/pixi/renderers/webgl/utils/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/utils/WebGLGraphics.js @@ -61,6 +61,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -70,7 +73,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 01721c0..471f725 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -20,13 +20,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -273,19 +274,22 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js index b206e79..62383e0 100644 --- a/src/pixi/renderers/webgl/PrimitiveShader.js +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -24,13 +24,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -46,6 +47,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index e84898b..83c2eac 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -69,6 +69,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -132,7 +140,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -141,6 +149,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch diff --git a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js index d834ee2..7fffd67 100644 --- a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js +++ b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js @@ -251,6 +251,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); diff --git a/src/pixi/renderers/webgl/utils/WebGLGraphics.js b/src/pixi/renderers/webgl/utils/WebGLGraphics.js index bb90529..99877cf 100644 --- a/src/pixi/renderers/webgl/utils/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/utils/WebGLGraphics.js @@ -61,6 +61,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -70,7 +73,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); diff --git a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js index c57137e..329f2c7 100644 --- a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js +++ b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js @@ -18,7 +18,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -63,7 +63,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -71,9 +71,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -84,12 +84,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -97,7 +104,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -113,7 +120,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -132,6 +139,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -141,6 +149,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -150,6 +159,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -159,9 +169,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -174,6 +187,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -205,7 +223,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -221,7 +239,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -240,6 +258,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -249,7 +268,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -258,6 +278,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -267,7 +288,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -293,7 +315,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -315,7 +337,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -323,9 +345,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } diff --git a/bin/pixi.dev.js b/bin/pixi.dev.js index 4e69327..b5fb2f0 100644 --- a/bin/pixi.dev.js +++ b/bin/pixi.dev.js @@ -1456,14 +1456,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -1519,6 +1522,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -1738,6 +1745,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -1750,6 +1758,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; @@ -3374,6 +3389,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */ @@ -3822,13 +3863,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -4075,23 +4117,26 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4186,13 +4231,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -4208,6 +4254,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -4282,6 +4330,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -4291,7 +4342,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); @@ -4815,6 +4865,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -4878,7 +4936,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -4887,6 +4945,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch @@ -5157,7 +5216,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -5202,7 +5261,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -5210,9 +5269,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -5223,12 +5282,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -5236,7 +5302,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -5252,7 +5318,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -5271,6 +5337,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5280,6 +5347,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -5289,6 +5357,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5298,9 +5367,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -5313,6 +5385,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -5344,7 +5421,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -5360,7 +5437,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -5379,6 +5456,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -5388,7 +5466,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -5397,6 +5476,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -5406,7 +5486,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -5432,7 +5513,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -5454,7 +5535,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -5462,9 +5543,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } @@ -5722,6 +5818,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); @@ -6050,6 +6149,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -6190,116 +6298,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -6337,40 +6336,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip @@ -6717,6 +6682,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -6899,6 +6868,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -6909,6 +6886,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } @@ -7351,6 +7334,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -7438,7 +7422,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -7452,6 +7435,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -7459,6 +7444,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; @@ -10740,14 +10732,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10794,14 +10786,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10867,7 +10859,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -10891,7 +10883,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; @@ -10978,7 +10970,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', @@ -11032,7 +11024,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11086,7 +11078,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11213,7 +11205,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -11221,7 +11213,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11266,7 +11258,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -11275,7 +11267,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; @@ -11322,7 +11314,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11421,14 +11413,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; @@ -11476,7 +11468,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', @@ -11553,7 +11545,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', @@ -11623,7 +11615,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 66e0daf..ac92be9 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -3,14 +3,17 @@ */ PIXI.blendModes = {}; -PIXI.blendModes.NORMAL = 0; -PIXI.blendModes.SCREEN = 1; +PIXI.blendModes.NORMAL = 0; +PIXI.blendModes.ADD = 1; +PIXI.blendModes.MULTIPLY = 2; +PIXI.blendModes.SCREEN = 3; + /** * The SPrite object is the base for all textured objects that are rendered to the screen * - * @class Sprite + * @class Sprite™ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture for this sprite @@ -66,6 +69,10 @@ */ this._height = 0; + this.tint = 0xFFFFFF;// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + if(texture.baseTexture.hasLoaded) { this.updateFrame = true; @@ -285,6 +292,7 @@ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { + var frame = this.texture.frame; var context = renderSession.context; @@ -297,6 +305,13 @@ context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + //if smoothingEnabled is supported and we need to change the smoothing property for this texture // if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { // this.scaleMode = displayObject.texture.baseTexture.scaleMode; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index dd0cdc4..db06ec8 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -39,6 +39,7 @@ this.renderable = true; + this.tint = 0xFFFFFF; this.blendMode = PIXI.blendModes.NORMAL; }; @@ -126,7 +127,6 @@ } else { - console.log("!!") renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -140,6 +140,8 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) { + if(this.visible === false || this.alpha === 0)return; + var context = renderSession.context; context.globalAlpha = this.worldAlpha; @@ -147,6 +149,13 @@ if(!this.__tilePattern) this.__tilePattern = context.createPattern(this.texture.baseTexture.source, 'repeat'); + // check blend mode + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.beginPath(); var tilePosition = this.tilePosition; diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 6e7be33..3583791 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 99829fb..82a7460 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 122b6fb..8d08eea 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -27,14 +27,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform mat4 matrix;', 'uniform sampler2D uSampler;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index c83c887..1bb3901 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float step;', 'void main(void) {', ' vec4 color = texture2D(uSampler, vTextureCoord);', ' color = floor(color * step) / step;', - ' gl_FragColor = color * vColor;', + ' gl_FragColor = color;', '}' ]; }; diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 43f3c26..3426b54 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -16,7 +16,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float blur;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 40af870..f36447b 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -43,7 +43,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D displacementMap;', 'uniform sampler2D uSampler;', 'uniform vec2 scale;', @@ -67,7 +67,7 @@ ' vec2 cord = vTextureCoord;', //' gl_FragColor = texture2D(displacementMap, cord);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 7a684a1..d898f26 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -25,7 +25,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 5065834..34a52b1 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -22,14 +22,14 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform float gray;', 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor;', '}' ]; }; diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index ac4393f..3778048 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float invert;', 'uniform sampler2D uSampler;', @@ -30,7 +30,7 @@ ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index e4320eb..4d4adb1 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 testDim;', 'uniform vec4 dimensions;', 'uniform vec2 pixelSize;', diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 81439dd..fba3bde 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -19,7 +19,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec2 red;', 'uniform vec2 green;', 'uniform vec2 blue;', diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index f114d76..9aff305 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -22,7 +22,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform float sepia;', 'uniform sampler2D uSampler;', @@ -31,7 +31,7 @@ 'void main(void) {', ' gl_FragColor = texture2D(uSampler, vTextureCoord);', ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - ' gl_FragColor = gl_FragColor * vColor;', + // ' gl_FragColor = gl_FragColor * vColor;', '}' ]; }; diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index c529dd7..39270b2 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -24,7 +24,7 @@ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index ea9bf74..c6142aa 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -51,6 +51,10 @@ */ this.graphicsData = []; + this.tint = 0xFFFFFF// * Math.random(); + + this.blendMode = PIXI.blendModes.NORMAL; + /** * Current path * @@ -233,6 +237,14 @@ { renderSession.spriteBatch.stop(); + // check blend mode + if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) + { + this.spriteBatch.currentBlendMode = sprite.blendMode; + var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; + this.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); + } + PIXI.WebGLGraphics.renderGraphics(this, renderSession.projection); renderSession.spriteBatch.start(); @@ -243,6 +255,12 @@ var context = renderSession.context; var transform = this.worldTransform; + if(this.blendMode !== renderSession.currentBlendMode) + { + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + } + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); PIXI.CanvasGraphics.renderGraphics(this, context); } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index e587ef7..7311679 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -17,6 +17,15 @@ { this.transparent = transparent; + if(!PIXI.blendModesCanvas) + { + PIXI.blendModesCanvas = []; + PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; + PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? + PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; + PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; + } + /** * The width of the canvas view * @@ -157,116 +166,7 @@ var transform; var context = this.context; - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - // var testObject = displayObject.last._iNext; - // displayObject = displayObject.first; - displayObject._renderCanvas(this.renderSession); - - /* - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - //if smoothingEnabled is supported and we need to change the smoothing property for this texture - if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { - this.scaleMode = displayObject.texture.baseTexture.scaleMode; - context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); - } - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; - - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - } - //count++ - displayObject = displayObject._iNext; - } - while(displayObject !== testObject); - - */ }; /** @@ -304,40 +204,6 @@ }; /** - * Renders a tiling sprite - * - * @method renderTilingSprite - * @param sprite {TilingSprite} The tilingsprite to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) -{ - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) - sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - - // offset - context.scale(tileScale.x,tileScale.y); - context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); - context.translate(-tilePosition.x, -tilePosition.y); - - context.closePath(); -}; - -/** * Renders a strip * * @method renderStrip diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 01721c0..471f725 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -20,13 +20,14 @@ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', '}' ]; + /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ @@ -273,19 +274,22 @@ PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'varying vec2 vTextureCoord;', - 'varying float vColor;', + 'varying vec4 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;', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js index b206e79..62383e0 100644 --- a/src/pixi/renderers/webgl/PrimitiveShader.js +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -24,13 +24,14 @@ 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', + 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' 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;', + ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; }; @@ -46,6 +47,8 @@ // get and store the uniforms for the shader this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.tintColor = gl.getUniformLocation(program, 'tint'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index e84898b..83c2eac 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -69,6 +69,14 @@ var gl = this.gl; + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + + console.log( PIXI.blendModesWebGL[PIXI.blendModes.SCREEN]) gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; @@ -132,7 +140,7 @@ // make sure we are bound to the main frame buffer gl.bindFramebuffer(gl.FRAMEBUFFER, null); - + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); gl.clear(gl.COLOR_BUFFER_BIT); @@ -141,6 +149,7 @@ // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; this.renderSession.projection = PIXI.projection; // start the sprite batch diff --git a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js index d834ee2..7fffd67 100644 --- a/src/pixi/renderers/webgl/utils/WebGLFilterManager.js +++ b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js @@ -251,6 +251,9 @@ // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + // set the blend mode! + //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + // set texture gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture.texture); diff --git a/src/pixi/renderers/webgl/utils/WebGLGraphics.js b/src/pixi/renderers/webgl/utils/WebGLGraphics.js index bb90529..99877cf 100644 --- a/src/pixi/renderers/webgl/utils/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/utils/WebGLGraphics.js @@ -61,6 +61,9 @@ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + gl.uniform3fv(PIXI.primitiveShader.tintColor, PIXI.hex2rgb(graphics.tint)); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); @@ -70,7 +73,6 @@ // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); PIXI.deactivatePrimitiveShader(); diff --git a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js index c57137e..329f2c7 100644 --- a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js +++ b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js @@ -18,7 +18,7 @@ // 65535 is max index, so 65535 / 6 = 10922. //the total number of floats in our batch - var numVerts = this.size * 4 * 5; + var numVerts = this.size * 4 * 6; //the total number of indices in our batch var numIndices = this.size * 6; @@ -63,7 +63,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = renderSession.projection; @@ -71,9 +71,9 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + this.currentBlendMode = 99999; } PIXI.WebGLSpriteBatch.prototype.end = function() @@ -84,12 +84,19 @@ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { + // check texture.. if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); this.currentBaseTexture = sprite.texture.baseTexture; } + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); + } + // get the uvs for the texture var uvs = sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! @@ -97,7 +104,7 @@ // get the sprites current alpha var alpha = sprite.worldAlpha; - + var tint = sprite.tint; var verticies = this.vertices; @@ -113,7 +120,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = sprite.worldTransform; @@ -132,6 +139,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -141,6 +149,7 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h0 + tx; @@ -150,6 +159,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -159,9 +169,12 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; + verticies[index++] = tint; // increment the batchs this.currentBatchSize++; + + } PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) @@ -174,6 +187,11 @@ this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } // set the textures uvs temporarily // TODO create a seperate texture so that we can tile part of a texture @@ -205,7 +223,7 @@ // get the tilingSprites current alpha var alpha = tilingSprite.worldAlpha; - + var tint = tilingSprite.tint; var verticies = this.vertices; @@ -221,7 +239,7 @@ var h0 = height * (1-aY); var h1 = height * -aY; - var index = this.currentBatchSize * 4 * 5; + var index = this.currentBatchSize * 4 * 6; worldTransform = tilingSprite.worldTransform; @@ -240,6 +258,7 @@ verticies[index++] = uvs[1]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w0 + c * h1 + tx; @@ -249,7 +268,8 @@ verticies[index++] = uvs[3]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // xy verticies[index++] = a * w0 + c * h0 + tx; verticies[index++] = d * h0 + b * w0 + ty; @@ -258,6 +278,7 @@ verticies[index++] = uvs[5]; // color verticies[index++] = alpha; + verticies[index++] = tint; // xy verticies[index++] = a * w1 + c * h0 + tx; @@ -267,7 +288,8 @@ verticies[index++] = uvs[7]; // color verticies[index++] = alpha; - + verticies[index++] = tint; + // increment the batchs this.currentBatchSize++; } @@ -293,7 +315,7 @@ // this is faster (especially if you are not filling the entire batch) // but it could do with more testing. In theory it SHOULD be faster // since bufferData allocates memory, whereas this should not. - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 5); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * 6); gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -315,7 +337,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - var stride = 5 * 4; + var stride = 6 * 4; var projection = this.renderSession.projection; @@ -323,9 +345,24 @@ gl.vertexAttribPointer(PIXI.defaultShader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); gl.vertexAttribPointer(PIXI.defaultShader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 1, gl.FLOAT, false, stride, 4 * 4); + gl.vertexAttribPointer(PIXI.defaultShader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } +} + +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } diff --git a/src/pixi/utils/Utils.js b/src/pixi/utils/Utils.js index 4551722..9b7f8e3 100644 --- a/src/pixi/utils/Utils.js +++ b/src/pixi/utils/Utils.js @@ -112,6 +112,32 @@ } }; +PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a) +{ + // console.log(r, b, c, d) + return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6)// | (Math.floor((a)*63)) + // i = i | (Math.floor((a)*63)); + // return i; + // var r = (i / 262144.0 ) / 64; + // var g = (i / 4096.0)%64 / 64; + // var b = (i / 64.0)%64 / 64; + // var a = (i)%64 / 64; + + // console.log(r, g, b, a); + // return i; + +} + +PIXI.packColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + +PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) +{ + return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255)); +} + /* * DEBUGGING ONLY */