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 CanvasRenderer = require('../renderer/canvas/CanvasRenderer');
//var WebGLRenderer = require('../renderer/webgl/WebGLRenderer'); //var WebGLRenderer = require('../renderer/webgl/WebGLRenderer');
var CanvasInterpolation = require('../dom/CanvasInterpolation'); 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. * 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 CreateRenderer = function (game)
{ {
var config = game.config; var config = game.config;
var backend = null;
var resourceManager = null;
var rendererList = null;
// Game either requested Canvas, // Game either requested Canvas,
// or requested AUTO or WEBGL but the browser doesn't support it, so fall back to 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)) 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'; 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 // Create the renderer
/*if (config.renderType === CONST.WEBGL) /*if (config.renderType === CONST.WEBGL)
{ {

View file

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

View file

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

View file

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

View file

@ -1,10 +1,10 @@
var BlendModes = require('../renderer/BlendModes'); // var BlendModes = require('../renderer/BlendModes');
// BlendMode Component // BlendMode Component
var BlendMode = { var BlendMode = {
_blendMode: BlendModes.NORMAL, //_blendMode: BlendModes.NORMAL,
blendMode: { 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 // ScaleMode Component
var ScaleMode = { var ScaleMode = {
_scaleMode: ScaleModes.DEFAULT, //_scaleMode: ScaleModes.DEFAULT,
scaleMode: { scaleMode: {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -50,6 +50,24 @@ var Phaser = {
Objects: require('./utils/object/'), Objects: require('./utils/object/'),
String: require('./utils/string/') 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) addCommand: function (command)
{ {
this.commandBuffer.push(command) this.commandBuffer.push(command);
}, },
clearList: function () clearList: function ()
@ -22,7 +22,7 @@ CommandList.prototype = {
{ {
var commandBuffer = this.commandBuffer; var commandBuffer = this.commandBuffer;
var commandCount = commandBuffer.length; var commandCount = commandBuffer.length;
for(var inde = 0 index < commandCount; ++index) for(var index = 0; index < commandCount; ++index)
{ {
commandBuffer[index].dispatch(backend); 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.commandListArray = [];
this.resourceManager = resourceManager;
this.rendererList = rendererList;
}; };
RenderDevice.prototype.constructor = RenderDevice; RenderDevice.prototype.constructor = RenderDevice;
RenderDevice.prototype = { RenderDevice.prototype = {
addCommandList: function (commandList) addCommandList: function (commandList)
{ {
this.commandListArray.push(commandList); this.commandListArray.push(commandList);
@ -21,12 +25,15 @@ RenderDevice.prototype = {
}, },
dispatch: function () dispatch: function ()
{ {
var listCount = commandListArray.length; var listCount = this.commandListArray.length;
var commandListArray = this.commandListArray; var commandListArray = this.commandListArray;
var backend = this.backend;
this.backendInterface.clearScreen(0, 0, 0, 1);
for (var index = 0; index < listCount; ++index) for (var index = 0; index < listCount; ++index)
{ {
commandListArray[index].dispatch(this.backend); commandListArray[index].dispatch(backend);
} }
commandListArray.length = 0; 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 Resources = require('./resources');
var GL = require('./GL'); var GL = require('./GL');
var ResourceCreator = function (gl) var ResourceManager = function (gl)
{ {
this.gl = gl; this.gl = gl;
/* Maybe add pooling here */ /* Maybe add pooling here */
this.shaderCache = {};
}; };
ResourceCreator.prototype.constructor = ResourceCreator; ResourceManager.prototype.constructor = ResourceManager;
ResourceCreator.prototype = { ResourceManager.prototype = {
createRenderTarget: function (width, height, colorBuffer, depthStencilBuffer) createRenderTarget: function (width, height, colorBuffer, depthStencilBuffer)
{ {
@ -74,7 +75,7 @@ ResourceCreator.prototype = {
var gl = this.gl; var gl = this.gl;
var bufferObject = gl.createBuffer(); var bufferObject = gl.createBuffer();
gl.bindBuffer(target, bufferObject); gl.bindBuffer(target, bufferObject);
gl.bufferData(target, bufferObject, initialDataOrSize, bufferUsage); gl.bufferData(target, initialDataOrSize, bufferUsage);
switch (target) switch (target)
{ {
@ -114,48 +115,56 @@ ResourceCreator.prototype = {
return new Resources.Texture(texture, width, height); return new Resources.Texture(texture, width, height);
}, },
createShaderPipeline: function (vertexShaderSource, fragmentShaderSource) createShaderPipeline: function (shaderName, shaderSources)
{ {
var gl = this.gl; if (!(shaderName in this.shaderCache))
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)
{ {
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));
} }
else
error = gl.getShaderInfoLog(fragShader);
if (error.length > 0)
{ {
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 () 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 () var BaseDrawCommand = function ()
{ {
@ -57,7 +57,7 @@ BaseDrawCommand.prototype = {
if (outputStage.enableBlending) if (outputStage.enableBlending)
{ {
gl.enable(GL.BLEND); 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.blendEquationSeparate(outputStage.blendEqRgb, outputStage.blendEqAlpha);
gl.blendColor(outputStage.blendRed, outputStage.blendGreen, outputStage.blendBlue, outputStage.blendAlpha) 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 () var ClearRenderTargetCommand = function ()
{ {

View file

@ -1,4 +1,4 @@
var GL = require('../../GL'); var GL = require('../GL');
var BaseDrawCommand = require('./BaseDrawCommand'); var BaseDrawCommand = require('./BaseDrawCommand');
var DrawCommand = function () var DrawCommand = function ()
@ -9,66 +9,75 @@ var DrawCommand = function ()
this.vertexBuffer = null; this.vertexBuffer = null;
}; };
DrawCommand.prototype.constructor = DrawCommand;
DrawCommand.prototype = Object.create(BaseDrawCommand.prototype, { DrawCommand.prototype = Object.create(BaseDrawCommand.prototype, {
setVertexBuffer: function (vertexBuffer) setVertexBuffer:
{ {
this.vertexBuffer = vertexBuffer; value: function (vertexBuffer)
{
return this; this.vertexBuffer = vertexBuffer;
},
setVertexCount: function (first, vertexCount)
{
this.first = first;
this.vertexCount = vertexCount;
return this; return this;
}
}, },
dispatch: function (backend) setVertexCount:
{ {
var gl = backend; value: function (first, vertexCount)
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.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); dispatch:
{
for (var index = 0; index < inputLength; ++index) value: function (backend)
{ {
var element = inputElements[index]; var gl = backend;
if (element !== undefined && element !== null) 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.bindFramebuffer(GL.FRAMEBUFFER, renderTarget.framebufferObject);
gl.vertexAttribPointer(
element.index,
element.size,
element.type,
element.normalized,
element.stride,
element.offset
);
} }
} 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; module.exports = DrawCommand;

View file

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

View file

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

View file

@ -1,4 +1,4 @@
var GL = require('../../GL'); var GL = require('../GL');
var UpdateBufferResourceCommand = function () var UpdateBufferResourceCommand = function ()
{ {
@ -33,7 +33,7 @@ UpdateBufferResourceCommand.prototype = {
var bufferTarget = buffer.bufferTarget; var bufferTarget = buffer.bufferTarget;
gl.bindBuffer(bufferTarget, buffer.bufferObject); 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; return this;
}, },
setBlendFuncSeparate: function (srcRgb, srcAlpha, dstRgb, dstAlpha, eqRgb, eqAlpha) setBlendFuncSeparate: function (srcRgb, dstRgb, srcAlpha, dstAlpha, eqRgb, eqAlpha)
{ {
this.blendSrcRgb = srcRgb; this.blendSrcRgb = srcRgb;
this.blendSrcAlpha = srcAlpha; this.blendSrcAlpha = srcAlpha;
@ -80,14 +80,23 @@ OutputStage.prototype = {
setDefaultBlending: function () 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; return this;
}, },
setNoBlending: function () setNoBlending: function ()
{ {
this.setBlendFunc(GL.ONE, GL.ZERO, GL.ADD); this.setBlendFunc(GL.ONE, GL.ZERO, GL.FUNC_ADD);
return this; return this;
} }
}; };
module.exports = OutputStage;

View file

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

View file

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

View file

@ -141,14 +141,14 @@ Systems.prototype = {
this.state.update.call(this.state, timestep, physicsStep); this.state.update.call(this.state, timestep, physicsStep);
}, },
render: function (interpolation, renderer) render: function (interpolation, renderDevice)
{ {
if (!this.settings.visible) if (!this.settings.visible)
{ {
return; 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 Camera = require('../../camera/Camera');
var GlobalCommandList = require('../../renderer/GlobalCommandList');
var CameraManager = function (state) var CameraManager = function (state)
{ {
@ -84,18 +85,26 @@ CameraManager.prototype = {
} }
}, },
render: function (renderer, children, interpolation) render: function (renderDevice, children, interpolation)
{ {
var cameras = this.cameras; var cameras = this.cameras;
for (var i = 0, l = cameras.length; i < l; ++i) for (var i = 0, l = cameras.length; i < l; ++i)
{ {
var camera = cameras[i]; var camera = cameras[i];
var childCount = children.length;
var list = children.list;
camera.preRender(); camera.preRender();
GlobalCommandList.commandList.clearList();
renderer.render(this.state, children, interpolation, camera); 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 () destroy: function ()

View file

@ -5,10 +5,10 @@
*/ */
var CONST = require('../const'); var CONST = require('../const');
var ScaleModes = require('../renderer/ScaleModes'); //var ScaleModes = require('../renderer/ScaleModes');
var IsSizePowerOfTwo = require('../math/pow2/IsSizePowerOfTwo'); 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 * @class Phaser.TextureSource
@ -58,7 +58,7 @@ var TextureSource = function (texture, source)
* @type {Number} * @type {Number}
* @default Phaser.scaleModes.DEFAULT; * @default Phaser.scaleModes.DEFAULT;
*/ */
this.scaleMode = ScaleModes.DEFAULT; //this.scaleMode = ScaleModes.DEFAULT;
/** /**
* Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) * 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) 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);
} }
}; };