diff --git a/v3/src/boot/CreateRenderer.js b/v3/src/boot/CreateRenderer.js index c0201ebf2..05b8848fa 100644 --- a/v3/src/boot/CreateRenderer.js +++ b/v3/src/boot/CreateRenderer.js @@ -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) { diff --git a/v3/src/boot/Game.js b/v3/src/boot/Game.js index cf6f525bb..f1332012b 100644 --- a/v3/src/boot/Game.js +++ b/v3/src/boot/Game.js @@ -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; diff --git a/v3/src/boot/MainLoop.js b/v3/src/boot/MainLoop.js index 734b03a0f..129a8fb0e 100644 --- a/v3/src/boot/MainLoop.js +++ b/v3/src/boot/MainLoop.js @@ -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) { diff --git a/v3/src/checksum.js b/v3/src/checksum.js index c3869cca6..e79586963 100644 --- a/v3/src/checksum.js +++ b/v3/src/checksum.js @@ -1,4 +1,4 @@ var CHECKSUM = { -build: '02229ca0-1488-11e7-8e2a-13177b968951' +build: 'aac3ab90-18ef-11e7-b3fd-71ae0f91d1c8' }; module.exports = CHECKSUM; \ No newline at end of file diff --git a/v3/src/components/BlendMode.js b/v3/src/components/BlendMode.js index 5f76009c4..8009c18cd 100644 --- a/v3/src/components/BlendMode.js +++ b/v3/src/components/BlendMode.js @@ -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: { diff --git a/v3/src/components/Render.js b/v3/src/components/Render.js new file mode 100644 index 000000000..2c9afa566 --- /dev/null +++ b/v3/src/components/Render.js @@ -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; diff --git a/v3/src/components/RenderPass.js b/v3/src/components/RenderPass.js deleted file mode 100644 index bd7c3c642..000000000 --- a/v3/src/components/RenderPass.js +++ /dev/null @@ -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; diff --git a/v3/src/components/ScaleMode.js b/v3/src/components/ScaleMode.js index b40add79e..65d5df93c 100644 --- a/v3/src/components/ScaleMode.js +++ b/v3/src/components/ScaleMode.js @@ -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: { diff --git a/v3/src/components/index.js b/v3/src/components/index.js index 9e0b46af5..f565d4848 100644 --- a/v3/src/components/index.js +++ b/v3/src/components/index.js @@ -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'), diff --git a/v3/src/gameobjects/bitmaptext/dynamic/DynamicBitmapText.js b/v3/src/gameobjects/bitmaptext/dynamic/DynamicBitmapText.js index fb52c7bc2..c7eca6f6f 100644 --- a/v3/src/gameobjects/bitmaptext/dynamic/DynamicBitmapText.js +++ b/v3/src/gameobjects/bitmaptext/dynamic/DynamicBitmapText.js @@ -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) diff --git a/v3/src/gameobjects/bitmaptext/static/BitmapText.js b/v3/src/gameobjects/bitmaptext/static/BitmapText.js index 699eb32db..3cc4139e2 100644 --- a/v3/src/gameobjects/bitmaptext/static/BitmapText.js +++ b/v3/src/gameobjects/bitmaptext/static/BitmapText.js @@ -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) diff --git a/v3/src/gameobjects/blitter/Blitter.js b/v3/src/gameobjects/blitter/Blitter.js index 7b743cfc9..a18006a09 100644 --- a/v3/src/gameobjects/blitter/Blitter.js +++ b/v3/src/gameobjects/blitter/Blitter.js @@ -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 diff --git a/v3/src/gameobjects/graphics/Graphics.js b/v3/src/gameobjects/graphics/Graphics.js index b7fd7b6bc..c73ede914 100644 --- a/v3/src/gameobjects/graphics/Graphics.js +++ b/v3/src/gameobjects/graphics/Graphics.js @@ -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; diff --git a/v3/src/gameobjects/image/Image.js b/v3/src/gameobjects/image/Image.js index c62a742eb..6b8127a22 100644 --- a/v3/src/gameobjects/image/Image.js +++ b/v3/src/gameobjects/image/Image.js @@ -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(); } }); diff --git a/v3/src/gameobjects/text/static/Text.js b/v3/src/gameobjects/text/static/Text.js index 8eac0478a..b58d8da73 100644 --- a/v3/src/gameobjects/text/static/Text.js +++ b/v3/src/gameobjects/text/static/Text.js @@ -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) diff --git a/v3/src/phaser.js b/v3/src/phaser.js index 9d3f266ae..0d4145b39 100644 --- a/v3/src/phaser.js +++ b/v3/src/phaser.js @@ -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') + + } + } }; diff --git a/v3/src/renderer/CommandList.js b/v3/src/renderer/CommandList.js index eade77ceb..991d73ea7 100644 --- a/v3/src/renderer/CommandList.js +++ b/v3/src/renderer/CommandList.js @@ -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); } diff --git a/v3/src/renderer/GlobalCommandList.js b/v3/src/renderer/GlobalCommandList.js new file mode 100644 index 000000000..35b757795 --- /dev/null +++ b/v3/src/renderer/GlobalCommandList.js @@ -0,0 +1,5 @@ +var CommandList = require('./CommandList'); + +module.exports = { + commandList: new CommandList() +}; diff --git a/v3/src/renderer/RenderDevice.js b/v3/src/renderer/RenderDevice.js index 64c8230c7..0ca76664c 100644 --- a/v3/src/renderer/RenderDevice.js +++ b/v3/src/renderer/RenderDevice.js @@ -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; diff --git a/v3/src/renderer/RendererList.js b/v3/src/renderer/RendererList.js new file mode 100644 index 000000000..9f5cd36fd --- /dev/null +++ b/v3/src/renderer/RendererList.js @@ -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; diff --git a/v3/src/renderer/webgl/BackendInterface.js b/v3/src/renderer/webgl/BackendInterface.js new file mode 100644 index 000000000..5831bbec1 --- /dev/null +++ b/v3/src/renderer/webgl/BackendInterface.js @@ -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; diff --git a/v3/src/renderer/webgl/ResourceCreator.js b/v3/src/renderer/webgl/ResourceManager.js similarity index 70% rename from v3/src/renderer/webgl/ResourceCreator.js rename to v3/src/renderer/webgl/ResourceManager.js index 084fe1c61..d7f8bd0a0 100644 --- a/v3/src/renderer/webgl/ResourceCreator.js +++ b/v3/src/renderer/webgl/ResourceManager.js @@ -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; diff --git a/v3/src/renderer/webgl/commands/BaseDrawCommand.js b/v3/src/renderer/webgl/commands/BaseDrawCommand.js index abff5706f..1b0fae97a 100644 --- a/v3/src/renderer/webgl/commands/BaseDrawCommand.js +++ b/v3/src/renderer/webgl/commands/BaseDrawCommand.js @@ -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) } diff --git a/v3/src/renderer/webgl/commands/ClearRenderTargetCommand.js b/v3/src/renderer/webgl/commands/ClearRenderTargetCommand.js index ef6198b83..22424a9b7 100644 --- a/v3/src/renderer/webgl/commands/ClearRenderTargetCommand.js +++ b/v3/src/renderer/webgl/commands/ClearRenderTargetCommand.js @@ -1,4 +1,4 @@ -var GL = require('../../GL'); +var GL = require('../GL'); var ClearRenderTargetCommand = function () { diff --git a/v3/src/renderer/webgl/commands/DrawCommand.js b/v3/src/renderer/webgl/commands/DrawCommand.js index 9550264ea..5f28f68c6 100644 --- a/v3/src/renderer/webgl/commands/DrawCommand.js +++ b/v3/src/renderer/webgl/commands/DrawCommand.js @@ -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; diff --git a/v3/src/renderer/webgl/commands/DrawIndexedCommand.js b/v3/src/renderer/webgl/commands/DrawIndexedCommand.js index 3956b64a9..b078a7cab 100644 --- a/v3/src/renderer/webgl/commands/DrawIndexedCommand.js +++ b/v3/src/renderer/webgl/commands/DrawIndexedCommand.js @@ -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) { diff --git a/v3/src/renderer/webgl/commands/SetViewportCommand.js b/v3/src/renderer/webgl/commands/SetViewportCommand.js index a892907b8..f0aaed82e 100644 --- a/v3/src/renderer/webgl/commands/SetViewportCommand.js +++ b/v3/src/renderer/webgl/commands/SetViewportCommand.js @@ -1,4 +1,4 @@ -var GL = require('../../GL'); +var GL = require('../GL'); var SetViewportCommand = function () { diff --git a/v3/src/renderer/webgl/commands/UpdateBufferResourceCommand.js b/v3/src/renderer/webgl/commands/UpdateBufferResourceCommand.js index bc3b5ce63..b6f801b7d 100644 --- a/v3/src/renderer/webgl/commands/UpdateBufferResourceCommand.js +++ b/v3/src/renderer/webgl/commands/UpdateBufferResourceCommand.js @@ -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); } }; diff --git a/v3/src/renderer/webgl/renderer/TextureRenderer.js b/v3/src/renderer/webgl/renderer/TextureRenderer.js new file mode 100644 index 000000000..9f6420895 --- /dev/null +++ b/v3/src/renderer/webgl/renderer/TextureRenderer.js @@ -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; diff --git a/v3/src/renderer/webgl/resources/OutputStage.js b/v3/src/renderer/webgl/resources/OutputStage.js index 22276d72a..081a77979 100644 --- a/v3/src/renderer/webgl/resources/OutputStage.js +++ b/v3/src/renderer/webgl/resources/OutputStage.js @@ -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; diff --git a/v3/src/renderer/webgl/resources/ShaderPipeline.js b/v3/src/renderer/webgl/resources/ShaderPipeline.js index 101367b4a..509800801 100644 --- a/v3/src/renderer/webgl/resources/ShaderPipeline.js +++ b/v3/src/renderer/webgl/resources/ShaderPipeline.js @@ -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; } diff --git a/v3/src/state/Settings.js b/v3/src/state/Settings.js index 8a7626cc2..82d2cf7f2 100644 --- a/v3/src/state/Settings.js +++ b/v3/src/state/Settings.js @@ -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), diff --git a/v3/src/state/Systems.js b/v3/src/state/Systems.js index 7db13ab96..964fa6ec8 100644 --- a/v3/src/state/Systems.js +++ b/v3/src/state/Systems.js @@ -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); } }; diff --git a/v3/src/state/systems/CameraManager.js b/v3/src/state/systems/CameraManager.js index 618888c73..c8b22292b 100644 --- a/v3/src/state/systems/CameraManager.js +++ b/v3/src/state/systems/CameraManager.js @@ -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 () diff --git a/v3/src/textures/TextureSource.js b/v3/src/textures/TextureSource.js index 5fb0b0082..33974442f 100644 --- a/v3/src/textures/TextureSource.js +++ b/v3/src/textures/TextureSource.js @@ -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); } };