From 070d946dcabb264e3fb0524a5cb1e514ebf3f8b9 Mon Sep 17 00:00:00 2001 From: Felipe Alfonso Date: Tue, 23 Jan 2018 16:29:47 -0300 Subject: [PATCH] Mesh and Sprite rendering --- src/gameobjects/index.js | 12 +- src/gameobjects/mesh/Mesh.js | 3 +- src/gameobjects/mesh/MeshCreator.js | 3 +- src/gameobjects/mesh/MeshFactory.js | 2 +- src/gameobjects/mesh/MeshWebGLRenderer.js | 9 +- src/gameobjects/sprite/SpriteWebGLRenderer.js | 2 +- src/renderer/webgl/WebGLRenderer.js | 21 ++- .../webgl/pipelines/TextureTintPipeline.js | 148 +++++++++++++----- 8 files changed, 139 insertions(+), 61 deletions(-) diff --git a/src/gameobjects/index.js b/src/gameobjects/index.js index 56dd3161b..1cf77fabf 100644 --- a/src/gameobjects/index.js +++ b/src/gameobjects/index.js @@ -22,7 +22,7 @@ var GameObjects = { //Particles: require('./particles/ParticleEmitterManager'), //PathFollower: require('./pathfollower/PathFollower'), //Sprite3D: require('./sprite3d/Sprite3D'), - //Sprite: require('./sprite/Sprite'), + Sprite: require('./sprite/Sprite'), //StaticTilemapLayer: require('./tilemap/staticlayer/StaticTilemapLayer'), //Text: require('./text/static/Text'), //Tile: require('./tilemap/Tile'), @@ -42,7 +42,7 @@ var GameObjects = { //Image: require('./image/ImageFactory'), //Particles: require('./particles/ParticleManagerFactory'), //PathFollower: require('./pathfollower/PathFollowerFactory'), - //Sprite: require('./sprite/SpriteFactory'), + Sprite: require('./sprite/SpriteFactory'), //Sprite3D: require('./sprite3d/Sprite3DFactory'), //StaticBitmapText: require('./bitmaptext/static/BitmapTextFactory'), //Text: require('./text/static/TextFactory'), @@ -59,7 +59,7 @@ var GameObjects = { //Group: require('./group/GroupCreator'), //Image: require('./image/ImageCreator'), //Particles: require('./particles/ParticleManagerCreator'), - //Sprite: require('./sprite/SpriteCreator'), + Sprite: require('./sprite/SpriteCreator'), //Sprite3D: require('./sprite3d/Sprite3DCreator'), //StaticBitmapText: require('./bitmaptext/static/BitmapTextCreator'), //Text: require('./text/static/TextCreator'), @@ -74,17 +74,17 @@ if (WEBGL_RENDERER) { // WebGL only Game Objects //GameObjects.LightLayer = require('./lightlayer/LightLayer'); - //GameObjects.Mesh = require('./mesh/Mesh'); + GameObjects.Mesh = require('./mesh/Mesh'); //GameObjects.Quad = require('./quad/Quad'); //GameObjects.Factories.EffectLayer = require('./effectlayer/EffectLayerFactory'); //GameObjects.Factories.LightLayer = require('./lightlayer/LightLayerFactory'); - //GameObjects.Factories.Mesh = require('./mesh/MeshFactory'); + GameObjects.Factories.Mesh = require('./mesh/MeshFactory'); //GameObjects.Factories.Quad = require('./quad/QuadFactory'); //GameObjects.Creators.EffectLayer = require('./effectlayer/EffectLayerCreator'); //GameObjects.Creators.LightLayer = require('./lightlayer/LightLayerCreator'); - //GameObjects.Creators.Mesh = require('./mesh/MeshCreator'); + GameObjects.Creators.Mesh = require('./mesh/MeshCreator'); //GameObjects.Creators.Quad = require('./quad/QuadCreator'); } diff --git a/src/gameobjects/mesh/Mesh.js b/src/gameobjects/mesh/Mesh.js index f1980f850..0435adfb5 100644 --- a/src/gameobjects/mesh/Mesh.js +++ b/src/gameobjects/mesh/Mesh.js @@ -25,7 +25,7 @@ var Mesh = new Class({ initialize: - function Mesh (scene, x, y, vertices, uv, indices, colors, alphas, texture, frame) + function Mesh (scene, x, y, vertices, uv, colors, alphas, texture, frame) { GameObject.call(this, scene, 'Mesh'); @@ -71,7 +71,6 @@ var Mesh = new Class({ this.vertices = new Float32Array(vertices); this.uv = new Float32Array(uv); - this.indices = new Uint16Array(indices); this.colors = new Uint32Array(colors); this.alphas = new Float32Array(alphas); } diff --git a/src/gameobjects/mesh/MeshCreator.js b/src/gameobjects/mesh/MeshCreator.js index 7fdff5df3..51b51d548 100644 --- a/src/gameobjects/mesh/MeshCreator.js +++ b/src/gameobjects/mesh/MeshCreator.js @@ -11,12 +11,11 @@ GameObjectCreator.register('mesh', function (config) var key = GetAdvancedValue(config, 'key', null); var frame = GetAdvancedValue(config, 'frame', null); var vertices = GetValue(config, 'vertices', []); - var indices = GetValue(config, 'indices', []); var colors = GetValue(config, 'colors', []); var alphas = GetValue(config, 'alphas', []); var uv = GetValue(config, 'uv', []); - var mesh = new Mesh(this.scene, 0, 0, vertices, uv, indices, colors, alphas, key, frame); + var mesh = new Mesh(this.scene, 0, 0, vertices, uv, colors, alphas, key, frame); BuildGameObject(this.scene, mesh, config); diff --git a/src/gameobjects/mesh/MeshFactory.js b/src/gameobjects/mesh/MeshFactory.js index ec32d85af..c4ef60de0 100644 --- a/src/gameobjects/mesh/MeshFactory.js +++ b/src/gameobjects/mesh/MeshFactory.js @@ -11,7 +11,7 @@ var GameObjectFactory = require('../GameObjectFactory'); if (WEBGL_RENDERER) { - GameObjectFactory.register('mesh', function (x, y, vertices, uv, key, frame) + GameObjectFactory.register('mesh', function (x, y, vertices, uv, colors, alphas, texture, frame) { return this.displayList.add(new Mesh(this.scene, x, y, vertices, uv, key, frame)); }); diff --git a/src/gameobjects/mesh/MeshWebGLRenderer.js b/src/gameobjects/mesh/MeshWebGLRenderer.js index 139fdefdb..a7a594653 100644 --- a/src/gameobjects/mesh/MeshWebGLRenderer.js +++ b/src/gameobjects/mesh/MeshWebGLRenderer.js @@ -7,14 +7,7 @@ var MeshWebGLRenderer = function (renderer, src, interpolationPercentage, camera return; } - if (src.indices.length > 0) - { - renderer.spriteBatch.addMeshIndexed(src, camera); - } - else - { - renderer.spriteBatch.addMesh(src, camera); - } + renderer.pipelines.TextureTintPipeline.batchMesh(src, camera); }; module.exports = MeshWebGLRenderer; diff --git a/src/gameobjects/sprite/SpriteWebGLRenderer.js b/src/gameobjects/sprite/SpriteWebGLRenderer.js index 8f4a7b2f6..11c5b7b86 100644 --- a/src/gameobjects/sprite/SpriteWebGLRenderer.js +++ b/src/gameobjects/sprite/SpriteWebGLRenderer.js @@ -7,7 +7,7 @@ var SpriteWebGLRenderer = function (renderer, src, interpolationPercentage, came return; } - renderer.spriteRenderer.drawSprite(src, camera); + renderer.pipelines.TextureTintPipeline.batchSprite(src, camera); }; module.exports = SpriteWebGLRenderer; diff --git a/src/renderer/webgl/WebGLRenderer.js b/src/renderer/webgl/WebGLRenderer.js index a6341688a..59630260c 100644 --- a/src/renderer/webgl/WebGLRenderer.js +++ b/src/renderer/webgl/WebGLRenderer.js @@ -212,7 +212,7 @@ var WebGLRenderer = new Class({ this.currentPipeline.bind(overrideProgram); } - return pipeline; + return this.currentPipeline; }, setBlendMode: function (blendModeId) @@ -251,6 +251,8 @@ var WebGLRenderer = new Class({ if (texture !== this.currentTextures[textureUnit]) { + this.flush(); + gl.activeTexture(gl.TEXTURE0 + textureUnit); gl.bindTexture(gl.TEXTURE_2D, texture); @@ -266,6 +268,8 @@ var WebGLRenderer = new Class({ if (framebuffer !== this.currentFramebuffer) { + this.flush(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); } @@ -278,6 +282,8 @@ var WebGLRenderer = new Class({ if (program !== this.currentProgram) { + this.flush(); + gl.useProgram(program); } @@ -290,6 +296,8 @@ var WebGLRenderer = new Class({ if (vertexBuffer !== this.currentVertexBuffer) { + this.flush(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); } @@ -302,6 +310,8 @@ var WebGLRenderer = new Class({ if (indexBuffer !== this.currentIndexBuffer) { + this.flush(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); } @@ -545,10 +555,11 @@ var WebGLRenderer = new Class({ pipeline = this.currentPipeline; - if (pipeline && pipeline.shouldFlush()) - { - pipeline.flush(); - } + } + + if (pipeline && pipeline.vertexCount > 0) + { + pipeline.flush(); } if (scissorEnabled) diff --git a/src/renderer/webgl/pipelines/TextureTintPipeline.js b/src/renderer/webgl/pipelines/TextureTintPipeline.js index c5e414b82..31a9a901c 100644 --- a/src/renderer/webgl/pipelines/TextureTintPipeline.js +++ b/src/renderer/webgl/pipelines/TextureTintPipeline.js @@ -95,11 +95,10 @@ var TextureTintPipeline = new Class({ { this.renderer.setPipeline(this); + var getTint = Utils.getTintAppendFloatAlpha; var vertexViewF32 = this.vertexViewF32; var vertexViewU32 = this.vertexViewU32; var renderer = this.renderer; - var gl = this.gl; - var shader = this.currentProgram; var list = blitter.getRenderList(); var length = list.length; var cameraMatrix = camera.matrix.matrix; @@ -126,7 +125,7 @@ var TextureTintPipeline = new Class({ var bob = list[batchOffset + index]; var frame = bob.frame; var alpha = bob.alpha; - var tint = Utils.getTintAppendFloatAlpha(0xffffff, bob.alpha); + var tint = getTint(0xffffff, bob.alpha); var uvs = frame.uvs; var flipX = bob.flipX; var flipY = bob.flipY; @@ -202,9 +201,11 @@ var TextureTintPipeline = new Class({ this.flush(); } + var getTint = Utils.getTintAppendFloatAlpha; var vertexViewF32 = this.vertexViewF32; var vertexViewU32 = this.vertexViewU32; - var shader = this.currentProgram; + var renderer = this.renderer; + var vertexOffset = this.vertexCount * this.vertexComponentCount; var cameraMatrix = camera.matrix.matrix; var a = cameraMatrix[0]; var b = cameraMatrix[1]; @@ -265,47 +266,122 @@ var TextureTintPipeline = new Class({ var ty2 = xw * mvb + yh * mvd + mvf; var tx3 = xw * mva + y * mvc + mve; var ty3 = xw * mvb + y * mvd + mvf; - var getTint = Utils.getTintAppendFloatAlpha; var tint0 = getTint(tintTL, alphaTL); var tint1 = getTint(tintTR, alphaTR); var tint2 = getTint(tintBL, alphaBL); var tint3 = getTint(tintBR, alphaBR); - renderer.setTexture2D(frame.texture.source[frame.sourceIndex].glTexture, 0); + renderer.setTexture2D(texture, 0); - vertexViewF32[0] = tx0; - vertexViewF32[1] = ty0; - vertexViewF32[2] = uvs.x0; - vertexViewF32[3] = uvs.y0; - vertexViewU32[4] = tint0; - vertexViewF32[5] = tx1; - vertexViewF32[6] = ty1; - vertexViewF32[7] = uvs.x1; - vertexViewF32[8] = uvs.y1; - vertexViewU32[9] = tint1; - vertexViewF32[10] = tx2; - vertexViewF32[11] = ty2; - vertexViewF32[12] = uvs.x2; - vertexViewF32[13] = uvs.y2; - vertexViewU32[14] = tint2; - vertexViewF32[15] = tx0; - vertexViewF32[16] = ty0; - vertexViewF32[17] = uvs.x0; - vertexViewF32[18] = uvs.y0; - vertexViewU32[19] = tint0; - vertexViewF32[20] = tx2; - vertexViewF32[21] = ty2; - vertexViewF32[22] = uvs.x2; - vertexViewF32[23] = uvs.y2; - vertexViewU32[24] = tint2; - vertexViewF32[25] = tx3; - vertexViewF32[26] = ty3; - vertexViewF32[27] = uvs.x3; - vertexViewF32[28] = uvs.y3; - vertexViewU32[29] = tint3; + vertexViewF32[vertexOffset + 0] = tx0; + vertexViewF32[vertexOffset + 1] = ty0; + vertexViewF32[vertexOffset + 2] = uvs.x0; + vertexViewF32[vertexOffset + 3] = uvs.y0; + vertexViewU32[vertexOffset + 4] = tint0; + vertexViewF32[vertexOffset + 5] = tx1; + vertexViewF32[vertexOffset + 6] = ty1; + vertexViewF32[vertexOffset + 7] = uvs.x1; + vertexViewF32[vertexOffset + 8] = uvs.y1; + vertexViewU32[vertexOffset + 9] = tint1; + vertexViewF32[vertexOffset + 10] = tx2; + vertexViewF32[vertexOffset + 11] = ty2; + vertexViewF32[vertexOffset + 12] = uvs.x2; + vertexViewF32[vertexOffset + 13] = uvs.y2; + vertexViewU32[vertexOffset + 14] = tint2; + vertexViewF32[vertexOffset + 15] = tx0; + vertexViewF32[vertexOffset + 16] = ty0; + vertexViewF32[vertexOffset + 17] = uvs.x0; + vertexViewF32[vertexOffset + 18] = uvs.y0; + vertexViewU32[vertexOffset + 19] = tint0; + vertexViewF32[vertexOffset + 20] = tx2; + vertexViewF32[vertexOffset + 21] = ty2; + vertexViewF32[vertexOffset + 22] = uvs.x2; + vertexViewF32[vertexOffset + 23] = uvs.y2; + vertexViewU32[vertexOffset + 24] = tint2; + vertexViewF32[vertexOffset + 25] = tx3; + vertexViewF32[vertexOffset + 26] = ty3; + vertexViewF32[vertexOffset + 27] = uvs.x3; + vertexViewF32[vertexOffset + 28] = uvs.y3; + vertexViewU32[vertexOffset + 29] = tint3; this.vertexCount += 6; + }, + batchMesh: function (mesh, camera) + { + this.renderer.setPipeline(this); + var vertices = mesh.vertices; + var length = vertices.length; + var vertexCount = (length / 2)|0; + + if (this.vertexCount + vertexCount > this.vertexCapacity) + { + this.flush(); + } + + var getTint = Utils.getTintAppendFloatAlpha; + var uvs = mesh.uv; + var colors = mesh.colors; + var alphas = mesh.alphas; + var vertexViewF32 = this.vertexViewF32; + var vertexViewU32 = this.vertexViewU32; + var renderer = this.renderer; + var vertexOffset = this.vertexCount * this.vertexComponentCount; + var cameraMatrix = camera.matrix.matrix; + var a = cameraMatrix[0]; + var b = cameraMatrix[1]; + var c = cameraMatrix[2]; + var d = cameraMatrix[3]; + var e = cameraMatrix[4]; + var f = cameraMatrix[5]; + var frame = mesh.frame; + var texture = mesh.texture.source[frame.sourceIndex].glTexture; + var translateX = mesh.x - camera.scrollX * mesh.scrollFactorX; + var translateY = mesh.y - camera.scrollY * mesh.scrollFactorY; + var scaleX = mesh.scaleX; + var scaleY = mesh.scaleY; + var rotation = -mesh.rotation; + var sr = Math.sin(rotation); + var cr = Math.cos(rotation); + var sra = cr * scaleX; + var srb = -sr * scaleX; + var src = sr * scaleY; + var srd = cr * scaleY; + var sre = translateX; + var srf = translateY; + var cma = cameraMatrix[0]; + var cmb = cameraMatrix[1]; + var cmc = cameraMatrix[2]; + var cmd = cameraMatrix[3]; + var cme = cameraMatrix[4]; + var cmf = cameraMatrix[5]; + var mva = sra * cma + srb * cmc; + var mvb = sra * cmb + srb * cmd; + var mvc = src * cma + srd * cmc; + var mvd = src * cmb + srd * cmd; + var mve = sre * cma + srf * cmc + cme; + var mvf = sre * cmb + srf * cmd + cmf; + + renderer.setTexture2D(texture, 0); + + for (var index = 0, index0 = 0; index < length; index += 2) + { + var x = vertices[index + 0]; + var y = vertices[index + 1]; + var tx = x * mva + y * mvc + mve; + var ty = x * mvb + y * mvd + mvf; + + vertexViewF32[vertexOffset + 0] = tx; + vertexViewF32[vertexOffset + 1] = ty; + vertexViewF32[vertexOffset + 2] = uvs[index + 0]; + vertexViewF32[vertexOffset + 3] = uvs[index + 1]; + vertexViewU32[vertexOffset + 4] = getTint(colors[index0], alphas[index0]); + + vertexOffset += 5; + index0 += 1; + } + + this.vertexCount += vertexCount; } });