mirror of
https://github.com/photonstorm/phaser
synced 2024-12-14 07:13:00 +00:00
WebGLRenderer cleanup
This commit is contained in:
parent
1da31fb2a5
commit
31be6fa51d
3 changed files with 194 additions and 57 deletions
|
@ -1,7 +1,7 @@
|
|||
var WebGLSnapshot = function (sourceCanvas, type, encoderOptions)
|
||||
{
|
||||
if (type === undefined) { type = 'image/png'; }
|
||||
if (encoderOptions === undefined) { encoderOptions = 0.92; }
|
||||
if (!type) { type = 'image/png'; }
|
||||
if (!encoderOptions) { encoderOptions = 0.92; }
|
||||
|
||||
var gl = sourceCanvas.getContext('experimental-webgl');
|
||||
var pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
|
||||
|
|
|
@ -15,41 +15,13 @@ var WebGLPipeline = new Class({
|
|||
this.gl = config.gl;
|
||||
this.vertexCount = 0;
|
||||
this.vertexCapacity = config.vertexCapacity;
|
||||
this.manager = config.manager;
|
||||
this.resources = config.manager.resourceManager;
|
||||
this.renderer = config.renderer;
|
||||
this.vertexData = new ArrayBuffer(config.vertexCapacity * config.vertexSize);
|
||||
this.vertexBuffer = null;
|
||||
this.program = null;
|
||||
this.vertexLayout = config.vertexLayout;
|
||||
this.vertexBuffer = renderer.createVertexBuffer(this.vertexData.byteLength, gl.STREAM_DRAW);
|
||||
this.program = renderer.createProgram(config.shader.vert, config.shader.frag);
|
||||
this.attributes = config.attributes;
|
||||
this.vertexSize = config.vertexSize;
|
||||
this.topology = config.topology;
|
||||
|
||||
// Initialize Shaders and Buffers
|
||||
{
|
||||
var gl = this.gl;
|
||||
var resources = this.resources;
|
||||
var vertexSize = this.vertexSize;
|
||||
var vertexLayout = this.vertexLayout;
|
||||
var program = resources.createShader(this.name, config.shader);
|
||||
var vertexBuffer = resources.createBuffer(gl.ARRAY_BUFFER, this.vertexData.byteLength, gl.STREAM_DRAW);
|
||||
|
||||
for (var key in vertexLayout)
|
||||
{
|
||||
var element = vertexLayout[key];
|
||||
|
||||
vertexBuffer.addAttribute(
|
||||
program.getAttribLocation(key),
|
||||
element.size,
|
||||
element.type,
|
||||
element.normalize,
|
||||
vertexSize,
|
||||
element.offset
|
||||
);
|
||||
}
|
||||
|
||||
this.vertexBuffer = vertexBuffer;
|
||||
this.program = program;
|
||||
}
|
||||
},
|
||||
|
||||
shouldFlush: function ()
|
||||
|
@ -66,12 +38,31 @@ var WebGLPipeline = new Class({
|
|||
|
||||
bind: function (overrideProgram)
|
||||
{
|
||||
// Check if we're using a custom program or
|
||||
// the default one from the pipeline.
|
||||
if (!overrideProgram) this.program.bind();
|
||||
else overrideProgram.bind();
|
||||
var gl = this.gl;
|
||||
var vertexBuffer = this.vertexBuffer;
|
||||
var attributes = this.attributes;
|
||||
var program = (!overrideProgram ? this.program : overrideProgram);
|
||||
var renderer = this.renderer;
|
||||
var vertexSize = this.vertexSize;
|
||||
|
||||
this.vertexBuffer.bind();
|
||||
renderer.setProgram(program);
|
||||
renderer.setVertexBuffer(vertexBuffer);
|
||||
|
||||
for (var index = 0; index < attributes.length; ++index)
|
||||
{
|
||||
var element = attributes[index];
|
||||
var location = gl.getAttribLocation(program, element.name);
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
gl.enableVertexAttribArray(location);
|
||||
gl.vertexAttribPointer(location, element.size, element.type, element.normalized, vertexSize, element.offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.disableVertexAttribArray(location);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
@ -86,7 +77,7 @@ var WebGLPipeline = new Class({
|
|||
|
||||
if (vertexCount === 0) return;
|
||||
|
||||
vertexBuffer.updateResource(vertexData, 0);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertexData);
|
||||
gl.drawArrays(topology, 0, vertexCount);
|
||||
|
||||
this.vertexCount = 0;
|
||||
|
@ -96,10 +87,10 @@ var WebGLPipeline = new Class({
|
|||
|
||||
destroy: function ()
|
||||
{
|
||||
var resources = this.resources;
|
||||
var gl = this.gl;
|
||||
|
||||
resources.deleteShader(this.program);
|
||||
resources.deleteBuffer(this.vertexBuffer);
|
||||
gl.deleteShader(this.program);
|
||||
gl.deleteBuffer(this.vertexBuffer);
|
||||
|
||||
this.program = null;
|
||||
this.vertexBuffer = null;
|
||||
|
@ -109,67 +100,67 @@ var WebGLPipeline = new Class({
|
|||
|
||||
setFloat1: function (name, x)
|
||||
{
|
||||
this.gl.uniform1f(this.gl.getUniformLocation(this.program.program, name), x);
|
||||
this.gl.uniform1f(this.gl.getUniformLocation(this.program, name), x);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat2: function (name, x, y)
|
||||
{
|
||||
this.gl.uniform2f(this.gl.getUniformLocation(this.program.program, name), x, y);
|
||||
this.gl.uniform2f(this.gl.getUniformLocation(this.program, name), x, y);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat3: function (name, x, y, z)
|
||||
{
|
||||
this.gl.uniform3f(this.gl.getUniformLocation(this.program.program, name), x, y, z);
|
||||
this.gl.uniform3f(this.gl.getUniformLocation(this.program, name), x, y, z);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat4: function (name, x, y, z, w)
|
||||
{
|
||||
this.gl.uniform4f(this.gl.getUniformLocation(this.program.program, name), x, y, z, w);
|
||||
this.gl.uniform4f(this.gl.getUniformLocation(this.program, name), x, y, z, w);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt1: function (name, x)
|
||||
{
|
||||
this.gl.uniform1i(this.gl.getUniformLocation(this.program.program, name), x);
|
||||
this.gl.uniform1i(this.gl.getUniformLocation(this.program, name), x);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt2: function (name, x, y)
|
||||
{
|
||||
this.gl.uniform2i(this.gl.getUniformLocation(this.program.program, name), x, y);
|
||||
this.gl.uniform2i(this.gl.getUniformLocation(this.program, name), x, y);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt3: function (name, x, y, z)
|
||||
{
|
||||
this.gl.uniform3i(this.gl.getUniformLocation(this.program.program, name), x, y, z);
|
||||
this.gl.uniform3i(this.gl.getUniformLocation(this.program, name), x, y, z);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt4: function (name, x, y, z, w)
|
||||
{
|
||||
this.gl.uniform4i(this.gl.getUniformLocation(this.program.program, name), x, y, z, w);
|
||||
this.gl.uniform4i(this.gl.getUniformLocation(this.program, name), x, y, z, w);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix2: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program, name), transpose, matrix);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix3: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program, name), transpose, matrix);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix4: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program, name), transpose, matrix);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
var Class = require('../../utils/Class');
|
||||
var CONST = require('../../const');
|
||||
var WebGLSnapshot = require('../snapshot/WebGLSnapshot');
|
||||
var IsSizePowerOfTwo = require('../../math/pow2/IsSizePowerOfTwo');
|
||||
|
||||
var WebGLRenderer = new Class({
|
||||
|
||||
|
@ -30,6 +32,11 @@ var WebGLRenderer = new Class({
|
|||
this.contextLost = false;
|
||||
this.autoResize = false;
|
||||
this.pipelines = null;
|
||||
this.snapshotState = {
|
||||
callback: null,
|
||||
type: null,
|
||||
encoder: null
|
||||
};
|
||||
|
||||
for (var i = 0; i <= 16; i++)
|
||||
{
|
||||
|
@ -108,6 +115,7 @@ var WebGLRenderer = new Class({
|
|||
resize: function (width, height, resolution)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var piplines = this.pipelines;
|
||||
|
||||
this.width = width * resolution;
|
||||
this.height = height * resolution;
|
||||
|
@ -124,6 +132,10 @@ var WebGLRenderer = new Class({
|
|||
gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
// Update all registered pipelines
|
||||
for (var pipelineName in pipelines)
|
||||
{
|
||||
pipeline[pipelineName].resize(width, height, resolution);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
@ -145,6 +157,14 @@ var WebGLRenderer = new Class({
|
|||
return this.extensions[extensionName];
|
||||
},
|
||||
|
||||
flush: function ()
|
||||
{
|
||||
if (this.currentPipeline)
|
||||
{
|
||||
this.currentPipeline.flush();
|
||||
}
|
||||
},
|
||||
|
||||
/* Renderer State Manipulation Functions */
|
||||
|
||||
hasPipeline: function (pipelineName)
|
||||
|
@ -174,18 +194,30 @@ var WebGLRenderer = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
setPipeline: function (pipelineName)
|
||||
{
|
||||
var pipeline = this.getPipeline(pipelineName);
|
||||
|
||||
if (this.currentPipeline !== pipeline)
|
||||
{
|
||||
this.currentPipeline = pipeline;
|
||||
this.currentPipeline.bind();
|
||||
}
|
||||
|
||||
return pipeline;
|
||||
},
|
||||
|
||||
setBlendMode: function (blendModeId)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var pipeline = this.currentPipeline;
|
||||
var blendMode = this.blendModes[blendModeId];
|
||||
|
||||
if (blendModeId === CONST.BlendModes.SKIP_CHECK || !pipeline)
|
||||
if (blendModeId === CONST.BlendModes.SKIP_CHECK)
|
||||
return;
|
||||
|
||||
if (this.currentBlendMode !== blendModeId)
|
||||
{
|
||||
pipeline.flush();
|
||||
this.flush();
|
||||
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendEquation(blendMode.equation);
|
||||
|
@ -257,6 +289,44 @@ var WebGLRenderer = new Class({
|
|||
},
|
||||
|
||||
/* Renderer Resource Creation Functions */
|
||||
createTextureFromSource: function (source, width, height)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var filter = gl.NEAREST;
|
||||
var wrap = gl.CLAMP_TO_EDGE;
|
||||
|
||||
width = source ? source.width : width;
|
||||
height = source ? source.height : height;
|
||||
|
||||
if (IsSizePowerOfTwo(width, height))
|
||||
{
|
||||
wrap = gl.REPEAT;
|
||||
}
|
||||
|
||||
if (!source.glTexture)
|
||||
{
|
||||
if (source.scaleMode === ScaleModes.LINEAR)
|
||||
{
|
||||
filter = gl.LINEAR;
|
||||
}
|
||||
else if (source.scaleMode === ScaleModes.NEAREST || this.game.config.pixelArt)
|
||||
{
|
||||
filter = gl.NEAREST;
|
||||
}
|
||||
|
||||
if (!source && typeof width === 'number' && typeof height === 'number')
|
||||
{
|
||||
source.glTexture = this.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, null, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
source.glTexture = this.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, source.image);
|
||||
}
|
||||
}
|
||||
|
||||
return source;
|
||||
},
|
||||
|
||||
createTexture2D: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
@ -389,6 +459,82 @@ var WebGLRenderer = new Class({
|
|||
this.setIndexBuffer(null);
|
||||
|
||||
return indexBuffer;
|
||||
},
|
||||
|
||||
/* Rendering Functions */
|
||||
preRender: function ()
|
||||
{
|
||||
if (this.contextLost) return;
|
||||
|
||||
},
|
||||
|
||||
render: function (scene, children, interpolationPercentage, camera)
|
||||
{
|
||||
if (this.contextLost) return;
|
||||
|
||||
},
|
||||
|
||||
postRender: function ()
|
||||
{
|
||||
if (this.contextLost) return;
|
||||
|
||||
if (this.snapshotState.callback)
|
||||
{
|
||||
this.snapshotState.callback(WebGLSnapshot(this.canvas, this.snapshotState.type, this.snapshotState.encoder));
|
||||
this.snapshotState.callback = null;
|
||||
}
|
||||
},
|
||||
|
||||
snapshot: function (callback, type, encoderOptions)
|
||||
{
|
||||
this.snapshotState.callback = callback;
|
||||
this.snapshotState.type = type;
|
||||
this.snapshotState.encoder = encoderOptions;
|
||||
return this;
|
||||
},
|
||||
|
||||
canvasToTexture: function (srcCanvas, dstTexture, shouldReallocate)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (!dstTexture)
|
||||
{
|
||||
dstTexture = this.createTextureFromSource(srcCanvas, srcCanvas.width, srcCanvas.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setTexture2D(dstTexture);
|
||||
|
||||
if (!shouldReallocate)
|
||||
{
|
||||
gl.texSubImage2D(0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
||||
dstTexture.width = srcCanvas.width;
|
||||
dstTexture.height = srcCanvas.height;
|
||||
}
|
||||
|
||||
this.setTexture2D(null);
|
||||
}
|
||||
|
||||
return dstTexture;
|
||||
},
|
||||
|
||||
setTextureFilter: function (texture, filter)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var glFilter = [ gl.LINEAR, gl.NEAREST ][filter];
|
||||
|
||||
this.setTexture2D(texture, 0);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter);
|
||||
|
||||
this.setTexture2D(null, 0);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue