diff --git a/src/pixi/extras/Strip.js b/src/pixi/extras/Strip.js index 2013490..93458ab 100644 --- a/src/pixi/extras/Strip.js +++ b/src/pixi/extras/Strip.js @@ -3,19 +3,19 @@ */ /** - * + * * @class Strip * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture to use - * @param width {Number} the width + * @param width {Number} the width * @param height {Number} the height - * + * */ PIXI.Strip = function(texture) { PIXI.DisplayObjectContainer.call( this ); - + /** * The texture of the strip @@ -39,7 +39,7 @@ this.colors = new PIXI.Float32Array([1, 1, 1, 1]); this.indices = new PIXI.Uint16Array([0, 1, 2, 3]); - + /** * Whether the strip is dirty or not * @@ -56,7 +56,7 @@ * @default PIXI.blendModes.NORMAL; */ this.blendMode = PIXI.blendModes.NORMAL; - + /** * if you need a padding, not yet implemented * @@ -66,6 +66,8 @@ this.padding = 0; // NYI, TODO padding ? + this.drawMode = PIXI.Strip.DrawModes.TRIANGLE_STRIP; + }; // constructor @@ -82,7 +84,7 @@ // init! init! if(!this._vertexBuffer)this._initWebGL(renderSession); - + renderSession.shaderManager.setShader(renderSession.shaderManager.stripShader); this._renderStrip(renderSession); @@ -91,19 +93,19 @@ renderSession.spriteBatch.start(); - //TODO check culling + //TODO check culling }; PIXI.Strip.prototype._initWebGL = function(renderSession) { // build the strip! var gl = renderSession.gl; - + this._vertexBuffer = gl.createBuffer(); this._indexBuffer = gl.createBuffer(); this._uvBuffer = gl.createBuffer(); this._colorBuffer = gl.createBuffer(); - + gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.verticies, gl.DYNAMIC_DRAW); @@ -112,7 +114,7 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); - + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); }; @@ -124,11 +126,12 @@ offset = renderSession.offset, shader = renderSession.shaderManager.stripShader; + var drawMode = this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP ? gl.TRIANGLE_STRIP : gl.TRIANGLES; // gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mat4Real); renderSession.blendModeManager.setBlendMode(this.blendMode); - + // set uniforms gl.uniformMatrix3fv(shader.translationMatrix, false, this.worldTransform.toArray(true)); @@ -138,15 +141,15 @@ if(!this.dirty) { - + gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies); gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - + // update the uvs gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - + gl.activeTexture(gl.TEXTURE0); // check if a texture is dirty.. @@ -159,11 +162,11 @@ // bind the current texture gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); } - + // dont need to upload! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - - + + } else { @@ -172,12 +175,12 @@ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.verticies, gl.STATIC_DRAW); gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - + // update the uvs gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - + gl.activeTexture(gl.TEXTURE0); // check if a texture is dirty.. @@ -189,18 +192,18 @@ { gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); } - + // dont need to upload! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - + } //console.log(gl.TRIANGLE_STRIP) // // - gl.drawElements(gl.TRIANGLE_STRIP, this.indices.length, gl.UNSIGNED_SHORT, 0); - - + gl.drawElements(drawMode, this.indices.length, gl.UNSIGNED_SHORT, 0); + + }; @@ -208,7 +211,7 @@ PIXI.Strip.prototype._renderCanvas = function(renderSession) { var context = renderSession.context; - + var transform = this.worldTransform; if (renderSession.roundPixels) @@ -219,54 +222,64 @@ { context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); } - + + if (this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP) + { + this._renderCanvasTriangleStrip(context); + } + else + { + this._renderCanvasTriangles(context); + } +}; + +PIXI.Strip.prototype._renderCanvasTriangleStrip = function(context) +{ var strip = this; // draw triangles!! var verticies = strip.verticies; var uvs = strip.uvs; - var length = verticies.length/2; + var length = verticies.length / 2; this.count++; - for (var i = 0; i < length-2; i++) - { + for (var i = 0; i < length - 2; i++) { // draw some triangles! - var index = i*2; + var index = i * 2; - var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; - var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + var x0 = verticies[index], x1 = verticies[index + 2], x2 = verticies[index + 4]; + var y0 = verticies[index + 1], y1 = verticies[index + 3], y2 = verticies[index + 5]; - if(this.padding > 0) - { - var centerX = (x0 + x1 + x2)/3; - var centerY = (y0 + y1 + y2)/3; + if (this.padding > 0) { + var centerX = (x0 + x1 + x2) / 3; + var centerY = (y0 + y1 + y2) / 3; var normX = x0 - centerX; var normY = y0 - centerY; - var dist = Math.sqrt( normX * normX + normY * normY ); + var dist = Math.sqrt(normX * normX + normY * normY); x0 = centerX + (normX / dist) * (dist + 3); y0 = centerY + (normY / dist) * (dist + 3); - // - + // + normX = x1 - centerX; normY = y1 - centerY; - dist = Math.sqrt( normX * normX + normY * normY ); + dist = Math.sqrt(normX * normX + normY * normY); x1 = centerX + (normX / dist) * (dist + 3); y1 = centerY + (normY / dist) * (dist + 3); normX = x2 - centerX; normY = y2 - centerY; - dist = Math.sqrt( normX * normX + normY * normY ); + dist = Math.sqrt(normX * normX + normY * normY); x2 = centerX + (normX / dist) * (dist + 3); y2 = centerY + (normY / dist) * (dist + 3); } - var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width; - var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height; + var u0 = uvs[index] * strip.texture.width, u1 = uvs[index + 2] * strip.texture.width, u2 = uvs[index + 4] * strip.texture.width; + var v0 = uvs[index + 1] * strip.texture.height, v1 = uvs[index + 3] * strip.texture.height, v2 = uvs[index + 5] * strip.texture.height; context.save(); context.beginPath(); @@ -281,23 +294,104 @@ context.clip(); // Compute matrix transform - var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2; - var deltaA = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; - var deltaB = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; - var deltaC = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; - var deltaD = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; - var deltaE = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; - var deltaF = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; + var delta = u0 * v1 + v0 * u2 + u1 * v2 - v1 * u2 - v0 * u1 - u0 * v2; + var deltaA = x0 * v1 + v0 * x2 + x1 * v2 - v1 * x2 - v0 * x1 - x0 * v2; + var deltaB = u0 * x1 + x0 * u2 + u1 * x2 - x1 * u2 - x0 * u1 - u0 * x2; + var deltaC = u0 * v1 * x2 + v0 * x1 * u2 + x0 * u1 * v2 - x0 * v1 * u2 - v0 * u1 * x2 - u0 * x1 * v2; + var deltaD = y0 * v1 + v0 * y2 + y1 * v2 - v1 * y2 - v0 * y1 - y0 * v2; + var deltaE = u0 * y1 + y0 * u2 + u1 * y2 - y1 * u2 - y0 * u1 - u0 * y2; + var deltaF = u0 * v1 * y2 + v0 * y1 * u2 + y0 * u1 * v2 - y0 * v1 * u2 - v0 * u1 * y2 - u0 * y1 * v2; context.transform(deltaA / delta, deltaD / delta, - deltaB / delta, deltaE / delta, - deltaC / delta, deltaF / delta); + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); context.drawImage(strip.texture.baseTexture.source, 0, 0); context.restore(); } }; +PIXI.Strip.prototype._renderCanvasTriangles = function(context) +{ + var strip = this; + // draw triangles!! + var verticies = strip.verticies; + var uvs = strip.uvs; + var indices = strip.indices; + + var length = indices.length; + this.count++; + + for (var i = 0; i < length; i += 3) { + // draw some triangles! + var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; + + var x0 = verticies[index0], x1 = verticies[index1], x2 = verticies[index2]; + var y0 = verticies[index0 + 1], y1 = verticies[index1 + 1], y2 = verticies[index2 + 1]; + + if (this.padding > 0) { + var padding = this.padding; + var centerX = (x0 + x1 + x2) / 3; + var centerY = (y0 + y1 + y2) / 3; + + var normX = x0 - centerX; + var normY = y0 - centerY; + + var dist = Math.sqrt(normX * normX + normY * normY); + x0 = centerX + (normX / dist) * (dist + padding); + y0 = centerY + (normY / dist) * (dist + padding); + + // + + normX = x1 - centerX; + normY = y1 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x1 = centerX + (normX / dist) * (dist + padding); + y1 = centerY + (normY / dist) * (dist + padding); + + normX = x2 - centerX; + normY = y2 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x2 = centerX + (normX / dist) * (dist + padding); + y2 = centerY + (normY / dist) * (dist + padding); + } + + var u0 = uvs[index0] * strip.texture.width, u1 = uvs[index1] * strip.texture.width, u2 = uvs[index2] * strip.texture.width; + var v0 = uvs[index0 + 1] * strip.texture.height, v1 = uvs[index1 + 1] * strip.texture.height, v2 = uvs[index2 + 1] * strip.texture.height; + + context.save(); + context.beginPath(); + + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + + context.closePath(); + + context.clip(); + + // Compute matrix transform + var delta = u0 * v1 + v0 * u2 + u1 * v2 - v1 * u2 - v0 * u1 - u0 * v2; + var deltaA = x0 * v1 + v0 * x2 + x1 * v2 - v1 * x2 - v0 * x1 - x0 * v2; + var deltaB = u0 * x1 + x0 * u2 + u1 * x2 - x1 * u2 - x0 * u1 - u0 * x2; + var deltaC = u0 * v1 * x2 + v0 * x1 * u2 + x0 * u1 * v2 - x0 * v1 * u2 - v0 * u1 * x2 - u0 * x1 * v2; + var deltaD = y0 * v1 + v0 * y2 + y1 * v2 - v1 * y2 - v0 * y1 - y0 * v2; + var deltaE = u0 * y1 + y0 * u2 + u1 * y2 - y1 * u2 - y0 * u1 - u0 * y2; + var deltaF = u0 * v1 * y2 + v0 * y1 * u2 + y0 * u1 * v2 - y0 * v1 * u2 - v0 * u1 * y2 - u0 * y1 * v2; + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(strip.texture.baseTexture.source, 0, 0); + context.restore(); + } +}; + + /** * Renders a flat strip @@ -328,7 +422,7 @@ context.lineTo(x2, y2); } - context.fillStyle = "#FF0000"; + context.fillStyle = '#FF0000'; context.fill(); context.closePath(); }; @@ -358,4 +452,9 @@ PIXI.Strip.prototype.onTextureUpdate = function() { this.updateFrame = true; -}; \ No newline at end of file +}; + +PIXI.Strip.DrawModes = { + TRIANGLE_STRIP: 0, + TRIANGLES: 1 +};