Added Sprite Batch

Added new Sprite Batch for fast rendering - pushes transforms to the GPU
Added setAttribs function to manage VertexAttribArrays in webGL
Modified Point.set function
This commit is contained in:
Mat Groves 2014-01-18 20:21:34 +00:00
parent 2ee1f778b3
commit 620d134055
17 changed files with 1781 additions and 21 deletions

View file

@ -21,6 +21,7 @@ module.exports = function(grunt) {
'<%= dirs.src %>/display/DisplayObject.js',
'<%= dirs.src %>/display/DisplayObjectContainer.js',
'<%= dirs.src %>/display/Sprite.js',
'<%= dirs.src %>/display/SpriteBatch.js',
'<%= dirs.src %>/display/MovieClip.js',
'<%= dirs.src %>/filters/FilterBlock.js',
'<%= dirs.src %>/text/Text.js',
@ -33,6 +34,7 @@ module.exports = function(grunt) {
'<%= dirs.src %>/utils/Polyk.js',
'<%= dirs.src %>/renderers/webgl/utils/WebGLShaderUtils.js',
'<%= dirs.src %>/renderers/webgl/shaders/PixiShader.js',
'<%= dirs.src %>/renderers/webgl/shaders/PixiFastShader.js',
'<%= dirs.src %>/renderers/webgl/shaders/StripShader.js',
'<%= dirs.src %>/renderers/webgl/shaders/PrimitiveShader.js',
'<%= dirs.src %>/renderers/webgl/utils/WebGLGraphics.js',
@ -40,6 +42,7 @@ module.exports = function(grunt) {
'<%= dirs.src %>/renderers/webgl/utils/WebGLMaskManager.js',
'<%= dirs.src %>/renderers/webgl/utils/WebGLShaderManager.js',
'<%= dirs.src %>/renderers/webgl/utils/WebGLSpriteBatch.js',
'<%= dirs.src %>/renderers/webgl/utils/WebGLFastSpriteBatch.js',
'<%= dirs.src %>/renderers/webgl/utils/WebGLFilterManager.js',
'<%= dirs.src %>/renderers/canvas/utils/CanvasMaskManager.js',
'<%= dirs.src %>/renderers/canvas/utils/CanvasTinter.js',

View file

@ -4,7 +4,7 @@
* Copyright (c) 2012, Mat Groves
* http://goodboydigital.com/
*
* Compiled: 2014-01-16
* Compiled: 2014-01-18
*
* pixi.js is licensed under the MIT License.
* http://www.opensource.org/licenses/mit-license.php
@ -75,7 +75,7 @@ PIXI.Point.prototype.constructor = PIXI.Point;
PIXI.Point.prototype.set = function(x, y)
{
this.x = x || 0;
this.y = y || (y !== 0) ? x : 0 ;
this.y = y || ( (y !== 0) ? this.x : 0 ) ;
};
@ -1969,6 +1969,75 @@ PIXI.Sprite.fromImage = function(imageId)
return new PIXI.Sprite(texture);
};
PIXI.SpriteBatch = function(texture)
{
PIXI.DisplayObjectContainer.call( this);
this.textureThing = texture;
this.ready = false;
};
PIXI.SpriteBatch.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
PIXI.SpriteBatch.constructor = PIXI.SpriteBatch;
PIXI.SpriteBatch.prototype.initWebGL = function(gl)
{
this.fastSpriteBatch = new PIXI.WebGLFastSpriteBatch(gl);
this.ready = true;
// alert("!")
};
PIXI.SpriteBatch.prototype.updateTransform = function()
{
// dont need to!
// PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
};
PIXI.SpriteBatch.prototype._renderWebGL = function(renderSession)
{
if(!this.visible)return;
// renderSession.shaderManager.deactivateDefaultShader()
if(!this.ready)this.initWebGL( renderSession.gl );
renderSession.spriteBatch.stop();
renderSession.shaderManager.activateShader(renderSession.shaderManager.fastShader);
this.fastSpriteBatch.begin(renderSession);
this.fastSpriteBatch.render(this.children);
//console.log("!!")
// renderSession.shaderManager.activateDefaultShader()
renderSession.shaderManager.activateShader(renderSession.shaderManager.defaultShader);
renderSession.spriteBatch.start();
/*
gl.useProgram(PIXI.defaultShader.program);
gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition);
gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute);
gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
*/
};
PIXI.SpriteBatch.prototype._renderCanvas = function(renderSession)
{
PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
PIXI.DisplayObjectContainer.prototype._renderCanvas.call(this, renderSession);
};
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
@ -3990,6 +4059,7 @@ PIXI.PixiShader = function(gl)
*/
this.textureCount = 0;
this.attributes = [];
this.init();
};
@ -4029,6 +4099,8 @@ PIXI.PixiShader.prototype.init = function()
this.colorAttribute = 2;
}
this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute];
// End worst hack eva //
// add those custom shaders!
@ -4272,6 +4344,129 @@ PIXI.PixiShader.defaultVertexSrc = [
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
* @author Richard Davey http://www.photonstorm.com @photonstorm
*/
/**
* @class PIXI.PixiFastShader
* @constructor
*/
PIXI.PixiFastShader = function(gl)
{
this.gl = gl;
/**
* @property {any} program - The WebGL program.
*/
this.program = null;
/**
* @property {array} fragmentSrc - The fragment shader.
*/
this.fragmentSrc = [
'precision lowp float;',
'varying vec2 vTextureCoord;',
'varying float vColor;',
'uniform sampler2D uSampler;',
'void main(void) {',
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
'}'
];
this.vertexSrc = [
'attribute vec2 aVertexPosition;',
'attribute vec2 aPositionCoord;',
'attribute vec2 aScale;',
'attribute float aRotation;',
'attribute vec2 aTextureCoord;',
'attribute float aColor;',
'uniform vec2 projectionVector;',
'uniform vec2 offsetVector;',
'uniform mat3 uMatrix;',
'varying vec2 vTextureCoord;',
'varying float vColor;',
'const vec2 center = vec2(-1.0, 1.0);',
'void main(void) {',
' vec2 v;',
' vec2 sv = aVertexPosition * aScale;',
' v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);',
' v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);',
' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;',
' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);',
' vTextureCoord = aTextureCoord;',
// ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;',
' vColor = aColor;',
'}'
];
/**
* @property {number} textureCount - A local texture counter for multi-texture shaders.
*/
this.textureCount = 0;
this.init();
};
/**
* @method PIXI.PixiFastShader#init
*/
PIXI.PixiFastShader.prototype.init = function()
{
var gl = this.gl;
var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
gl.useProgram(program);
// get and store the uniforms for the shader
this.uSampler = gl.getUniformLocation(program, 'uSampler');
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
this.dimensions = gl.getUniformLocation(program, 'dimensions');
this.uMatrix = gl.getUniformLocation(program, 'uMatrix');
// get and store the attributes
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
this.aPositionCoord = gl.getAttribLocation(program, 'aPositionCoord');
this.aScale = gl.getAttribLocation(program, 'aScale');
this.aRotation = gl.getAttribLocation(program, 'aRotation');
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
// Begin worst hack eva //
// WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
// maybe its somthing to do with the current state of the gl context.
// Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
// If theres any webGL people that know why could happen please help :)
if(this.colorAttribute === -1)
{
this.colorAttribute = 2;
}
this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute];
// End worst hack eva //
this.program = program;
};
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
@ -4400,6 +4595,8 @@ PIXI.PrimitiveShader.prototype.init = function()
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
this.attributes = [this.aVertexPosition, this.colorAttribute];
this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix');
this.alpha = gl.getUniformLocation(program, 'alpha');
@ -5446,8 +5643,16 @@ PIXI.WebGLMaskManager.prototype.popMask = function(renderSession)
PIXI.WebGLShaderManager = function(gl)
{
this.setContext(gl);
this.maxAttibs = 10;
this.attribState = [];
this.tempAttribState = [];
for (var i = 0; i < this.maxAttibs; i++) {
this.attribState[i] = false;
}
this.setContext(gl);
// the final one is used for the rendering strips
//this.stripShader = new PIXI.StripShader(gl);
};
@ -5462,15 +5667,80 @@ PIXI.WebGLShaderManager.prototype.setContext = function(gl)
// this shader is used for the default sprite rendering
this.defaultShader = new PIXI.PixiShader(gl);
var shaderProgram = this.defaultShader.program;
// this shader is used for the fast sprite rendering
this.fastShader = new PIXI.PixiFastShader(gl);
// var shaderProgram = this.defaultShader.program;
this.activateShader(this.defaultShader);
/*
gl.useProgram(shaderProgram);
gl.enableVertexAttribArray(this.defaultShader.aVertexPosition);
gl.enableVertexAttribArray(this.defaultShader.colorAttribute);
gl.enableVertexAttribArray(this.defaultShader.aTextureCoord);
// console.log(">>")
//
// alert(this.defaultShader.aPositionCoord)
gl.enableVertexAttribArray(this.defaultShader.aPositionCoord);
gl.enableVertexAttribArray(this.defaultShader.aScale);
gl.enableVertexAttribArray(this.defaultShader.aRotation);*/
};
PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs)
{
// reset temp state
var i;
for (i = 0; i < this.tempAttribState.length; i++)
{
this.tempAttribState[i] = false;
}
// set the new attribs
for (i = 0; i < attribs.length; i++)
{
var attribId = attribs[i];
this.tempAttribState[attribId] = true;
}
var gl = this.gl;
for (i = 0; i < this.attribState.length; i++)
{
if(this.attribState[i] !== this.tempAttribState[i])
{
this.attribState[i] = this.tempAttribState[i];
if(this.tempAttribState[i])
{
gl.enableVertexAttribArray(i);
}
else
{
gl.disableVertexAttribArray(i);
}
}
}
// console.log(this.tempAttribState)
};
PIXI.WebGLShaderManager.prototype.activateShader = function(shader)
{
//if(this.currentShader == shader)return;
this.currentShader = shader;
// console.log(shader.program)
this.gl.useProgram(shader.program);
this.setAttribs(shader.attributes);
// console.log(shader.attributes)
};
PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function()
@ -5479,12 +5749,14 @@ PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function()
gl.useProgram(this.primitiveShader.program);
this.setAttribs(this.primitiveShader.attributes);
/*
gl.disableVertexAttribArray(this.defaultShader.aVertexPosition);
gl.disableVertexAttribArray(this.defaultShader.colorAttribute);
gl.disableVertexAttribArray(this.defaultShader.aTextureCoord);
gl.enableVertexAttribArray(this.primitiveShader.aVertexPosition);
gl.enableVertexAttribArray(this.primitiveShader.colorAttribute);
gl.enableVertexAttribArray(this.primitiveShader.colorAttribute);*/
};
PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function()
@ -5493,12 +5765,16 @@ PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function()
gl.useProgram(this.defaultShader.program);
this.setAttribs(this.defaultShader.attributes);
/*
gl.disableVertexAttribArray(this.primitiveShader.aVertexPosition);
gl.disableVertexAttribArray(this.primitiveShader.colorAttribute);
gl.enableVertexAttribArray(this.defaultShader.aVertexPosition);
gl.enableVertexAttribArray(this.defaultShader.colorAttribute);
gl.enableVertexAttribArray(this.defaultShader.aTextureCoord);
gl.enableVertexAttribArray(this.defaultShader.aPositionCoord);*/
};
/**
* @author Mat Groves
@ -5514,9 +5790,10 @@ PIXI.WebGLSpriteBatch = function(gl)
{
this.size = 2000;
this.vertSize = 6;
this.size = 10000;//Math.pow(2, 16) / this.vertSize;
// console.log(this.size);
//the total number of floats in our batch
var numVerts = this.size * 4 * this.vertSize;
//the total number of indices in our batch
@ -5880,6 +6157,344 @@ PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode)
/**
* @author Mat Groves
*
* Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
* for creating the original pixi version!
*
* Heavily inspired by LibGDX's WebGLSpriteBatch:
* https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java
*/
PIXI.WebGLFastSpriteBatch = function(gl)
{
this.vertSize = 10;
this.maxSize = 6000;//Math.pow(2, 16) / this.vertSize;
this.size = this.maxSize;
// console.log(this.size);
//the total number of floats in our batch
var numVerts = this.size * 4 * this.vertSize;
//the total number of indices in our batch
var numIndices = this.maxSize * 6;
//vertex data
this.vertices = new Float32Array(numVerts);
//index data
this.indices = new Uint16Array(numIndices);
this.vertexBuffer = null;
this.indexBuffer = null;
this.lastIndexCount = 0;
for (var i=0, j=0; i < numIndices; i += 6, j += 4)
{
this.indices[i + 0] = j + 0;
this.indices[i + 1] = j + 1;
this.indices[i + 2] = j + 2;
this.indices[i + 3] = j + 0;
this.indices[i + 4] = j + 2;
this.indices[i + 5] = j + 3;
}
this.drawing = false;
this.currentBatchSize = 0;
this.currentBaseTexture = null;
this.currentBlendMode = 0;
this.renderSession = null;
this.shader = null;
this.tempMatrix = PIXI.mat3.create();
PIXI.mat3.transpose( this.tempMatrix);
this.setContext(gl);
};
PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl)
{
this.gl = gl;
// create a couple of buffers
this.vertexBuffer = gl.createBuffer();
this.indexBuffer = gl.createBuffer();
// 65535 is max index, so 65535 / 6 = 10922.
//upload the index data
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
this.currentBlendMode = 99999;
};
PIXI.WebGLFastSpriteBatch.prototype.begin = function(renderSession)
{
this.renderSession = renderSession;
this.shader = this.renderSession.shaderManager.fastShader;
this.start();
};
PIXI.WebGLFastSpriteBatch.prototype.end = function()
{
this.flush();
};
PIXI.WebGLFastSpriteBatch.prototype.render = function(children)
{
var sprite = children[0];
// if the uvs have not updated then no point rendering just yet!
if(!sprite.texture._uvs)return;
// check texture.
this.currentBaseTexture = sprite.texture.baseTexture;
// check blend mode
if(sprite.blendMode !== this.currentBlendMode)
{
this.setBlendMode(sprite.blendMode);
}
for(var i=0,j= children.length; i<j; i++)
{
this.renderSprite(children[i]);
}
this.flush();
};
PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite)
{
//sprite = children[i];
var uvs, verticies = this.vertices, width, height, w0, w1, h0, h1, index;
uvs = sprite.texture._uvs;
width = sprite.texture.frame.width;
height = sprite.texture.frame.height;
// TODO trim??
if (sprite.texture.trimmed)
{
// if the sprite is trimmed then we need to add the extra space before transforming the sprite coords..
var trim = sprite.texture.trim;
w1 = trim.x - sprite.anchor.x * trim.realWidth;
w0 = w1 + sprite.texture.frame.width;
h1 = trim.y - sprite.anchor.y * trim.realHeight;
h0 = h1 + sprite.texture.frame.height;
}
else
{
w0 = (sprite.texture.frame.width ) * (1-sprite.anchor.x);
w1 = (sprite.texture.frame.width ) * -sprite.anchor.x;
h0 = sprite.texture.frame.height * (1-sprite.anchor.y);
h1 = sprite.texture.frame.height * -sprite.anchor.y;
}
index = this.currentBatchSize * 4 * this.vertSize;
// xy
verticies[index++] = w1;
verticies[index++] = h1;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[0];
verticies[index++] = uvs[1];
// color
verticies[index++] = sprite.alpha;
// xy
verticies[index++] = w0;
verticies[index++] = h1;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[2];
verticies[index++] = uvs[3];
// color
verticies[index++] = sprite.alpha;
// xy
verticies[index++] = w0;
verticies[index++] = h0;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[4];
verticies[index++] = uvs[5];
// color
verticies[index++] = sprite.alpha;
// xy
verticies[index++] = w1;
verticies[index++] = h0;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[6];
verticies[index++] = uvs[7];
// color
verticies[index++] = sprite.alpha;
// increment the batchs
this.currentBatchSize++;
if(this.currentBatchSize >= this.size)
{
this.flush();
}
};
PIXI.WebGLFastSpriteBatch.prototype.flush = function()
{
// If the batch is length 0 then return as there is nothing to draw
if (this.currentBatchSize===0)return;
var gl = this.gl;
// bind the current texture
if(!this.currentBaseTexture._glTextures[gl.id])PIXI.createWebGLTexture(this.currentBaseTexture, gl);
gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]);// || PIXI.createWebGLTexture(this.currentBaseTexture, gl));
// upload the verts to the buffer
if(this.currentBatchSize > ( this.size * 0.5 ) )
{
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
}
else
{
var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
}
// now draw those suckas!
gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
// then reset the batch!
this.currentBatchSize = 0;
// increment the draw count
this.renderSession.drawCount++;
};
PIXI.WebGLFastSpriteBatch.prototype.stop = function()
{
this.flush();
};
PIXI.WebGLFastSpriteBatch.prototype.start = function()
{
var gl = this.gl;
// bind the main texture
gl.activeTexture(gl.TEXTURE0);
// bind the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// set the projection
var projection = this.renderSession.projection;
gl.uniform2f(this.shader.projectionVector, projection.x, projection.y);
// set the matrix
gl.uniformMatrix3fv(this.shader.uMatrix, false, this.tempMatrix);
// set the pointers
var stride = this.vertSize * 4;
gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
gl.vertexAttribPointer(this.shader.aPositionCoord, 2, gl.FLOAT, false, stride, 2 * 4);
gl.vertexAttribPointer(this.shader.aScale, 2, gl.FLOAT, false, stride, 4 * 4);
gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4);
gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4);
gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4);
// set the blend mode..
if(this.currentBlendMode !== PIXI.blendModes.NORMAL)
{
this.setBlendMode(PIXI.blendModes.NORMAL);
}
};
PIXI.WebGLFastSpriteBatch.prototype.setBlendMode = function(blendMode)
{
this.flush();
this.currentBlendMode = blendMode;
var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode];
this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
};
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
@ -10067,7 +10682,7 @@ PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode)
PIXI.Texture.fromFrame = function(frameId)
{
var texture = PIXI.TextureCache[frameId];
if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this);
if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ');
return texture;
};

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,159 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Sprite Batch</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #000000;
}
.rendererView {
position: absolute;
display: block;
width: 100%;
height: 100%;
}
</style>
<script src="pixi.js"></script>
<script src="../../bin/pixi.dev.js"></script>
</head>
<body>
<script>
var viewWidth = 800;
var viewHeight = 600;
// Create a pixi renderer
var renderer = PIXI.autoDetectRenderer(viewWidth, viewHeight);
renderer.view.className = "rendererView";
// add render view to DOM
document.body.appendChild(renderer.view);
// create an new instance of a pixi stage
var stage = new PIXI.Stage(0xFFFFFF);
// create a background texture
var pondFloorTexture = PIXI.Texture.fromImage("BGrotate.jpg");
// create a new background sprite
// var pondFloorSprite = new PIXI.Sprite(pondFloorTexture);
//stage.addChild(pondFloorSprite);
var particles = new PIXI.DisplayObjectContainer()//
var particles = new PIXI.SpriteBatch(PIXI.Texture.fromImage("eggHead.png"));
stage.addChild(particles);
// create an array to store a refference to the fish in the pond
var dudeArray = [];
var totalDude = renderer instanceof PIXI.WebGLRenderer ? 10000 : 100//.view.className = "rendererView";
var tints = [0xFFFFFF,
0xfffbee,
0xffeeee,
0xfadeed,
0xe8d4cd];
for (var i = 0; i < totalDude; i++)
{
// create a new Sprite that uses the image name that we just generated as its source
var dude = PIXI.Sprite.fromImage("tinyMaggot.png");
// set the anchor point so the the dude texture is centerd on the sprite
dude.anchor.x = dude.anchor.y = 0.5;
// set a random scale for the dude - no point them all being the same size!
dude.scale.x = dude.scale.y = 0.8 + Math.random() * 0.3;
// finally lets set the dude to be a random position..
dude.position.x = Math.random() * viewWidth;
dude.position.y = Math.random() * viewHeight;
// time to add the dude to the pond container!
// stage.addChild(dude);
// create some extra properties that will control movment
//dude.tint = i > 3000 ? 0x977d76 : tints[i % tints.length];//Math.random() * 0xFFFFFF;
// create a random direction in radians. This is a number between 0 and PI*2 which is the equivalent of 0 - 360 degrees
dude.direction = Math.random() * Math.PI * 2;
// this number will be used to modify the direction of the dude over time
dude.turningSpeed = Math.random() - 0.8;
// create a random speed for the dude between 0 - 2
dude.speed = (2 + Math.random() * 2) * 0.2;
dude.offset = Math.random() * 100;
// finally we push the dude into the dudeArray so it it can be easily accessed later
dudeArray.push(dude);
particles.addChild(dude);
}
// create a bounding box box for the little dudes
var dudeBoundsPadding = 100;
var dudeBounds = new PIXI.Rectangle(-dudeBoundsPadding,
-dudeBoundsPadding,
viewWidth + dudeBoundsPadding * 2,
viewHeight + dudeBoundsPadding * 2);
// create a displacment map
var tick = 0;
requestAnimationFrame(animate);
function animate()
{
// iterate through the dude and update the positiond
for (var i = 0; i < dudeArray.length; i++)
{
var dude = dudeArray[i];
dude.scale.y = 0.95 + Math.sin(tick + dude.offset) * 0.05
dude.direction += dude.turningSpeed * 0.01;
dude.position.x += Math.sin(dude.direction) * (dude.speed * dude.scale.y);
dude.position.y += Math.cos(dude.direction) * (dude.speed *dude.scale.y );
dude.rotation = -dude.direction + Math.PI;
// wrap the dudes by testing there bounds..
if(dude.position.x < dudeBounds.x)dude.position.x += dudeBounds.width;
else if(dude.position.x > dudeBounds.x + dudeBounds.width)dude.position.x -= dudeBounds.width
if(dude.position.y < dudeBounds.y)dude.position.y += dudeBounds.height;
else if(dude.position.y > dudeBounds.y + dudeBounds.height)dude.position.y -= dudeBounds.height
}
// increment the ticker
tick += 0.1;
// time to render the state!
renderer.render(stage);
// request another animation frame..
requestAnimationFrame( animate );
}
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

