Resource clean up and adapted batches to allow shader swapping

This commit is contained in:
Felipe Alfonso 2017-04-05 19:01:44 -03:00
parent 85a3830f1a
commit aa8f0820c0
34 changed files with 911 additions and 1162 deletions

View file

@ -0,0 +1 @@
module.exports = (window.WebGLRenderingContext ? WebGLRenderingContext : {});

View file

@ -0,0 +1,210 @@
var Resources = require('./resources');
var GL = require('./GL');
var ResourceManager = function (gl)
{
this.gl = gl;
/* Maybe add pooling here */
this.shaderCache = {};
};
ResourceManager.prototype.constructor = ResourceManager;
ResourceManager.prototype = {
createRenderTarget: function (width, height, colorBuffer, depthStencilBuffer)
{
var gl = this.gl;
var framebufferObject = gl.createFramebuffer();
var depthStencilRenderbufferObject = null;
var colorRenderbufferObject = null;
var complete = 0;
gl.bindFramebuffer(GL.FRAMEBUFFER, framebufferObject)
if (depthStencilBuffer !== undefined && depthStencilBuffer !== null)
{
depthStencilBuffer.isRenderTexture = true;
gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_2D, depthStencilBuffer.texture, depthStencilBuffer.mipLevel);
}
else
{
depthStencilRenderbufferObject = gl.createRenderbuffer();
gl.bindRenderbuffer(GL.RENDERBUFFER, depthStencilRenderbufferObject);
gl.renderbufferStorage(GL.RENDERBUFFER, GL.DEPTH_STENCIL, width, height);
gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.RENDERBUFFER, depthStencilRenderbufferObject);
}
if (colorBuffer !== undefined && colorBuffer !== null)
{
colorBuffer.isRenderTexture = true;
gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, colorBuffer.texture, colorBuffer.mipLevel);
}
else
{
colorRenderbufferObject = gl.createRenderbuffer();
gl.bindRenderbuffer(GL.RENDERBUFFER, colorRenderbufferObject);
gl.renderbufferStorage(GL.RENDERBUFFER, GL.RGBA4, width, height);
gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.RENDERBUFFER, colorRenderbufferObject);
}
complete = gl.checkFramebufferStatus(GL.FRAMEBUFFER);
if (complete !== GL.FRAMEBUFFER_COMPLETE)
{
var errors = {
36054: 'Incomplete Attachment',
36055: 'Missing Attachment',
36057: 'Incomplete Dimensions',
36061: 'Framebuffer Unsupported'
};
throw new Error('Framebuffer incomplete. Framebuffer status: ' + errors[complete]);
}
gl.bindFramebuffer(GL.FRAMEBUFFER, null);
return new Resources.RenderTarget(
framebufferObject,
width, height,
(colorBuffer === undefined ? null : colorBuffer),
(depthStencilBuffer === undefined ? null : depthStencilBuffer)
);
},
createBuffer: function (target, initialDataOrSize, bufferUsage)
{
var gl = this.gl;
var bufferObject = gl.createBuffer();
gl.bindBuffer(target, bufferObject);
gl.bufferData(target, initialDataOrSize, bufferUsage);
switch (target)
{
case GL.ARRAY_BUFFER:
return new Resources.VertexBuffer(gl, bufferObject);
case GL.ELEMENT_ARRAY_BUFFER:
return new Resources.IndexBuffer(gl, bufferObject);
default:
throw new Error('Invalid Buffer Target');
}
return null;
},
createTexture: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height)
{
var gl = this.gl;
var texture = gl.createTexture();
gl.bindTexture(GL.TEXTURE_2D, texture);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, minFilter);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, magFilter);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, wrapS);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, wrapT);
if (pixels === null || pixels === undefined)
{
gl.texImage2D(GL.TEXTURE_2D, mipLevel, format, width, height, 0, format, GL.UNSIGNED_BYTE, null);
}
else
{
gl.texImage2D(GL.TEXTURE_2D, mipLevel, format, format, GL.UNSIGNED_BYTE, pixels);
width = pixels.width;
height = pixels.height;
}
return new Resources.Texture(texture, width, height);
},
createShader: function (shaderName, shaderSources)
{
if (!(shaderName in this.shaderCache))
{
var gl = this.gl;
var program = gl.createProgram();
var vertShader = gl.createShader(GL.VERTEX_SHADER);
var fragShader = gl.createShader(GL.FRAGMENT_SHADER);
var error;
var shader;
gl.shaderSource(vertShader, shaderSources.vert);
gl.shaderSource(fragShader, shaderSources.frag);
gl.compileShader(vertShader);
gl.compileShader(fragShader);
error = gl.getShaderInfoLog(vertShader);
if (error.length > 0)
{
throw new Error('Vertex Shader Compilation Error.\n' + error);
}
error = gl.getShaderInfoLog(fragShader);
if (error.length > 0)
{
throw new Error('Fragment Shader Compilation Error.\n' + error);
}
gl.attachShader(program, vertShader);
gl.attachShader(program, fragShader);
gl.linkProgram(program);
error = gl.getProgramParameter(program, GL.LINK_STATUS);
if (error === 0)
{
error = gl.getProgramInfoLog(program);
throw new Error('Program Linking Error.\n' + error);
}
shader = new Resources.Shader(shaderName, gl, program, vertShader, fragShader);
this.shaderCache[shaderName] = shader;
return shader;
}
else
{
return this.shaderCache[shaderName];
}
},
createOutputStage: function ()
{
var outputStage = new Resources.OutputStage();
outputStage.setDefaultDepthStencilState();
outputStage.setNoBlending();
return outputStage;
},
deleteShader: function (shader)
{
var storedShader = this.shaderCache[shader.name]
var gl = this.gl;
if (storedShader !== undefined)
{
delete this.shaderCache;
}
gl.deleteShader(shader.vertexShader);
gl.deleteShader(shader.fragmentShader);
gl.deleteProgram(shader.program);
shader.vertexShader = null;
shader.fragmentShader = null;
shader.program = null;
shader.name = null;
},
deleteBuffer: function (buffer)
{
var gl = this.gl;
gl.deleteBuffer(buffer.bufferObject);
}
};
module.exports = ResourceManager;

View file

