Tilemap Rendering

This commit is contained in:
Felipe Alfonso 2017-06-01 17:05:50 -04:00
parent d19d1f6b8d
commit dc035ddaab
9 changed files with 175 additions and 23 deletions

View file

@ -1,4 +1,4 @@
var CHECKSUM = {
build: '71ee6280-4165-11e7-9e97-1b8919a78c4a'
build: 'd6e1c770-470c-11e7-a023-cd5ccd3d9536'
};
module.exports = CHECKSUM;

View file

@ -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')
};

View file

@ -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;
}

View file

@ -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);
}
};

View file

@ -1,6 +1,6 @@
module.exports = {
renderCanvas: require('./StaticTilemapCanvasRenderer'),
renderWebGL: require('./StaticTilemapTextWebGLRenderer')
renderWebGL: require('./StaticTilemapWebGLRenderer')
};

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;