summaryrefslogtreecommitdiffstats
path: root/src/view
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2018-10-31 14:24:38 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2018-10-31 14:24:38 +0100
commitaf04cbe3592656cf6981232550a460f1b10e2560 (patch)
treee39a0c01385d4aec6c8b85bf93b4555c33c63fc1 /src/view
parent272e37a4084526688cb4408d9e2b959f57c0d2c7 (diff)
downloadrpgedit-af04cbe3592656cf6981232550a460f1b10e2560.tar
rpgedit-af04cbe3592656cf6981232550a460f1b10e2560.zip
view: refactor generic parts of MapView into a TileView
Diffstat (limited to 'src/view')
-rw-r--r--src/view/MapLoader.ts8
-rw-r--r--src/view/MapView.ts80
-rw-r--r--src/view/tile.ts74
3 files changed, 101 insertions, 61 deletions
diff --git a/src/view/MapLoader.ts b/src/view/MapLoader.ts
index 878fef4..a35eeec 100644
--- a/src/view/MapLoader.ts
+++ b/src/view/MapLoader.ts
@@ -1,4 +1,6 @@
-import {mapValues, mapValuesAsync, nextPowerOf2} from '../util';
+import { mapValues, mapValuesAsync, nextPowerOf2 } from '../util';
+
+import { TileCoords } from './tile';
import MapState from '../model/state/MapState';
import MapView from './MapView';
@@ -6,7 +8,7 @@ import Renderer from './renderer/Renderer';
export interface TileMap {
texture: WebGLTexture;
- tiles: Map<string, [number, number, number, number]>;
+ tiles: Map<string, TileCoords>;
}
function loadImage(url: string): Promise<HTMLImageElement> {
@@ -54,7 +56,7 @@ function mkTileMap(
canvas.width = canvas.height = canvasSize;
let x = 0, y = 0;
- const map: Map<string, [number, number, number, number]> = new Map();
+ const map: Map<string, TileCoords> = new Map();
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
for (const [k, tile] of tiles) {
diff --git a/src/view/MapView.ts b/src/view/MapView.ts
index 1061196..a5af8f7 100644
--- a/src/view/MapView.ts
+++ b/src/view/MapView.ts
@@ -1,74 +1,38 @@
import MapState from '../model/state/MapState';
-import {TileMap} from './MapLoader';
+import { TileMap } from './MapLoader';
import Renderer from './renderer/Renderer';
+import { TileView, TileViewBuilder } from './tile';
export default class MapView {
- private readonly vertexBuffer: WebGLBuffer;
- private readonly textureBuffer: WebGLBuffer;
+ private static addTile(builder: TileViewBuilder, tileMap: TileMap, x: number, y: number, tile: string) {
+ if (tile === ' ')
+ return;
+
+ const tilePos = tileMap.tiles.get(tile);
+ if (!tilePos)
+ throw new Error('invalid tile specifier in map data');
+
+ builder.addTile([x, y, x + 1, y + 1], tilePos);
+ }
+
+ private readonly tileView: TileView;
constructor(
- private readonly r: Renderer,
- private readonly map: MapState,
- private readonly tileMap: TileMap,
+ r: Renderer,
+ map: MapState,
+ tileMap: TileMap,
) {
- const vertexData: number[] = [];
- const textureData: number[] = [];
+ const builder = new TileViewBuilder(r, tileMap.texture);
for (let x = 0; x < map.data.width; x++)
for (let y = 0; y < map.data.height; y++)
for (const layer of map.data.layers)
- this.addTile(vertexData, textureData, x, y, layer[y][x]);
-
- const gl = r.getContext();
+ MapView.addTile(builder, tileMap, x, y, layer[y][x]);
- this.vertexBuffer = r.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
-
- this.textureBuffer = r.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureData), gl.STATIC_DRAW);
+ this.tileView = builder.build();
}
- public draw(): void {
- const gl = this.r.getContext();
-
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.tileMap.texture);
- gl.uniform1i(this.r.getSamplerLoc(), 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.vertexAttribPointer(this.r.getVertexPosLoc(), 2, gl.FLOAT, false, 0, 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
- gl.vertexAttribPointer(this.r.getTextureCoordLoc(), 2, gl.FLOAT, false, 0, 0);
-
- gl.drawArrays(gl.TRIANGLES, 0, 6 * this.map.data.width * this.map.data.height);
- }
-
- private pushTile(buf: number[], coords: [number, number, number, number]) {
- const [x1, y1, x2, y2] = coords;
-
- buf.push(x1); buf.push(y1);
- buf.push(x2); buf.push(y1);
- buf.push(x1); buf.push(y2);
-
- buf.push(x1); buf.push(y2);
- buf.push(x2); buf.push(y1);
- buf.push(x2); buf.push(y2);
- }
-
- private addTile(vertexData: number[], textureData: number[], x: number, y: number, tile: string) {
- if (tile === ' ')
- return;
-
- const tilePos = this.tileMap.tiles.get(tile);
- if (!tilePos)
- throw new Error('invalid tile specifier in map data');
-
- this.pushTile(vertexData, [x, y, x + 1, y + 1]);
- this.pushTile(textureData, tilePos);
+ public render(): void {
+ this.tileView.render();
}
}
diff --git a/src/view/tile.ts b/src/view/tile.ts
new file mode 100644
index 0000000..d748ec9
--- /dev/null
+++ b/src/view/tile.ts
@@ -0,0 +1,74 @@
+import Renderer from './renderer/Renderer';
+
+export type TileCoords = [number, number, number, number];
+
+export class TileViewBuilder {
+ private static pushTile(buf: number[], coords: TileCoords): void {
+ const [x1, y1, x2, y2] = coords;
+
+ buf.push(x1); buf.push(y1);
+ buf.push(x2); buf.push(y1);
+ buf.push(x1); buf.push(y2);
+
+ buf.push(x1); buf.push(y2);
+ buf.push(x2); buf.push(y1);
+ buf.push(x2); buf.push(y2);
+ }
+
+ private readonly vertexData: number[] = [];
+ private readonly textureData: number[] = [];
+
+ constructor(private readonly r: Renderer, private readonly texture: WebGLTexture) {}
+
+ public addTile(vertexCoords: TileCoords, texCoords: TileCoords): void {
+ TileViewBuilder.pushTile(this.vertexData, vertexCoords);
+ TileViewBuilder.pushTile(this.textureData, texCoords);
+ }
+
+ public build(): TileView {
+ return new TileView(this.r, this.texture, this.vertexData, this.textureData);
+ }
+}
+
+export class TileView {
+ private readonly primitiveCount: number;
+ private readonly vertexBuffer: WebGLBuffer;
+ private readonly textureBuffer: WebGLBuffer;
+
+ constructor(
+ private readonly r: Renderer,
+ private readonly texture: WebGLTexture,
+ vertexData: number[],
+ textureData: number[],
+ ) {
+ const gl = r.getContext();
+
+ this.vertexBuffer = r.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
+
+ this.textureBuffer = r.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureData), gl.STATIC_DRAW);
+
+ this.primitiveCount = vertexData.length / 3;
+ }
+
+ public render(): void {
+ const gl = this.r.getContext();
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
+ gl.uniform1i(this.r.getSamplerLoc(), 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.vertexAttribPointer(this.r.getVertexPosLoc(), 2, gl.FLOAT, false, 0, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
+ gl.vertexAttribPointer(this.r.getTextureCoordLoc(), 2, gl.FLOAT, false, 0, 0);
+
+ gl.drawArrays(gl.TRIANGLES, 0, this.primitiveCount);
+ }
+}