From 4b680776a3c0896a7dbe9943e1fa5c8bed0109b0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Oct 2018 23:11:14 +0200 Subject: MapLoader: use square tile texture rather than long Nx1 rectangle By placing the tiles in a square texture, the dimensions are bounded by the square root of the dimension in the old solution. This way we can fit a significantly higher number of tiles into it without using up all the accuracy of the coordinates. --- src/view/MapView.ts | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'src/view/MapView.ts') diff --git a/src/view/MapView.ts b/src/view/MapView.ts index 92784b7..5c30f20 100644 --- a/src/view/MapView.ts +++ b/src/view/MapView.ts @@ -1,6 +1,5 @@ -import {nextPowerOf2} from '../util'; - import MapState from '../model/state/MapState'; +import {TileMap} from './MapLoader'; import Renderer from './renderer/Renderer'; export default class MapView { @@ -14,17 +13,14 @@ export default class MapView { constructor( private readonly r: Renderer, private readonly map: MapState, - private readonly tileTexture: WebGLTexture, - private readonly tileMap: Map, + private readonly tileMap: TileMap, ) { const vertexData: number[] = []; const textureData: number[] = []; - const tileCount = nextPowerOf2(tileMap.size); - for (let x = 0; x < map.data.width; x++) for (let y = 0; y < map.data.height; y++) - this.addTile(vertexData, textureData, x, y, map.data.layers[0][y][x], tileCount); + this.addTile(vertexData, textureData, x, y, map.data.layers[0][y][x]); const gl = r.getContext(); @@ -43,7 +39,7 @@ export default class MapView { gl.clear(gl.COLOR_BUFFER_BIT); gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.tileTexture); + gl.bindTexture(gl.TEXTURE_2D, this.tileMap.texture); gl.uniform1i(this.r.getSamplerLoc(), 0); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); @@ -55,25 +51,24 @@ export default class MapView { gl.drawArrays(gl.TRIANGLES, 0, 6 * this.map.data.width * this.map.data.height); } - private addTile(vertexData: number[], textureData: number[], x: number, y: number, tile: string, tileCount: number) { - const tileID = this.tileMap.get(tile); - if (tileID === undefined) - throw new Error('invalid tile specifier in map data'); + private pushTile(buf: number[], coords: [number, number, number, number]) { + const [x1, y1, x2, y2] = coords; - vertexData.push(x); vertexData.push(y); - vertexData.push(x + 1); vertexData.push(y); - vertexData.push(x); vertexData.push(y + 1); + buf.push(x1); buf.push(y1); + buf.push(x2); buf.push(y1); + buf.push(x1); buf.push(y2); - vertexData.push(x); vertexData.push(y + 1); - vertexData.push(x + 1); vertexData.push(y); - vertexData.push(x + 1); vertexData.push(y + 1); + buf.push(x1); buf.push(y2); + buf.push(x2); buf.push(y1); + buf.push(x2); buf.push(y2); + } - textureData.push(tileID / tileCount); textureData.push(0); - textureData.push((tileID + 1) / tileCount); textureData.push(0); - textureData.push(tileID / tileCount); textureData.push(1); + private addTile(vertexData: number[], textureData: number[], x: number, y: number, tile: string) { + const tilePos = this.tileMap.tiles.get(tile); + if (!tilePos) + throw new Error('invalid tile specifier in map data'); - textureData.push(tileID / tileCount); textureData.push(1); - textureData.push((tileID + 1) / tileCount); textureData.push(0); - textureData.push((tileID + 1) / tileCount); textureData.push(1); + this.pushTile(vertexData, [x, y, x + 1, y + 1]); + this.pushTile(textureData, tilePos); } } -- cgit v1.2.3