From 869087044b6f481c976977759b9c8b0e4f7b6aea Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Thu, 12 Jul 2018 01:14:34 +0100 Subject: [PATCH] Starting work on proper tile culling --- src/tilemaps/components/CullTiles.js | 102 +++++++++++------- .../staticlayer/StaticTilemapLayer.js | 64 +++++++---- 2 files changed, 110 insertions(+), 56 deletions(-) diff --git a/src/tilemaps/components/CullTiles.js b/src/tilemaps/components/CullTiles.js index 6ec3bc118..340d9eb46 100644 --- a/src/tilemaps/components/CullTiles.js +++ b/src/tilemaps/components/CullTiles.js @@ -24,69 +24,95 @@ var CullTiles = function (layer, camera, outputArray) outputArray.length = 0; - var zoom = camera.zoom; - var originX = camera.width / 2; - var originY = camera.height / 2; + // var zoom = camera.zoom; + // var originX = camera.width / 2; + // var originY = camera.height / 2; - camera.matrix.loadIdentity(); - camera.matrix.translate(camera.x + originX, camera.y + originY); - camera.matrix.rotate(camera.rotation); - camera.matrix.scale(zoom, zoom); - camera.matrix.translate(-originX, -originY); - camera.matrix.invert(); + // var matrix = camera.matrix; - camera.shakeEffect.preRender(); + // matrix.applyITRS(camera.x, camera.y, camera.rotation, zoom, zoom); + + // camera.matrix.loadIdentity(); + // camera.matrix.translate(camera.x + originX, camera.y + originY); + // camera.matrix.rotate(camera.rotation); + // camera.matrix.scale(zoom, zoom); + // camera.matrix.translate(-originX, -originY); + // camera.matrix.invert(); + + // camera.shakeEffect.preRender(); var tilemapLayer = layer.tilemapLayer; - var tileW = layer.tileWidth; - var tileH = layer.tileHeight; - var cullX = ((camera.scrollX * tilemapLayer.scrollFactorX) - tileW); - var cullY = ((camera.scrollY * tilemapLayer.scrollFactorY) - tileH); - var cullW = (cullX + (camera.width + tileW * 2)); - var cullH = (cullY + (camera.height + tileH * 2)); + + // var tileW = layer.tileWidth; + // var tileH = layer.tileHeight; + + // var cullX = ((camera.scrollX * tilemapLayer.scrollFactorX) - tileW); + // var cullY = ((camera.scrollY * tilemapLayer.scrollFactorY) - tileH); + // var cullW = (cullX + (camera.width + tileW * 2)); + // var cullH = (cullY + (camera.height + tileH * 2)); + var mapData = layer.data; var mapWidth = layer.width; var mapHeight = layer.height; - 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 tCullX = cullX * a + cullY * c + e; - var tCullY = cullX * b + cullY * d + f; - var tCullW = cullW * a + cullH * c + e; - var tCullH = cullW * b + cullH * d + f; - for (var y = 0; y < mapHeight; ++y) + var boundsLeft = camera.worldBounds.left; + var boundsRight = camera.worldBounds.right; + var boundsTop = camera.worldBounds.top; + var boundsBottom = camera.worldBounds.bottom; + + // 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 tCullX = cullX * a + cullY * c + e; + // var tCullY = cullX * b + cullY * d + f; + // var tCullW = cullW * a + cullH * c + e; + // var tCullH = cullW * b + cullH * d + f; + + var i = 0; + + for (var y = 0; y < mapHeight; y++) { - for (var x = 0; x < mapWidth; ++x) + for (var x = 0; x < mapWidth; x++) { var tile = mapData[y][x]; - if (tile === null || tile.index === -1) + if (!tile || tile.index === -1 || !tile.visible) { continue; } var tilePixelX = (tile.pixelX + tilemapLayer.x); var tilePixelY = (tile.pixelY + tilemapLayer.y); - var tileX = (tilePixelX * a + tilePixelY * c + e); - var tileY = (tilePixelX * b + tilePixelY * d + f); - if (tile.visible && - tileX >= tCullX && - tileY >= tCullY && - tileX + tileW <= tCullW && - tileY + tileH <= tCullH - ) + if (tilePixelX >= boundsLeft && tilePixelX < boundsRight && tilePixelY >= boundsTop && tilePixelY < boundsBottom) { outputArray.push(tile); } + + i++; + + // var tileX = (tilePixelX * a + tilePixelY * c + e); + // var tileY = (tilePixelX * b + tilePixelY * d + f); + + // if (tile.visible && + // tileX >= tCullX && + // tileY >= tCullY && + // tileX + tileW <= tCullW && + // tileY + tileH <= tCullH + // ) + // { + // outputArray.push(tile); + // } } } + window.noCull = i; + window.cull = outputArray.length; + /* var tilemapLayer = layer.tilemapLayer; var mapData = layer.data; var mapWidth = layer.width; diff --git a/src/tilemaps/staticlayer/StaticTilemapLayer.js b/src/tilemaps/staticlayer/StaticTilemapLayer.js index 3729eb90b..0bb7ce029 100644 --- a/src/tilemaps/staticlayer/StaticTilemapLayer.js +++ b/src/tilemaps/staticlayer/StaticTilemapLayer.js @@ -217,25 +217,32 @@ var StaticTilemapLayer = new Class({ */ upload: function (camera) { - var tileset = this.tileset; - var mapWidth = this.layer.width; - var mapHeight = this.layer.height; - var width = tileset.image.source[0].width; - var height = tileset.image.source[0].height; - var mapData = this.layer.data; var renderer = this.renderer; - var tile; - var row; - var col; - var texCoords; - if (renderer.gl) + var gl = renderer.gl; + + if (gl) { var pipeline = renderer.pipelines.TextureTintPipeline; if (this.dirty) { - var gl = renderer.gl; + var tileset = this.tileset; + var mapWidth = this.layer.width; + var mapHeight = this.layer.height; + var width = tileset.image.source[0].width; + var height = tileset.image.source[0].height; + var mapData = this.layer.data; + var tile; + var row; + var col; + var texCoords; + + var boundsLeft = camera.worldBounds.left; + var boundsRight = camera.worldBounds.right; + var boundsTop = camera.worldBounds.top; + var boundsBottom = camera.worldBounds.bottom; + var vertexBuffer = this.vertexBuffer; var bufferData = this.bufferData; var voffset = -1; @@ -254,13 +261,18 @@ var StaticTilemapLayer = new Class({ var vertexViewF32 = this.vertexViewF32; var vertexViewU32 = this.vertexViewU32; + var c = 0; + var i = 0; + for (row = 0; row < mapHeight; ++row) { for (col = 0; col < mapWidth; ++col) { + c++; + tile = mapData[row][col]; - if (tile === null || tile.index === -1) + if (!tile || tile.index === -1 || !tile.visible) { continue; } @@ -270,18 +282,28 @@ var StaticTilemapLayer = new Class({ var txw = tx + tile.width; var tyh = ty + tile.height; + var tilePixelX = (tx + this.x); + var tilePixelY = (ty + this.y); + texCoords = tileset.getTileTextureCoordinates(tile.index); - if (texCoords === null) + if (!texCoords) { continue; } + + if (!texCoords || tilePixelX < boundsLeft || tilePixelX > boundsRight || tilePixelY < boundsTop || tilePixelY > boundsBottom) + { + // continue; + } var u0 = texCoords.x / width; var v0 = texCoords.y / height; var u1 = (texCoords.x + tile.width) / width; var v1 = (texCoords.y + tile.height) / height; + var tint = Utils.getTintAppendFloatAlpha(0xffffff, camera.alpha * this.alpha * tile.alpha); + var tx0 = tx; var ty0 = ty; var tx1 = tx; @@ -291,8 +313,6 @@ var StaticTilemapLayer = new Class({ var tx3 = txw; var ty3 = ty; - var tint = Utils.getTintAppendFloatAlpha(0xffffff, camera.alpha * this.alpha * tile.alpha); - vertexViewF32[++voffset] = tx0; vertexViewF32[++voffset] = ty0; vertexViewF32[++voffset] = u0; @@ -336,27 +356,35 @@ var StaticTilemapLayer = new Class({ vertexViewU32[++voffset] = tint; vertexCount += 6; + + i++; } } this.vertexCount = vertexCount; + this.dirty = false; if (vertexBuffer === null) { vertexBuffer = renderer.createVertexBuffer(bufferData, gl.STATIC_DRAW); + this.vertexBuffer = vertexBuffer; } else { renderer.setVertexBuffer(vertexBuffer); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, bufferData); } + + window.noCull = c; + window.cull = i; } pipeline.modelIdentity(); - pipeline.modelTranslate(this.x - (camera.scrollX * this.scrollFactorX), this.y - (camera.scrollY * this.scrollFactorY), 0.0); - pipeline.modelScale(this.scaleX, this.scaleY, 1.0); + pipeline.modelTranslate(this.x - (camera.scrollX * this.scrollFactorX), this.y - (camera.scrollY * this.scrollFactorY), 0); + pipeline.modelScale(this.scaleX, this.scaleY, 1); pipeline.viewLoad2D(camera.matrix.matrix); }