initial implementation of WebGL-based brush renderer
This commit is contained in:
parent
b4c3260f49
commit
bb55e23979
14 changed files with 385 additions and 247 deletions
|
@ -2,6 +2,8 @@ import { listen, Pool } from "rkgk/framework.js";
|
|||
import { Viewport } from "rkgk/viewport.js";
|
||||
import { Wall, chunkKey } from "rkgk/wall.js";
|
||||
import { AtlasAllocator } from "rkgk/chunk-allocator.js";
|
||||
import { compileProgram } from "rkgk/webgl.js";
|
||||
import { BrushRenderer } from "rkgk/brush-renderer.js";
|
||||
|
||||
class CanvasRenderer extends HTMLElement {
|
||||
viewport = new Viewport();
|
||||
|
@ -74,7 +76,7 @@ class CanvasRenderer extends HTMLElement {
|
|||
// Renderer initialization
|
||||
|
||||
#initializeRenderer() {
|
||||
console.groupCollapsed("initializeRenderer");
|
||||
console.group("initializeRenderer");
|
||||
|
||||
console.info("vendor", this.gl.getParameter(this.gl.VENDOR));
|
||||
console.info("renderer", this.gl.getParameter(this.gl.RENDERER));
|
||||
|
@ -93,7 +95,9 @@ class CanvasRenderer extends HTMLElement {
|
|||
// We also realistically don't need anymore, because (at least at the time I'm writing this)
|
||||
// we store (8 * 8 = 64) chunks per texture atlas, so we can't batch more than that.
|
||||
const maxRects = 64;
|
||||
let renderChunksProgramId = this.#compileProgram(
|
||||
let renderChunksProgramId = compileProgram(
|
||||
this.gl,
|
||||
|
||||
// Vertex
|
||||
`#version 300 es
|
||||
|
||||
|
@ -200,47 +204,13 @@ class CanvasRenderer extends HTMLElement {
|
|||
this.batches = [];
|
||||
this.batchPool = new Pool();
|
||||
|
||||
this.brushRenderer = new BrushRenderer(this.gl, this.atlasAllocator.canvasSource());
|
||||
|
||||
console.debug("GL error state", this.gl.getError());
|
||||
|
||||
console.groupEnd();
|
||||
}
|
||||
|
||||
#compileShader(kind, source) {
|
||||
let shader = this.gl.createShader(kind);
|
||||
|
||||
this.gl.shaderSource(shader, source);
|
||||
this.gl.compileShader(shader);
|
||||
|
||||
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
|
||||
let error = new Error(`failed to compile shader: ${this.gl.getShaderInfoLog(shader)}`);
|
||||
this.gl.deleteShader(shader);
|
||||
throw error;
|
||||
} else {
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
||||
#compileProgram(vertexSource, fragmentSource) {
|
||||
let vertexShader = this.#compileShader(this.gl.VERTEX_SHADER, vertexSource);
|
||||
let fragmentShader = this.#compileShader(this.gl.FRAGMENT_SHADER, fragmentSource);
|
||||
|
||||
let program = this.gl.createProgram();
|
||||
this.gl.attachShader(program, vertexShader);
|
||||
this.gl.attachShader(program, fragmentShader);
|
||||
this.gl.linkProgram(program);
|
||||
|
||||
this.gl.deleteShader(vertexShader);
|
||||
this.gl.deleteShader(fragmentShader);
|
||||
|
||||
if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
|
||||
let error = new Error(`failed to link program: ${this.gl.getProgramInfoLog(program)}`);
|
||||
this.gl.deleteProgram(program);
|
||||
throw error;
|
||||
} else {
|
||||
return program;
|
||||
}
|
||||
}
|
||||
|
||||
// Renderer
|
||||
|
||||
#render() {
|
||||
|
@ -256,6 +226,7 @@ class CanvasRenderer extends HTMLElement {
|
|||
}
|
||||
|
||||
this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
|
||||
this.gl.scissor(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
||||
this.gl.clearColor(1, 1, 1, 1);
|
||||
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
||||
|
@ -303,8 +274,9 @@ class CanvasRenderer extends HTMLElement {
|
|||
|
||||
this.#resetRectBuffer();
|
||||
for (let chunk of chunks) {
|
||||
let { i, allocation } = chunk.allocation;
|
||||
let atlas = this.atlasAllocator.atlases[i];
|
||||
let atlasIndex = this.atlasAllocator.getAtlasIndex(chunk.id);
|
||||
let allocation = this.atlasAllocator.getAllocation(chunk.id);
|
||||
let atlas = this.atlasAllocator.atlases[atlasIndex];
|
||||
this.#pushRect(
|
||||
chunk.x * this.wall.chunkSize,
|
||||
chunk.y * this.wall.chunkSize,
|
||||
|
@ -358,15 +330,14 @@ class CanvasRenderer extends HTMLElement {
|
|||
for (let chunkX = left; chunkX < right; ++chunkX) {
|
||||
let chunk = layer.getChunk(chunkX, chunkY);
|
||||
if (chunk != null) {
|
||||
let allocation = chunk.id;
|
||||
|
||||
let array = batch.get(allocation.i);
|
||||
let atlasIndex = this.atlasAllocator.getAtlasIndex(chunk.id);
|
||||
let array = batch.get(atlasIndex);
|
||||
if (array == null) {
|
||||
array = [];
|
||||
batch.set(allocation.i, array);
|
||||
batch.set(atlasIndex, array);
|
||||
}
|
||||
|
||||
array.push({ layerId: layer.id, x: chunkX, y: chunkY, allocation });
|
||||
array.push({ layerId: layer.id, x: chunkX, y: chunkY, id: chunk.id });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue