diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index efd936a..d0ef80c 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -91,7 +91,8 @@ * * @member {PIXI.ObjectRenderer} */ - this.currentRenderer = new ObjectRenderer(this); + this.emptyRenderer = new ObjectRenderer(this); + this.currentRenderer = this.emptyRenderer; this.initPlugins(); @@ -227,6 +228,16 @@ }; /** + * This shoudl be called if you wish to do some custom rendering + * It will basically render anything that may be batched up such as sprites + * + */ +WebGLRenderer.prototype.flush = function () +{ + this.setObjectRenderer(this.emptyRenderer) +} + +/** * Resizes the webGL view to the specified width and height. * * @param width {number} the new width of the webGL view diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index efd936a..d0ef80c 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -91,7 +91,8 @@ * * @member {PIXI.ObjectRenderer} */ - this.currentRenderer = new ObjectRenderer(this); + this.emptyRenderer = new ObjectRenderer(this); + this.currentRenderer = this.emptyRenderer; this.initPlugins(); @@ -227,6 +228,16 @@ }; /** + * This shoudl be called if you wish to do some custom rendering + * It will basically render anything that may be batched up such as sprites + * + */ +WebGLRenderer.prototype.flush = function () +{ + this.setObjectRenderer(this.emptyRenderer) +} + +/** * Resizes the webGL view to the specified width and height. * * @param width {number} the new width of the webGL view diff --git a/src/index.js b/src/index.js index cd1d14b..aa515c8 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ core.filters = require('./filters'); core.interaction = require('./interaction'); core.loaders = require('./loaders'); -//core.mesh = require('./mesh'); +core.mesh = require('./mesh'); core.accessibility = require('./accessibility'); // export a premade loader instance diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index efd936a..d0ef80c 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -91,7 +91,8 @@ * * @member {PIXI.ObjectRenderer} */ - this.currentRenderer = new ObjectRenderer(this); + this.emptyRenderer = new ObjectRenderer(this); + this.currentRenderer = this.emptyRenderer; this.initPlugins(); @@ -227,6 +228,16 @@ }; /** + * This shoudl be called if you wish to do some custom rendering + * It will basically render anything that may be batched up such as sprites + * + */ +WebGLRenderer.prototype.flush = function () +{ + this.setObjectRenderer(this.emptyRenderer) +} + +/** * Resizes the webGL view to the specified width and height. * * @param width {number} the new width of the webGL view diff --git a/src/index.js b/src/index.js index cd1d14b..aa515c8 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ core.filters = require('./filters'); core.interaction = require('./interaction'); core.loaders = require('./loaders'); -//core.mesh = require('./mesh'); +core.mesh = require('./mesh'); core.accessibility = require('./accessibility'); // export a premade loader instance diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index b9edfe3..38104bc 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -1,4 +1,6 @@ var core = require('../core'), + glCore = require('pixi-gl-core'), + Shader = require('./webgl/MeshShader'), tempPoint = new core.Point(), tempPolygon = new core.Polygon(); @@ -91,6 +93,8 @@ * @member {PIXI.Shader} */ this.shader = null; + + this._glDatas = []; } // constructor @@ -143,8 +147,53 @@ */ Mesh.prototype._renderWebGL = function (renderer) { - renderer.setObjectRenderer(renderer.plugins.mesh); - renderer.plugins.mesh.render(this); + // get rid of any thing that may be batching. + renderer.flush(); + + // renderer.plugins.mesh.render(this); + var gl = renderer.gl; + var glData = this._glDatas[renderer.CONTEXT_UID]; + + if(!glData) + { + glData = { + shader:new Shader(gl), + vertexBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.vertices, gl.STREAM_DRAW), + uvBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.uvs, gl.STREAM_DRAW), + indexBuffer:glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW), + // build the vao object that will render.. + vao:new glCore.VertexArrayObject(gl) + } + + // build the vao object that will render.. + glData.vao = new glCore.VertexArrayObject(gl) + .addIndex(glData.indexBuffer) + .addAttribute(glData.vertexBuffer, glData.shader.attributes.aVertexPosition, gl.FLOAT, false, 2 * 4, 0) + .addAttribute(glData.uvBuffer, glData.shader.attributes.aTextureCoord, gl.FLOAT, false, 2 * 4, 0) + + this._glDatas[renderer.CONTEXT_UID] = glData; + } + + if(this.dirty) + { + this.dirty = false; + glData.uvBuffer.upload(); + } + + glData.vertexBuffer.upload(); + + renderer.bindShader(glData.shader); + renderer.bindTexture(this._texture, 0); + + glData.shader.uniforms.translationMatrix = this.worldTransform.toArray(true); + glData.shader.uniforms.alpha = this.worldAlpha; + + var drawMode = this.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; + + + glData.vao.bind() + .draw(drawMode, this.indices.length) + .unbind(); }; /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index efd936a..d0ef80c 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -91,7 +91,8 @@ * * @member {PIXI.ObjectRenderer} */ - this.currentRenderer = new ObjectRenderer(this); + this.emptyRenderer = new ObjectRenderer(this); + this.currentRenderer = this.emptyRenderer; this.initPlugins(); @@ -227,6 +228,16 @@ }; /** + * This shoudl be called if you wish to do some custom rendering + * It will basically render anything that may be batched up such as sprites + * + */ +WebGLRenderer.prototype.flush = function () +{ + this.setObjectRenderer(this.emptyRenderer) +} + +/** * Resizes the webGL view to the specified width and height. * * @param width {number} the new width of the webGL view diff --git a/src/index.js b/src/index.js index cd1d14b..aa515c8 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ core.filters = require('./filters'); core.interaction = require('./interaction'); core.loaders = require('./loaders'); -//core.mesh = require('./mesh'); +core.mesh = require('./mesh'); core.accessibility = require('./accessibility'); // export a premade loader instance diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index b9edfe3..38104bc 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -1,4 +1,6 @@ var core = require('../core'), + glCore = require('pixi-gl-core'), + Shader = require('./webgl/MeshShader'), tempPoint = new core.Point(), tempPolygon = new core.Polygon(); @@ -91,6 +93,8 @@ * @member {PIXI.Shader} */ this.shader = null; + + this._glDatas = []; } // constructor @@ -143,8 +147,53 @@ */ Mesh.prototype._renderWebGL = function (renderer) { - renderer.setObjectRenderer(renderer.plugins.mesh); - renderer.plugins.mesh.render(this); + // get rid of any thing that may be batching. + renderer.flush(); + + // renderer.plugins.mesh.render(this); + var gl = renderer.gl; + var glData = this._glDatas[renderer.CONTEXT_UID]; + + if(!glData) + { + glData = { + shader:new Shader(gl), + vertexBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.vertices, gl.STREAM_DRAW), + uvBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.uvs, gl.STREAM_DRAW), + indexBuffer:glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW), + // build the vao object that will render.. + vao:new glCore.VertexArrayObject(gl) + } + + // build the vao object that will render.. + glData.vao = new glCore.VertexArrayObject(gl) + .addIndex(glData.indexBuffer) + .addAttribute(glData.vertexBuffer, glData.shader.attributes.aVertexPosition, gl.FLOAT, false, 2 * 4, 0) + .addAttribute(glData.uvBuffer, glData.shader.attributes.aTextureCoord, gl.FLOAT, false, 2 * 4, 0) + + this._glDatas[renderer.CONTEXT_UID] = glData; + } + + if(this.dirty) + { + this.dirty = false; + glData.uvBuffer.upload(); + } + + glData.vertexBuffer.upload(); + + renderer.bindShader(glData.shader); + renderer.bindTexture(this._texture, 0); + + glData.shader.uniforms.translationMatrix = this.worldTransform.toArray(true); + glData.shader.uniforms.alpha = this.worldAlpha; + + var drawMode = this.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; + + + glData.vao.bind() + .draw(drawMode, this.indices.length) + .unbind(); }; /** diff --git a/src/mesh/index.js b/src/mesh/index.js index 38a3f41..5328159 100644 --- a/src/mesh/index.js +++ b/src/mesh/index.js @@ -12,6 +12,5 @@ Mesh: require('./Mesh'), Plane: require('./Plane'), Rope: require('./Rope'), - MeshRenderer: require('./webgl/MeshRenderer'), MeshShader: require('./webgl/MeshShader') }; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index efd936a..d0ef80c 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -91,7 +91,8 @@ * * @member {PIXI.ObjectRenderer} */ - this.currentRenderer = new ObjectRenderer(this); + this.emptyRenderer = new ObjectRenderer(this); + this.currentRenderer = this.emptyRenderer; this.initPlugins(); @@ -227,6 +228,16 @@ }; /** + * This shoudl be called if you wish to do some custom rendering + * It will basically render anything that may be batched up such as sprites + * + */ +WebGLRenderer.prototype.flush = function () +{ + this.setObjectRenderer(this.emptyRenderer) +} + +/** * Resizes the webGL view to the specified width and height. * * @param width {number} the new width of the webGL view diff --git a/src/index.js b/src/index.js index cd1d14b..aa515c8 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ core.filters = require('./filters'); core.interaction = require('./interaction'); core.loaders = require('./loaders'); -//core.mesh = require('./mesh'); +core.mesh = require('./mesh'); core.accessibility = require('./accessibility'); // export a premade loader instance diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index b9edfe3..38104bc 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -1,4 +1,6 @@ var core = require('../core'), + glCore = require('pixi-gl-core'), + Shader = require('./webgl/MeshShader'), tempPoint = new core.Point(), tempPolygon = new core.Polygon(); @@ -91,6 +93,8 @@ * @member {PIXI.Shader} */ this.shader = null; + + this._glDatas = []; } // constructor @@ -143,8 +147,53 @@ */ Mesh.prototype._renderWebGL = function (renderer) { - renderer.setObjectRenderer(renderer.plugins.mesh); - renderer.plugins.mesh.render(this); + // get rid of any thing that may be batching. + renderer.flush(); + + // renderer.plugins.mesh.render(this); + var gl = renderer.gl; + var glData = this._glDatas[renderer.CONTEXT_UID]; + + if(!glData) + { + glData = { + shader:new Shader(gl), + vertexBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.vertices, gl.STREAM_DRAW), + uvBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.uvs, gl.STREAM_DRAW), + indexBuffer:glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW), + // build the vao object that will render.. + vao:new glCore.VertexArrayObject(gl) + } + + // build the vao object that will render.. + glData.vao = new glCore.VertexArrayObject(gl) + .addIndex(glData.indexBuffer) + .addAttribute(glData.vertexBuffer, glData.shader.attributes.aVertexPosition, gl.FLOAT, false, 2 * 4, 0) + .addAttribute(glData.uvBuffer, glData.shader.attributes.aTextureCoord, gl.FLOAT, false, 2 * 4, 0) + + this._glDatas[renderer.CONTEXT_UID] = glData; + } + + if(this.dirty) + { + this.dirty = false; + glData.uvBuffer.upload(); + } + + glData.vertexBuffer.upload(); + + renderer.bindShader(glData.shader); + renderer.bindTexture(this._texture, 0); + + glData.shader.uniforms.translationMatrix = this.worldTransform.toArray(true); + glData.shader.uniforms.alpha = this.worldAlpha; + + var drawMode = this.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; + + + glData.vao.bind() + .draw(drawMode, this.indices.length) + .unbind(); }; /** diff --git a/src/mesh/index.js b/src/mesh/index.js index 38a3f41..5328159 100644 --- a/src/mesh/index.js +++ b/src/mesh/index.js @@ -12,6 +12,5 @@ Mesh: require('./Mesh'), Plane: require('./Plane'), Rope: require('./Rope'), - MeshRenderer: require('./webgl/MeshRenderer'), MeshShader: require('./webgl/MeshShader') }; diff --git a/src/mesh/webgl/MeshRenderer.js b/src/mesh/webgl/MeshRenderer.js deleted file mode 100644 index 328a1bd..0000000 --- a/src/mesh/webgl/MeshRenderer.js +++ /dev/null @@ -1,227 +0,0 @@ -var core = require('../../core'), - Mesh = require('../Mesh'); - -/** - * @author Mat Groves - * - * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/ - * for creating the original pixi version! - * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer - * - * Heavily inspired by LibGDX's MeshRenderer: - * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/MeshRenderer.java - */ - -/** - * - * @class - * @private - * @memberof PIXI.mesh - * @extends PIXI.ObjectRenderer - * @param renderer {PIXI.WebGLRenderer} The renderer this sprite batch works for. - */ -function MeshRenderer(renderer) -{ - core.ObjectRenderer.call(this, renderer); - - - /** - * Holds the indices - * - * @member {Uint16Array} - */ - - this.indices = new Uint16Array(15000); - - //TODO this could be a single buffer shared amongst all renderers as we reuse this set up in most renderers - for (var i=0, j=0; i < 15000; i += 6, j += 4) - { - this.indices[i + 0] = j + 0; - this.indices[i + 1] = j + 1; - this.indices[i + 2] = j + 2; - this.indices[i + 3] = j + 0; - this.indices[i + 4] = j + 2; - this.indices[i + 5] = j + 3; - } - - this.currentShader = null; -} - -MeshRenderer.prototype = Object.create(core.ObjectRenderer.prototype); -MeshRenderer.prototype.constructor = MeshRenderer; -module.exports = MeshRenderer; - -core.WebGLRenderer.registerPlugin('mesh', MeshRenderer); - -/** - * Sets up the renderer context and necessary buffers. - * - * @private - * @param gl {WebGLRenderingContext} the current WebGL drawing context - */ -MeshRenderer.prototype.onContextChange = function () -{ - -}; - -/** - * Renders the sprite object. - * - * @param mesh {PIXI.mesh.Mesh} the mesh to render - */ -MeshRenderer.prototype.render = function (mesh) -{ - if(!mesh._vertexBuffer) - { - this._initWebGL(mesh); - } - - var renderer = this.renderer, - gl = renderer.gl, - texture = mesh._texture.baseTexture, - shader = mesh.shader;// || renderer.shaderManager.plugins.meshShader; - - var drawMode = mesh.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; - - renderer.blendModeManager.setBlendMode(mesh.blendMode); - - //TODO cache custom state.. - if (!shader) - { - shader = renderer.shaderManager.plugins.meshShader; - } - else - { - shader = shader.shaders[renderer.CONTEXT_UID] || shader.getShader(renderer);// : shader; - } - - this.renderer.shaderManager.setShader(shader); - - shader.uniforms.translationMatrix.value = mesh.worldTransform.toArray(true); - shader.uniforms.projectionMatrix.value = renderer.currentRenderTarget.projectionMatrix.toArray(true); - shader.uniforms.alpha.value = mesh.worldAlpha; - - shader.syncUniforms(); - - if (!mesh.dirty) - { - - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, mesh.vertices); - gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer); - gl.vertexAttribPointer(shader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - - gl.activeTexture(gl.TEXTURE0); - - if (!texture._glTextures[renderer.CONTEXT_UID]) - { - this.renderer.updateTexture(texture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[renderer.CONTEXT_UID]); - } - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer); - gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, mesh.indices); - } - else - { - - mesh.dirty = false; - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.vertices, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.uvs, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.activeTexture(gl.TEXTURE0); - - if (!texture._glTextures[renderer.CONTEXT_UID]) - { - this.renderer.updateTexture(texture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[renderer.CONTEXT_UID]); - } - - // dont need to upload! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, mesh.indices, gl.STATIC_DRAW); - - } - - gl.drawElements(drawMode, mesh.indices.length, gl.UNSIGNED_SHORT, 0); - -}; - -/** - * Prepares all the buffers to render this mesh - * @param mesh {PIXI.mesh.Mesh} the mesh to render - */ -MeshRenderer.prototype._initWebGL = function (mesh) -{ - // build the strip! - var gl = this.renderer.gl; - - mesh._vertexBuffer = gl.createBuffer(); - mesh._indexBuffer = gl.createBuffer(); - mesh._uvBuffer = gl.createBuffer(); - - - - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.vertices, gl.STREAM_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.uvs, gl.STATIC_DRAW); - - if(mesh.colors){ - mesh._colorBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.colors, gl.STATIC_DRAW); - } - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, mesh.indices, gl.STATIC_DRAW); -}; - - -/** - * Empties the current batch. - * - */ -MeshRenderer.prototype.flush = function () -{ - -}; - -/** - * Starts a new mesh renderer. - * - */ -MeshRenderer.prototype.start = function () -{ - - - this.currentShader = null; -}; - -/** - * Destroys the Mesh renderer - * - */ -MeshRenderer.prototype.destroy = function () -{ - core.ObjectRenderer.prototype.destroy.call(this); -}; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index efd936a..d0ef80c 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -91,7 +91,8 @@ * * @member {PIXI.ObjectRenderer} */ - this.currentRenderer = new ObjectRenderer(this); + this.emptyRenderer = new ObjectRenderer(this); + this.currentRenderer = this.emptyRenderer; this.initPlugins(); @@ -227,6 +228,16 @@ }; /** + * This shoudl be called if you wish to do some custom rendering + * It will basically render anything that may be batched up such as sprites + * + */ +WebGLRenderer.prototype.flush = function () +{ + this.setObjectRenderer(this.emptyRenderer) +} + +/** * Resizes the webGL view to the specified width and height. * * @param width {number} the new width of the webGL view diff --git a/src/index.js b/src/index.js index cd1d14b..aa515c8 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ core.filters = require('./filters'); core.interaction = require('./interaction'); core.loaders = require('./loaders'); -//core.mesh = require('./mesh'); +core.mesh = require('./mesh'); core.accessibility = require('./accessibility'); // export a premade loader instance diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index b9edfe3..38104bc 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -1,4 +1,6 @@ var core = require('../core'), + glCore = require('pixi-gl-core'), + Shader = require('./webgl/MeshShader'), tempPoint = new core.Point(), tempPolygon = new core.Polygon(); @@ -91,6 +93,8 @@ * @member {PIXI.Shader} */ this.shader = null; + + this._glDatas = []; } // constructor @@ -143,8 +147,53 @@ */ Mesh.prototype._renderWebGL = function (renderer) { - renderer.setObjectRenderer(renderer.plugins.mesh); - renderer.plugins.mesh.render(this); + // get rid of any thing that may be batching. + renderer.flush(); + + // renderer.plugins.mesh.render(this); + var gl = renderer.gl; + var glData = this._glDatas[renderer.CONTEXT_UID]; + + if(!glData) + { + glData = { + shader:new Shader(gl), + vertexBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.vertices, gl.STREAM_DRAW), + uvBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.uvs, gl.STREAM_DRAW), + indexBuffer:glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW), + // build the vao object that will render.. + vao:new glCore.VertexArrayObject(gl) + } + + // build the vao object that will render.. + glData.vao = new glCore.VertexArrayObject(gl) + .addIndex(glData.indexBuffer) + .addAttribute(glData.vertexBuffer, glData.shader.attributes.aVertexPosition, gl.FLOAT, false, 2 * 4, 0) + .addAttribute(glData.uvBuffer, glData.shader.attributes.aTextureCoord, gl.FLOAT, false, 2 * 4, 0) + + this._glDatas[renderer.CONTEXT_UID] = glData; + } + + if(this.dirty) + { + this.dirty = false; + glData.uvBuffer.upload(); + } + + glData.vertexBuffer.upload(); + + renderer.bindShader(glData.shader); + renderer.bindTexture(this._texture, 0); + + glData.shader.uniforms.translationMatrix = this.worldTransform.toArray(true); + glData.shader.uniforms.alpha = this.worldAlpha; + + var drawMode = this.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; + + + glData.vao.bind() + .draw(drawMode, this.indices.length) + .unbind(); }; /** diff --git a/src/mesh/index.js b/src/mesh/index.js index 38a3f41..5328159 100644 --- a/src/mesh/index.js +++ b/src/mesh/index.js @@ -12,6 +12,5 @@ Mesh: require('./Mesh'), Plane: require('./Plane'), Rope: require('./Rope'), - MeshRenderer: require('./webgl/MeshRenderer'), MeshShader: require('./webgl/MeshShader') }; diff --git a/src/mesh/webgl/MeshRenderer.js b/src/mesh/webgl/MeshRenderer.js deleted file mode 100644 index 328a1bd..0000000 --- a/src/mesh/webgl/MeshRenderer.js +++ /dev/null @@ -1,227 +0,0 @@ -var core = require('../../core'), - Mesh = require('../Mesh'); - -/** - * @author Mat Groves - * - * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/ - * for creating the original pixi version! - * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer - * - * Heavily inspired by LibGDX's MeshRenderer: - * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/MeshRenderer.java - */ - -/** - * - * @class - * @private - * @memberof PIXI.mesh - * @extends PIXI.ObjectRenderer - * @param renderer {PIXI.WebGLRenderer} The renderer this sprite batch works for. - */ -function MeshRenderer(renderer) -{ - core.ObjectRenderer.call(this, renderer); - - - /** - * Holds the indices - * - * @member {Uint16Array} - */ - - this.indices = new Uint16Array(15000); - - //TODO this could be a single buffer shared amongst all renderers as we reuse this set up in most renderers - for (var i=0, j=0; i < 15000; i += 6, j += 4) - { - this.indices[i + 0] = j + 0; - this.indices[i + 1] = j + 1; - this.indices[i + 2] = j + 2; - this.indices[i + 3] = j + 0; - this.indices[i + 4] = j + 2; - this.indices[i + 5] = j + 3; - } - - this.currentShader = null; -} - -MeshRenderer.prototype = Object.create(core.ObjectRenderer.prototype); -MeshRenderer.prototype.constructor = MeshRenderer; -module.exports = MeshRenderer; - -core.WebGLRenderer.registerPlugin('mesh', MeshRenderer); - -/** - * Sets up the renderer context and necessary buffers. - * - * @private - * @param gl {WebGLRenderingContext} the current WebGL drawing context - */ -MeshRenderer.prototype.onContextChange = function () -{ - -}; - -/** - * Renders the sprite object. - * - * @param mesh {PIXI.mesh.Mesh} the mesh to render - */ -MeshRenderer.prototype.render = function (mesh) -{ - if(!mesh._vertexBuffer) - { - this._initWebGL(mesh); - } - - var renderer = this.renderer, - gl = renderer.gl, - texture = mesh._texture.baseTexture, - shader = mesh.shader;// || renderer.shaderManager.plugins.meshShader; - - var drawMode = mesh.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; - - renderer.blendModeManager.setBlendMode(mesh.blendMode); - - //TODO cache custom state.. - if (!shader) - { - shader = renderer.shaderManager.plugins.meshShader; - } - else - { - shader = shader.shaders[renderer.CONTEXT_UID] || shader.getShader(renderer);// : shader; - } - - this.renderer.shaderManager.setShader(shader); - - shader.uniforms.translationMatrix.value = mesh.worldTransform.toArray(true); - shader.uniforms.projectionMatrix.value = renderer.currentRenderTarget.projectionMatrix.toArray(true); - shader.uniforms.alpha.value = mesh.worldAlpha; - - shader.syncUniforms(); - - if (!mesh.dirty) - { - - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, mesh.vertices); - gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer); - gl.vertexAttribPointer(shader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - - gl.activeTexture(gl.TEXTURE0); - - if (!texture._glTextures[renderer.CONTEXT_UID]) - { - this.renderer.updateTexture(texture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[renderer.CONTEXT_UID]); - } - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer); - gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, mesh.indices); - } - else - { - - mesh.dirty = false; - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.vertices, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.attributes.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.uvs, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.activeTexture(gl.TEXTURE0); - - if (!texture._glTextures[renderer.CONTEXT_UID]) - { - this.renderer.updateTexture(texture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[renderer.CONTEXT_UID]); - } - - // dont need to upload! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, mesh.indices, gl.STATIC_DRAW); - - } - - gl.drawElements(drawMode, mesh.indices.length, gl.UNSIGNED_SHORT, 0); - -}; - -/** - * Prepares all the buffers to render this mesh - * @param mesh {PIXI.mesh.Mesh} the mesh to render - */ -MeshRenderer.prototype._initWebGL = function (mesh) -{ - // build the strip! - var gl = this.renderer.gl; - - mesh._vertexBuffer = gl.createBuffer(); - mesh._indexBuffer = gl.createBuffer(); - mesh._uvBuffer = gl.createBuffer(); - - - - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.vertices, gl.STREAM_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.uvs, gl.STATIC_DRAW); - - if(mesh.colors){ - mesh._colorBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, mesh._colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, mesh.colors, gl.STATIC_DRAW); - } - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, mesh.indices, gl.STATIC_DRAW); -}; - - -/** - * Empties the current batch. - * - */ -MeshRenderer.prototype.flush = function () -{ - -}; - -/** - * Starts a new mesh renderer. - * - */ -MeshRenderer.prototype.start = function () -{ - - - this.currentShader = null; -}; - -/** - * Destroys the Mesh renderer - * - */ -MeshRenderer.prototype.destroy = function () -{ - core.ObjectRenderer.prototype.destroy.call(this); -}; diff --git a/src/mesh/webgl/MeshShader.js b/src/mesh/webgl/MeshShader.js index beababb..29d2862 100644 --- a/src/mesh/webgl/MeshShader.js +++ b/src/mesh/webgl/MeshShader.js @@ -1,4 +1,4 @@ -var core = require('../../core'); +var Shader = require('pixi-gl-core').GLShader; /** * @class @@ -6,10 +6,10 @@ * @memberof PIXI.mesh * @param shaderManager {PIXI.ShaderManager} The WebGL shader manager this shader works for. */ -function MeshShader(shaderManager) +function MeshShader(gl) { - core.Shader.call(this, - shaderManager, + Shader.call(this, + gl, // vertex shader [ 'precision lowp float;', @@ -36,23 +36,13 @@ 'void main(void){', ' gl_FragColor = texture2D(uSampler, vTextureCoord) * alpha ;', + // ' gl_FragColor = vec4(1.0);', '}' - ].join('\n'), - // custom uniforms - { - alpha: { type: '1f', value: 0 }, - translationMatrix: { type: 'mat3', value: new Float32Array(9) }, - projectionMatrix: { type: 'mat3', value: new Float32Array(9) } - }, - // custom attributes - { - aVertexPosition:0, - aTextureCoord:0 - } + ].join('\n') ); } -MeshShader.prototype = Object.create(core.Shader.prototype); +MeshShader.prototype = Object.create(Shader.prototype); MeshShader.prototype.constructor = MeshShader; module.exports = MeshShader;