From dc6ff785ba615b96278f52041103cd441d27a71e Mon Sep 17 00:00:00 2001 From: Azgaar Date: Thu, 12 Mar 2026 19:36:25 +0100 Subject: [PATCH] refactor: Simplify texture loading and disposal in draw-relief-icons renderer --- src/modules/webgl-layer.ts | 19 +++++++++--------- src/renderers/draw-relief-icons.ts | 31 +++++++++--------------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/modules/webgl-layer.ts b/src/modules/webgl-layer.ts index d6ed3d50..a7f9bde3 100644 --- a/src/modules/webgl-layer.ts +++ b/src/modules/webgl-layer.ts @@ -4,7 +4,7 @@ import { byId } from "../utils"; export interface WebGLLayerConfig { id: string; setup: (group: Group) => void; // called once after WebGL2 confirmed; add meshes to group - render: (group: Group) => void; // called each frame before renderer.render(); update uniforms/geometry + render?: (group: Group) => void; // called each frame before renderer.render(); update uniforms/geometry dispose: (group: Group) => void; // called on unregister(); dispose all GPU objects in group } interface RegisteredLayer { @@ -48,7 +48,7 @@ export class WebGL2LayerClass { return true; } - register(config: WebGLLayerConfig): void { + register(config: WebGLLayerConfig) { if (!this.scene) { // init() has not been called yet — queue for processing in init() this.pendingConfigs.push(config); @@ -63,7 +63,7 @@ export class WebGL2LayerClass { this.layers.set(config.id, { config, group }); } - unregister(id: string): void { + unregister(id: string) { const layer = this.layers.get(id); if (!layer || !this.scene) return; const scene = this.scene; @@ -74,7 +74,7 @@ export class WebGL2LayerClass { if (this.canvas && !anyVisible) this.canvas.style.display = "none"; } - setVisible(id: string, visible: boolean): void { + setVisible(id: string, visible: boolean) { const layer = this.layers.get(id); if (!layer) return; layer.group.visible = visible; @@ -83,14 +83,14 @@ export class WebGL2LayerClass { if (visible) this.requestRender(); } - clearLayer(id: string): void { + clearLayer(id: string) { const layer = this.layers.get(id); if (!layer) return; layer.group.clear(); this.requestRender(); } - requestRender(): void { + requestRender() { if (this.rafId !== null) return; this.rafId = requestAnimationFrame(() => { this.rafId = null; @@ -98,7 +98,7 @@ export class WebGL2LayerClass { }); } - syncTransform(): void { + private syncTransform() { if (!this.camera) return; const x = -viewX / scale; const y = -viewY / scale; @@ -112,11 +112,12 @@ export class WebGL2LayerClass { this.camera.updateProjectionMatrix(); } - private render(): void { + private render() { if (!this.renderer || !this.scene || !this.camera) return; this.syncTransform(); for (const layer of this.layers.values()) { - if (layer.group.visible) layer.config.render(layer.group); + if (layer.group.visible && layer.config.render) + layer.config.render(layer.group); } this.renderer.render(this.scene, this.camera); } diff --git a/src/renderers/draw-relief-icons.ts b/src/renderers/draw-relief-icons.ts index a39285eb..c36c1491 100644 --- a/src/renderers/draw-relief-icons.ts +++ b/src/renderers/draw-relief-icons.ts @@ -25,10 +25,7 @@ WebGLLayer.register({ id: "terrain", setup(group: Group): void { terrainGroup = group; - preloadTextures(); - }, - render(_group: Group): void { - // no-op: relief geometry is static between drawRelief() calls + for (const set of Object.keys(RELIEF_SYMBOLS)) loadTexture(set); }, dispose(group: Group): void { group.traverse((obj) => { @@ -38,14 +35,11 @@ WebGLLayer.register({ (obj.material as MeshBasicMaterial).dispose(); } }); - disposeTextureCache(); + for (const tex of textureCache.values()) tex?.dispose(); + textureCache.clear(); }, }); -function preloadTextures(): void { - for (const set of Object.keys(RELIEF_SYMBOLS)) loadTexture(set); -} - function loadTexture(set: string): Promise { if (textureCache.has(set)) return Promise.resolve(textureCache.get(set) ?? null); @@ -147,11 +141,6 @@ function buildSetMesh( return new Mesh(geo, mat); } -function disposeTextureCache(): void { - for (const tex of textureCache.values()) tex?.dispose(); - textureCache.clear(); -} - function buildReliefScene(icons: ReliefIcon[]): void { if (!terrainGroup) return; terrainGroup.traverse((obj) => { @@ -208,14 +197,12 @@ window.drawRelief = ( drawSvg(icons, parentEl); } else { const set = parentEl.getAttribute("set") || "simple"; - loadTexture(set).then(() => { - if (icons !== lastBuiltIcons || set !== lastBuiltSet) { - buildReliefScene(icons); - lastBuiltIcons = icons; - lastBuiltSet = set; - } - WebGLLayer.requestRender(); - }); + if (icons !== lastBuiltIcons || set !== lastBuiltSet) { + buildReliefScene(icons); + lastBuiltIcons = icons; + lastBuiltSet = set; + } + WebGLLayer.requestRender(); } };