diff options
Diffstat (limited to 'src/view/MapView.ts')
-rw-r--r-- | src/view/MapView.ts | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/view/MapView.ts b/src/view/MapView.ts new file mode 100644 index 0000000..61b8336 --- /dev/null +++ b/src/view/MapView.ts @@ -0,0 +1,81 @@ +import * as _ from 'lodash'; + +import {nextPowerOf2} from '../util'; + +import Renderer from './Renderer'; +import MapData from '../model/MapData'; + + +class MapView { + private redrawPending: boolean = false; + + private vertexBuffer: WebGLBuffer; + private textureBuffer: WebGLBuffer; + + + private addTile(vertexData: number[], textureData: number[], x: number, y: number, tile: string, tileCount: number) { + let tileID = this.tileMap.get(tile); + if (tileID === undefined) + throw new Error('invalid tile specifier in map data'); + + vertexData.push(x); vertexData.push(y); + vertexData.push(x+1); vertexData.push(y); + vertexData.push(x); vertexData.push(y+1); + + vertexData.push(x); vertexData.push(y+1); + vertexData.push(x+1); vertexData.push(y); + vertexData.push(x+1); vertexData.push(y+1); + + textureData.push((tileID) / tileCount); textureData.push(0); + textureData.push((tileID+1) / tileCount); textureData.push(0); + textureData.push((tileID) / tileCount); textureData.push(1); + + textureData.push((tileID) / tileCount); textureData.push(1); + textureData.push((tileID+1) / tileCount); textureData.push(0); + textureData.push((tileID+1) / tileCount); textureData.push(1); + } + + constructor(private r: Renderer, private map: MapData, private tileTexture: WebGLTexture, private tileMap: Map<string, number>) { + let vertexData: number[] = []; + let textureData: number[] = []; + + let tileCount = nextPowerOf2(tileMap.size); + + for (let x = 0; x < map.width; x++) { + for (let y = 0; y < map.height; y++) { + this.addTile(vertexData, textureData, x, y, map.layers[0][y][x], tileCount); + } + } + + this.vertexBuffer = r.createBuffer(); + r.gl.bindBuffer(r.gl.ARRAY_BUFFER, this.vertexBuffer); + r.gl.bufferData(r.gl.ARRAY_BUFFER, new Float32Array(vertexData), r.gl.STATIC_DRAW); + + this.textureBuffer = r.createBuffer(); + r.gl.bindBuffer(r.gl.ARRAY_BUFFER, this.textureBuffer); + r.gl.bufferData(r.gl.ARRAY_BUFFER, new Float32Array(textureData), r.gl.STATIC_DRAW); + } + + draw(): void { + this.r.gl.clear(this.r.gl.COLOR_BUFFER_BIT); + + this.r.gl.activeTexture(this.r.gl.TEXTURE0); + this.r.gl.bindTexture(this.r.gl.TEXTURE_2D, this.tileTexture); + this.r.gl.uniform1i(this.r.samplerLoc, 0); + + this.r.gl.bindBuffer(this.r.gl.ARRAY_BUFFER, this.vertexBuffer); + this.r.gl.vertexAttribPointer(this.r.vertexPosLoc, 2, this.r.gl.FLOAT, false, 0, 0); + + this.r.gl.bindBuffer(this.r.gl.ARRAY_BUFFER, this.textureBuffer); + this.r.gl.vertexAttribPointer(this.r.textureCoordLoc, 2, this.r.gl.FLOAT, false, 0, 0); + + this.r.gl.drawArrays(this.r.gl.TRIANGLES, 0, 6 * this.map.width * this.map.height); + } +} + +module MapView { + export const tileSize = 32; +} + + +export default MapView; |