@ -44,6 +44,6 @@ PIXI.Point.prototype.constructor = PIXI.Point;
PIXI.Point.prototype.set = function(x, y)
{
this.x = x || 0;
this.y = y || ( (y !== 0) ? x : 0 ) ;
this.y = y || ( (y !== 0) ? this.x : 0 ) ;
};

View file

@ -0,0 +1,371 @@
PIXI.ParticleBatch = function(texture)
{
PIXI.DisplayObjectContainer.call( this);
this.textureThing = texture;
this.ready = false;
}
PIXI.ParticleBatch.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
PIXI.ParticleBatch.constructor = PIXI.ParticleBatch;
PIXI.ParticleBatch.prototype.initWebGL = function(gl)
{
var vecShaderSrc = [
"attribute vec2 aVertexPosition;",
"attribute vec2 aMovement;",
"attribute vec2 aTexture;",
"uniform mat3 translationMatrix;",
"uniform float time;",
// "uniform float pos;",
"uniform vec2 projectionVector;",
"varying vec2 vTextureCoord;",
"const float PI = 3.14159265358;",
"void main(void) {",
"vec2 v = aVertexPosition;",
"float x = aMovement.x * 0.01;",
"vec2 scaledVertex = aVertexPosition;",
"v.x = (scaledVertex.x) * cos(x) - (scaledVertex.y) * sin(x);",
"v.y = (scaledVertex.x) * sin(x) + (scaledVertex.y) * cos(x);",
//"float pos = p * p * ((this._p1 + 1) * p - this._p1);"
//"v.y = sin(-time*PI * 2.0) * -aMovement.y;",
"v += aMovement;",
// "v += aVertexPosition;",
// "v.y *= 1.0 + smoothstep(time, 0.5, 1.0) * 3.0;",
// "v.y += aMovement.y * time + aVertexPosition.y;",
// "v.y = time * aMovement.y;;",
// "v.y += aVertexPosition.y;",
//"v.x += aMovement.x ;",
// "v.y *= -1.0;",
"v.x += 1280.0/2.0;",
"v.y += 800.0/2.0;",
"gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);",
// "gl_Position = vec4(aVertexPosition, 0.0, 1.0);",
"vTextureCoord = aTexture;",
"}"
];
var fragShaderSrc = [
"precision lowp float;",
"varying vec2 vTextureCoord;",
"uniform sampler2D uSampler;",
"void main(void) {",
"gl_FragColor = texture2D(uSampler, vTextureCoord);",
"}"
];
this.program = PIXI.compileProgram(gl, vecShaderSrc, fragShaderSrc)
gl.useProgram(this.program);
this.translationMatrix = gl.getUniformLocation(this.program, "translationMatrix");
this.projectionVector = gl.getUniformLocation(this.program, "projectionVector");
this.time = gl.getUniformLocation(this.program, "time");
this.aVertexPosition = gl.getAttribLocation(this.program, "aVertexPosition");
this.aMovement = gl.getAttribLocation(this.program, "aMovement");
this.aTexture = gl.getAttribLocation(this.program, "aTexture");
// console.log(":::" + this.aMovement)
this.totalItems = 10000;
this.verticies = new Float32Array( this.totalItems * 8 );
this.movement = new Float32Array( this.totalItems * 8 );
this.posData = new Float32Array( this.totalItems * 3 );
this.texture = new Float32Array( this.totalItems * 8 );
this.indices = new Uint16Array( this.totalItems * 6);
for (var i = 0; i < this.totalItems * 8; i+=8) {
var scale = 1// + Math.random()
// position..
this.verticies[i] = -20 * scale;
this.verticies[i+1] = -20 * scale;
this.verticies[i+2] = 20 * scale;
this.verticies[i+3] = -20 * scale;
this.verticies[i+4] = 20 * scale;
this.verticies[i+5] = 20 * scale;
this.verticies[i+6] = -20 * scale;
this.verticies[i+7] = 20 * scale;
};
var fullWidth = 142;
var fullHeight= 157;
var simpleFrame = new PIXI.Rectangle(0, 0, 142, 157);
var gemCount = 0;
for (var i = 0; i < this.totalItems * 8; i+=8) {
gemCount++
var gemFrame = this.texture.frame || simpleFrame;//this.gems[gemCount % this.gems.length].frame;
// console.log(gemFrame);
// position..
var xoff = gemFrame.x / fullWidth;
var yoff = gemFrame.y / fullHeight;
this.texture[i] = xoff;
this.texture[i+1] = yoff;
this.texture[i+2] = xoff + gemFrame.width / fullWidth;
this.texture[i+3] = yoff;
this.texture[i+4] = xoff + gemFrame.width / fullWidth;
this.texture[i+5] = yoff + gemFrame.height / fullHeight;
this.texture[i+6] = xoff;
this.texture[i+7] = yoff + gemFrame.height / fullHeight;
//
};
for (var i = 0; i < this.totalItems* 8; i+=8) {
var pos = 0//Math.random() * 200;
var angle = Math.random() * Math.PI * 2;
var speed = (0.3 + Math.random() * 0.9) * 0.01;
var pos = Math.sin(angle) * speed;//Math.random() * 10 - 5;
var posY = Math.cos(angle) * speed;
var scale = 1;
// var posY = 0.5 + Math.random()// * 200
// console.log(pos);
this.movement[i] = pos;
this.movement[i+1] = posY;
this.movement[i+2] = scale;
this.movement[i+3] = scale;
this.movement[i+4] = rotation;
this.movement[i+5] = scale;
this.movement[i+2] = pos;
this.movement[i+3] = posY;
this.movement[i+4] = pos;
this.movement[i+5] = posY;
this.movement[i+6] = pos;
this.movement[i+7] = posY;
}
this.reset();
for (var i = 0; i < this.totalItems * 6; i+=6) {
var i3 = (i / 6) * 4;
this.indices[i] = i3;
this.indices[i+1] = i3+1;
this.indices[i+2] = i3+2;
this.indices[i+3] = i3;
this.indices[i+4] = i3+2;
this.indices[i+5] = i3+3;
}
// console.log(this);
this.vertexBuffer = gl.createBuffer();
this.textureBuffer = gl.createBuffer();
this.movementBuffer = gl.createBuffer();
this.indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.verticies, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.texture, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, this.movementBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.movement, gl.DYNAMIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
this.count = 0;
this.speed = 18;
this.posy = 0;
this.ready = true;
// alert("!")
}
PIXI.ParticleBatch.prototype.addChild = function(child)
{
PIXI.DisplayObjectContainer.prototype.addChild.call(child);
}
PIXI.ParticleBatch.prototype.reset = function()
{
for (var i = 0; i < this.totalItems* 4; i+=4) {
this.posData[i] = 0; // pos x
this.posData[i + 1] = 0; // pos y
var angle = Math.random() * Math.PI * 2;
var speed = 10 + Math.random() * 15;
var pos = Math.sin(angle) * speed;//Math.random() * 10 - 5;
var posY = Math.cos(angle) *speed;
this.posData[i + 2] = pos; // speed x
this.posData[i + 3] = posY - 10; // speed y
}
}
PIXI.ParticleBatch.prototype._renderWebGL = function(renderSession)
{
if(!this.visible)return;
renderSession.shaderManager.deactivateDefaultShader()
if(!this.ready)this.initWebGL( renderSession.gl );
renderSession.spriteBatch.stop();
this.speed -= 0.4;
this.count += this.speed;
var gl = renderSession.gl;
var glTexture = this.textureThing.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture(this.textureThing.baseTexture, gl)
gl.useProgram(this.program);
gl.enableVertexAttribArray(this.aVertexPosition);
gl.enableVertexAttribArray(this.aMovement);
gl.enableVertexAttribArray(this.aTexture);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, glTexture);
gl.uniform1f(this.time, this.count);
gl.uniform2f(this.projectionVector, renderSession.projection.x, renderSession.projection.y);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
gl.vertexAttribPointer(this.aTexture, 2, gl.FLOAT, false, 0, 0);
for (var i = 0; i < this.totalItems* 8; i+=8) {
var val = ( i / 8 ) * 4;
this.posData[val + 3] += 0.02;
this.posData[val] += this.posData[val + 2];
this.posData[val + 1] += this.posData[val + 3];
var pos = this.posData[val];
var posY = this.posData[val + 1];
//pos += this.posData[val + 2];
//posY += this.posData[val + 3];
this.movement[i] = pos;
this.movement[i+1] = posY;
this.movement[i+2] = pos;
this.movement[i+3] = posY;
this.movement[i+4] = pos;
this.movement[i+5] = posY;
this.movement[i+6] = pos;
this.movement[i+7] = posY;
}
gl.bindBuffer(gl.ARRAY_BUFFER, this.movementBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.movement);
gl.vertexAttribPointer(this.aMovement, 2, gl.FLOAT, false, 0, 0);
//gl.bindBuffer(gl.ARRAY_BUFFER, this.movementBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.drawElements(gl.TRIANGLES, 6 * this.totalItems , gl.UNSIGNED_SHORT, 0);
// not sure if both needed? but ya have for now!
// override!
// disable the current stuff..
// gl.disableVertexAttribArray(PIXI.stripShader.aVertexPosition);
//gl.disableVertexAttribArray(PIXI.stripShader.colorAttribute);
//gl.disableVertexAttribArray(PIXI.stripShader.aTextureCoord);
gl.disableVertexAttribArray(this.aVertexPosition);
gl.disableVertexAttribArray(this.aMovement);
gl.disableVertexAttribArray(this.aTexture);
renderSession.shaderManager.activateDefaultShader()
renderSession.spriteBatch.start();
/*
gl.useProgram(PIXI.defaultShader.program);
gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition);
gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute);
gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
*/
}

