2017-04-05 22:01:44 +00:00
|
|
|
var Resources = require('./resources');
|
|
|
|
|
|
|
|
var ResourceManager = function (gl)
|
|
|
|
{
|
|
|
|
this.gl = gl;
|
|
|
|
/* Maybe add pooling here */
|
|
|
|
this.shaderCache = {};
|
2017-04-07 01:49:15 +00:00
|
|
|
this.shaderCount = 0;
|
2017-04-05 22:01:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferObject)
|
2017-04-05 22:01:44 +00:00
|
|
|
|
|
|
|
if (depthStencilBuffer !== undefined && depthStencilBuffer !== null)
|
|
|
|
{
|
|
|
|
depthStencilBuffer.isRenderTexture = true;
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilBuffer.texture, depthStencilBuffer.mipLevel);
|
2017-04-05 22:01:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
depthStencilRenderbufferObject = gl.createRenderbuffer();
|
2017-04-07 01:49:15 +00:00
|
|
|
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);
|
2017-04-05 22:01:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (colorBuffer !== undefined && colorBuffer !== null)
|
|
|
|
{
|
|
|
|
colorBuffer.isRenderTexture = true;
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorBuffer.texture, colorBuffer.mipLevel);
|
2017-04-05 22:01:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
colorRenderbufferObject = gl.createRenderbuffer();
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorRenderbufferObject);
|
|
|
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height);
|
|
|
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRenderbufferObject);
|
2017-04-05 22:01:44 +00:00
|
|
|
}
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
2017-04-05 22:01:44 +00:00
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
if (complete !== gl.FRAMEBUFFER_COMPLETE)
|
2017-04-05 22:01:44 +00:00
|
|
|
{
|
|
|
|
var errors = {
|
|
|
|
36054: 'Incomplete Attachment',
|
|
|
|
36055: 'Missing Attachment',
|
|
|
|
36057: 'Incomplete Dimensions',
|
|
|
|
36061: 'Framebuffer Unsupported'
|
|
|
|
};
|
2017-04-07 01:49:15 +00:00
|
|
|
alert('Framebuffer incomplete. Framebuffer status: ' + errors[complete]);
|
2017-04-05 22:01:44 +00:00
|
|
|
throw new Error('Framebuffer incomplete. Framebuffer status: ' + errors[complete]);
|
|
|
|
}
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
2017-04-05 22:01:44 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2017-04-07 01:49:15 +00:00
|
|
|
case gl.ARRAY_BUFFER:
|
2017-04-05 22:01:44 +00:00
|
|
|
return new Resources.VertexBuffer(gl, bufferObject);
|
2017-04-07 01:49:15 +00:00
|
|
|
case gl.ELEMENT_ARRAY_BUFFER:
|
2017-04-05 22:01:44 +00:00
|
|
|
return new Resources.IndexBuffer(gl, bufferObject);
|
|
|
|
default:
|
2017-04-07 01:49:15 +00:00
|
|
|
alert('Invalid Buffer Target');
|
2017-04-05 22:01:44 +00:00
|
|
|
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();
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
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);
|
2017-04-05 22:01:44 +00:00
|
|
|
|
|
|
|
if (pixels === null || pixels === undefined)
|
|
|
|
{
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, null);
|
2017-04-05 22:01:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, format, gl.UNSIGNED_BYTE, pixels);
|
2017-04-05 22:01:44 +00:00
|
|
|
width = pixels.width;
|
|
|
|
height = pixels.height;
|
|
|
|
}
|
2017-04-07 01:49:15 +00:00
|
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
2017-04-05 22:01:44 +00:00
|
|
|
|
|
|
|
return new Resources.Texture(texture, width, height);
|
|
|
|
},
|
|
|
|
|
|
|
|
createShader: function (shaderName, shaderSources)
|
|
|
|
{
|
2017-04-07 01:49:15 +00:00
|
|
|
if (shaderName === null || shaderName === undefined)
|
|
|
|
{
|
|
|
|
shaderName += 'Shader' + this.shaderCount;
|
|
|
|
this.shaderCount += 1;
|
|
|
|
}
|
2017-04-05 22:01:44 +00:00
|
|
|
if (!(shaderName in this.shaderCache))
|
|
|
|
{
|
|
|
|
var gl = this.gl;
|
|
|
|
var program = gl.createProgram();
|
2017-04-07 01:49:15 +00:00
|
|
|
var vertShader = gl.createShader(gl.VERTEX_SHADER);
|
|
|
|
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
|
2017-04-05 22:01:44 +00:00
|
|
|
var error;
|
|
|
|
var shader;
|
|
|
|
|
|
|
|
gl.shaderSource(vertShader, shaderSources.vert);
|
|
|
|
gl.shaderSource(fragShader, shaderSources.frag);
|
|
|
|
|
|
|
|
gl.compileShader(vertShader);
|
|
|
|
gl.compileShader(fragShader);
|
|
|
|
|
|
|
|
error = gl.getShaderInfoLog(vertShader);
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
if (error && error.length > 0)
|
2017-04-05 22:01:44 +00:00
|
|
|
{
|
2017-04-07 01:49:15 +00:00
|
|
|
alert('Vertex Shader Compilation Error.\n' + error);
|
2017-04-05 22:01:44 +00:00
|
|
|
throw new Error('Vertex Shader Compilation Error.\n' + error);
|
|
|
|
}
|
|
|
|
|
|
|
|
error = gl.getShaderInfoLog(fragShader);
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
if (error && error.length > 0)
|
2017-04-05 22:01:44 +00:00
|
|
|
{
|
2017-04-07 01:49:15 +00:00
|
|
|
alert('Fragment Shader Compilation Error.\n' + error);
|
2017-04-05 22:01:44 +00:00
|
|
|
throw new Error('Fragment Shader Compilation Error.\n' + error);
|
|
|
|
}
|
|
|
|
|
|
|
|
gl.attachShader(program, vertShader);
|
|
|
|
gl.attachShader(program, fragShader);
|
|
|
|
gl.linkProgram(program);
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
error = gl.getProgramParameter(program, gl.LINK_STATUS);
|
2017-04-05 22:01:44 +00:00
|
|
|
|
|
|
|
if (error === 0)
|
|
|
|
{
|
|
|
|
error = gl.getProgramInfoLog(program);
|
|
|
|
|
2017-04-07 01:49:15 +00:00
|
|
|
alert('Program Linking Error.\n' + error);
|
2017-04-05 22:01:44 +00:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
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;
|