Image renderering

This commit is contained in:
Felipe Alfonso 2017-04-04 01:36:26 -03:00
parent 49272eb9c3
commit b520bd0469
35 changed files with 518 additions and 346 deletions

View file

@ -10,7 +10,10 @@ var Features = require('../device/Features');
//var CanvasRenderer = require('../renderer/canvas/CanvasRenderer');
//var WebGLRenderer = require('../renderer/webgl/WebGLRenderer');
var CanvasInterpolation = require('../dom/CanvasInterpolation');
var RenderDevice = require('../renderer/RenderDevice');
var WebGLBackendInterface = require('../renderer/webgl/BackendInterface');
var WebGLResourceManager = require('../renderer/webgl/ResourceManager');
var RendererList = require('../renderer/RendererList');
/**
* Checks if the device is capable of using the requested renderer and sets it up or an alternative if not.
*
@ -20,7 +23,9 @@ var CanvasInterpolation = require('../dom/CanvasInterpolation');
var CreateRenderer = function (game)
{
var config = game.config;
var backend = null;
var resourceManager = null;
var rendererList = null;
// Game either requested Canvas,
// or requested AUTO or WEBGL but the browser doesn't support it, so fall back to Canvas
if (config.renderType === CONST.CANVAS || (config.renderType !== CONST.CANVAS && !Features.webGL))
@ -70,6 +75,27 @@ var CreateRenderer = function (game)
game.canvas.style.height = (config.height * config.zoom).toString() + 'px';
}
if (config.renderType === CONST.WEBGL)
{
var contextConfig = {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
};
var gl = game.canvas.getContext('webgl', contextConfig) ||
game.canvas.getContext('experimental-webgl', contextConfig);
if (!gl)
{
throw new Error('This browser does not support WebGL. Try using the Canvas renderer.');
}
backend = new WebGLBackendInterface(gl);
resourceManager = new WebGLResourceManager(gl);
}
rendererList = new RendererList(game);
game.renderDevice = new RenderDevice(backend, resourceManager, rendererList);
// Create the renderer
/*if (config.renderType === CONST.WEBGL)
{

View file

@ -24,7 +24,8 @@ var Game = function (config)
{
this.config = new Config(config);
this.renderer = null;
this.renderDevice = null;
//this.renderer = null;
this.canvas = null;
this.context = null;

View file

@ -143,7 +143,8 @@ MainLoop.prototype = {
step: function (timestamp)
{
var active = this.game.state.active;
var renderer = this.game.renderer;
var renderDevice = this.game.renderDevice;
//var renderer = this.game.renderer;
var len = active.length;
@ -213,15 +214,13 @@ MainLoop.prototype = {
var interpolation = this.frameDelta / this.timestep;
renderer.preRender();
// This uses active.length, in case state.update removed the state from the active list
for (i = 0; i < active.length; i++)
{
active[i].state.sys.render(interpolation, renderer);
active[i].state.sys.render(interpolation, renderDevice);
}
renderer.postRender();
if (this.panic)
{

View file

@ -1,4 +1,4 @@
var CHECKSUM = {
build: '02229ca0-1488-11e7-8e2a-13177b968951'
build: 'aac3ab90-18ef-11e7-b3fd-71ae0f91d1c8'
};
module.exports = CHECKSUM;

View file

@ -1,10 +1,10 @@
var BlendModes = require('../renderer/BlendModes');
// var BlendModes = require('../renderer/BlendModes');
// BlendMode Component
var BlendMode = {
_blendMode: BlendModes.NORMAL,
//_blendMode: BlendModes.NORMAL,
blendMode: {

View file

@ -0,0 +1,13 @@
var Render = {
render: function (camera)
{
this.renderer.begin();
this.renderer.setTexture(this.texture);
this.renderer.render(this, camera);
this.renderer.end();
}
};
module.exports = Render;

View file

@ -1,190 +0,0 @@
/* This is a WebGL ONLY component */
var RenderPass = {
outputStage: {
renderTarget: null,
enableDepthTest: false,
enableStencilTest: false,
enableBlending: false,
/* Blend State */
blendLogicOp: 0,
blendSrcRgb: 0,
blendDstRgb: 0,
blendSrcAlpha: 0,
blendDstAlpha: 0,
blendEqRgb: 0,
blendEqAlpha: 0,
blendRed: 0,
blendGreen: 0,
blendBlue: 0,
blendAlpha: 0,
/* Depth-Stencil State */
depthFunc: 0,
depthMask: 0,
stencilFunc: 0,
stencilFail: 0,
stencilZFail: 0,
stencilZPass: 0
},
renderPass: {
shaderPipeline: null,
textures: [],
topology: 0
},
/* Needed for getting constant values
* Form the WebGL context.
*/
renderingContext: null,
/* Utility functions */
initRenderPassComponent: function ()
{
var renderingContext = this.state.game.renderer.gl;
if (renderingContext !== undefined &&
((renderingContext instanceof WebGLRenderingContext) || (renderingContext !== null && renderingContext.rawgl !== undefined)))
{
this.renderingContext = renderingContext;
this.setDefaultDepthStencilState();
this.setNoBlending();
}
},
setRenderTarget: function (renderTarget)
{
this.outputStage.renderTarget = renderTarget;
return this;
},
setDefaultDepthStencilState: function ()
{
var gl = this.renderingContext;
var outputStage = this.outputStage;
outputStage.depthEnabled = false;
outputStage.stencilEnabled = false;
outputStage.depthMask = true;
outputStage.depthFunc = gl.LESS;
outputStage.stencilFunc = gl.NEVER;
outputStage.stencilZFail = gl.KEEP;
outputStage.stencilZPass = gl.KEEP;
return this;
},
setBlendColor: function (r, g, b, a)
{
var outputStage = this.outputStage;
outputStage.blendRed = r;
outputStage.blendGreen = g;
outputStage.blendBlue = b;
outputStage.blendAlpha = a;
return this;
},
setBlendFunc: function (src, dst, eq)
{
var outputStage = this.outputStage;
outputStage.blendSrcRgb = outputStage.blendSrcAlpha = src;
outputStage.blendDstRgb = outputStage.blendDstAlpha = dst;
outputStage.blendEqRgb = outputStage.blendEqAlpha = eq;
return this;
},
setBlendFuncSeparate: function (srcRgb, srcAlpha, dstRgb, dstAlpha, eqRgb, eqAlpha)
{
var outputStage = this.outputStage;
outputStage.blendSrcRgb = srcRgb;
outputStage.blendSrcAlpha = srcAlpha;
outputStage.blendDstRgb = dstRgb;
outputStage.blendDstAlpha = dstAlpha;
outputStage.blendEqRgb = eqRgb;
outputStage.blendEqAlpha = eqAlpha;
return this;
},
setDefaultBlending: function () {
var gl = this.renderingContext;
this.setBlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ADD);
return this;
},
setNoBlending: function () {
var gl = this.renderingContext;
this.setBlendFunc(gl.ONE, gl.ZERO, gl.ADD);
return this;
},
setTexture: function (texture, textureUnit) {
this.renderPass.textures[textureUnit] = texture;
return this;
},
setTopology: function (topology) {
this.renderPass.topology = topology;
return this;
},
setShaderPipeline: function (shaderPipeline) {
this.renderPass.shaderPipeline = shaderPipeline;
return this;
},
/* Call this on render pass */
dispatchRenderPassState: function () {
var gl = this.renderingContext;
var textures = this.textures;
var length = textures.length;
var outputStage = this.outputStage;
for (var index = 0; index < length; ++index) {
if (textures[index] !== null) {
gl.activeTexture(gl.TEXTURE0 + index);
gl.bindTexture(gl.TEXTURE_2D, textures[index].texture);
} else {
gl.activeTexture(gl.TEXTURE0 + index);
gl.bindTexture(gl.TEXTURE_2D, null);
}
}
if (outputStage.enableBlending) {
gl.enable(gl.BLEND);
gl.blendFuncSeparate(outputStage.blendSrcRGB, outputStage.blendDstRGB, outputStage.blendSrcAlpha, outputStage.blendDstAlpha);
gl.blendEquationSeparate(outputStage.blendEqRgb, outputStage.blendEqAlpha);
gl.blendColor(outputStage.blendRed, outputStage.blendGreen, outputStage.blendBlue, outputStage.blendAlpha)
} else {
gl.disable(gl.BLEND);
}
if (outputStage.enableDepthTest) {
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(outputStage.depthFunc);
gl.depthMask(outputStage.depthMask);
} else {
gl.disable(gl.DEPTH_TEST);
}
if (outputStage.enableStencilTest) {
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(this.stencilFunc, 0, 1);
gl.stencilOp(this.stencilFail, this.stencilZFail, this.stencilZPass);
} else {
gl.disable(gl.STENCIL_TEST);
}
}
};
module.exports = RenderPass;