View file

@ -0,0 +1,68 @@
PIXI.SpriteBatch = function(texture)
{
PIXI.DisplayObjectContainer.call( this);
this.textureThing = texture;
this.ready = false;
};
PIXI.SpriteBatch.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
PIXI.SpriteBatch.constructor = PIXI.SpriteBatch;
PIXI.SpriteBatch.prototype.initWebGL = function(gl)
{
this.fastSpriteBatch = new PIXI.WebGLFastSpriteBatch(gl);
this.ready = true;
// alert("!")
};
PIXI.SpriteBatch.prototype.updateTransform = function()
{
// dont need to!
// PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
};
PIXI.SpriteBatch.prototype._renderWebGL = function(renderSession)
{
if(!this.visible)return;
// renderSession.shaderManager.deactivateDefaultShader()
if(!this.ready)this.initWebGL( renderSession.gl );
renderSession.spriteBatch.stop();
renderSession.shaderManager.activateShader(renderSession.shaderManager.fastShader);
this.fastSpriteBatch.begin(renderSession);
this.fastSpriteBatch.render(this.children);
//console.log("!!")
// renderSession.shaderManager.activateDefaultShader()
renderSession.shaderManager.activateShader(renderSession.shaderManager.defaultShader);
renderSession.spriteBatch.start();
/*
gl.useProgram(PIXI.defaultShader.program);
gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition);
gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute);
gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
*/
};
PIXI.SpriteBatch.prototype._renderCanvas = function(renderSession)
{
PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
PIXI.DisplayObjectContainer.prototype._renderCanvas.call(this, renderSession);
};