@ -6,14 +6,13 @@
*/
var CONST = require('../../const');
var CreateEmptyTexture = require('./utils/CreateEmptyTexture');
var CreateTexture2DImage = require('./utils/texture/CreateTexture2DImage');
var BlitterBatch = require('./batches/blitter/BlitterBatch');
var AAQuadBatch = require('./batches/aaquad/AAQuadBatch');
var SpriteBatch = require('./batches/sprite/SpriteBatch');
var ShapeBatch = require('./batches/shape/ShapeBatch');
var BlendModes = require('../BlendModes');
var Shader = require('./utils/shader/Shader');
var ScaleModes = require('../ScaleModes');
var ResourceManager = require('./ResourceManager');
var WebGLRenderer = function (game)
{
@ -55,6 +54,7 @@ var WebGLRenderer = function (game)
this.currentTexture2D = null;
this.shaderCache = {};
this.currentShader = null;
this.resourceManager = null;
this.init();
};
@ -77,6 +77,8 @@ WebGLRenderer.prototype = {
var gl = this.gl;
var color = this.game.config.backgroundColor;
this.resourceManager = new ResourceManager(gl);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
@ -107,21 +109,40 @@ WebGLRenderer.prototype = {
this.shapeBatch = this.addBatch(new ShapeBatch(this.game, gl, this));
},
createTexture2D: function (source)
createTexture: function (source)
{
var gl = this.gl;
var filter = gl.NEAREST;
if (!source.glTexture)
{
source.glTexture = CreateTexture2DImage(gl, source.image, gl.NEAREST, 0);
if (source.scaleMode === ScaleModes.LINEAR)
{
filter = gl.LINEAR;
}
else if (source.scaleMode === ScaleModes.NEAREST)
{
filter = gl.NEAREST;
}
source.glTexture = this.resourceManager.createTexture(
0,
filter,
filter,
gl.CLAMP_TO_EDGE,
gl.CLAMP_TO_EDGE,
gl.RGBA,
source.image
);
}
this.currentTexture2D = source.glTexture;
},
setTexture2D: function (texture2D)
setTexture: function (texture)
{
if (this.currentTexture2D !== texture2D)
if (this.currentTexture2D !== texture)
{
if (this.batch)
{
@ -131,16 +152,23 @@ WebGLRenderer.prototype = {
var gl = this.gl;
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture2D);
if (texture !== null)
{
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
}
else
{
gl.bindTexture(gl.TEXTURE_2D, null);
}
this.currentTexture2D = texture2D;
this.currentTexture2D = texture;
}
},
setBatch: function (batch, texture2D, camera)
setBatch: function (batch, texture, camera)
{
var gl = this.gl;
this.setTexture2D(texture2D);
this.setTexture(texture);
if (this.batch !== batch)
{
@ -149,8 +177,6 @@ WebGLRenderer.prototype = {
this.batch.flush();
}
batch.bind();
this.batch = batch;
}
},
@ -379,73 +405,6 @@ WebGLRenderer.prototype = {
gl.bindTexture(gl.TEXTURE_2D, this.currentTexture2D);
return dstTexture;
},
createShader: function (shaderName, shaderSources)
{
if (!(shaderName in this.shaderCache))
{
var gl = this.gl;
var program = gl.createProgram();
var vertShader = gl.createShader(gl.VERTEX_SHADER);
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
var error;
var shader;
gl.shaderSource(vertShader, shaderSources.vert);
gl.shaderSource(fragShader, shaderSources.frag);
gl.compileShader(vertShader);
gl.compileShader(fragShader);
error = gl.getShaderInfoLog(vertShader);
if (error.length > 0)
{
throw new Error('Vertex Shader Compilation Error.\n' + error);
}
error = gl.getShaderInfoLog(fragShader);
if (error.length > 0)
{
throw new Error('Fragment Shader Compilation Error.\n' + error);
}
gl.attachShader(program, vertShader);
gl.attachShader(program, fragShader);
gl.linkProgram(program);
error = gl.getProgramParameter(program, gl.LINK_STATUS);
if (error === 0)
{
error = gl.getProgramInfoLog(program);
throw new Error('Program Linking Error.\n' + error);
}
shader = new Shader(shaderName, gl, program, vertShader, fragShader);
this.shaderCache[shaderName] = shader;
return shader;
}
return this.shaderCache[shaderName];
},
deleteShader: function (shader)
{
var storedShader = this.shaderCache[shader.name]
var gl = this.gl;
if (storedShader !== undefined)
{
delete this.shaderCache;
}
gl.deleteShader(shader.vertexShader);
gl.deleteShader(shader.fragmentShader);
gl.deleteProgram(shader.program);
shader.vertexShader = null;
shader.fragmentShader = null;
shader.program = null;
shader.name = null;
}
};

View file

@ -1,11 +1,5 @@
var BindVertexArray = require('../../utils/vao/BindVertexArray');
var CreateProgram = require('../../utils/shader/CreateProgram');
var CreateShader = require('../../utils/shader/CreateShader');
var CreateBuffer = require('../../utils/buffer/CreateBuffer');
var CreateAttribDesc = require('../../utils/vao/CreateAttribDesc');
var Buffer32 = require('../../utils/buffer/Buffer32');
var Buffer16 = require('../../utils/buffer/Buffer16');
var VertexArray = require('../../utils/vao/VertexArray');
var DataBuffer32 = require('../../utils/DataBuffer32');
var DataBuffer16 = require('../../utils/DataBuffer16');
var UntexturedAndTintedShader = require('../../shaders/UntexturedAndTintedShader');
var PHASER_CONST = require('../../../../const');
@ -22,7 +16,7 @@ var AAQuadBatch = function (game, gl, manager)
this.glContext = gl;
this.maxQuads = null;
this.shader = null;
this.vertexArray = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
@ -58,24 +52,23 @@ AAQuadBatch.prototype = {
init: function (gl)
{
var vertexDataBuffer = new Buffer32(CONST.VERTEX_SIZE * CONST.AAQUAD_VERTEX_COUNT * CONST.MAX_AAQUAD);
var indexDataBuffer = new Buffer16(CONST.INDEX_SIZE * CONST.AAQUAD_INDEX_COUNT * CONST.MAX_AAQUAD);
var shader = this.manager.createShader('UntexturedAndTintedShader', UntexturedAndTintedShader);
var indexBufferObject = CreateBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, gl.STATIC_DRAW, null, indexDataBuffer.getByteCapacity());
var attribArray = [
CreateAttribDesc(gl, shader.program, 'a_position', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0),
CreateAttribDesc(gl, shader.program, 'a_color', 4, gl.FLOAT, false, CONST.VERTEX_SIZE, 8)
];
var vertexArray = new VertexArray(CreateBuffer(gl, gl.ARRAY_BUFFER, gl.STREAM_DRAW, null, vertexDataBuffer.getByteCapacity()), attribArray);
var viewMatrixLocation = gl.getUniformLocation(shader.program, 'u_view_matrix');
var vertexDataBuffer = new DataBuffer32(CONST.VERTEX_SIZE * CONST.AAQUAD_VERTEX_COUNT * CONST.MAX_AAQUAD);
var indexDataBuffer = new DataBuffer16(CONST.INDEX_SIZE * CONST.AAQUAD_INDEX_COUNT * CONST.MAX_AAQUAD);
var shader = this.manager.resourceManager.createShader('UntexturedAndTintedShader', UntexturedAndTintedShader);
var indexBufferObject = this.manager.resourceManager.createBuffer(gl.ELEMENT_ARRAY_BUFFER, indexDataBuffer.getByteCapacity(), gl.STATIC_DRAW);
var vertexBufferObject = this.manager.resourceManager.createBuffer(gl.ARRAY_BUFFER, vertexDataBuffer.getByteCapacity(), gl.STREAM_DRAW);
var viewMatrixLocation = shader.getUniformLocation('u_view_matrix');
var indexBuffer = indexDataBuffer.uintView;
var max = CONST.MAX_AAQUAD * CONST.AAQUAD_INDEX_COUNT;
vertexBufferObject.addAttribute(0, 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0);
vertexBufferObject.addAttribute(1, 4, gl.FLOAT, false, CONST.VERTEX_SIZE, 8);
this.vertexDataBuffer = vertexDataBuffer;
this.indexDataBuffer = indexDataBuffer;
this.shader = shader;
this.indexBufferObject = indexBufferObject;
this.vertexArray = vertexArray;
this.vertexBufferObject = vertexBufferObject;
this.viewMatrixLocation = viewMatrixLocation;
// Populate the index buffer only once
@ -89,12 +82,9 @@ AAQuadBatch.prototype = {
indexBuffer[indexA + 5] = indexB + 3;
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, indexBuffer);
indexBufferObject.updateResource(indexBuffer, 0);
this.bind();
this.resize(this.width, this.height, this.game.config.resolution);
this.unbind();
},
isFull: function ()
@ -141,52 +131,48 @@ AAQuadBatch.prototype = {
this.elementCount += CONST.AAQUAD_INDEX_COUNT;
},
bind: function ()
bind: function (shader)
{
var gl = this.glContext;
gl.useProgram(this.shader.program);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBufferObject);
this.bindVertexAttributes();
if (shader === undefined)
{
this.shader.bind();
}
else
{
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.indexBufferObject.bind();
this.vertexBufferObject.bind();
},
bindVertexAttributes: function ()
{
var gl = this.glContext;
BindVertexArray(gl, this.vertexArray);
},
unbind: function ()
{
var gl = this.glContext;
gl.useProgram(null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
},
flush: function ()
flush: function (shader)
{
var gl = this.glContext;
var vertexDataBuffer = this.vertexDataBuffer;
gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertexDataBuffer.getUsedBufferAsFloat());
if (this.elementCount === 0)
{
return;
}
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawElements(gl.TRIANGLES, this.elementCount, gl.UNSIGNED_SHORT, 0);
vertexDataBuffer.clear();
this.elementCount = 0;
},
resize: function (width, height, resolution)
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
this.height = height * resolution;
gl.uniformMatrix4fv(
activeShader.setConstantMatrix4x4(
this.viewMatrixLocation,
false,
new Float32Array([
2 / this.width, 0, 0, 0,
0, -2 / this.height, 0, 0,
@ -198,14 +184,13 @@ AAQuadBatch.prototype = {
destroy: function ()
{
var gl = this.glContext;
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.indexBufferObject);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
if (gl)
{
this.manager.deleteShader(this.shader);
gl.deleteBuffer(this.indexBufferObject);
gl.deleteBuffer(this.vertexArray.buffer);
}
this.shader = null;
this.indexBufferObject = null;
this.vertexBufferObject = null;
}
};

View file

@ -1,13 +1,5 @@
// Could you move these into sub-folders please, i.e. 'vao', 'shader' etc?
var BindVertexArray = require('../../utils/vao/BindVertexArray');
var CreateProgram = require('../../utils/shader/CreateProgram');
var CreateShader = require('../../utils/shader/CreateShader');
var CreateBuffer = require('../../utils/buffer/CreateBuffer');
var CreateAttribDesc = require('../../utils/vao/CreateAttribDesc');
var Buffer32 = require('../../utils/buffer/Buffer32');
var Buffer16 = require('../../utils/buffer/Buffer16');
var VertexArray = require('../../utils/vao/VertexArray');
var DataBuffer32 = require('../../utils/DataBuffer32');
var DataBuffer16 = require('../../utils/DataBuffer16');
var TexturedAndAlphaShader = require('../../shaders/TexturedAndAlphaShader');
var PHASER_CONST = require('../../../../const');
@ -24,7 +16,7 @@ var BlitterBatch = function (game, gl, manager)
this.glContext = gl;
this.maxParticles = null;
this.shader = null;
this.vertexArray = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
@ -61,25 +53,24 @@ BlitterBatch.prototype = {
init: function (gl)
{
var vertexDataBuffer = new Buffer32(CONST.VERTEX_SIZE * CONST.PARTICLE_VERTEX_COUNT * CONST.MAX_PARTICLES);
var indexDataBuffer = new Buffer16(CONST.INDEX_SIZE * CONST.PARTICLE_INDEX_COUNT * CONST.MAX_PARTICLES);
var shader = this.manager.createShader('TexturedAndAlphaShader', TexturedAndAlphaShader);
var indexBufferObject = CreateBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, gl.STATIC_DRAW, null, indexDataBuffer.getByteCapacity());
var attribArray = [
CreateAttribDesc(gl, shader.program, 'a_position', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0),
CreateAttribDesc(gl, shader.program, 'a_tex_coord', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 8),
CreateAttribDesc(gl, shader.program, 'a_alpha', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 16)
];
var vertexArray = new VertexArray(CreateBuffer(gl, gl.ARRAY_BUFFER, gl.STREAM_DRAW, null, vertexDataBuffer.getByteCapacity()), attribArray);
var viewMatrixLocation = gl.getUniformLocation(shader.program, 'u_view_matrix');
var vertexDataBuffer = new DataBuffer32(CONST.VERTEX_SIZE * CONST.PARTICLE_VERTEX_COUNT * CONST.MAX_PARTICLES);
var indexDataBuffer = new DataBuffer16(CONST.INDEX_SIZE * CONST.PARTICLE_INDEX_COUNT * CONST.MAX_PARTICLES);
var shader = this.manager.resourceManager.createShader('TexturedAndAlphaShader', TexturedAndAlphaShader);
var indexBufferObject = this.manager.resourceManager.createBuffer(gl.ELEMENT_ARRAY_BUFFER, indexDataBuffer.getByteCapacity(), gl.STATIC_DRAW);
var vertexBufferObject = this.manager.resourceManager.createBuffer(gl.ARRAY_BUFFER, vertexDataBuffer.getByteCapacity(), gl.STREAM_DRAW);
var viewMatrixLocation = shader.getUniformLocation('u_view_matrix');
var indexBuffer = indexDataBuffer.uintView;
var max = CONST.MAX_PARTICLES * CONST.PARTICLE_INDEX_COUNT;
vertexBufferObject.addAttribute(0, 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0);
vertexBufferObject.addAttribute(1, 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 8);
vertexBufferObject.addAttribute(2, 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 16);
this.vertexDataBuffer = vertexDataBuffer;
this.indexDataBuffer = indexDataBuffer;
this.shader = shader;
this.indexBufferObject = indexBufferObject;
this.vertexArray = vertexArray;
this.vertexBufferObject = vertexBufferObject;
this.viewMatrixLocation = viewMatrixLocation;
this.maxParticles = max;
@ -94,12 +85,9 @@ BlitterBatch.prototype = {
indexBuffer[indexA + 5] = indexB + 3;
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, indexBuffer);
indexBufferObject.updateResource(indexBuffer, 0);
this.bind();
this.resize(this.width, this.height, this.game.config.resolution);
this.unbind();
},
isFull: function ()
@ -107,53 +95,48 @@ BlitterBatch.prototype = {
return (this.vertexDataBuffer.getByteLength() >= this.vertexDataBuffer.getByteCapacity());
},
bind: function ()
bind: function (shader)
{
var gl = this.glContext;
gl.useProgram(this.shader.program);
gl.clearColor(0, 0, 0, 1);
this.bindVertexAttributes();
if (shader === undefined)
{
this.shader.bind();
}
else
{
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.indexBufferObject.bind();
this.vertexBufferObject.bind();
},
bindVertexAttributes: function ()
{
var gl = this.glContext;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBufferObject);
BindVertexArray(gl, this.vertexArray);
},
unbind: function ()
{
var gl = this.glContext;
gl.useProgram(null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
},
flush: function ()
flush: function (shader)
{
var gl = this.glContext;
var vertexDataBuffer = this.vertexDataBuffer;
gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertexDataBuffer.getUsedBufferAsFloat());
if (this.elementCount === 0)
{
return;
}
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawElements(gl.TRIANGLES, this.elementCount, gl.UNSIGNED_SHORT, 0);
vertexDataBuffer.clear();
this.elementCount = 0;
},
resize: function (width, height, resolution)
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
this.height = height * resolution;
gl.uniformMatrix4fv(
activeShader.setConstantMatrix4x4(
this.viewMatrixLocation,
false,
new Float32Array([
2 / this.width, 0, 0, 0,
0, -2 / this.height, 0, 0,
@ -165,14 +148,13 @@ BlitterBatch.prototype = {
destroy: function ()
{
var gl = this.glContext;
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.indexBufferObject);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
if (gl)
{
this.manager.deleteShader(this.shader);
gl.deleteBuffer(this.indexBufferObject);
gl.deleteBuffer(this.vertexArray.buffer);
}
this.shader = null;
this.indexBufferObject = null;
this.vertexBufferObject = null;
}
};

View file

@ -1,10 +1,4 @@
var BindVertexArray = require('../../utils/vao/BindVertexArray');
var CreateProgram = require('../../utils/shader/CreateProgram');
var CreateShader = require('../../utils/shader/CreateShader');
var CreateBuffer = require('../../utils/buffer/CreateBuffer');
var CreateAttribDesc = require('../../utils/vao/CreateAttribDesc');
var Buffer32 = require('../../utils/buffer/Buffer32');
var VertexArray = require('../../utils/vao/VertexArray');
var DataBuffer32 = require('../../utils/DataBuffer32');
var Earcut = require('./earcut');
var UntexturedAndNormalizedTintedShader = require('../../shaders/UntexturedAndNormalizedTintedShader');
@ -22,7 +16,7 @@ var ShapeBatch = function (game, gl, manager)
this.glContext = gl;
this.maxVertices = null;
this.shader = null;
this.vertexArray = null;
this.vertexBufferObject = null;
this.vertexDataBuffer = null;
this.vertexCount = 0;
this.viewMatrixLocation = null;
@ -62,27 +56,24 @@ ShapeBatch.prototype = {
init: function (gl)
{
var vertexDataBuffer = new Buffer32(CONST.VERTEX_SIZE * CONST.MAX_VERTICES);
var shader = this.manager.createShader('UntexturedAndNormalizedTintedShader', UntexturedAndNormalizedTintedShader);
var attribArray = [
CreateAttribDesc(gl, shader.program, 'a_position', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0),
CreateAttribDesc(gl, shader.program, 'a_color', 4, gl.UNSIGNED_BYTE, true, CONST.VERTEX_SIZE, 8),
CreateAttribDesc(gl, shader.program, 'a_alpha', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 12)
];
var vertexArray = new VertexArray(CreateBuffer(gl, gl.ARRAY_BUFFER, gl.STREAM_DRAW, null, vertexDataBuffer.getByteCapacity()), attribArray);
var viewMatrixLocation = gl.getUniformLocation(shader.program, 'u_view_matrix');
var vertexDataBuffer = new DataBuffer32(CONST.VERTEX_SIZE * CONST.MAX_VERTICES);
var shader = this.manager.resourceManager.createShader('UntexturedAndNormalizedTintedShader', UntexturedAndNormalizedTintedShader);
var vertexBufferObject = this.manager.resourceManager.createBuffer(gl.ARRAY_BUFFER, vertexDataBuffer.getByteCapacity(), gl.STREAM_DRAW);
var viewMatrixLocation = shader.getUniformLocation('u_view_matrix');
var max = CONST.MAX_VERTICES;
vertexBufferObject.addAttribute(0, 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0);
vertexBufferObject.addAttribute(1, 4, gl.UNSIGNED_BYTE, true, CONST.VERTEX_SIZE, 8);
vertexBufferObject.addAttribute(2, 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 12);
this.vertexDataBuffer = vertexDataBuffer;
this.shader = shader;
this.vertexArray = vertexArray;
this.vertexBufferObject = vertexBufferObject;
this.viewMatrixLocation = viewMatrixLocation;
this.maxVertices = max;
this.polygonCache = [];
this.bind();
this.resize(this.width, this.height, this.game.config.resolution);
this.unbind();
},
isFull: function ()
@ -90,53 +81,47 @@ ShapeBatch.prototype = {
return (this.vertexDataBuffer.getByteLength() >= this.vertexDataBuffer.getByteCapacity());
},
bind: function ()
bind: function (shader)
{
var gl = this.glContext;
gl.useProgram(this.shader.program);
gl.clearColor(0, 0, 0, 1);
this.bindVertexAttributes();
if (shader === undefined)
{
this.shader.bind();
}
else
{
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.vertexBufferObject.bind();
},
bindVertexAttributes: function ()
{
var gl = this.glContext;
BindVertexArray(gl, this.vertexArray);
},
unbind: function ()
{
var gl = this.glContext;
gl.useProgram(null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
},
flush: function ()
flush: function (shader)
{
var gl = this.glContext;
var vertexDataBuffer = this.vertexDataBuffer;
if (this.vertexCount > 0)
if (this.vertexCount === 0)
{
gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertexDataBuffer.getUsedBufferAsFloat());
gl.drawArrays(gl.TRIANGLES, 0, this.vertexCount);
vertexDataBuffer.clear();
this.vertexCount = 0;
return;
}
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawArrays(gl.TRIANGLES, 0, this.vertexCount);
vertexDataBuffer.clear();
this.vertexCount = 0;
},
resize: function (width, height, resolution)
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
this.height = height * resolution;
gl.uniformMatrix4fv(
activeShader.setConstantMatrix4x4(
this.viewMatrixLocation,
false,
new Float32Array([
2 / this.width, 0, 0, 0,
0, -2 / this.height, 0, 0,
@ -148,13 +133,11 @@ ShapeBatch.prototype = {
destroy: function ()
{
var gl = this.glContext;
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
if (gl)
{
this.manager.deleteShader(this.shader.program);
gl.deleteBuffer(this.vertexArray.buffer);
}
this.shader = null;
this.vertexBufferObject = null;
},
addLine: function (

View file

@ -1,11 +1,5 @@
var BindVertexArray = require('../../utils/vao/BindVertexArray');
var CreateProgram = require('../../utils/shader/CreateProgram');
var CreateShader = require('../../utils/shader/CreateShader');
var CreateBuffer = require('../../utils/buffer/CreateBuffer');
var CreateAttribDesc = require('../../utils/vao/CreateAttribDesc');
var Buffer32 = require('../../utils/buffer/Buffer32');
var Buffer16 = require('../../utils/buffer/Buffer16');
var VertexArray = require('../../utils/vao/VertexArray');
var DataBuffer32 = require('../../utils/DataBuffer32');
var DataBuffer16 = require('../../utils/DataBuffer16');
var TransformMatrix = require('../../../../components/TransformMatrix');
var TexturedAndNormalizedTintedShader = require('../../shaders/TexturedAndNormalizedTintedShader');
@ -23,7 +17,7 @@ var SpriteBatch = function (game, gl, manager)
this.glContext = gl;
this.maxSprites = null;
this.shader = null;
this.vertexArray = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
@ -60,18 +54,12 @@ SpriteBatch.prototype = {
init: function (gl)
{
var vertexDataBuffer = new Buffer32(CONST.VERTEX_SIZE * CONST.SPRITE_VERTEX_COUNT * CONST.MAX_SPRITES);
var indexDataBuffer = new Buffer16(CONST.INDEX_SIZE * CONST.SPRITE_INDEX_COUNT * CONST.MAX_SPRITES);
var shader = this.manager.createShader('TexturedAndNormalizedTintedShader', TexturedAndNormalizedTintedShader);
var indexBufferObject = CreateBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, gl.STATIC_DRAW, null, indexDataBuffer.getByteCapacity());
var attribArray = [
CreateAttribDesc(gl, shader.program, 'a_position', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0),
CreateAttribDesc(gl, shader.program, 'a_tex_coord', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 8),
CreateAttribDesc(gl, shader.program, 'a_color', 3, gl.UNSIGNED_BYTE, true, CONST.VERTEX_SIZE, 16),
CreateAttribDesc(gl, shader.program, 'a_alpha', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 20)
];
var vertexArray = new VertexArray(CreateBuffer(gl, gl.ARRAY_BUFFER, gl.STREAM_DRAW, null, vertexDataBuffer.getByteCapacity()), attribArray);
var viewMatrixLocation = gl.getUniformLocation(shader.program, 'u_view_matrix');
var vertexDataBuffer = new DataBuffer32(CONST.VERTEX_SIZE * CONST.SPRITE_VERTEX_COUNT * CONST.MAX_SPRITES);
var indexDataBuffer = new DataBuffer16(CONST.INDEX_SIZE * CONST.SPRITE_INDEX_COUNT * CONST.MAX_SPRITES);
var shader = this.manager.resourceManager.createShader('TexturedAndNormalizedTintedShader', TexturedAndNormalizedTintedShader);
var indexBufferObject = this.manager.resourceManager.createBuffer(gl.ELEMENT_ARRAY_BUFFER, indexDataBuffer.getByteCapacity(), gl.STATIC_DRAW);
var vertexBufferObject = this.manager.resourceManager.createBuffer(gl.ARRAY_BUFFER, vertexDataBuffer.getByteCapacity(), gl.STREAM_DRAW);
var viewMatrixLocation = shader.getUniformLocation('u_view_matrix');
var indexBuffer = indexDataBuffer.uintView;
var max = CONST.MAX_SPRITES * CONST.SPRITE_INDEX_COUNT;
@ -79,9 +67,14 @@ SpriteBatch.prototype = {
this.indexDataBuffer = indexDataBuffer;
this.shader = shader;
this.indexBufferObject = indexBufferObject;
this.vertexArray = vertexArray;
this.vertexBufferObject = vertexBufferObject;
this.viewMatrixLocation = viewMatrixLocation;
vertexBufferObject.addAttribute(0, 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0);
vertexBufferObject.addAttribute(1, 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 8);
vertexBufferObject.addAttribute(2, 3, gl.UNSIGNED_BYTE, true, CONST.VERTEX_SIZE, 16);
vertexBufferObject.addAttribute(3, 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 20);
// Populate the index buffer only once
for (var indexA = 0, indexB = 0; indexA < max; indexA += CONST.SPRITE_INDEX_COUNT, indexB += CONST.SPRITE_VERTEX_COUNT)
{
@ -93,12 +86,9 @@ SpriteBatch.prototype = {
indexBuffer[indexA + 5] = indexB + 3;
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, indexBuffer);
indexBufferObject.updateResource(indexBuffer, 0);
this.bind();
this.resize(this.width, this.height, this.game.config.resolution);
this.unbind();
},
isFull: function ()
@ -106,58 +96,48 @@ SpriteBatch.prototype = {
return (this.vertexDataBuffer.getByteLength() >= this.vertexDataBuffer.getByteCapacity());
},
bind: function ()
bind: function (shader)
{
var gl = this.glContext;
gl.useProgram(this.shader.program);
gl.clearColor(0, 0, 0, 1);
this.bindVertexAttributes();
if (shader === undefined)
{
this.shader.bind();
}
else
{
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.indexBufferObject.bind();
this.vertexBufferObject.bind();
},
bindVertexAttributes: function ()
flush: function (shader)
{
var gl = this.glContext;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBufferObject);
BindVertexArray(gl, this.vertexArray);
},
var vertexDataBuffer = this.vertexDataBuffer;
unbind: function ()
{
var gl = this.glContext;
gl.useProgram(null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
},
flush: function ()
{
if (this.elementCount === 0)
{
return;
}
var gl = this.glContext;
var vertexDataBuffer = this.vertexDataBuffer;
gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertexDataBuffer.getUsedBufferAsFloat());
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawElements(gl.TRIANGLES, this.elementCount, gl.UNSIGNED_SHORT, 0);
vertexDataBuffer.clear();
this.elementCount = 0;
},
resize: function (width, height, resolution)
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
this.height = height * resolution;
gl.uniformMatrix4fv(
activeShader.setConstantMatrix4x4(
this.viewMatrixLocation,
false,
new Float32Array([
2 / this.width, 0, 0, 0,
0, -2 / this.height, 0, 0,
@ -169,17 +149,13 @@ SpriteBatch.prototype = {
destroy: function ()
{
var gl = this.glContext;
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.indexBufferObject);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
if (gl)
{
this.manager.deleteShader(this.shader);
gl.deleteBuffer(this.indexBufferObject);
gl.deleteBuffer(this.vertexArray.buffer);
this.shader = null;
this.indexBufferObject = null
this.vertexArray = null;
}
this.shader = null;
this.indexBufferObject = null;
this.vertexBufferObject = null;
},
addSpriteTexture: function (src, camera, texture, textureWidth, textureHeight)
@ -187,8 +163,8 @@ SpriteBatch.prototype = {
var tempMatrix = this.tempMatrix;
var alpha = 16777216;
var vertexDataBuffer = this.vertexDataBuffer;
var vertexBufferF32 = vertexDataBuffer.floatView;
var vertexBufferU32 = vertexDataBuffer.uintView;
var vertexBufferObjectF32 = vertexDataBuffer.floatView;
var vertexBufferObjectU32 = vertexDataBuffer.uintView;
var vertexOffset = 0;
var width = textureWidth * (src.flipX ? -1 : 1);
var height = textureHeight * (src.flipY ? -1 : 1);
@ -243,33 +219,33 @@ SpriteBatch.prototype = {
vertexOffset = vertexDataBuffer.allocate(24);
this.elementCount += 6;
vertexBufferF32[vertexOffset++] = tx0;
vertexBufferF32[vertexOffset++] = ty0;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topLeft;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx0;
vertexBufferObjectF32[vertexOffset++] = ty0;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topLeft;
vertexBufferObjectF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx1;
vertexBufferF32[vertexOffset++] = ty1;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomLeft;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx1;
vertexBufferObjectF32[vertexOffset++] = ty1;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomLeft;
vertexBufferObjectF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx2;
vertexBufferF32[vertexOffset++] = ty2;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomRight;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx2;
vertexBufferObjectF32[vertexOffset++] = ty2;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomRight;
vertexBufferObjectF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx3;
vertexBufferF32[vertexOffset++] = ty3;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topRight;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx3;
vertexBufferObjectF32[vertexOffset++] = ty3;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topRight;
vertexBufferObjectF32[vertexOffset++] = alpha;
},
addSprite: function (src, camera)
@ -278,8 +254,8 @@ SpriteBatch.prototype = {
var frame = src.frame;
var alpha = 16777216;
var vertexDataBuffer = this.vertexDataBuffer;
var vertexBufferF32 = vertexDataBuffer.floatView;
var vertexBufferU32 = vertexDataBuffer.uintView;
var vertexBufferObjectF32 = vertexDataBuffer.floatView;
var vertexBufferObjectU32 = vertexDataBuffer.uintView;
var vertexOffset = 0;
var uvs = frame.uvs;
var width = frame.width * (src.flipX ? -1 : 1);
@ -335,33 +311,33 @@ SpriteBatch.prototype = {
vertexOffset = vertexDataBuffer.allocate(24);
this.elementCount += 6;
vertexBufferF32[vertexOffset++] = tx0;
vertexBufferF32[vertexOffset++] = ty0;
vertexBufferF32[vertexOffset++] = uvs.x0;
vertexBufferF32[vertexOffset++] = uvs.y0;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topLeft;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx0;
vertexBufferObjectF32[vertexOffset++] = ty0;
vertexBufferObjectF32[vertexOffset++] = uvs.x0;
vertexBufferObjectF32[vertexOffset++] = uvs.y0;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topLeft;
vertexBufferObjectF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx1;
vertexBufferF32[vertexOffset++] = ty1;
vertexBufferF32[vertexOffset++] = uvs.x1;
vertexBufferF32[vertexOffset++] = uvs.y1;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomLeft;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx1;
vertexBufferObjectF32[vertexOffset++] = ty1;
vertexBufferObjectF32[vertexOffset++] = uvs.x1;
vertexBufferObjectF32[vertexOffset++] = uvs.y1;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomLeft;
vertexBufferObjectF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx2;
vertexBufferF32[vertexOffset++] = ty2;
vertexBufferF32[vertexOffset++] = uvs.x2;
vertexBufferF32[vertexOffset++] = uvs.y2;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomRight;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx2;
vertexBufferObjectF32[vertexOffset++] = ty2;
vertexBufferObjectF32[vertexOffset++] = uvs.x2;
vertexBufferObjectF32[vertexOffset++] = uvs.y2;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomRight;
vertexBufferObjectF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx3;
vertexBufferF32[vertexOffset++] = ty3;
vertexBufferF32[vertexOffset++] = uvs.x3;
vertexBufferF32[vertexOffset++] = uvs.y3;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topRight;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferObjectF32[vertexOffset++] = tx3;
vertexBufferObjectF32[vertexOffset++] = ty3;
vertexBufferObjectF32[vertexOffset++] = uvs.x3;
vertexBufferObjectF32[vertexOffset++] = uvs.y3;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topRight;
vertexBufferObjectF32[vertexOffset++] = alpha;
}
};

View file

@ -0,0 +1,31 @@
var GL = require('../GL');
var IndexBuffer = function (gl, bufferObject)
{
this.gl = gl;
this.bufferTarget = GL.ELEMENT_ARRAY_BUFFER;
this.bufferObject = bufferObject;
};
IndexBuffer.prototype.constructor = IndexBuffer;
IndexBuffer.prototype = {
bind: function ()
{
var gl = this.gl;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufferObject);
return this;
},
updateResource: function (bufferData, offset)
{
var gl = this.gl;
gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.bufferObject);
gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, offset, bufferData);
return this;
}
};
module.exports = IndexBuffer;

View file

@ -0,0 +1,102 @@
var GL = require('../GL');
var OutputStage = function ()
{
this.renderTarget = null;
this.enableDepthTest = false;
this.enableStencilTest = false;
this.enableBlending = false;
/* Blend State */
this.blendLogicOp = 0;
this.blendSrcRgb = 0;
this.blendDstRgb = 0;
this.blendSrcAlpha = 0;
this.blendDstAlpha = 0;
this.blendEqRgb = 0;
this.blendEqAlpha = 0;
this.blendRed = 0;
this.blendGreen = 0;
this.blendBlue = 0;
this.blendAlpha = 0;
/* Depth-Stencil State */
this.depthFunc = 0;
this.depthMask = 0;
this.stencilFunc = 0;
this.stencilFail = 0;
this.stencilZFail = 0;
this.stencilZPass = 0;
};
OutputStage.prototype.constructor = OutputStage;
OutputStage.prototype = {
setRenderTarget: function (renderTarget)
{
this.renderTarget = renderTarget;
return this;
},
setDefaultDepthStencilState: function ()
{
this.depthEnabled = false;
this.stencilEnabled = false;
this.depthMask = true;
this.depthFunc = GL.LESS;
this.stencilFunc = GL.NEVER;
this.stencilZFail = GL.KEEP;
this.stencilZPass = GL.KEEP;
return this;
},
setBlendColor: function (r, g, b, a)
{
this.blendRed = r;
this.blendGreen = g;
this.blendBlue = b;
this.blendAlpha = a;
},
setBlendFunc: function (src, dst, eq)
{
this.blendSrcRgb = this.blendSrcAlpha = src;
this.blendDstRgb = this.blendDstAlpha = dst;
this.blendEqRgb = this.blendEqAlpha = eq;
return this;
},
setBlendFuncSeparate: function (srcRgb, dstRgb, srcAlpha, dstAlpha, eqRgb, eqAlpha)
{
this.blendSrcRgb = srcRgb;
this.blendSrcAlpha = srcAlpha;
this.blendDstRgb = dstRgb;
this.blendDstAlpha = dstAlpha;
this.blendEqRgb = eqRgb;
this.blendEqAlpha = eqAlpha;
return this;
},
setDefaultBlending: function ()
{
this.setBlendFuncSeparate(
GL.SRC_ALPHA,
GL.ONE_MINUS_SRC_ALPHA,
GL.ONE,
GL.ONE_MINUS_SRC_ALPHA,
GL.FUNC_ADD,
GL.FUNC_ADD
);
return this;
},
setNoBlending: function ()
{
this.setBlendFunc(GL.ONE, GL.ZERO, GL.FUNC_ADD);
return this;
}
};
module.exports = OutputStage;

View file

@ -0,0 +1,10 @@
var RenderTarget = function (framebufferObject, width, height, colorBuffer, depthStencilBuffer)
{
this.framebufferObject = framebufferObject;
this.width = width;
this.height = height;
this.colorBuffer = colorBuffer;
this.depthStencilBuffer = depthStencilBuffer;
};
module.exports = RenderTarget;

View file

@ -0,0 +1,96 @@
var Shader = function(name, gl, program, vertexShader, fragmentShader)
{
this.gl = gl;
this.program = program;
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.name = name;
};
Shader.prototype.constructor = Shader;
/* For WebGL2 this won't be necessary */
Shader.prototype = {
getUniformLocation: function(name)
{
return this.gl.getUniformLocation(this.program, name);
},
setConstantFloat1: function(location, x)
{
this.gl.useProgram(this.program);
this.gl.uniform1f(location, x);
return this;
},
setConstantFloat2: function(location, x, y)
{
this.gl.useProgram(this.program);
this.gl.uniform2f(location, x, y);
return this;
},
setConstantFloat3: function(location, x, y, z) {
this.gl.useProgram(this.program);
this.gl.uniform3f(location, x, y, z);
return this;
},
setConstantFloat4: function(location, x, y, z, w) {
this.gl.useProgram(this.program);
this.gl.uniform4f(location, x, y, z, w);
return this;
},
setConstantInt1: function(location, x) {
this.gl.useProgram(this.program);
this.gl.uniform1i(location, x);
return this;
},
setConstantInt2: function(location, x, y) {
this.gl.useProgram(this.program);
this.gl.uniform2i(location, x, y);
return this;
},
setConstantInt3: function(location, x, y, z) {
this.gl.useProgram(this.program);
this.gl.uniform3i(location, x, y, z);
return this;
},
setConstantInt4: function(location, x, y, z, w) {
this.gl.useProgram(this.program);
this.gl.uniform4i(location, x, y, z, w);
return this;
},
setConstantMatrix2x2: function(location, floatArray) {
this.gl.useProgram(this.program);
this.gl.uniformMatrix2fv(location, false, floatArray);
return this;
},
setConstantMatrix3x3: function(location, floatArray) {
this.gl.useProgram(this.program);
this.gl.uniformMatrix3fv(location, false, floatArray);
return this;
},
setConstantMatrix4x4: function(location, floatArray) {
this.gl.useProgram(this.program);
this.gl.uniformMatrix4fv(location, false, floatArray);
return this;
},
bind: function ()
{
this.gl.useProgram(this.program);
return this;
}
};
module.exports = Shader;

View file

@ -0,0 +1,11 @@
var Texture = function (texture, width, height)
{
this.texture = texture;
this.width = width;
this.height = height;
this.isRenderTexture = false;
};
Texture.prototype.constructor = Texture;
module.exports = Texture;

View file

@ -0,0 +1,65 @@
var GL = require('../GL');
var VertexBuffer = function (gl, bufferObject)
{
this.gl = gl;
this.bufferTarget = GL.ARRAY_BUFFER;
this.bufferObject = bufferObject;
this.attributes = [];
};
VertexBuffer.prototype.constructor = VertexBuffer;
VertexBuffer.prototype = {
addAttribute: function (index, size, type, normalized, stride, offset)
{
this.attributes.push({
index: index,
size: size,
type: type,
normalized: normalized,
stride: stride,
offset: offset
});
return this;
},
updateResource: function (bufferData, offset)
{
var gl = this.gl;
gl.bindBuffer(GL.ARRAY_BUFFER, this.bufferObject);
gl.bufferSubData(GL.ARRAY_BUFFER, offset, bufferData);
return this;
},
bind: function ()
{
var gl = this.gl;
var bufferObject = this.bufferObject;
var attributes = this.attributes;
var attributesLength = attributes.length;
gl.bindBuffer(GL.ARRAY_BUFFER, bufferObject);
for (var index = 0; index < attributesLength; ++index)
{
var element = attributes[index];
if (element !== undefined && element !== null)
{
gl.enableVertexAttribArray(element.index);
gl.vertexAttribPointer(
element.index,
element.size,
element.type,
element.normalized,
element.stride,
element.offset
);
}
}
return this;
}
};
module.exports = VertexBuffer;

View file

@ -0,0 +1,10 @@
module.exports = {
IndexBuffer: require('./IndexBuffer'),
OutputStage: require('./OutputStage'),
RenderTarget: require('./RenderTarget'),
Shader: require('./Shader'),
Texture: require('./Texture'),
VertexBuffer: require('./VertexBuffer')
};

View file

@ -0,0 +1,19 @@
module.exports = {
vert: [
'attribute vec2 a_position;',
'attribute vec2 a_tex_coord;',
'varying vec2 v_tex_coord;',
'void main(void) {',
' gl_Position = vec4(a_position, 0.0, 1.0);',
' v_tex_coord = a_tex_coord;',
'}'
].join('\n'),
frag: [
'precision mediump float;',
'uniform sampler2D u_sampler;',
'varying vec2 v_tex_coord;',
'void main(void) {',
' gl_FragColor = texture2D(u_sampler, v_tex_coord);',
'}'
].join('\n')
};

View file

@ -0,0 +1,32 @@
module.exports = {
vert: [
'attribute vec2 a_position;',
'attribute vec2 a_tex_coord;',
'varying vec2 v_tex_coord;',
'void main(void) {',
' gl_Position = vec4(a_position, 0.0, 1.0);',
' v_tex_coord = a_tex_coord;',
'}'
].join('\n'),
frag: [
'precision mediump float;',
'uniform sampler2D u_sampler;',
'uniform float time;',
'varying vec2 v_tex_coord;',
'const float radius = 0.5;',
'const float angle = 5.0;',
'const vec2 offset = vec2(0.5, 0.5);',
'void main(void) {',
' vec2 coord = v_tex_coord - offset;',
' float distance = length(coord);',
' if (distance < radius) {',
' float ratio = (radius - distance) / radius;',
' float angleMod = ratio * ratio * angle;',
' float s = sin(angleMod);',
' float c = cos(angleMod);',
' coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);',
' }',
' gl_FragColor = texture2D(u_sampler, coord + offset);',
'}'
].join('\n')
};

View file

@ -0,0 +1,43 @@
module.exports = {
vert: [
'attribute vec2 a_position;',
'void main(void) {',
' gl_Position = vec4(a_position, 0.0, 1.0);',
'}'
].join('\n'),
frag: [
'precision mediump float;',
'uniform float time;',
'// Oldskool plasm shader. (c) Victor Korsun, bitekas@gmail.com; 1996-2013.',
'//',
'// Attribution-ShareAlike CC License.',
'//----------------',
'const int ps = 2; // use values > 1..10 for oldskool',
'const vec2 resolution = vec2(1280.0, 720.0);',
'//----------------',
'void main(void) {',
' float x = gl_FragCoord.x / resolution.x * 1280.0;',
' float y = gl_FragCoord.y / resolution.y * 720.0;',
' if (ps > 0)',
' {',
' x = float(int(x / float(ps)) * ps);',
' y = float(int(y / float(ps)) * ps);',
' }',
' float mov0 = x+y+sin(time)*10.+sin(x/90.)*70.+time*2.;',
' float mov1 = (mov0 / 5. + sin(mov0 / 30.))/ 10. + time * 3.;',
' float mov2 = mov1 + sin(mov1)*5. + time*1.0;',
' float cl1 = sin(sin(mov1/4. + time)+mov1);',
' float c1 = cl1 +mov2/2.-mov1-mov2+time;',
' float c2 = sin(c1+sin(mov0/100.+time)+sin(y/57.+time/50.)+sin((x+y)/200.)*2.);',
' float c3 = abs(sin(c2+cos((mov1+mov2+c2) / 10.)+cos((mov2) / 10.)+sin(x/80.)));',
' float dc = float(16-ps);',
' if (ps > 0)',
' {',
' cl1 = float(int(cl1*dc))/dc;',
' c2 = float(int(c2*dc))/dc;',
' c3 = float(int(c3*dc))/dc;',
' }',
' gl_FragColor = vec4(cl1, c2, c3, 1.0);',
'}'
].join('\n')
};

View file

@ -1,23 +0,0 @@
var ScaleModes = require('../../ScaleModes');
var CreateEmptyTexture = function (gl, width, height, scaleMode, textureIndex)
{
var texture = gl.createTexture();
var glScaleMode = (scaleMode === ScaleModes.LINEAR) ? gl.LINEAR : gl.NEAREST;
gl.activeTexture(gl.TEXTURE0 + textureIndex);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// We'll read from this texture, but it won't have mipmaps, so turn them off:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glScaleMode);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glScaleMode);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
return texture;
};
module.exports = CreateEmptyTexture;

View file

@ -1,4 +1,4 @@
var Buffer16 = function (byteSize)
var DataBuffer16 = function (byteSize)
{
this.wordLength = 0;
this.wordCapacity = byteSize / 2;
@ -7,36 +7,36 @@ var Buffer16 = function (byteSize)
this.uintView = new Uint16Array(this.buffer);
};
Buffer16.prototype.clear = function ()
DataBuffer16.prototype.clear = function ()
{
this.wordLength = 0;
};
Buffer16.prototype.getByteLength = function ()
DataBuffer16.prototype.getByteLength = function ()
{
return this.wordLength * 2;
};
Buffer16.prototype.getByteCapacity = function ()
DataBuffer16.prototype.getByteCapacity = function ()
{
return this.buffer.byteLength;
};
Buffer16.prototype.allocate = function (wordSize)
DataBuffer16.prototype.allocate = function (wordSize)
{
var currentLength = this.wordLength;
this.wordLength += wordSize;
return currentLength;
};
Buffer16.prototype.getUsedBufferAsShort = function ()
DataBuffer16.prototype.getUsedBufferAsShort = function ()
{
return this.intView.subarray(0, this.wordLength);
};
Buffer16.prototype.getUsedBufferAsWord = function ()
DataBuffer16.prototype.getUsedBufferAsWord = function ()
{
return this.uintView.subarray(0, this.wordLength);
};
module.exports = Buffer16;
module.exports = DataBuffer16;

View file

@ -1,4 +1,4 @@
var Buffer32 = function (byteSize)
var DataBuffer32 = function (byteSize)
{
this.dwordLength = 0;
this.dwordCapacity = byteSize / 4;
@ -8,41 +8,41 @@ var Buffer32 = function (byteSize)
this.uintView = new Uint32Array(this.buffer);
};
Buffer32.prototype.clear = function ()
DataBuffer32.prototype.clear = function ()
{
this.dwordLength = 0;
};
Buffer32.prototype.getByteLength = function ()
DataBuffer32.prototype.getByteLength = function ()
{
return this.dwordLength * 4;
};
Buffer32.prototype.getByteCapacity = function ()
DataBuffer32.prototype.getByteCapacity = function ()
{
return this.buffer.byteLength;
};
Buffer32.prototype.allocate = function (dwordSize)
DataBuffer32.prototype.allocate = function (dwordSize)
{
var currentLength = this.dwordLength;
this.dwordLength += dwordSize;
return currentLength;
};
Buffer32.prototype.getUsedBufferAsFloat = function ()
DataBuffer32.prototype.getUsedBufferAsFloat = function ()
{
return this.floatView.subarray(0, this.dwordLength);
};
Buffer32.prototype.getUsedBufferAsInt = function ()
DataBuffer32.prototype.getUsedBufferAsInt = function ()
{
return this.intView.subarray(0, this.dwordLength);
};
Buffer32.prototype.getUsedBufferAsUint = function ()
DataBuffer32.prototype.getUsedBufferAsUint = function ()
{
return this.uintView.subarray(0, this.dwordLength);
};
module.exports = Buffer32;
module.exports = DataBuffer32;

View file

@ -1,457 +0,0 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
var CreateEmptyTexture = require('./CreateEmptyTexture');
/**
* Frame Buffer Object with drawing quad + shader
*
* @class Phaser.Renderer.Canvas
* @constructor
* @param {Phaser.Game} game - Game reference to the currently running game.
*/
var QuadFBO = function (renderer, parent, x, y, width, height)
{
this.renderer = renderer;
this.parent = parent;
this.gl = renderer.gl;
this._x = x;
this._y = y;
this._width = width;
this._height = height;
this.textureIndex = 0;
this.clipX = function (x)
{
return (renderer.clipUnitX * x) - 1;
};
this.clipY = function (y)
{
return 1 - (renderer.clipUnitY * y);
};
this.vertexBuffer;
this.indexBuffer;
this.textureBuffer;
this.vertices;
this.texture;
this.renderBuffer;
this.frameBuffer;
this.program;
this.aVertexPosition;
this.aTextureCoord;
this._normal;
this._twirl;
this.init();
};
QuadFBO.prototype.constructor = QuadFBO;
QuadFBO.prototype = {
init: function ()
{
var gl = this.gl;
// An FBO quad is made up of 2 triangles (A and B in the image below)
//
// 0 = Bottom Left (-1, -1)
// 1 = Bottom Right (1, -1)
// 2 = Top Left (-1, 1)
// 3 = Top Right (1, 1)
//
// 2----3
// |\ B|
// | \ |
// | \ |
// | A \|
// | \
// 0----1
var width = this.renderer.width;
var height = this.renderer.height;
this.indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([ 0, 1, 2, 2, 1, 3 ]), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
this.vertices = new Float32Array(8);
this.updateVerts();
this.vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
this.textureBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 0, 1, 0, 0, 1, 1, 1 ]), gl.STATIC_DRAW);
// Create a texture for our color buffer
this.texture = CreateEmptyTexture(gl, width, height, 0, 0);
// The FBO's depth buffer
this.renderBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
this.frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
// May need to optionally be: gl.DEPTH_STENCIL_ATTACHMENT
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);
var fbStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (fbStatus !== gl.FRAMEBUFFER_COMPLETE)
{
window.console.error('FrameBuffer Error: ', this.renderer._fbErrors[fbStatus]);
}
this.createShader();
},
// This whole function ought to be split out into the Shader Manager
// so they can easily change the shader being used for an FBO.
// This class will have to expose those shader attribs though.
createShader: function ()
{
// Create the quad shader
var gl = this.gl;
var vertexSrc = [
'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
'varying vec2 vTextureCoord;',
'void main(void) {',
' vTextureCoord = aTextureCoord;',
' gl_Position = vec4(aVertexPosition, 0.0, 1.0);',
'}'
];
var fragmentSrc = [
'precision mediump float;',
'uniform sampler2D uSampler;',
'uniform float time;',
'varying vec2 vTextureCoord;',
'void main(void) {',
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
'}'
];
var twirlFragmentSrc = [
'precision mediump float;',
'uniform sampler2D uSampler;',
'uniform float time;',
'varying vec2 vTextureCoord;',
'const float radius = 0.5;',
'const float angle = 5.0;',
'const vec2 offset = vec2(0.5, 0.5);',
'void main(void) {',
' vec2 coord = vTextureCoord - offset;',
' float distance = length(coord);',
' if (distance < radius) {',
' float ratio = (radius - distance) / radius;',
' float angleMod = ratio * ratio * angle;',
' float s = sin(angleMod);',
' float c = cos(angleMod);',
' coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);',
' }',
' gl_FragColor = texture2D(uSampler, coord + offset);',
'}'
];
var plasmaFragmentSrc = [
'precision mediump float;',
'uniform sampler2D uSampler;',
'uniform float time;',
'varying vec2 vTextureCoord;',
'// Oldskool plasm shader. (c) Victor Korsun, bitekas@gmail.com; 1996-2013.',
'//',
'// Attribution-ShareAlike CC License.',
'//----------------',
'const int ps = 2; // use values > 1..10 for oldskool',
'const vec2 resolution = vec2(1280.0, 720.0);',
'//----------------',
'void main(void) {',
'float x = gl_FragCoord.x / resolution.x * 1280.0;',
'float y = gl_FragCoord.y / resolution.y * 720.0;',
'if (ps > 0)',
'{',
'x = float(int(x / float(ps)) * ps);',
'y = float(int(y / float(ps)) * ps);',
'}',
'float mov0 = x+y+sin(time)*10.+sin(x/90.)*70.+time*2.;',
'float mov1 = (mov0 / 5. + sin(mov0 / 30.))/ 10. + time * 3.;',
'float mov2 = mov1 + sin(mov1)*5. + time*1.0;',
'float cl1 = sin(sin(mov1/4. + time)+mov1);',
'float c1 = cl1 +mov2/2.-mov1-mov2+time;',
'float c2 = sin(c1+sin(mov0/100.+time)+sin(y/57.+time/50.)+sin((x+y)/200.)*2.);',
'float c3 = abs(sin(c2+cos((mov1+mov2+c2) / 10.)+cos((mov2) / 10.)+sin(x/80.)));',
'float dc = float(16-ps);',
'if (ps > 0)',
'{',
'cl1 = float(int(cl1*dc))/dc;',
'c2 = float(int(c2*dc))/dc;',
'c3 = float(int(c3*dc))/dc;',
'}',
'gl_FragColor = vec4(cl1, c2, c3, 1.0);',
'}'
];
// This compiles, attaches and links the shader
this._normal = this.renderer.compileProgram(vertexSrc, fragmentSrc);
// this._twirl = this.renderer.compileProgram(vertexSrc, twirlFragmentSrc);
this._twirl = this.renderer.compileProgram(vertexSrc, plasmaFragmentSrc);
this.program = this._normal;
this.aVertexPosition = gl.getAttribLocation(this.program, 'aVertexPosition');
this.aTextureCoord = gl.getAttribLocation(this.program, 'aTextureCoord');
},
setPosition: function (x, y)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (x !== this._x || y !== this._y)
{
this._x = x;
this._y = y;
this.updateVerts();
}
},
setSize: function (width, height)
{
if (width === undefined) { width = this.renderer.width; }
if (height === undefined) { height = this.renderer.height; }
if (width !== this._width || height !== this._height)
{
this._width = width;
this._height = height;
this.updateVerts();
}
},
updateVerts: function ()
{
var x = this._x;
var y = this._y;
var width = this._width;
var height = this._height;
// Bottom Left
this.vertices[0] = this.clipX(x);
this.vertices[1] = this.clipY(y + height);
// Bottom Right
this.vertices[2] = this.clipX(x + width);
this.vertices[3] = this.clipY(y + height);
// Top Left
this.vertices[4] = this.clipX(x);
this.vertices[5] = this.clipY(y);
// Top Right
this.vertices[6] = this.clipX(x + width);
this.vertices[7] = this.clipY(y);
},
activate: function ()
{
var gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
// FBO textures always use index zero
this.renderer.textureArray[0] = this.texture;
},
bindShader: function ()
{
var program = this.program;
var gl = this.gl;
gl.useProgram(program);
gl.uniform1i(gl.getUniformLocation(program, 'uSampler'), 0);
gl.uniform1f(gl.getUniformLocation(program, 'time'), this.parent.sys.mainloop.frameDelta);
gl.enableVertexAttribArray(this.aTextureCoord);
gl.enableVertexAttribArray(this.aVertexPosition);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
gl.vertexAttribPointer(this.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
},
// destinationBuffer MUST be set, even if just to 'null'
render: function (destinationBuffer)
{
var gl = this.gl;
// Set the framebuffer to render to
gl.bindFramebuffer(gl.FRAMEBUFFER, destinationBuffer);
// Bind the texture we rendered to, for reading, always TEXTURE0
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
// The shader that will read from the fbo texture
if (this.renderer.shaderManager.setShader(this.program))
{
this.bindShader();
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
this.renderer.drawCount++;
},
destroy: function ()
{
// TODO!
}
};
Object.defineProperties(QuadFBO.prototype, {
x: {
enumerable: true,
get: function ()
{
return this._x;
},
set: function (value)
{
if (value !== this._x)
{
this._x = value;
this.updateVerts();
}
}
},
y: {
enumerable: true,
get: function ()
{
return this._y;
},
set: function (value)
{
if (value !== this._y)
{
this._y = value;
this.updateVerts();
}
}
},
width: {
enumerable: true,
get: function ()
{
return this._width;
},
set: function (value)
{
if (value !== this._width)
{
this._width = value;
this.updateVerts();
}
}
},
height: {
enumerable: true,
get: function ()
{
return this._height;
},
set: function (value)
{
if (value !== this._height)
{
this._height = value;
this.updateVerts();
}
}
}
});
module.exports = QuadFBO;

View file

@ -1,16 +0,0 @@
var CreateBuffer = function (gl, bufferType, usage, bufferData, bufferSize)
{
var buffer = gl.createBuffer();
gl.bindBuffer(bufferType, buffer);
if (bufferData && ArrayBuffer.isView(bufferData))
{
gl.bufferData(bufferType, bufferData, usage);
}
else
{
gl.bufferData(bufferType, bufferSize, usage);
}
return buffer;
};
module.exports = CreateBuffer;

View file

@ -1,16 +0,0 @@
var CreateProgram = function (gl, vertexShader, fragmentShader)
{
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
{
console.error('Failed to link program. Error: \n' + gl.getProgramInfoLog(program));
return null;
}
return program;
};
module.exports = CreateProgram;

View file

@ -1,15 +0,0 @@
var CreateShader = function (gl, shaderSource, shaderType)
{
var shader = null;
shader = gl.createShader(shaderType);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
{
console.error('Failed ' + (shaderType === gl.VERTEX_SHADER ? 'vertex' : shaderType === gl.FRAGMENT_SHADER ? 'fragment' : 'invalid') + ' shader compilation. Error: \n' + gl.getShaderInfoLog(shader));
return null;
}
return shader;
};
module.exports = CreateShader;

View file

@ -1,99 +0,0 @@
var Shader = function(name, gl, program, vertexShader, fragmentShader)
{
this.context = gl;
this.program = program;
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.name = name;
};
Shader.prototype.constructor = Shader;
/* For WebGL2 this won't be necessary because of UBOs */
Shader.prototype = {
getUniformLocation: function(name)
{
return this.context.getUniformLocation(this.program, name);
},
setConstantFloat1: function(location, x)
{
this.context.useProgram(this.program);
this.context.uniform1f(location, x);
return this;
},
setConstantFloat2: function(location, x, y)
{
this.context.useProgram(this.program);
this.context.uniform2f(location, x, y);
return this;
},
setConstantFloat3: function(location, x, y, z)
{
this.context.useProgram(this.program);
this.context.uniform3f(location, x, y, z);
return this;
},
setConstantFloat4: function(location, x, y, z, w)
{
this.context.useProgram(this.program);
this.context.uniform4f(location, x, y, z, w);
return this;
},
setConstantInt1: function(location, x)
{
this.context.useProgram(this.program);
this.context.uniform1i(location, x);
return this;
},
setConstantInt2: function(location, x, y)
{
this.context.useProgram(this.program);
this.context.uniform2i(location, x, y);
return this;
},
setConstantInt3: function(location, x, y, z)
{
this.context.useProgram(this.program);
this.context.uniform3i(location, x, y, z);
return this;
},
setConstantInt4: function(location, x, y, z, w)
{
this.context.useProgram(this.program);
this.context.uniform4i(location, x, y, z, w);
return this;
},
setConstantMatrix2x2: function(location, floatArray)
{
this.context.useProgram(this.program);
this.context.uniformMatrix2fv(location, false, floatArray);
return this;
},
setConstantMatrix3x3: function(location, floatArray)
{
this.context.useProgram(this.program);
this.context.uniformMatrix3fv(location, false, floatArray);
return this;
},
setConstantMatrix4x4: function(location, floatArray)
{
this.context.useProgram(this.program);
this.context.uniformMatrix4fv(location, false, floatArray);
return this;
}
};
module.exports = Shader;

View file

@ -1,23 +0,0 @@
var CreateTexture2DArrayBuffer = function (gl, width, height, border, filter, arrayBuffer)
{
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
width,
height,
border,
gl.RGBA,
gl.UNSIGNED_BYTE,
arrayBuffer
);
return texture;
};
module.exports = CreateTexture2DArrayBuffer;

View file

@ -1,20 +0,0 @@
var ScaleModes = require('../../../ScaleModes');
var CreateTexture2DImage = require('./CreateTexture2DImage');
var CreateTexture2DFromSource = function (gl, source)
{
var filter;
if (source.scaleMode === ScaleModes.LINEAR)
{
filter = gl.LINEAR;
}
else if (source.scaleMode === ScaleModes.NEAREST)
{
filter = gl.NEAREST;
}
source.glTexture = CreateTexture2DImage(gl, source.image, filter, source.mipmapLevel)
};
module.exports = CreateTexture2DFromSource;

View file

@ -1,21 +0,0 @@
var CreateTexture2DImage = function (gl, pixels, filter, mipLevels)
{
var texture = gl.createTexture();
mipLevels = mipLevels || 0;
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
gl.texImage2D(
gl.TEXTURE_2D,
mipLevels,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE,
pixels
);
return texture;
};
module.exports = CreateTexture2DImage;

View file

@ -1,11 +0,0 @@
var Attribute = function (location, size, type, normalized, stride, offset)
{
this.location = location;
this.size = size;
this.type = type;
this.normalized = normalized;
this.stride = stride;
this.offset = offset;
};
module.exports = Attribute;

View file

@ -1,21 +0,0 @@
var BindVertexArray = function (gl, vao)
{
var attributes = vao.attributes;
gl.bindBuffer(gl.ARRAY_BUFFER, vao.buffer);
for (var index = 0, length = attributes.length; index < length; ++index)
{
var attrib = attributes[index];
var location = attrib.location;
gl.enableVertexAttribArray(location);
gl.vertexAttribPointer(
location,
attrib.size,
attrib.type,
attrib.normalized,
attrib.stride,
attrib.offset
);
}
};
module.exports = BindVertexArray;

View file

@ -1,21 +0,0 @@
var Attribute = require('./Attribute');
var CreateAttribArray = function (gl, program, attributeDescArray)
{
var attributes = [];
for (var index = 0, length = attributeDescArray.length; index < length; ++index)
{
var desc = attributeDescArray[index];
attributes.push(new Attribute(
gl.getAttribLocation(program, desc.name),
desc.size,
desc.type,
desc.normalized ? gl.TRUE : gl.FALSE,
desc.stride,
desc.offset
));
}
return attributes;
};
module.exports = CreateAttribArray;

View file

@ -1,15 +0,0 @@
var Attribute = require('./Attribute');
var CreateAttribDesc = function (gl, program, name, size, type, normalized, stride, offset)
{
return new Attribute(
gl.getAttribLocation(program, name),
size,
type,
normalized,
stride,
offset
);
};
module.exports = CreateAttribDesc;

View file

@ -1,7 +0,0 @@
var VertexArray = function (vbo, attributes)
{
this.buffer = vbo;
this.attributes = attributes;
};
module.exports = VertexArray;

View file

@ -7,7 +7,6 @@
var CONST = require('../const');
var ScaleModes = require('../renderer/ScaleModes');
var IsSizePowerOfTwo = require('../math/pow2/IsSizePowerOfTwo');
var CreateTexture2DFromSource = require('../renderer/webgl/utils/texture/CreateTexture2DFromSource');
/**
*
@ -124,7 +123,7 @@ var TextureSource = function (texture, source)
if (game.config.renderType === CONST.WEBGL)
{
CreateTexture2DFromSource(game.renderer.gl, this);
game.renderer.createTexture(this);
}
};