Skip to content

Commit f9f4824

Browse files
committed
Reimplement all other debug renderers
1 parent 8dbde45 commit f9f4824

10 files changed

Lines changed: 213 additions & 40 deletions

src/renderer/GameGLContext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ type AttributeOptions = {
442442
};
443443

444444
export type WebGLUniforms<T extends string> = {
445-
[K in `set${1 | 2 | 3 | 4}${"i" | "ui" | "f"}`]: (uniform: T, ...args: K extends `set${infer U extends number}${"i" | "ui" | "f"}` ? Tuple<number, U> : never) => void
445+
[K in `set${1 | 2 | 3 | 4}${"i" | "ui" | "f"}`]: (uniform: T, ...args: K extends `set${infer U extends 1 | 2 | 3 | 4}${"i" | "ui" | "f"}` ? Tuple<number, U> : never) => void
446446
} & {
447447
[K in `set${1 | 2 | 3 | 4}${"i" | "ui" | "f"}v`]: (uniform: T, data: K extends `set${1 | 2 | 3 | 4}${infer U}v` ? U extends "i" ? Int32List : U extends "ui" ? Uint32List : U extends "f" ? Float32List : never : never, srcOffset?: number, srcLength?: GLuint) => void
448448
} & Omit<{

src/renderer/layer/debug/BoatBotWaypointDebugRenderer.ts

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,60 @@ import {DebugRendererLayer} from "./DebugRenderer";
22
import {mapNavigationHandler} from "../../../game/action/MapNavigationHandler";
33
import {gameMap} from "../../../game/GameData";
44
import {getSettingObject} from "../../../util/settings/UserSettingManager";
5+
import {GameGLContext, WebGLUniforms} from "../../GameGLContext";
6+
import {compositeVertexShader, constantColorFragmentShader} from "../../shader/ShaderManager";
7+
import {BaseRendererLayer} from "../BaseRendererLayer";
58

69
//@module renderer-debug
710

8-
export class BoatBotWaypointDebugRenderer implements DebugRendererLayer {
11+
export class BoatBotWaypointDebugRenderer extends BaseRendererLayer implements DebugRendererLayer {
912
readonly useCache = false;
13+
private program: WebGLProgram;
14+
private vao: WebGLVertexArrayObject;
15+
private uniforms: WebGLUniforms<"offset" | "size" | "color">;
16+
private positionBuffer: WebGLBuffer;
1017

11-
render(context: CanvasRenderingContext2D): void {
12-
context.strokeStyle = "red";
13-
context.fillStyle = "orange";
18+
setup(context: GameGLContext): void {
19+
this.program = context.requireProgram(compositeVertexShader, constantColorFragmentShader, "Boat waypoint debug renderer failed to init");
20+
this.positionBuffer = context.createBuffer();
21+
this.vao = context.createVertexArray(this.program, {name: "pos", size: 2, type: WebGL2RenderingContext.FLOAT, buffer: this.positionBuffer});
22+
this.uniforms = context.loadUniforms(this.program, "offset", "size", "color");
23+
}
24+
25+
render(context: GameGLContext): void {
26+
context.bind(this.program, this.vao);
27+
28+
let lineCount = 0;
29+
for (const [_, targets] of gameMap.boatTargets) {
30+
for (const target of targets) {
31+
lineCount += target.path.length - 1;
32+
}
33+
}
34+
35+
const lines = new Float32Array(lineCount * 2);
36+
let offset = 0;
1437
for (const [source, targets] of gameMap.boatTargets) {
1538
for (const target of targets) {
1639
if (source > target.tile) continue; // Only draw each edge once
17-
context.beginPath();
18-
context.moveTo((target.path[0] % gameMap.width + 0.5) * mapNavigationHandler.zoom + mapNavigationHandler.x, (Math.floor(target.path[0] / gameMap.width) + 0.5) * mapNavigationHandler.zoom + mapNavigationHandler.y);
1940
for (let i = 1; i < target.path.length; i++) {
20-
context.lineTo((target.path[i] % gameMap.width + 0.5) * mapNavigationHandler.zoom + mapNavigationHandler.x, (Math.floor(target.path[i] / gameMap.width) + 0.5) * mapNavigationHandler.zoom + mapNavigationHandler.y);
41+
lines[offset++] = target.path[i - 1] % gameMap.width + 0.5;
42+
lines[offset++] = Math.floor(target.path[i - 1] / gameMap.width) + 0.5;
43+
lines[offset++] = target.path[i] % gameMap.width + 0.5;
44+
lines[offset++] = Math.floor(target.path[i] / gameMap.width) + 0.5;
2145
}
22-
context.stroke();
2346
}
2447
}
48+
49+
const parentWidth = context.raw.canvas.width;
50+
const parentHeight = context.raw.canvas.height;
51+
52+
this.uniforms.set2f("offset", mapNavigationHandler.x / parentWidth, mapNavigationHandler.y / parentHeight);
53+
this.uniforms.set2f("size", mapNavigationHandler.zoom / parentWidth, mapNavigationHandler.zoom / parentHeight);
54+
this.uniforms.set4f("color", 1, 0, 0, 0.8);
55+
56+
context.bufferData(this.positionBuffer, lines, WebGL2RenderingContext.STATIC_DRAW);
57+
58+
context.drawLines(lineCount / 2);
2559
}
2660
}
2761

src/renderer/layer/debug/BoatMeshDebugRenderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class BoatMeshDebugRenderer extends BaseRendererLayer implements DebugRen
1717
private edgeCount: number;
1818

1919
setup(context: GameGLContext): void {
20-
this.program = context.requireProgram(compositeVertexShader, constantColorFragmentShader, "Boat renderer failed to init");
20+
this.program = context.requireProgram(compositeVertexShader, constantColorFragmentShader, "Boat mesh debug renderer failed to init");
2121
this.positionBuffer = context.createBuffer();
2222
this.vao = context.createVertexArray(this.program, {name: "pos", size: 2, type: WebGL2RenderingContext.FLOAT, buffer: this.positionBuffer});
2323
this.uniforms = context.loadUniforms(this.program, "offset", "size", "color");

src/renderer/layer/debug/DebugRenderer.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,26 @@ class DebugRenderer extends CachedLayer {
2222
* @param layers layers to be rendered
2323
*/
2424
updateLayers(layers: DebugRendererLayer[]): void {
25-
if (!this.context) return;
2625
this.mapLayers.length = 0;
2726
this.liveLayers.length = 0;
28-
layers.forEach(layer => layer.init(this.context));
29-
this.context.raw.clearBufferiv(WebGL2RenderingContext.COLOR, 0, [0, 0, 0, 0]);
30-
this.context.bindFramebuffer(this.framebuffer);
27+
if (this.context) {
28+
layers.forEach(layer => layer.init(this.context));
29+
this.context.bindFramebuffer(this.framebuffer);
30+
this.context.raw.clearBufferfv(WebGL2RenderingContext.COLOR, 0, [0, 0, 0, 0]);
31+
this.context.viewport(gameMap.width, gameMap.height);
32+
}
3133
for (const layer of layers) {
3234
if (layer.useCache) {
3335
this.mapLayers.push(layer);
34-
layer.render(this.context);
36+
if (this.context) layer.render(this.context);
3537
} else {
3638
this.liveLayers.push(layer);
3739
}
3840
}
39-
this.context.resetFramebuffer();
41+
if (this.context) {
42+
this.context.resetFramebuffer();
43+
this.context.viewport();
44+
}
4045
}
4146

4247
render(context: GameGLContext) {
@@ -50,8 +55,10 @@ class DebugRenderer extends CachedLayer {
5055
this.mapLayers.forEach(layer => layer.init(context));
5156
this.liveLayers.forEach(layer => layer.init(context));
5257
context.bindFramebuffer(this.framebuffer);
58+
this.context.viewport(gameMap.width, gameMap.height);
5359
this.mapLayers.forEach(layer => layer.render(context));
5460
context.resetFramebuffer();
61+
context.viewport();
5562
}
5663

5764
onMapMove(this: void, x: number, y: number): void {

src/renderer/layer/debug/NameDepthDebugRenderer.ts

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,67 @@ import {playerNameRenderingManager} from "../../manager/PlayerNameRenderingManag
33
import {gameMap} from "../../../game/GameData";
44
import {mapNavigationHandler} from "../../../game/action/MapNavigationHandler";
55
import {getSettingObject} from "../../../util/settings/UserSettingManager";
6+
import {BaseRendererLayer} from "../BaseRendererLayer";
7+
import {GameGLContext, WebGLUniforms} from "../../GameGLContext";
8+
import {linearLookupFragmentShader, mapGridCompositeVertexShader} from "../../shader/ShaderManager";
69

710
//@module renderer-debug
811

9-
export class NameDepthDebugRenderer implements DebugRendererLayer {
12+
export class NameDepthDebugRenderer extends BaseRendererLayer implements DebugRendererLayer {
1013
readonly useCache = false;
14+
private program: WebGLProgram;
15+
private vao: WebGLVertexArrayObject;
16+
private uniforms: WebGLUniforms<"width" | "scale" | "size" | "offset" | "palette_data" | "length">;
17+
private palette: WebGLTexture;
18+
private positionBuffer: WebGLBuffer;
19+
private depthBuffer: WebGLBuffer;
20+
21+
setup(context: GameGLContext): void {
22+
this.program = context.requireProgram(mapGridCompositeVertexShader, linearLookupFragmentShader, "Name depth debug renderer failed to init");
23+
this.positionBuffer = context.createBuffer();
24+
this.depthBuffer = context.createBuffer();
25+
this.vao = context.createVertexArray(this.program, {name: "pos", size: 1, type: WebGL2RenderingContext.UNSIGNED_INT, buffer: this.positionBuffer, asInt: true}, {name: "id", size: 1, type: WebGL2RenderingContext.UNSIGNED_BYTE, buffer: this.depthBuffer, asInt: true});
26+
this.uniforms = context.loadUniforms(this.program, "width", "scale", "size", "offset", "palette_data", "length");
27+
this.palette = context.createTexture(2, 1, new Uint8Array([0, 255, 0, 128, 255, 0, 0, 128]), {internalFormat: WebGL2RenderingContext.RGBA, format: WebGL2RenderingContext.RGBA, magFilter: WebGL2RenderingContext.LINEAR});
28+
}
29+
30+
render(context: GameGLContext): void {
31+
context.bind(this.program, this.vao);
32+
context.bindTexture(this.palette);
1133

12-
render(context: CanvasRenderingContext2D): void {
1334
const map = playerNameRenderingManager.getNameDepth();
1435
const xMin = mapNavigationHandler.getMapX(0);
15-
const xMax = mapNavigationHandler.getMapX(context.canvas.width);
36+
const xMax = mapNavigationHandler.getMapX(context.raw.canvas.width);
1637
const yMin = mapNavigationHandler.getMapY(0);
17-
const yMax = mapNavigationHandler.getMapY(context.canvas.height);
38+
const yMax = mapNavigationHandler.getMapY(context.raw.canvas.height);
39+
40+
const tileData: number[] = [];
41+
const depthData: number[] = [];
1842
for (let i = 0; i < gameMap.width * gameMap.height; i++) {
1943
if (mapNavigationHandler.zoom < 1 || i % gameMap.width + 1 < xMin || i % gameMap.width > xMax || Math.floor(i / gameMap.width) + 1 < yMin || Math.floor(i / gameMap.width) > yMax) {
2044
continue;
2145
}
2246
const depth = map[i];
2347
if (depth !== 0) {
24-
context.fillStyle = `rgba(${255 * depth / 50}, 0, 0, 0.5)`;
25-
context.fillRect((i % gameMap.width) * mapNavigationHandler.zoom + mapNavigationHandler.x, Math.floor(i / gameMap.width) * mapNavigationHandler.zoom + mapNavigationHandler.y, mapNavigationHandler.zoom, mapNavigationHandler.zoom);
48+
tileData.push(i);
49+
depthData.push(depth);
2650
}
2751
}
52+
const parentWidth = context.raw.canvas.width;
53+
const parentHeight = context.raw.canvas.height;
54+
55+
this.uniforms.set1ui("width", gameMap.width);
56+
this.uniforms.set1f("scale", mapNavigationHandler.zoom);
57+
this.uniforms.set2f("offset", mapNavigationHandler.x / parentWidth, mapNavigationHandler.y / parentHeight);
58+
this.uniforms.set2f("size", mapNavigationHandler.zoom / parentWidth, mapNavigationHandler.zoom / parentHeight);
59+
this.uniforms.set1ui("length", 50);
60+
this.uniforms.set1i("palette_data", 0);
61+
62+
context.bufferData(this.positionBuffer, new Uint32Array(tileData), WebGL2RenderingContext.DYNAMIC_DRAW);
63+
context.bufferData(this.depthBuffer, new Uint8Array(depthData), WebGL2RenderingContext.DYNAMIC_DRAW);
64+
65+
context.drawPoints(tileData.length);
66+
2867
}
2968
}
3069

src/renderer/layer/debug/TerrainDepthRenderer.ts

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,52 @@
11
import {DebugRendererLayer} from "./DebugRenderer";
22
import {gameMap} from "../../../game/GameData";
33
import {getSettingObject} from "../../../util/settings/UserSettingManager";
4+
import {GameGLContext, WebGLUniforms} from "../../GameGLContext";
5+
import {linearLookupFragmentShader, mapGridLookupVertexShader} from "../../shader/ShaderManager";
6+
import {BaseRendererLayer} from "../BaseRendererLayer";
47

58
//@module renderer-debug
69

7-
export class TerrainDepthRenderer implements DebugRendererLayer {
10+
export class TerrainDepthRenderer extends BaseRendererLayer implements DebugRendererLayer {
811
readonly useCache = true;
12+
private program: WebGLProgram;
13+
private vao: WebGLVertexArrayObject;
14+
private uniforms: WebGLUniforms<"size" | "palette_data" | "length">;
15+
private palette: WebGLTexture;
16+
private positionBuffer: WebGLBuffer;
17+
private depthBuffer: WebGLBuffer;
918

10-
render(context: CanvasRenderingContext2D): void {
19+
setup(context: GameGLContext): void {
20+
this.program = context.requireProgram(mapGridLookupVertexShader, linearLookupFragmentShader, "Name depth debug renderer failed to init");
21+
this.positionBuffer = context.createBuffer();
22+
this.depthBuffer = context.createBuffer();
23+
this.vao = context.createVertexArray(this.program, {name: "pos", size: 1, type: WebGL2RenderingContext.UNSIGNED_INT, buffer: this.positionBuffer, asInt: true}, {name: "id", size: 1, type: WebGL2RenderingContext.UNSIGNED_SHORT, buffer: this.depthBuffer, asInt: true});
24+
this.uniforms = context.loadUniforms(this.program, "size", "palette_data", "length");
25+
this.palette = context.createTexture(3, 1, new Uint8Array([0, 0, 0, 128, 0, 255, 0, 128, 0, 0, 255, 128, 255, 0, 255, 128]), {internalFormat: WebGL2RenderingContext.RGBA, format: WebGL2RenderingContext.RGBA, magFilter: WebGL2RenderingContext.LINEAR});
26+
}
27+
28+
init(context: GameGLContext) {
29+
super.init(context);
30+
31+
const tiles = new Uint32Array(gameMap.width * gameMap.height);
1132
for (let i = 0; i < gameMap.width * gameMap.height; i++) {
12-
const depth = gameMap.distanceMap[i];
13-
if (depth > 0) {
14-
context.fillStyle = `rgba(0, ${255 * depth / 50}, 0, 0.5)`;
15-
} else {
16-
context.fillStyle = `rgba(0, 0, ${255 * -depth / 50}, 0.5)`;
17-
}
18-
context.fillRect(i % gameMap.width, Math.floor(i / gameMap.width), 1, 1);
33+
tiles[i] = i;
1934
}
35+
36+
context.bufferData(this.positionBuffer, tiles, WebGL2RenderingContext.DYNAMIC_DRAW);
37+
}
38+
39+
render(context: GameGLContext): void {
40+
context.bind(this.program, this.vao);
41+
context.bindTexture(this.palette);
42+
43+
this.uniforms.set2i("size", gameMap.width, gameMap.height);
44+
this.uniforms.set1ui("length", 100);
45+
this.uniforms.set1i("palette_data", 0);
46+
47+
context.bufferData(this.depthBuffer, Uint16Array.from(gameMap.distanceMap, v => Math.max(0, v + 50)), WebGL2RenderingContext.DYNAMIC_DRAW);
48+
49+
context.drawPoints(gameMap.width * gameMap.height);
2050
}
2151
}
2252

src/renderer/layer/debug/TerrainInfluenceRenderer.ts

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,66 @@
11
import {DebugRendererLayer} from "./DebugRenderer";
22
import {gameMap} from "../../../game/GameData";
33
import {getSettingObject} from "../../../util/settings/UserSettingManager";
4+
import {GameGLContext, WebGLUniforms} from "../../GameGLContext";
5+
import {linearLookupFragmentShader, mapGridLookupVertexShader} from "../../shader/ShaderManager";
6+
import {BaseRendererLayer} from "../BaseRendererLayer";
47

58
//@module renderer-debug
69

7-
export class TerrainInfluenceRenderer implements DebugRendererLayer {
10+
export class TerrainInfluenceRenderer extends BaseRendererLayer implements DebugRendererLayer{
811
readonly useCache = true;
12+
private program: WebGLProgram;
13+
private vao: WebGLVertexArrayObject;
14+
private uniforms: WebGLUniforms<"size" | "palette_data" | "length">;
15+
private palette: WebGLTexture;
16+
private positionBuffer: WebGLBuffer;
17+
private influenceBuffer: WebGLBuffer;
918

1019
/**
1120
* Create a new terrain influence renderer
1221
* @param simplified Whether to show tiles of the same area in the same color.
1322
* @param navigableOnly Whether to only show navigable tiles.
1423
*/
15-
constructor(private simplified: boolean, private navigableOnly: boolean) {}
24+
constructor(private simplified: boolean, private navigableOnly: boolean) {
25+
super();
26+
}
27+
28+
setup(context: GameGLContext): void {
29+
this.program = context.requireProgram(mapGridLookupVertexShader, linearLookupFragmentShader, "Terrain influence debug renderer failed to init");
30+
this.positionBuffer = context.createBuffer();
31+
this.influenceBuffer = context.createBuffer();
32+
this.vao = context.createVertexArray(this.program, {name: "pos", size: 1, type: WebGL2RenderingContext.UNSIGNED_INT, buffer: this.positionBuffer, asInt: true}, {name: "id", size: 1, type: WebGL2RenderingContext.UNSIGNED_SHORT, buffer: this.influenceBuffer, asInt: true});
33+
this.uniforms = context.loadUniforms(this.program, "size", "palette_data", "length");
34+
this.palette = context.createTexture(3, 1, new Uint8Array([255, 0, 0, 128, 255, 255, 0, 128, 0, 255, 0, 128, 0, 255, 255, 128, 0, 0, 255, 128, 255, 0, 255, 128, 255, 0, 0, 128]), {internalFormat: WebGL2RenderingContext.RGBA, format: WebGL2RenderingContext.RGBA, magFilter: WebGL2RenderingContext.LINEAR});
35+
}
36+
37+
render(context: GameGLContext): void {
38+
context.bind(this.program, this.vao);
39+
context.bindTexture(this.palette);
1640

17-
render(context: CanvasRenderingContext2D): void {
18-
const colorMap = new Map<number, string>();
41+
const tiles = [];
42+
const influence = [];
43+
const colorMap: number[] = [];
1944
for (let i = 0; i < gameMap.width * gameMap.height; i++) {
2045
if (this.navigableOnly && !gameMap.getTile(i).navigable) continue;
2146
const area = this.simplified ? gameMap.areaMap[gameMap.tileInfluence[i]] : gameMap.tileInfluence[i];
22-
let color = colorMap.get(area);
47+
let color = colorMap[area];
2348
if (!color) {
24-
color = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 0.5)`;
25-
colorMap.set(area, color);
49+
color = Math.floor(Math.random() * 6 * 255);
50+
colorMap[area] = color;
2651
}
27-
context.fillStyle = color;
28-
context.fillRect(i % gameMap.width, Math.floor(i / gameMap.width), 1, 1);
52+
tiles.push(i);
53+
influence.push(color);
2954
}
55+
56+
this.uniforms.set2i("size", gameMap.width, gameMap.height);
57+
this.uniforms.set1ui("length", 6 * 255);
58+
this.uniforms.set1i("palette_data", 0);
59+
60+
context.bufferData(this.positionBuffer, new Uint32Array(tiles), WebGL2RenderingContext.DYNAMIC_DRAW);
61+
context.bufferData(this.influenceBuffer, new Uint16Array(influence), WebGL2RenderingContext.DYNAMIC_DRAW);
62+
63+
context.drawPoints(gameMap.width * gameMap.height);
3064
}
3165
}
3266

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#version 300 es
2+
3+
precision highp float;
4+
5+
flat in uint texture_pos;
6+
uniform sampler2D palette_data;
7+
uniform uint length;
8+
out vec4 outColor;
9+
10+
void main() {
11+
outColor = texture(palette_data, vec2(float(texture_pos) / float(length), .5));
12+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#version 300 es
2+
3+
in uint pos;
4+
in uint id;
5+
uniform uint width;
6+
uniform float scale;
7+
uniform vec2 offset;
8+
uniform vec2 size;
9+
flat out uint texture_pos;
10+
11+
void main() {
12+
gl_Position = vec4((((size * (vec2(int(pos) % int(width), int(pos) / int(width)) + .5) + offset) * 2.) - 1.) * vec2(1, -1), 0, 1);
13+
gl_PointSize = scale;
14+
texture_pos = id;
15+
}

src/renderer/shader/ShaderManager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ export const colorCompositeVertexShader = (ctx: GameGLContext) => ctx.loadVertex
77
export const compositeVertexShader = (ctx: GameGLContext) => ctx.loadVertexShader("CompositeShader.vert");
88
export const simpleTextureVertexShader = (ctx: GameGLContext) => ctx.loadVertexShader("SimpleTextureShader.vert");
99
export const mapGridLookupVertexShader = (ctx: GameGLContext) => ctx.loadVertexShader("MapGridLookupShader.vert");
10+
export const mapGridCompositeVertexShader = (ctx: GameGLContext) => ctx.loadVertexShader("MapGridCompositeShader.vert");
1011
export const msdfTextureVertexShader = (ctx: GameGLContext) => ctx.loadVertexShader("MSDFTextureShader.vert");
1112

1213
export const simpleTextureFragmentShader = (ctx: GameGLContext) => ctx.loadFragmentShader("SimpleTextureShader.frag");
1314
export const mapRenderingFragmentShader = (ctx: GameGLContext) => ctx.loadFragmentShader("MapRenderingShader.frag");
1415
export const territoryRenderingFragmentShader = (ctx: GameGLContext) => ctx.loadFragmentShader("TerritoryRenderingShader.frag");
16+
export const linearLookupFragmentShader = (ctx: GameGLContext) => ctx.loadFragmentShader("LinearLookupShader.frag");
1517
export const distanceMapFragmentShader = (ctx: GameGLContext) => ctx.loadFragmentShader("DistanceMapShader.frag");
1618
export const msdfTextureFragmentShader = (ctx: GameGLContext) => ctx.loadFragmentShader("MSDFTextureShader.frag");
1719
export const simpleColorFragmentShader = (ctx: GameGLContext) => ctx.loadFragmentShader("SimpleColorShader.frag");

0 commit comments

Comments
 (0)