summaryrefslogtreecommitdiff
path: root/apps/web/src/services/renderer/webgl/webgl-context.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/services/renderer/webgl/webgl-context.ts')
-rw-r--r--apps/web/src/services/renderer/webgl/webgl-context.ts49
1 files changed, 49 insertions, 0 deletions
diff --git a/apps/web/src/services/renderer/webgl/webgl-context.ts b/apps/web/src/services/renderer/webgl/webgl-context.ts
new file mode 100644
index 00000000..aeefc503
--- /dev/null
+++ b/apps/web/src/services/renderer/webgl/webgl-context.ts
@@ -0,0 +1,49 @@
+import { createOffscreenCanvas } from "../canvas-utils";
+
+let gl: WebGLRenderingContext | null = null;
+let webglCanvas: OffscreenCanvas | HTMLCanvasElement | null = null;
+const programCache = new Map<string, WebGLProgram>();
+
+export function getWebGLContext({
+ width,
+ height,
+}: {
+ width: number;
+ height: number;
+}): {
+ context: WebGLRenderingContext;
+ programCache: Map<string, WebGLProgram>;
+} {
+ if (!webglCanvas) {
+ webglCanvas = createOffscreenCanvas({ width, height });
+ gl = webglCanvas.getContext("webgl", {
+ premultipliedAlpha: false,
+ }) as WebGLRenderingContext | null;
+ if (!gl) throw new Error("WebGL not supported");
+ }
+ if (webglCanvas.width !== width || webglCanvas.height !== height) {
+ webglCanvas.width = width;
+ webglCanvas.height = height;
+ }
+ if (!gl) throw new Error("WebGL context lost");
+ return { context: gl, programCache };
+}
+
+export function readResult({
+ width,
+ height,
+}: {
+ width: number;
+ height: number;
+}): OffscreenCanvas | HTMLCanvasElement {
+ if (!webglCanvas) throw new Error("WebGL canvas not initialized");
+ const outputCanvas = createOffscreenCanvas({ width, height });
+ const outputCtx = outputCanvas.getContext("2d") as
+ | CanvasRenderingContext2D
+ | OffscreenCanvasRenderingContext2D
+ | null;
+ if (outputCtx) {
+ outputCtx.drawImage(webglCanvas, 0, 0, width, height);
+ }
+ return outputCanvas;
+}