2016-10-29 12:38:57 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
|
|
* @copyright 2016 Photon Storm Ltd.
|
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
2016-10-30 14:57:38 +00:00
|
|
|
* @class Phaser.Renderer.WebGL.Batch
|
2016-10-29 12:38:57 +00:00
|
|
|
* @constructor
|
|
|
|
* @param {Phaser.Renderer.WebGL} renderer - The WebGL Renderer.
|
|
|
|
*/
|
2016-10-30 14:57:38 +00:00
|
|
|
Phaser.Renderer.WebGL.Batch = function (manager, batchSize, vertSize)
|
2016-10-29 12:38:57 +00:00
|
|
|
{
|
|
|
|
this.batchManager = manager;
|
|
|
|
|
|
|
|
this.renderer = manager.renderer;
|
|
|
|
|
|
|
|
this.gl = null;
|
|
|
|
|
2016-10-31 19:44:46 +00:00
|
|
|
this.type = 0;
|
|
|
|
|
2016-10-29 12:38:57 +00:00
|
|
|
// Total number of objects we'll batch before flushing and rendering
|
|
|
|
// Integer
|
2016-10-30 14:57:38 +00:00
|
|
|
this.maxSize = batchSize;
|
2016-10-29 12:38:57 +00:00
|
|
|
|
|
|
|
// Integer
|
2016-10-30 14:57:38 +00:00
|
|
|
this.halfSize = Math.floor(this.maxSize / 2);
|
2016-10-29 12:38:57 +00:00
|
|
|
|
|
|
|
// Integer
|
|
|
|
this.vertSize = vertSize;
|
|
|
|
|
|
|
|
// * 4 because there are 4 verts per batch entry (each corner of the quad)
|
2016-10-30 14:57:38 +00:00
|
|
|
var numVerts = this.vertSize * this.maxSize * 4;
|
2016-10-29 12:38:57 +00:00
|
|
|
|
|
|
|
// ArrayBuffer
|
|
|
|
// This data is what changes every frame, populated by the game objects
|
|
|
|
// passed in. There are often views into it (position, color, etc)
|
|
|
|
this.vertices = new ArrayBuffer(numVerts);
|
|
|
|
|
|
|
|
// Number of total quads allowed in the batch * 6
|
|
|
|
// 6 because there are 2 triangles per quad, and each triangle has 3 indices
|
|
|
|
// This Typed Array is set in the build method of the extended class, and then
|
|
|
|
// doesn't change again (it's populated just once)
|
2016-10-30 14:57:38 +00:00
|
|
|
this.indices = new Uint16Array(this.maxSize * 6);
|
|
|
|
|
|
|
|
// Populated by the flush operation when the batch is < 50% of the max size
|
|
|
|
this.view = null;
|
2016-10-29 12:38:57 +00:00
|
|
|
|
|
|
|
// Integer
|
2016-10-30 14:57:38 +00:00
|
|
|
this.size = 0;
|
2016-10-29 12:38:57 +00:00
|
|
|
|
|
|
|
// Boolean
|
|
|
|
this.dirty = true;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The WebGL program.
|
|
|
|
* @property program
|
|
|
|
* @type WebGLProgram
|
|
|
|
*/
|
|
|
|
this.program = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Default Vertex shader source.
|
|
|
|
*
|
|
|
|
* @property defaultVertexSrc
|
|
|
|
* @type Array
|
|
|
|
*/
|
|
|
|
this.vertexSrc = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The fragment shader.
|
|
|
|
* @property fragmentSrc
|
|
|
|
* @type Array
|
|
|
|
*/
|
|
|
|
this.fragmentSrc = [];
|
|
|
|
|
|
|
|
// WebGLBuffer
|
|
|
|
this.indexBuffer = null;
|
|
|
|
|
|
|
|
// WebGLBuffer
|
|
|
|
this.vertexBuffer = null;
|
|
|
|
|
|
|
|
// Internal index count
|
|
|
|
// Integer
|
|
|
|
this._i = 0;
|
|
|
|
};
|
|
|
|
|
2016-10-30 14:57:38 +00:00
|
|
|
Phaser.Renderer.WebGL.Batch.prototype.constructor = Phaser.Renderer.WebGL.Batch;
|
2016-10-29 12:38:57 +00:00
|
|
|
|
2016-10-30 14:57:38 +00:00
|
|
|
Phaser.Renderer.WebGL.Batch.prototype = {
|
2016-10-29 12:38:57 +00:00
|
|
|
|
2016-11-03 17:19:16 +00:00
|
|
|
start: function ()
|
2016-10-29 12:38:57 +00:00
|
|
|
{
|
|
|
|
this._i = 0;
|
2016-10-29 20:29:16 +00:00
|
|
|
|
2016-10-30 14:57:38 +00:00
|
|
|
this.size = 0;
|
|
|
|
|
|
|
|
// We only need to do this if this batch isn't the current one
|
2016-10-29 12:38:57 +00:00
|
|
|
|
2016-11-03 17:19:16 +00:00
|
|
|
if (this.renderer.shaderManager.setShader(this.program))
|
2016-11-03 13:47:37 +00:00
|
|
|
{
|
2016-10-30 14:57:38 +00:00
|
|
|
this.bindShader();
|
2016-11-03 13:47:37 +00:00
|
|
|
}
|
2016-11-03 17:19:16 +00:00
|
|
|
|
|
|
|
// if (this.dirty || force)
|
|
|
|
// {
|
|
|
|
// this.bindShader();
|
|
|
|
// this.dirty = false;
|
|
|
|
// }
|
2016-10-29 12:38:57 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
stop: function ()
|
|
|
|
{
|
2016-10-29 20:29:16 +00:00
|
|
|
this.flush();
|
2016-10-31 17:15:36 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// Can be overridden by custom Batch processors
|
|
|
|
flush: function ()
|
|
|
|
{
|
|
|
|
if (this.size === 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var gl = this.gl;
|
|
|
|
|
|
|
|
// Upload the vertex data to the GPU - is this cheaper (overall) than creating a new TypedArray view?
|
|
|
|
// The tradeoff is sending 224KB of data to the GPU every frame, even if most of it is empty should the
|
|
|
|
// batch be only slightly populated, vs. the creation of a new TypedArray view and its corresponding gc every frame.
|
|
|
|
|
|
|
|
if (this.size > this.halfSize)
|
|
|
|
{
|
|
|
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
|
|
|
|
|
|
this.view = this.positions.subarray(0, this.size * this.vertSize);
|
|
|
|
|
|
|
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.view);
|
|
|
|
}
|
|
|
|
|
|
|
|
gl.drawElements(gl.TRIANGLES, this.size * 6, gl.UNSIGNED_SHORT, 0);
|
|
|
|
|
|
|
|
this.renderer.drawCount++;
|
|
|
|
|
|
|
|
// Reset the batch
|
|
|
|
this.size = 0;
|
|
|
|
|
|
|
|
this._i = 0;
|
2016-10-29 12:38:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|