/** * @author Mat Groves * * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/ * for creating the original pixi version! * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer * * Heavily inspired by LibGDX's ParticleBuffer: * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleBuffer.java */ /** * The particle buffer manages the static and dynamic buffers for a particle container. * * @class * @private * @memberof PIXI */ function ParticleBuffer(gl, properties, dynamicPropertyFlags, size) { /** * The current WebGL drawing context. * * @member {WebGLRenderingContext} */ this.gl = gl; /** * Size of a single vertex. * * @member {number} */ this.vertSize = 2; /** * Size of a single vertex in bytes. * * @member {number} */ this.vertByteSize = this.vertSize * 4; /** * The number of particles the buffer can hold * * @member {number} */ this.size = size; /** * A list of the properties that are dynamic. * * @member {object[]} */ this.dynamicProperties = []; /** * A list of the properties that are static. * * @member {object[]} */ this.staticProperties = []; for (var i = 0; i < properties.length; i++) { var property = properties[i]; if(dynamicPropertyFlags[i]) { this.dynamicProperties.push(property); } else { this.staticProperties.push(property); } } this.staticStride = 0; this.staticBuffer = null; this.staticData = null; this.dynamicStride = 0; this.dynamicBuffer = null; this.dynamicData = null; this.initBuffers(); } ParticleBuffer.prototype.constructor = ParticleBuffer; module.exports = ParticleBuffer; /** * Sets up the renderer context and necessary buffers. * * @private */ ParticleBuffer.prototype.initBuffers = function () { var gl = this.gl; var i; var property; var dynamicOffset = 0; this.dynamicStride = 0; for (i = 0; i < this.dynamicProperties.length; i++) { property = this.dynamicProperties[i]; property.offset = dynamicOffset; dynamicOffset += property.size; this.dynamicStride += property.size; } this.dynamicData = new Float32Array( this.size * this.dynamicStride * 4); this.dynamicBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.dynamicBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.dynamicData, gl.DYNAMIC_DRAW); // static // var staticOffset = 0; this.staticStride = 0; for (i = 0; i < this.staticProperties.length; i++) { property = this.staticProperties[i]; property.offset = staticOffset; staticOffset += property.size; this.staticStride += property.size; } this.staticData = new Float32Array( this.size * this.staticStride * 4); this.staticBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.staticBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.staticData, gl.DYNAMIC_DRAW); }; /** * Uploads the dynamic properties. * */ ParticleBuffer.prototype.uploadDynamic = function(children, startIndex, amount) { var gl = this.gl; for (var i = 0; i < this.dynamicProperties.length; i++) { var property = this.dynamicProperties[i]; property.uploadFunction(children, startIndex, amount, this.dynamicData, this.dynamicStride, property.offset); } gl.bindBuffer(gl.ARRAY_BUFFER, this.dynamicBuffer); gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.dynamicData); }; /** * Uploads the static properties. * */ ParticleBuffer.prototype.uploadStatic = function(children, startIndex, amount) { var gl = this.gl; for (var i = 0; i < this.staticProperties.length; i++) { var property = this.staticProperties[i]; property.uploadFunction(children, startIndex, amount, this.staticData, this.staticStride, property.offset); } gl.bindBuffer(gl.ARRAY_BUFFER, this.staticBuffer); gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.staticData); }; /** * Binds the buffers to the GPU * */ ParticleBuffer.prototype.bind = function () { var gl = this.gl; var i, property; gl.bindBuffer(gl.ARRAY_BUFFER, this.dynamicBuffer); for (i = 0; i < this.dynamicProperties.length; i++) { property = this.dynamicProperties[i]; gl.vertexAttribPointer(property.attribute, property.size, gl.FLOAT, false, this.dynamicStride * 4, property.offset * 4); } gl.bindBuffer(gl.ARRAY_BUFFER, this.staticBuffer); for (i = 0; i < this.staticProperties.length; i++) { property = this.staticProperties[i]; gl.vertexAttribPointer(property.attribute, property.size, gl.FLOAT, false, this.staticStride * 4, property.offset * 4); } }; /** * Destroys the ParticleBuffer. * */ ParticleBuffer.prototype.destroy = function () { this.dynamicProperties = null; this.dynamicData = null; this.gl.deleteBuffer(this.dynamicBuffer); this.staticProperties = null; this.staticData = null; this.gl.deleteBuffer(this.staticBuffer); };