View file

@ -0,0 +1,122 @@
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
* @author Richard Davey http://www.photonstorm.com @photonstorm
*/
/**
* @class PIXI.PixiFastShader
* @constructor
*/
PIXI.PixiFastShader = function(gl)
{
this.gl = gl;
/**
* @property {any} program - The WebGL program.
*/
this.program = null;
/**
* @property {array} fragmentSrc - The fragment shader.
*/
this.fragmentSrc = [
'precision lowp float;',
'varying vec2 vTextureCoord;',
'varying float vColor;',
'uniform sampler2D uSampler;',
'void main(void) {',
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
'}'
];
this.vertexSrc = [
'attribute vec2 aVertexPosition;',
'attribute vec2 aPositionCoord;',
'attribute vec2 aScale;',
'attribute float aRotation;',
'attribute vec2 aTextureCoord;',
'attribute float aColor;',
'uniform vec2 projectionVector;',
'uniform vec2 offsetVector;',
'uniform mat3 uMatrix;',
'varying vec2 vTextureCoord;',
'varying float vColor;',
'const vec2 center = vec2(-1.0, 1.0);',
'void main(void) {',
' vec2 v;',
' vec2 sv = aVertexPosition * aScale;',
' v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);',
' v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);',
' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;',
' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);',
' vTextureCoord = aTextureCoord;',
// ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;',
' vColor = aColor;',
'}'
];
/**
* @property {number} textureCount - A local texture counter for multi-texture shaders.
*/
this.textureCount = 0;
this.init();
};
/**
* @method PIXI.PixiFastShader#init
*/
PIXI.PixiFastShader.prototype.init = function()
{
var gl = this.gl;
var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
gl.useProgram(program);
// get and store the uniforms for the shader
this.uSampler = gl.getUniformLocation(program, 'uSampler');
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
this.dimensions = gl.getUniformLocation(program, 'dimensions');
this.uMatrix = gl.getUniformLocation(program, 'uMatrix');
// get and store the attributes
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
this.aPositionCoord = gl.getAttribLocation(program, 'aPositionCoord');
this.aScale = gl.getAttribLocation(program, 'aScale');
this.aRotation = gl.getAttribLocation(program, 'aRotation');
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
// Begin worst hack eva //
// WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
// maybe its somthing to do with the current state of the gl context.
// Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
// If theres any webGL people that know why could happen please help :)
if(this.colorAttribute === -1)
{
this.colorAttribute = 2;
}
this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute];
// End worst hack eva //
this.program = program;
};

