From dc035ddaaba774f3f81ec5ce2081c4132e054957 Mon Sep 17 00:00:00 2001 From: Felipe Alfonso Date: Thu, 1 Jun 2017 17:05:50 -0400 Subject: [PATCH] Tilemap Rendering --- v3/src/checksum.js | 2 +- v3/src/gameobjects/index.js | 5 +- .../tilemap/static/StaticTilemap.js | 35 +++--- .../tilemap/static/StaticTilemapFactory.js | 10 +- .../tilemap/static/StaticTilemapRender.js | 2 +- .../static/StaticTilemapWebGLRenderer.js | 9 ++ v3/src/renderer/webgl/WebGLRenderer.js | 2 + .../tilemaprenderer/TilemapRenderer.js | 118 ++++++++++++++++++ .../webgl/renderers/tilemaprenderer/const.js | 15 +++ 9 files changed, 175 insertions(+), 23 deletions(-) diff --git a/v3/src/checksum.js b/v3/src/checksum.js index 7f38aedd8..8143a4e8b 100644 --- a/v3/src/checksum.js +++ b/v3/src/checksum.js @@ -1,4 +1,4 @@ var CHECKSUM = { -build: '71ee6280-4165-11e7-9e97-1b8919a78c4a' +build: 'd6e1c770-470c-11e7-a023-cd5ccd3d9536' }; module.exports = CHECKSUM; \ No newline at end of file diff --git a/v3/src/gameobjects/index.js b/v3/src/gameobjects/index.js index 9f234e5a2..424b16b8d 100644 --- a/v3/src/gameobjects/index.js +++ b/v3/src/gameobjects/index.js @@ -16,6 +16,7 @@ require('./renderpass/RenderPassFactory'); require('./tilesprite/TileSpriteFactory'); require('./mesh/MeshFactory'); require('./quad/QuadFactory'); +require('./tilemap/static/StaticTilemapFactory'); // Phaser.GameObjects @@ -37,6 +38,6 @@ module.exports = { Zone: require('./zone/Zone'), EffectLayer: require('./effectlayer/EffectLayer'), Mesh: require('./mesh/Mesh'), - Quad: require('./quad/Quad') - + Quad: require('./quad/Quad'), + StaticTilemap: require('./tilemap/static/StaticTilemap') }; diff --git a/v3/src/gameobjects/tilemap/static/StaticTilemap.js b/v3/src/gameobjects/tilemap/static/StaticTilemap.js index 809394ce6..359362572 100644 --- a/v3/src/gameobjects/tilemap/static/StaticTilemap.js +++ b/v3/src/gameobjects/tilemap/static/StaticTilemap.js @@ -1,10 +1,11 @@ -var Class = require('../../utils/Class'); -var GameObject = require('../GameObject'); -var Components = require('../../components'); +var Class = require('../../../utils/Class'); +var GameObject = require('../../GameObject'); +var Components = require('../../../components'); var StaticTilemapRender = require('./StaticTilemapRender'); +var CONST = require('../../../renderer/webgl/renderers/tilemaprenderer/const'); -var TileSprite = new Class({ +var StaticTilemap = new Class({ Extends: GameObject, @@ -30,6 +31,9 @@ var TileSprite = new Class({ GameObject.call(this, state, 'StaticTilemap'); this.vbo = null; + this.gl = state.game.renderer.gl ? state.game.renderer.gl : null; + this.tilemapRenderer = state.game.renderer.tilemapRenderer ? state.game.renderer.tilemapRenderer : null; + this.resourceManager = this.gl ? state.game.renderer.resourceManager : null; this.bufferData = null; this.mapData = mapData; this.tileWidth = tileWidth; @@ -37,19 +41,19 @@ var TileSprite = new Class({ this.mapWidth = mapWidth; this.mapHeight = mapHeight; this.dirty = true; + this.vertexCount = 0; this.setTexture(texture, frame); this.setPosition(x, y); this.setSizeToFrame(); this.setOrigin(); - this.setSize(width, height); - + this.setSize(tileWidth * mapWidth, tileHeight * mapHeight); }, upload: function () { - if (this.dirty) + if (this.dirty && this.gl) { - var gl; + var gl = this.gl; var vbo = this.vbo; var mapWidth = this.mapWidth; var mapHeight = this.mapHeight; @@ -58,13 +62,15 @@ var TileSprite = new Class({ var bufferData = this.bufferData; var bufferF32, bufferU32; var voffset = 0; + var vertexCount = 0; if (this.vbo === null) { - vbo = this.vbo = gl.createBuffer(); + vbo = this.resourceManager.createBuffer(gl.ARRAY_BUFFER, (4 * 6 * (mapWidth * mapHeight)) * 4, gl.STATIC_DRAW); + vbo.addAttribute(this.tilemapRenderer.shader.getAttribLocation('a_position'), 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0); + vbo.addAttribute(this.tilemapRenderer.shader.getAttribLocation('a_tex_coord'), 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 8); bufferData = this.bufferData = new ArrayBuffer((4 * 6 * (mapWidth * mapHeight)) * 4); - gl.bindBuffer(gl.ARRAY_BUFFER, vbo); - gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.STATIC_DRAW); + this.vbo = vbo; } bufferF32 = new Float32Array(bufferData); @@ -115,11 +121,12 @@ var TileSprite = new Class({ bufferF32[voffset + 1] = ty3; bufferF32[voffset + 2] = 1; bufferF32[voffset + 3] = 0; + + vertexCount += 6; } } - - gl.bindBuffer(gl.ARRAY_BUFFER, vbo); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, bufferData); + this.vertexCount = vertexCount; + vbo.updateResource(bufferData, 0); this.dirty = false; } diff --git a/v3/src/gameobjects/tilemap/static/StaticTilemapFactory.js b/v3/src/gameobjects/tilemap/static/StaticTilemapFactory.js index b2b4a1c19..65ed60f02 100644 --- a/v3/src/gameobjects/tilemap/static/StaticTilemapFactory.js +++ b/v3/src/gameobjects/tilemap/static/StaticTilemapFactory.js @@ -1,19 +1,19 @@ var StaticTilemap = require('./StaticTilemap'); -var FactoryContainer = require('../../gameobjects/FactoryContainer'); +var FactoryContainer = require('../../../gameobjects/FactoryContainer'); var StaticTilemapFactory = { KEY: 'staticTilemap', - add: function (mapData, x, y, width, height, key, frame) + add: function (mapData, x, y, tileWidth, tileHeight, mapWidth, mapHeight, texture, frame) { - return this.children.add(new StaticTilemap(this.state, mapData, x, y, width, height, key, frame)); + return this.children.add(new StaticTilemap(this.state, mapData, x, y, tileWidth, tileHeight, mapWidth, mapHeight, texture, frame)); }, - make: function (mapData, x, y, width, height, key, frame) + make: function (mapData, x, y, tileWidth, tileHeight, mapWidth, mapHeight, texture, frame) { - return new StaticTilemap(this.state, mapData, x, y, width, height, key, frame); + return new StaticTilemap(this.state, mapData, x, y, tileWidth, tileHeight, mapWidth, mapHeight, texture, frame); } }; diff --git a/v3/src/gameobjects/tilemap/static/StaticTilemapRender.js b/v3/src/gameobjects/tilemap/static/StaticTilemapRender.js index 70afa0a42..4dc30e55a 100644 --- a/v3/src/gameobjects/tilemap/static/StaticTilemapRender.js +++ b/v3/src/gameobjects/tilemap/static/StaticTilemapRender.js @@ -1,6 +1,6 @@ module.exports = { renderCanvas: require('./StaticTilemapCanvasRenderer'), - renderWebGL: require('./StaticTilemapTextWebGLRenderer') + renderWebGL: require('./StaticTilemapWebGLRenderer') }; diff --git a/v3/src/gameobjects/tilemap/static/StaticTilemapWebGLRenderer.js b/v3/src/gameobjects/tilemap/static/StaticTilemapWebGLRenderer.js index e3ff11e00..d08efb31e 100644 --- a/v3/src/gameobjects/tilemap/static/StaticTilemapWebGLRenderer.js +++ b/v3/src/gameobjects/tilemap/static/StaticTilemapWebGLRenderer.js @@ -4,6 +4,15 @@ var StaticTilemapWebGLRenderer = function (renderer, src, interpolationPercentag { return; } + + var gameObject = src; + var frame = gameObject.frame; + var gl = gameObject.gl; + + renderer.setRenderer(gameObject.tilemapRenderer, frame.texture.source[frame.sourceIndex].glTexture, gameObject.renderTarget); + gameObject.upload(); + gameObject.vbo.bind(); + gl.drawArrays(gl.TRIANGLES, 0, gameObject.vertexCount); }; module.exports = StaticTilemapWebGLRenderer; diff --git a/v3/src/renderer/webgl/WebGLRenderer.js b/v3/src/renderer/webgl/WebGLRenderer.js index b1a33dc82..2fbca5a96 100644 --- a/v3/src/renderer/webgl/WebGLRenderer.js +++ b/v3/src/renderer/webgl/WebGLRenderer.js @@ -12,6 +12,7 @@ var SpriteBatch = require('./renderers/spritebatch/SpriteBatch'); var TileBatch = require('./renderers/tilebatch/TileBatch'); var ShapeBatch = require('./renderers/shapebatch/ShapeBatch'); var EffectRenderer = require('./renderers/effectrenderer/EffectRenderer'); +var TilemapRenderer = require('./renderers/tilemaprenderer/TilemapRenderer'); var BlendModes = require('../BlendModes'); var ScaleModes = require('../ScaleModes'); var ResourceManager = require('./ResourceManager'); @@ -115,6 +116,7 @@ WebGLRenderer.prototype = { this.shapeBatch = this.addRenderer(new ShapeBatch(this.game, gl, this)); this.effectRenderer = this.addRenderer(new EffectRenderer(this.game, gl, this)); this.tileBatch = this.addRenderer(new TileBatch(this.game, gl, this)); + this.tilemapRenderer = this.addRenderer(new TilemapRenderer(this.game, gl, this)); this.currentRenderer = this.spriteBatch; this.setBlendMode(0); this.resize(this.width, this.height); diff --git a/v3/src/renderer/webgl/renderers/tilemaprenderer/TilemapRenderer.js b/v3/src/renderer/webgl/renderers/tilemaprenderer/TilemapRenderer.js index e69de29bb..2852b5b75 100644 --- a/v3/src/renderer/webgl/renderers/tilemaprenderer/TilemapRenderer.js +++ b/v3/src/renderer/webgl/renderers/tilemaprenderer/TilemapRenderer.js @@ -0,0 +1,118 @@ +var DataBuffer32 = require('../../utils/DataBuffer32'); +var DataBuffer16 = require('../../utils/DataBuffer16'); +var TilemapShader = require('../../shaders/TilemapShader'); + +var PHASER_CONST = require('../../../../const'); +var CONST = require('./const'); + +var TilemapRenderer = function (game, gl, manager) +{ + this.game = game; + this.type = PHASER_CONST.WEBGL; + this.view = game.canvas; + this.resolution = game.config.resolution; + this.width = game.config.width * game.config.resolution; + this.height = game.config.height * game.config.resolution; + this.glContext = gl; + this.shader = null; + this.viewMatrixLocation = null; + + // All of these settings will be able to be controlled via the Game Config + this.config = { + clearBeforeRender: true, + transparent: false, + autoResize: false, + preserveDrawingBuffer: false, + + WebGLContextOptions: { + alpha: true, + antialias: true, + premultipliedAlpha: true, + stencil: true, + preserveDrawingBuffer: false + } + }; + + this.manager = manager; + this.dirty = false; + + this.init(this.glContext); +}; + +TilemapRenderer.prototype.constructor = TilemapRenderer; + +TilemapRenderer.prototype = { + + init: function (gl) + { + var shader = this.manager.resourceManager.createShader('TilemapShader', TilemapShader); + var viewMatrixLocation = shader.getUniformLocation('u_view_matrix'); + var scrollLocation = shader.getUniformLocation('u_scroll'); + + this.shader = shader; + this.viewMatrixLocation = viewMatrixLocation; + this.scrollLocation = scrollLocation; + + this.resize(this.width, this.height, this.game.config.resolution); + }, + + shouldFlush: function () + { + return false; + }, + + isFull: function () + { + return false; + }, + + add: function (x, y, width, height, red, green, blue, alpha) + { + + }, + + bind: function (shader) + { + if (shader === undefined) + { + this.shader.bind(); + } + else + { + shader.bind(); + this.resize(this.width, this.height, this.game.config.resolution, shader); + } + }, + + flush: function (shader) + { + }, + + resize: function (width, height, resolution, shader) + { + var gl = this.glContext; + var activeShader = shader !== undefined ? shader : this.shader; + + this.width = width * resolution; + this.height = height * resolution; + + activeShader.setConstantMatrix4x4( + this.viewMatrixLocation, + new Float32Array([ + 2 / this.width, 0, 0, 0, + 0, -2 / this.height, 0, 0, + 0, 0, 1, 1, + -1, 1, 0, 0 + ]) + ); + }, + + destroy: function () + { + this.manager.resourceManager.deleteShader(this.shader); + + this.shader = null; + } +}; + +module.exports = TilemapRenderer; diff --git a/v3/src/renderer/webgl/renderers/tilemaprenderer/const.js b/v3/src/renderer/webgl/renderers/tilemaprenderer/const.js index e69de29bb..eea3be4dd 100644 --- a/v3/src/renderer/webgl/renderers/tilemaprenderer/const.js +++ b/v3/src/renderer/webgl/renderers/tilemaprenderer/const.js @@ -0,0 +1,15 @@ +var CONST = { + + // VERTEX_SIZE = sizeof(vec2) + sizeof(vec2) + VERTEX_SIZE: 16, + INDEX_SIZE: 2, + TILEMAP_VERTEX_COUNT: 4, + TILEMAP_INDEX_COUNT: 6, + + // How many 32-bit components does the vertex have. + TILEMAP_VERTEX_COMPONENT_COUNT: 4, + MAX_TILEMAP: 2000, + +}; + +module.exports = CONST;