View file

@ -1,10 +1,10 @@
var ScaleModes = require('../renderer/ScaleModes');
//var ScaleModes = require('../renderer/ScaleModes');
// ScaleMode Component
var ScaleMode = {
_scaleMode: ScaleModes.DEFAULT,
//_scaleMode: ScaleModes.DEFAULT,
scaleMode: {

View file

@ -8,7 +8,7 @@ module.exports = {
Flip: require('./Flip'),
GetBounds: require('./GetBounds'),
Origin: require('./Origin'),
RenderPass: require('./RenderPass'),
Render: require('./Render'),
ScaleMode: require('./ScaleMode'),
Size: require('./Size'),
Texture: require('./Texture'),

View file

@ -13,7 +13,6 @@ var DynamicBitmapText = new Class({
Components.Size,
Components.Texture,
Components.Transform,
Components.RenderPass,
Components.Visible,
Render
],
@ -38,7 +37,6 @@ var DynamicBitmapText = new Class({
this.setTexture(font);
this.setPosition(x, y);
this.initRenderPassComponent();
},
setDisplayCallback: function (callback)

View file

@ -13,7 +13,6 @@ var BitmapText = new Class({
Components.Size,
Components.Texture,
Components.Transform,
Components.RenderPass,
Components.Visible,
Render
],
@ -37,7 +36,6 @@ var BitmapText = new Class({
this.setTexture(font);
this.setPosition(x, y);
this.setOrigin(0, 0);
this.initRenderPassComponent();
},
setFontSize: function (size)

View file

@ -32,7 +32,6 @@ var Blitter = new Class({
Components.Size,
Components.Texture,
Components.Transform,
Components.RenderPass,
Components.Visible,
BlitterRender
],
@ -51,7 +50,6 @@ var Blitter = new Class({
this.renderList = [];
this.dirty = false;
this.initRenderPassComponent();
},
// frame MUST be part of the Blitter texture

View file

@ -12,7 +12,6 @@ var Graphics = new Class({
Components.Alpha,
Components.BlendMode,
Components.Transform,
Components.RenderPass,
Components.Visible,
Render
],
@ -29,7 +28,6 @@ var Graphics = new Class({
this.setPosition(x, y);
this.commandBuffer = [];
this.initRenderPassComponent();
this.defaultFillColor = -1;
this.defaultFillAlpha = 1;

View file

@ -12,13 +12,12 @@ var Image = new Class({
Components.Flip,
Components.GetBounds,
Components.Origin,
Components.RenderPass,
Components.ScaleMode,
Components.Size,
Components.Texture,
Components.Transform,
Components.Visible,
ImageRender
Components.Render
],
initialize:
@ -27,11 +26,16 @@ var Image = new Class({
{
GameObject.call(this, state);
this.renderer = new state.
game.
renderDevice.
rendererList.
TextureRenderer(state.game, 1);
this.setTexture(texture, frame);
this.setPosition(x, y);
this.setSizeToFrame();
this.setOrigin();
this.initRenderPassComponent();
}
});

View file

@ -18,7 +18,6 @@ var Text = new Class({
Components.Transform,
Components.Visible,
Components.Flip,
Components.RenderPass,
TextRender
],
@ -75,7 +74,6 @@ var Text = new Class({
{
this.updateText();
}
this.initRenderPassComponent();
},
setText: function (value)

View file

@ -50,6 +50,24 @@ var Phaser = {
Objects: require('./utils/object/'),
String: require('./utils/string/')
},
Render: {
CommandList: require('./renderer/CommandList'),
GlobalCommandList: require('./renderer/GlobalCommandList'),
WebGL: {
BaseDrawCommand: require('./renderer/webgl/commands/BaseDrawCommand'),
ClearRenderTargetCommand: require('./renderer/webgl/commands/ClearRenderTargetCommand'),
DrawCommand: require('./renderer/webgl/commands/DrawCommand'),
DrawIndexedCommand: require('./renderer/webgl/commands/DrawIndexedCommand'),
SetViewportCommand: require('./renderer/webgl/commands/SetViewportCommand'),
UpdateBufferResourceCommand: require('./renderer/webgl/commands/UpdateBufferResourceCommand')
}
}
};

View file

@ -10,7 +10,7 @@ CommandList.prototype = {
addCommand: function (command)
{
this.commandBuffer.push(command)
this.commandBuffer.push(command);
},
clearList: function ()
@ -22,7 +22,7 @@ CommandList.prototype = {
{
var commandBuffer = this.commandBuffer;
var commandCount = commandBuffer.length;
for(var inde = 0 index < commandCount; ++index)
for(var index = 0; index < commandCount; ++index)
{
commandBuffer[index].dispatch(backend);
}

View file

@ -0,0 +1,5 @@
var CommandList = require('./CommandList');
module.exports = {
commandList: new CommandList()
};

View file

@ -1,12 +1,16 @@
var RenderDevice = function (backend)
var RenderDevice = function (backendInterface, resourceManager, rendererList)
{
this.backend = backend;
this.backendInterface = backendInterface;
this.backend = backendInterface.backend;
this.commandListArray = [];
this.resourceManager = resourceManager;
this.rendererList = rendererList;
};
RenderDevice.prototype.constructor = RenderDevice;
RenderDevice.prototype = {
addCommandList: function (commandList)
{
this.commandListArray.push(commandList);
@ -21,12 +25,15 @@ RenderDevice.prototype = {
},
dispatch: function ()
{
var listCount = commandListArray.length;
var listCount = this.commandListArray.length;
var commandListArray = this.commandListArray;
var backend = this.backend;
this.backendInterface.clearScreen(0, 0, 0, 1);
for (var index = 0; index < listCount; ++index)
{
commandListArray[index].dispatch(this.backend);
commandListArray[index].dispatch(backend);
}
commandListArray.length = 0;

View file

@ -0,0 +1,17 @@
var WebGLTextureRenderer = require('./webgl/renderer/TextureRenderer');
var GlobalCommandList = require('./GlobalCommandList');
var RendererList = function (game)
{
this.TextureRenderer = null;
this.GraphicsRenderer = null;
this.BlitterRenderer = null;
if (game.config.renderType === Phaser.WEBGL)
{
this.TextureRenderer = WebGLTextureRenderer;
}
};
module.exports = RendererList;

View file

@ -0,0 +1,22 @@
// Backends Interface should map to GL calls
// It should be 1 == 1 to Canvas Backend Interface
var BackendInterface = function (backend)
{
this.backend = backend;
};
BackendInterface.prototype.constructor = BackendInterface;
BackendInterface.prototype = {
clearScreen: function (r, g, b, a)
{
var gl = this.backend;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clearColor(r, g, b, a);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DETH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
}
};
module.exports = BackendInterface;

View file

@ -1,15 +1,16 @@
var Resources = require('./resources');
var GL = require('./GL');
var ResourceCreator = function (gl)
var ResourceManager = function (gl)
{
this.gl = gl;
/* Maybe add pooling here */
this.shaderCache = {};
};
ResourceCreator.prototype.constructor = ResourceCreator;
ResourceManager.prototype.constructor = ResourceManager;
ResourceCreator.prototype = {
ResourceManager.prototype = {
createRenderTarget: function (width, height, colorBuffer, depthStencilBuffer)
{
@ -74,7 +75,7 @@ ResourceCreator.prototype = {
var gl = this.gl;
var bufferObject = gl.createBuffer();
gl.bindBuffer(target, bufferObject);
gl.bufferData(target, bufferObject, initialDataOrSize, bufferUsage);
gl.bufferData(target, initialDataOrSize, bufferUsage);
switch (target)
{
@ -114,48 +115,56 @@ ResourceCreator.prototype = {
return new Resources.Texture(texture, width, height);
},
createShaderPipeline: function (vertexShaderSource, fragmentShaderSource)
createShaderPipeline: function (shaderName, shaderSources)
{
var gl = this.gl;
var program = gl.createProgram();
var vertShader = gl.createShader(GL.VERTEX_SHADER);
var fragShader = gl.createShader(GL.FRAGMENT_SHADER);
var error;
gl.shaderSoruce(vertShader, vertexShaderSource);
gl.shaderSoruce(fragShader, fragmentShaderSource);
gl.compileShader(vertShader);
gl.compileShader(fragShader);
error = gl.getShaderInfoLog(vertShader);
if (error.length > 0)
if (!(shaderName in this.shaderCache))
{
throw new Error('Vertex Shader Compilation Error.\n' + error);
var gl = this.gl;
var program = gl.createProgram();
var vertShader = gl.createShader(GL.VERTEX_SHADER);
var fragShader = gl.createShader(GL.FRAGMENT_SHADER);
var error;
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);
}
return (this.shaderCache[shaderName] = new Resources.ShaderPipeline(gl, program, vertShader, fragShader));
}
error = gl.getShaderInfoLog(fragShader);
if (error.length > 0)
else
{
throw new Error('Fragment Shader Compilation Error.\n' + error);
return this.shaderCache[shaderName];
}
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);
}
return new Resources.ShaderPipeline(gl, program, vertShader, fragShader);
},
createOutputStage: function ()
@ -170,4 +179,4 @@ ResourceCreator.prototype = {
};
module.exports = ResourceCreator;
module.exports = ResourceManager;

View file

@ -1,4 +1,4 @@
var GL = require('../../GL');
var GL = require('../GL');
var BaseDrawCommand = function ()
{
@ -57,7 +57,7 @@ BaseDrawCommand.prototype = {
if (outputStage.enableBlending)
{
gl.enable(GL.BLEND);
gl.blendFuncSeparate(outputStage.blendSrcRGB, outputStage.blendDstRGB, outputStage.blendSrcAlpha, outputStage.blendDstAlpha);
gl.blendFuncSeparate(outputStage.blendSrcRgb, outputStage.blendDstRgb, outputStage.blendSrcAlpha, outputStage.blendDstAlpha);
gl.blendEquationSeparate(outputStage.blendEqRgb, outputStage.blendEqAlpha);
gl.blendColor(outputStage.blendRed, outputStage.blendGreen, outputStage.blendBlue, outputStage.blendAlpha)
}

View file

@ -1,4 +1,4 @@
var GL = require('../../GL');
var GL = require('../GL');
var ClearRenderTargetCommand = function ()
{

View file

@ -1,4 +1,4 @@
var GL = require('../../GL');
var GL = require('../GL');
var BaseDrawCommand = require('./BaseDrawCommand');
var DrawCommand = function ()
@ -9,66 +9,75 @@ var DrawCommand = function ()
this.vertexBuffer = null;
};
DrawCommand.prototype.constructor = DrawCommand;
DrawCommand.prototype = Object.create(BaseDrawCommand.prototype, {
setVertexBuffer: function (vertexBuffer)
setVertexBuffer:
{
this.vertexBuffer = vertexBuffer;
return this;
},
setVertexCount: function (first, vertexCount)
{
this.first = first;
this.vertexCount = vertexCount;
value: function (vertexBuffer)
{
this.vertexBuffer = vertexBuffer;
return this;
return this;
}
},
dispatch: function (backend)
setVertexCount:
{
var gl = backend;
var renderTarget = this.outputStage.renderTarget
var vertexBuffer = this.vertexBuffer;
var inputElements = vertexBuffer.inputElements;
var inputLength = inputElements.length;
gl.useProgram(this.shaderPipeline.program);
if (renderTarget !== null)
value: function (first, vertexCount)
{
gl.bindFramebuffer(GL.FRAMEBUFFER, renderTarget.framebufferObject);
this.first = first;
this.vertexCount = vertexCount;
return this;
}
else
{
gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
this.dispatchBase(backend);
},
gl.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer.bufferObject);
for (var index = 0; index < inputLength; ++index)
dispatch:
{
value: function (backend)
{
var element = inputElements[index];
if (element !== undefined && element !== null)
var gl = backend;
var renderTarget = this.outputStage.renderTarget
var vertexBuffer = this.vertexBuffer;
var inputElements = vertexBuffer.inputElements;
var inputLength = inputElements.length;
gl.useProgram(this.shaderPipeline.program);
if (renderTarget !== null)
{
gl.enableVertexAttribArray(element.index);
gl.vertexAttribPointer(
element.index,
element.size,
element.type,
element.normalized,
element.stride,
element.offset
);
gl.bindFramebuffer(GL.FRAMEBUFFER, renderTarget.framebufferObject);
}
}
else
{
gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
this.dispatchBase(backend);
gl.drawArrays(this.topology, this.first, this.vertexCount);
gl.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer.bufferObject);
for (var index = 0; index < inputLength; ++index)
{
var element = inputElements[index];
if (element !== undefined && element !== null)
{
gl.enableVertexAttribArray(element.index);
gl.vertexAttribPointer(
element.index,
element.size,
element.type,
element.normalized,
element.stride,
element.offset
);
}
}
gl.drawArrays(this.topology, this.first, this.vertexCount);
}
}
});
DrawCommand.prototype.constructor = DrawCommand;
module.exports = DrawCommand;

View file

@ -1,4 +1,4 @@
var GL = require('../../GL');
var GL = require('../GL');
var BaseDrawCommand = require('./BaseDrawCommand');
var DrawIndexedCommand = function ()
@ -32,7 +32,7 @@ DrawIndexedCommand.prototype = Object.create(BaseDrawCommand.prototype, {
this.indexCount = indexCount;
return this;
}
},
setVertexCount: function (first, vertexCount)
{

View file

@ -1,4 +1,4 @@
var GL = require('../../GL');
var GL = require('../GL');
var SetViewportCommand = function ()
{

View file

@ -1,4 +1,4 @@
var GL = require('../../GL');
var GL = require('../GL');
var UpdateBufferResourceCommand = function ()
{
@ -33,7 +33,7 @@ UpdateBufferResourceCommand.prototype = {
var bufferTarget = buffer.bufferTarget;
gl.bindBuffer(bufferTarget, buffer.bufferObject);
gl.bufferSubData(bufferTarget, this.bufferData, this.bufferDataOffset);
gl.bufferSubData(bufferTarget, this.bufferDataOffset, this.bufferData);
}
};

View file

@ -0,0 +1,221 @@
var DrawCommand = require('../commands/DrawCommand');
var UpdateBufferResourceCommand = require('../commands/UpdateBufferResourceCommand');
var TexturedAndTintedShader = require('../shaders/TexturedAndTintedShader');
var GL = require('../GL');
var TransformMatrix = require('../../../components/TransformMatrix');
var GlobalCommandList = require('../../GlobalCommandList');
var TextureRenderer = function (game, maxSprites, commandList)
{
// Vertex Structure
// ---------------------
// struct SpriteVertex {
// float32 a_position[2]; // 8 bytes
// float32 a_tex_coord[2]; // 8 bytes
// uint32 a_color; // 4 bytes
// float32 a_alpha; // 4 bytes
// };
// ---------------------
// Internal use
this.vertexSize = 24;
this.maxVertices = 6 * (maxSprites !== undefined ? maxSprites : 1);
this.vertexCount = 0;
this.bufferResource = new ArrayBuffer(this.maxVertices * this.vertexSize);
this.float32View = new Float32Array(this.bufferResource);
this.uint32View = new Uint32Array(this.bufferResource);
this.tempMatrix = new TransformMatrix();
// Save resource manager and command list
this.resourceManager = game.renderDevice.resourceManager;
this.commandList = commandList !== undefined ? commandList : GlobalCommandList.commandList;
// Resource Creation
this.drawCommand = new DrawCommand();
this.updateBufferResourceCommand = new UpdateBufferResourceCommand();
this.shaderPipeline = this.resourceManager.createShaderPipeline('TexturedAndTintedShader', TexturedAndTintedShader);
this.vertexBuffer = this.resourceManager.createBuffer(GL.ARRAY_BUFFER, this.bufferResource, GL.STREAM_DRAW);
this.outputStage = this.resourceManager.createOutputStage();
// Setup output stage
this.outputStage.enableBlending = true;
this.outputStage.setDefaultBlending();
// Vertex Attribute Definition
this.vertexBuffer.setInputElement(0, 2, GL.FLOAT, false, this.vertexSize, 0);
this.vertexBuffer.setInputElement(1, 2, GL.FLOAT, false, this.vertexSize, 8);
this.vertexBuffer.setInputElement(2, 4, GL.UNSIGNED_BYTE, true, this.vertexSize, 16);
this.vertexBuffer.setInputElement(3, 1, GL.FLOAT, false, this.vertexSize, 20);
// Draw call setup
this.drawCommand.setTopology(GL.TRIANGLES);
this.drawCommand.setShaderPipeline(this.shaderPipeline);
this.drawCommand.setOutputStage(this.outputStage);
this.drawCommand.setVertexBuffer(this.vertexBuffer);
this.drawCommand.setVertexCount(0, 0);
// Update buffer resource setup
this.updateBufferResourceCommand.setBuffer(this.vertexBuffer);
this.updateBufferResourceCommand.setBufferData(this.bufferResource, 0);
// Set Clipping Martrix
this.setClippingRect(
game.config.width * game.config.resolution,
game.config.height * game.config.resolution
);
};
TextureRenderer.prototype.constructor = TextureRenderer;
TextureRenderer.prototype = {
setClippingRect: function (w, h)
{
this.shaderPipeline.setConstantMatrix4x4(
this.shaderPipeline.getUniformLocation('u_view_matrix'),
new Float32Array([
2 / w, 0, 0, 0,
0, -2 / h, 0, 0,
0, 0, 1, 1,
-1, 1, 0, 0
])
);
},
begin: function ()
{
this.vertexCount = 0;
},
end: function ()
{
this.drawCommand.setVertexCount(0, this.vertexCount);
this.commandList.addCommand(this.updateBufferResourceCommand);
this.commandList.addCommand(this.drawCommand);
},
setTexture: function (texture)
{
this.drawCommand.setTexture(texture.source[0].glTexture, 0);
},
render: function (gameObject, camera)
{
var tempMatrix, frame, vertexBufferF32, vertexBufferU32,
vertexOffset, uvs, width, height, translateX,
translateY, scaleX, scaleY, rotation,
tempMatrixMatrix, x, y, xw, yh,
cameraMatrix, mva, sra, alpha,
mva, mvb, mvc, mvd, mve, mvf, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3,
sra, srb, src, srd, sre, srf, cma, cmb, cmc, cmd, cme, cmf;
if (this.vertexCount + 6 <= this.maxVertices)
{
tempMatrix = this.tempMatrix;
frame = gameObject.frame;
vertexBufferF32 = this.float32View;
vertexBufferU32 = this.uint32View;
vertexOffset = 0;
uvs = frame.uvs;
width = frame.width * (gameObject.flipX ? -1 : 1);
height = frame.height * (gameObject.flipY ? -1 : 1);
translateX = gameObject.x - camera.scrollX;
translateY = gameObject.y - camera.scrollY;
scaleX = gameObject.scaleX;
scaleY = gameObject.scaleY;
rotation = -gameObject.rotation;
tempMatrixMatrix = tempMatrix.matrix;
x = -gameObject.displayOriginX + frame.x + ((frame.width) * (gameObject.flipX ? 1 : 0.0));
y = -gameObject.displayOriginY + frame.y + ((frame.height) * (gameObject.flipY ? 1 : 0.0));
xw = x + width;
yh = y + height;
cameraMatrix = camera.matrix.matrix;
alpha = gameObject.alpha;
// Maybe move this function to here.
tempMatrix.applyITRS(translateX, translateY, rotation, scaleX, scaleY);
sra = tempMatrixMatrix[0];
srb = tempMatrixMatrix[1];
src = tempMatrixMatrix[2];
srd = tempMatrixMatrix[3];
sre = tempMatrixMatrix[4];
srf = tempMatrixMatrix[5];
cma = cameraMatrix[0];
cmb = cameraMatrix[1];
cmc = cameraMatrix[2];
cmd = cameraMatrix[3];
cme = cameraMatrix[4];
cmf = cameraMatrix[5];
mva = sra * cma + srb * cmc;
mvb = sra * cmb + srb * cmd;
mvc = src * cma + srd * cmc;
mvd = src * cmb + srd * cmd;
mve = sre * cma + srf * cmc + cme;
mvf = sre * cmb + srf * cmd + cmf;
tx0 = x * mva + y * mvc + mve;
ty0 = x * mvb + y * mvd + mvf;
tx1 = x * mva + yh * mvc + mve;
ty1 = x * mvb + yh * mvd + mvf;
tx2 = xw * mva + yh * mvc + mve;
ty2 = xw * mvb + yh * mvd + mvf;
tx3 = xw * mva + y * mvc + mve;
ty3 = xw * mvb + y * mvd + mvf;
vertexOffset = (this.vertexCount * this.vertexSize);
vertexBufferF32[vertexOffset++] = tx0;
vertexBufferF32[vertexOffset++] = ty0;
vertexBufferF32[vertexOffset++] = uvs.x0;
vertexBufferF32[vertexOffset++] = uvs.y0;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topLeft;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx1;
vertexBufferF32[vertexOffset++] = ty1;
vertexBufferF32[vertexOffset++] = uvs.x1;
vertexBufferF32[vertexOffset++] = uvs.y1;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomLeft;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx2;
vertexBufferF32[vertexOffset++] = ty2;
vertexBufferF32[vertexOffset++] = uvs.x2;
vertexBufferF32[vertexOffset++] = uvs.y2;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomRight;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx0;
vertexBufferF32[vertexOffset++] = ty0;
vertexBufferF32[vertexOffset++] = uvs.x0;
vertexBufferF32[vertexOffset++] = uvs.y0;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topLeft;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx2;
vertexBufferF32[vertexOffset++] = ty2;
vertexBufferF32[vertexOffset++] = uvs.x2;
vertexBufferF32[vertexOffset++] = uvs.y2;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomRight;
vertexBufferF32[vertexOffset++] = alpha;
vertexBufferF32[vertexOffset++] = tx3;
vertexBufferF32[vertexOffset++] = ty3;
vertexBufferF32[vertexOffset++] = uvs.x3;
vertexBufferF32[vertexOffset++] = uvs.y3;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topRight;
vertexBufferF32[vertexOffset++] = alpha;
this.vertexCount += 6;
return true;
}
return false;
}
};
module.exports = TextureRenderer;

View file

@ -67,7 +67,7 @@ OutputStage.prototype = {
return this;
},
setBlendFuncSeparate: function (srcRgb, srcAlpha, dstRgb, dstAlpha, eqRgb, eqAlpha)
setBlendFuncSeparate: function (srcRgb, dstRgb, srcAlpha, dstAlpha, eqRgb, eqAlpha)
{
this.blendSrcRgb = srcRgb;
this.blendSrcAlpha = srcAlpha;
@ -80,14 +80,23 @@ OutputStage.prototype = {
setDefaultBlending: function ()
{
this.setBlendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ADD);
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.ADD);
this.setBlendFunc(GL.ONE, GL.ZERO, GL.FUNC_ADD);
return this;
}
};
module.exports = OutputStage;

View file

@ -13,73 +13,73 @@ ShaderPipeline.prototype = {
getUniformLocation: function(name)
{
return this.context.getUniformLocation(this.pipeline.program, name);
return this.context.getUniformLocation(this.program, name);
},
setConstantFloat1: function(location, x)
{
this.context.useProgram(this.pipeline.program);
this.context.useProgram(this.program);
this.context.uniform1f(location, x);
return this;
},
setConstantFloat2: function(location, x, y)
{
this.context.useProgram(this.pipeline.program);
this.context.useProgram(this.program);
this.context.uniform2f(location, x, y);
return this;
},
setConstantFloat3: function(location, x, y, z) {
this.context.useProgram(this.pipeline.program);
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.pipeline.program);
this.context.useProgram(this.program);
this.context.uniform4f(location, x, y, z, w);
return this;
},
setConstantInt1: function(location, x) {
this.context.useProgram(this.pipeline.program);
this.context.useProgram(this.program);
this.context.uniform1i(location, x);
return this;
},
setConstantInt2: function(location, x, y) {
this.context.useProgram(this.pipeline.program);
this.context.useProgram(this.program);
this.context.uniform2i(location, x, y);
return this;
},
setConstantInt3: function(location, x, y, z) {
this.context.useProgram(this.pipeline.program);
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.pipeline.program);
this.context.useProgram(this.program);
this.context.uniform4i(location, x, y, z, w);
return this;
},
setConstantMatrix2x2: function(location, floatArray) {
this.context.useProgram(this.pipeline.program);
this.context.useProgram(this.program);
this.context.uniformMatrix2fv(location, false, floatArray);
return this;
},
setConstantMatrix3x3: function(location, floatArray) {
this.context.useProgram(this.pipeline.program);
this.context.useProgram(this.program);
this.context.uniformMatrix3fv(location, false, floatArray);
return this;
},
setConstantMatrix4x4: function(location, floatArray) {
this.context.useProgram(this.pipeline.program);
this.context.useProgram(this.program);
this.context.uniformMatrix4fv(location, false, floatArray);
return this;
}

View file

@ -1,5 +1,5 @@
var CONST = require('./const');
var ScaleModes = require('../renderer/ScaleModes');
//var ScaleModes = require('../renderer/ScaleModes');
var GetObjectValue = require('../utils/object/GetObjectValue');
var Settings = {
@ -42,7 +42,7 @@ var Settings = {
// State Render Settings (applies only to this State)
scaleMode: GetObjectValue(config, 'scaleMode', ScaleModes.DEFAULT),
//scaleMode: GetObjectValue(config, 'scaleMode', ScaleModes.DEFAULT),
roundPixels: GetObjectValue(config, 'roundPixels', false),
dirtyRender: GetObjectValue(config, 'dirtyRender', false),

View file

@ -141,14 +141,14 @@ Systems.prototype = {
this.state.update.call(this.state, timestep, physicsStep);
},
render: function (interpolation, renderer)
render: function (interpolation, renderDevice)
{
if (!this.settings.visible)
{
return;
}
this.cameras.render(renderer, this.children, interpolation);
this.cameras.render(renderDevice, this.children, interpolation);
}
};

View file

@ -1,4 +1,5 @@
var Camera = require('../../camera/Camera');
var GlobalCommandList = require('../../renderer/GlobalCommandList');
var CameraManager = function (state)
{
@ -84,18 +85,26 @@ CameraManager.prototype = {
}
},
render: function (renderer, children, interpolation)
render: function (renderDevice, children, interpolation)
{
var cameras = this.cameras;
for (var i = 0, l = cameras.length; i < l; ++i)
{
var camera = cameras[i];
var childCount = children.length;
var list = children.list;
camera.preRender();
renderer.render(this.state, children, interpolation, camera);
GlobalCommandList.commandList.clearList();
renderDevice.addCommandList(GlobalCommandList.commandList);
for (var childIndex = 0; childIndex < childCount; ++childIndex)
{
list[childIndex].render(camera);
}
//renderer.render(this.state, children, interpolation, camera);
renderDevice.sortCommandLists();
renderDevice.dispatch();
}
},
destroy: function ()

View file

@ -5,10 +5,10 @@
*/
var CONST = require('../const');
var ScaleModes = require('../renderer/ScaleModes');
//var ScaleModes = require('../renderer/ScaleModes');
var IsSizePowerOfTwo = require('../math/pow2/IsSizePowerOfTwo');
var CreateTexture2DFromSource = require('../renderer/webgl/utils/texture/CreateTexture2DFromSource');
//var CreateTexture2DFromSource = require('../renderer/webgl/utils/texture/CreateTexture2DFromSource');
var GL = require('../renderer/webgl/GL');
/**
*
* @class Phaser.TextureSource
@ -58,7 +58,7 @@ var TextureSource = function (texture, source)
* @type {Number}
* @default Phaser.scaleModes.DEFAULT;
*/
this.scaleMode = ScaleModes.DEFAULT;
//this.scaleMode = ScaleModes.DEFAULT;
/**
* Controls if RGB channels should be pre-multiplied by Alpha (WebGL only)
@ -124,7 +124,10 @@ var TextureSource = function (texture, source)
if (game.config.renderType === CONST.WEBGL)
{
CreateTexture2DFromSource(game.renderer.gl, this);
this.glTexture = game.
renderDevice.
resourceManager.
createTexture(0, GL.LINEAR, GL.LINEAR, GL.CLAMP_TO_EDGE, GL.CLAMP_TO_EDGE, GL.RGBA, source);
}
};