View file

@ -35,6 +35,7 @@ PIXI.PixiShader = function(gl)
*/
this.textureCount = 0;
this.attributes = [];
this.init();
};
@ -74,6 +75,8 @@ PIXI.PixiShader.prototype.init = function()
this.colorAttribute = 2;
}
this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute];
// End worst hack eva //
// add those custom shaders!

View file

@ -58,6 +58,8 @@ PIXI.PrimitiveShader.prototype.init = function()
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
this.attributes = [this.aVertexPosition, this.colorAttribute];
this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix');
this.alpha = gl.getUniformLocation(program, 'alpha');

View file

@ -0,0 +1,337 @@
/**
* @author Mat Groves
*
* Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
* for creating the original pixi version!
*
* Heavily inspired by LibGDX's WebGLSpriteBatch:
* https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java
*/
PIXI.WebGLFastSpriteBatch = function(gl)
{
this.vertSize = 10;
this.maxSize = 6000;//Math.pow(2, 16) / this.vertSize;
this.size = this.maxSize;
// console.log(this.size);
//the total number of floats in our batch
var numVerts = this.size * 4 * this.vertSize;
//the total number of indices in our batch
var numIndices = this.maxSize * 6;
//vertex data
this.vertices = new Float32Array(numVerts);
//index data
this.indices = new Uint16Array(numIndices);
this.vertexBuffer = null;
this.indexBuffer = null;
this.lastIndexCount = 0;
for (var i=0, j=0; i < numIndices; i += 6, j += 4)
{
this.indices[i + 0] = j + 0;
this.indices[i + 1] = j + 1;
this.indices[i + 2] = j + 2;
this.indices[i + 3] = j + 0;
this.indices[i + 4] = j + 2;
this.indices[i + 5] = j + 3;
}
this.drawing = false;
this.currentBatchSize = 0;
this.currentBaseTexture = null;
this.currentBlendMode = 0;
this.renderSession = null;
this.shader = null;
this.tempMatrix = PIXI.mat3.create();
PIXI.mat3.transpose( this.tempMatrix);
this.setContext(gl);
};
PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl)
{
this.gl = gl;
// create a couple of buffers
this.vertexBuffer = gl.createBuffer();
this.indexBuffer = gl.createBuffer();
// 65535 is max index, so 65535 / 6 = 10922.
//upload the index data
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
this.currentBlendMode = 99999;
};
PIXI.WebGLFastSpriteBatch.prototype.begin = function(renderSession)
{
this.renderSession = renderSession;
this.shader = this.renderSession.shaderManager.fastShader;
this.start();
};
PIXI.WebGLFastSpriteBatch.prototype.end = function()
{
this.flush();
};
PIXI.WebGLFastSpriteBatch.prototype.render = function(children)
{
var sprite = children[0];
// if the uvs have not updated then no point rendering just yet!
if(!sprite.texture._uvs)return;
// check texture.
this.currentBaseTexture = sprite.texture.baseTexture;
// check blend mode
if(sprite.blendMode !== this.currentBlendMode)
{
this.setBlendMode(sprite.blendMode);
}
for(var i=0,j= children.length; i<j; i++)
{
this.renderSprite(children[i]);
}
this.flush();
};
PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite)
{
//sprite = children[i];
var uvs, verticies = this.vertices, width, height, w0, w1, h0, h1, index;
uvs = sprite.texture._uvs;
width = sprite.texture.frame.width;
height = sprite.texture.frame.height;
// TODO trim??
if (sprite.texture.trimmed)
{
// if the sprite is trimmed then we need to add the extra space before transforming the sprite coords..
var trim = sprite.texture.trim;
w1 = trim.x - sprite.anchor.x * trim.realWidth;
w0 = w1 + sprite.texture.frame.width;
h1 = trim.y - sprite.anchor.y * trim.realHeight;
h0 = h1 + sprite.texture.frame.height;
}
else
{
w0 = (sprite.texture.frame.width ) * (1-sprite.anchor.x);
w1 = (sprite.texture.frame.width ) * -sprite.anchor.x;
h0 = sprite.texture.frame.height * (1-sprite.anchor.y);
h1 = sprite.texture.frame.height * -sprite.anchor.y;
}
index = this.currentBatchSize * 4 * this.vertSize;
// xy
verticies[index++] = w1;
verticies[index++] = h1;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[0];
verticies[index++] = uvs[1];
// color
verticies[index++] = sprite.alpha;
// xy
verticies[index++] = w0;
verticies[index++] = h1;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[2];
verticies[index++] = uvs[3];
// color
verticies[index++] = sprite.alpha;
// xy
verticies[index++] = w0;
verticies[index++] = h0;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[4];
verticies[index++] = uvs[5];
// color
verticies[index++] = sprite.alpha;
// xy
verticies[index++] = w1;
verticies[index++] = h0;
verticies[index++] = sprite.position.x;
verticies[index++] = sprite.position.y;
//scale
verticies[index++] = sprite.scale.x;
verticies[index++] = sprite.scale.y;
//rotation
verticies[index++] = sprite.rotation;
// uv
verticies[index++] = uvs[6];
verticies[index++] = uvs[7];
// color
verticies[index++] = sprite.alpha;
// increment the batchs
this.currentBatchSize++;
if(this.currentBatchSize >= this.size)
{
this.flush();
}
};
PIXI.WebGLFastSpriteBatch.prototype.flush = function()
{
// If the batch is length 0 then return as there is nothing to draw
if (this.currentBatchSize===0)return;
var gl = this.gl;
// bind the current texture
if(!this.currentBaseTexture._glTextures[gl.id])PIXI.createWebGLTexture(this.currentBaseTexture, gl);
gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]);// || PIXI.createWebGLTexture(this.currentBaseTexture, gl));
// upload the verts to the buffer
if(this.currentBatchSize > ( this.size * 0.5 ) )
{
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
}
else
{
var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
}
// now draw those suckas!
gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
// then reset the batch!
this.currentBatchSize = 0;
// increment the draw count
this.renderSession.drawCount++;
};
PIXI.WebGLFastSpriteBatch.prototype.stop = function()
{
this.flush();
};
PIXI.WebGLFastSpriteBatch.prototype.start = function()
{
var gl = this.gl;
// bind the main texture
gl.activeTexture(gl.TEXTURE0);
// bind the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// set the projection
var projection = this.renderSession.projection;
gl.uniform2f(this.shader.projectionVector, projection.x, projection.y);
// set the matrix
gl.uniformMatrix3fv(this.shader.uMatrix, false, this.tempMatrix);
// set the pointers
var stride = this.vertSize * 4;
gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
gl.vertexAttribPointer(this.shader.aPositionCoord, 2, gl.FLOAT, false, stride, 2 * 4);
gl.vertexAttribPointer(this.shader.aScale, 2, gl.FLOAT, false, stride, 4 * 4);
gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4);
gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4);
gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4);
// set the blend mode..
if(this.currentBlendMode !== PIXI.blendModes.NORMAL)
{
this.setBlendMode(PIXI.blendModes.NORMAL);
}
};
PIXI.WebGLFastSpriteBatch.prototype.setBlendMode = function(blendMode)
{
this.flush();
this.currentBlendMode = blendMode;
var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode];
this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
};

View file

@ -4,8 +4,16 @@
PIXI.WebGLShaderManager = function(gl)
{
this.setContext(gl);
this.maxAttibs = 10;
this.attribState = [];
this.tempAttribState = [];
for (var i = 0; i < this.maxAttibs; i++) {
this.attribState[i] = false;
}
this.setContext(gl);
// the final one is used for the rendering strips
//this.stripShader = new PIXI.StripShader(gl);
};
@ -20,15 +28,80 @@ PIXI.WebGLShaderManager.prototype.setContext = function(gl)
// this shader is used for the default sprite rendering
this.defaultShader = new PIXI.PixiShader(gl);
var shaderProgram = this.defaultShader.program;
// this shader is used for the fast sprite rendering
this.fastShader = new PIXI.PixiFastShader(gl);
// var shaderProgram = this.defaultShader.program;
this.activateShader(this.defaultShader);
/*
gl.useProgram(shaderProgram);
gl.enableVertexAttribArray(this.defaultShader.aVertexPosition);
gl.enableVertexAttribArray(this.defaultShader.colorAttribute);
gl.enableVertexAttribArray(this.defaultShader.aTextureCoord);
// console.log(">>")
//
// alert(this.defaultShader.aPositionCoord)
gl.enableVertexAttribArray(this.defaultShader.aPositionCoord);
gl.enableVertexAttribArray(this.defaultShader.aScale);
gl.enableVertexAttribArray(this.defaultShader.aRotation);*/
};
PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs)
{
// reset temp state
var i;
for (i = 0; i < this.tempAttribState.length; i++)
{
this.tempAttribState[i] = false;
}
// set the new attribs
for (i = 0; i < attribs.length; i++)
{
var attribId = attribs[i];
this.tempAttribState[attribId] = true;
}
var gl = this.gl;
for (i = 0; i < this.attribState.length; i++)
{
if(this.attribState[i] !== this.tempAttribState[i])
{
this.attribState[i] = this.tempAttribState[i];
if(this.tempAttribState[i])
{
gl.enableVertexAttribArray(i);
}
else
{
gl.disableVertexAttribArray(i);
}
}
}
// console.log(this.tempAttribState)
};
PIXI.WebGLShaderManager.prototype.activateShader = function(shader)
{
//if(this.currentShader == shader)return;
this.currentShader = shader;
// console.log(shader.program)
this.gl.useProgram(shader.program);
this.setAttribs(shader.attributes);
// console.log(shader.attributes)
};
PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function()
@ -37,12 +110,14 @@ PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function()
gl.useProgram(this.primitiveShader.program);
this.setAttribs(this.primitiveShader.attributes);
/*
gl.disableVertexAttribArray(this.defaultShader.aVertexPosition);
gl.disableVertexAttribArray(this.defaultShader.colorAttribute);
gl.disableVertexAttribArray(this.defaultShader.aTextureCoord);
gl.enableVertexAttribArray(this.primitiveShader.aVertexPosition);
gl.enableVertexAttribArray(this.primitiveShader.colorAttribute);
gl.enableVertexAttribArray(this.primitiveShader.colorAttribute);*/
};
PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function()
@ -51,10 +126,14 @@ PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function()
gl.useProgram(this.defaultShader.program);
this.setAttribs(this.defaultShader.attributes);
/*
gl.disableVertexAttribArray(this.primitiveShader.aVertexPosition);
gl.disableVertexAttribArray(this.primitiveShader.colorAttribute);
gl.enableVertexAttribArray(this.defaultShader.aVertexPosition);
gl.enableVertexAttribArray(this.defaultShader.colorAttribute);
gl.enableVertexAttribArray(this.defaultShader.aTextureCoord);
gl.enableVertexAttribArray(this.defaultShader.aPositionCoord);*/
};

View file

@ -12,9 +12,10 @@ PIXI.WebGLSpriteBatch = function(gl)
{
this.size = 2000;
this.vertSize = 6;
this.size = 10000;//Math.pow(2, 16) / this.vertSize;
// console.log(this.size);
//the total number of floats in our batch
var numVerts = this.size * 4 * this.vertSize;
//the total number of indices in our batch

View file

@ -178,7 +178,7 @@ PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode)
PIXI.Texture.fromFrame = function(frameId)
{
var texture = PIXI.TextureCache[frameId];
if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this);
if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ');
return texture;
};