@babylonjs/lite-gl 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -34
- package/apply-states.d.ts +1 -0
- package/apply-states.js +30 -0
- package/apply-states.js.map +1 -0
- package/blend.d.ts +123 -0
- package/blend.js +194 -0
- package/blend.js.map +1 -0
- package/context.d.ts +130 -0
- package/context.js +354 -0
- package/context.js.map +1 -0
- package/depth-stencil.d.ts +155 -231
- package/depth-stencil.js +399 -262
- package/depth-stencil.js.map +1 -1
- package/dynamic-texture.d.ts +59 -149
- package/dynamic-texture.js +123 -69
- package/dynamic-texture.js.map +1 -1
- package/effect-renderer.d.ts +65 -0
- package/effect-renderer.js +132 -0
- package/effect-renderer.js.map +1 -0
- package/effect.d.ts +142 -0
- package/effect.js +465 -0
- package/effect.js.map +1 -0
- package/html-texture.d.ts +44 -143
- package/html-texture.js +87 -81
- package/html-texture.js.map +1 -1
- package/index.d.ts +23 -1482
- package/index.js +42 -263
- package/index.js.map +1 -1
- package/mesh.d.ts +210 -307
- package/mesh.js +436 -311
- package/mesh.js.map +1 -1
- package/package.json +5 -29
- package/render-loop.d.ts +8 -0
- package/render-loop.js +62 -0
- package/render-loop.js.map +1 -0
- package/render-target.d.ts +233 -290
- package/render-target.js +534 -335
- package/render-target.js.map +1 -1
- package/scissor.d.ts +30 -72
- package/scissor.js +47 -33
- package/scissor.js.map +1 -1
- package/shader.d.ts +22 -0
- package/shader.js +65 -0
- package/shader.js.map +1 -0
- package/sprites.d.ts +182 -263
- package/sprites.js +426 -10
- package/sprites.js.map +1 -1
- package/state.d.ts +126 -0
- package/state.js +153 -0
- package/state.js.map +1 -0
- package/texture.d.ts +142 -0
- package/texture.js +433 -0
- package/texture.js.map +1 -0
- package/effect-BxxwfB_O.js +0 -737
- package/effect-BxxwfB_O.js.map +0 -1
- package/sprites--1oyVtJ3.js +0 -437
- package/sprites--1oyVtJ3.js.map +0 -1
- package/state--j_ncWIi.js +0 -155
- package/state--j_ncWIi.js.map +0 -1
- package/texture-DaMd1gGm.js +0 -329
- package/texture-DaMd1gGm.js.map +0 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { GLEngineContext } from "./context.js";
|
|
2
|
+
import { type GLEffect } from "./effect.js";
|
|
3
|
+
/** Inputs to `createEffectWrapper`. Mirrors lite's `EffectWrapperOptions`: the
|
|
4
|
+
* wrapper compiles and OWNS the effect built from this shader source. */
|
|
5
|
+
export interface GLEffectWrapperOptions {
|
|
6
|
+
/** Human-readable label for the wrapper and its effect. Defaults to
|
|
7
|
+
* `"effect-wrapper"`. */
|
|
8
|
+
name?: string;
|
|
9
|
+
/** GLSL ES 3.00 vertex source. Defaults to a built-in fullscreen-quad
|
|
10
|
+
* vertex shader (exposing a `vUv` varying), mirroring lite's default
|
|
11
|
+
* `vertexWGSL`. */
|
|
12
|
+
vertexSource?: string;
|
|
13
|
+
/** GLSL ES 3.00 fragment source (≙ lite's `fragmentWGSL`). Required. */
|
|
14
|
+
fragmentSource: string;
|
|
15
|
+
/** Declared uniform names. Defaults to none. */
|
|
16
|
+
uniformNames?: readonly string[];
|
|
17
|
+
/** Declared sampler names, in unit-assignment order. Defaults to none. */
|
|
18
|
+
samplerNames?: readonly string[];
|
|
19
|
+
/** Attribute names; the first is bound to location 0. Defaults to
|
|
20
|
+
* `["position"]`. */
|
|
21
|
+
attributeNames?: readonly string[];
|
|
22
|
+
/** Optional `#define` block prepended to both shader stages. */
|
|
23
|
+
defines?: string;
|
|
24
|
+
}
|
|
25
|
+
/** A reusable fullscreen effect that compiles and OWNS its `GLEffect` — the
|
|
26
|
+
* WebGL counterpart of lite's `EffectWrapper`. The wrapper retains the engine
|
|
27
|
+
* it was created for, so `disposeEffectWrapper` / `applyEffectWrapper` take
|
|
28
|
+
* only the wrapper. */
|
|
29
|
+
export interface GLEffectWrapper {
|
|
30
|
+
/** Name alias for the wrapper (and its effect). */
|
|
31
|
+
readonly name: string;
|
|
32
|
+
/** The compiled effect this wrapper owns. Exposed so the per-uniform
|
|
33
|
+
* setters (`setEffectFloat`/`setEffectTexture`/…) can target it — the
|
|
34
|
+
* WebGL divergence from lite's UBO-based `setEffectUniforms(wrapper, …)`. */
|
|
35
|
+
readonly effect: GLEffect;
|
|
36
|
+
}
|
|
37
|
+
/** Compile a fullscreen effect from shader source and wrap it; the wrapper OWNS
|
|
38
|
+
* the resulting `GLEffect`. Mirrors lite's `createEffectWrapper(engine, options)`.
|
|
39
|
+
* When `vertexSource` is omitted, a built-in fullscreen-quad vertex shader is
|
|
40
|
+
* used, so callers can supply only `fragmentSource`. */
|
|
41
|
+
export declare function createEffectWrapper(engine: GLEngineContext, options: GLEffectWrapperOptions): GLEffectWrapper;
|
|
42
|
+
/** Dispose the wrapper and the effect it owns (idempotent). Mirrors lite's
|
|
43
|
+
* `disposeEffectWrapper(wrapper)`. */
|
|
44
|
+
export declare function disposeEffectWrapper(wrapper: GLEffectWrapper): void;
|
|
45
|
+
/** Pixel-space viewport rectangle passed to `setViewport`. */
|
|
46
|
+
export interface GLViewport {
|
|
47
|
+
/** Lower-left X origin in physical pixels. */
|
|
48
|
+
x: number;
|
|
49
|
+
/** Lower-left Y origin in physical pixels. */
|
|
50
|
+
y: number;
|
|
51
|
+
/** Width in physical pixels. */
|
|
52
|
+
w: number;
|
|
53
|
+
/** Height in physical pixels. */
|
|
54
|
+
h: number;
|
|
55
|
+
}
|
|
56
|
+
/** Cached `gl.viewport`. Defaults to the full canvas in pixel coordinates. */
|
|
57
|
+
export declare function setViewport(engine: GLEngineContext, viewport?: GLViewport): void;
|
|
58
|
+
/** Make `wrapper.effect` current and ensure the shared fullscreen quad VAO
|
|
59
|
+
* is bound. This MUST be called BEFORE any `setEffect*` call for the same
|
|
60
|
+
* effect in the current frame (uniform setters write to the currently bound
|
|
61
|
+
* program). */
|
|
62
|
+
export declare function applyEffectWrapper(wrapper: GLEffectWrapper): void;
|
|
63
|
+
/** `gl.drawElements(TRIANGLES, 6, UNSIGNED_SHORT, 0)`. No-op when the
|
|
64
|
+
* context is lost or there is no current program. */
|
|
65
|
+
export declare function drawEffect(engine: GLEngineContext): void;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createEffect, disposeEffect, useEffect } from "./effect.js";
|
|
2
|
+
import { applyGLStates } from "./apply-states.js";
|
|
3
|
+
/** Built-in fullscreen-quad vertex shader, used when `GLEffectWrapperOptions`
|
|
4
|
+
* omits `vertexSource`. Maps the package's fullscreen-quad positions
|
|
5
|
+
* (attribute location 0) to clip space and forwards a 0..1 `vUv` varying —
|
|
6
|
+
* the WebGL counterpart of lite's default `vertexWGSL`, so callers can pass
|
|
7
|
+
* only `fragmentSource`. */
|
|
8
|
+
const DEFAULT_FULLSCREEN_VERTEX_SOURCE = `#version 300 es
|
|
9
|
+
layout(location = 0) in vec2 position;
|
|
10
|
+
out vec2 vUv;
|
|
11
|
+
void main() {
|
|
12
|
+
vUv = position * 0.5 + 0.5;
|
|
13
|
+
gl_Position = vec4(position, 0.0, 1.0);
|
|
14
|
+
}`;
|
|
15
|
+
/** Compile a fullscreen effect from shader source and wrap it; the wrapper OWNS
|
|
16
|
+
* the resulting `GLEffect`. Mirrors lite's `createEffectWrapper(engine, options)`.
|
|
17
|
+
* When `vertexSource` is omitted, a built-in fullscreen-quad vertex shader is
|
|
18
|
+
* used, so callers can supply only `fragmentSource`. */
|
|
19
|
+
export function createEffectWrapper(engine, options) {
|
|
20
|
+
const name = options.name ?? "effect-wrapper";
|
|
21
|
+
const effect = createEffect(engine, {
|
|
22
|
+
name,
|
|
23
|
+
vertexSource: options.vertexSource ?? DEFAULT_FULLSCREEN_VERTEX_SOURCE,
|
|
24
|
+
fragmentSource: options.fragmentSource,
|
|
25
|
+
uniformNames: options.uniformNames ?? [],
|
|
26
|
+
samplerNames: options.samplerNames ?? [],
|
|
27
|
+
attributeNames: options.attributeNames,
|
|
28
|
+
defines: options.defines,
|
|
29
|
+
});
|
|
30
|
+
return { name, effect, _engine: engine, _disposed: false };
|
|
31
|
+
}
|
|
32
|
+
/** Dispose the wrapper and the effect it owns (idempotent). Mirrors lite's
|
|
33
|
+
* `disposeEffectWrapper(wrapper)`. */
|
|
34
|
+
export function disposeEffectWrapper(wrapper) {
|
|
35
|
+
if (wrapper._disposed) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
wrapper._disposed = true;
|
|
39
|
+
disposeEffect(wrapper._engine, wrapper.effect);
|
|
40
|
+
}
|
|
41
|
+
/** Cached `gl.viewport`. Defaults to the full canvas in pixel coordinates. */
|
|
42
|
+
export function setViewport(engine, viewport) {
|
|
43
|
+
if (engine._isLost || engine._disposed) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const x = viewport?.x ?? 0;
|
|
47
|
+
const y = viewport?.y ?? 0;
|
|
48
|
+
const w = viewport?.w ?? engine.canvas.width;
|
|
49
|
+
const h = viewport?.h ?? engine.canvas.height;
|
|
50
|
+
const s = engine._state;
|
|
51
|
+
if (s.viewportX === x && s.viewportY === y && s.viewportW === w && s.viewportH === h) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
s.viewportX = x;
|
|
55
|
+
s.viewportY = y;
|
|
56
|
+
s.viewportW = w;
|
|
57
|
+
s.viewportH = h;
|
|
58
|
+
engine.gl.viewport(x, y, w, h);
|
|
59
|
+
}
|
|
60
|
+
/** Make `wrapper.effect` current and ensure the shared fullscreen quad VAO
|
|
61
|
+
* is bound. This MUST be called BEFORE any `setEffect*` call for the same
|
|
62
|
+
* effect in the current frame (uniform setters write to the currently bound
|
|
63
|
+
* program). */
|
|
64
|
+
export function applyEffectWrapper(wrapper) {
|
|
65
|
+
const engine = wrapper._engine;
|
|
66
|
+
if (engine._isLost || engine._disposed || wrapper._disposed) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
ensureQuad(engine);
|
|
70
|
+
useEffect(engine, wrapper.effect);
|
|
71
|
+
}
|
|
72
|
+
/** `gl.drawElements(TRIANGLES, 6, UNSIGNED_SHORT, 0)`. No-op when the
|
|
73
|
+
* context is lost or there is no current program. */
|
|
74
|
+
export function drawEffect(engine) {
|
|
75
|
+
if (engine._isLost || engine._disposed) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (engine._state.currentProgram === null) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
applyGLStates(engine);
|
|
82
|
+
engine.gl.drawElements(engine.gl.TRIANGLES, 6, engine.gl.UNSIGNED_SHORT, 0);
|
|
83
|
+
}
|
|
84
|
+
/** Lazy fullscreen quad. Built on first call; thereafter the VAO is cached on
|
|
85
|
+
* `_state.quadVao` and rebinding is a single cached call. Cleared by
|
|
86
|
+
* `webglcontextlost` and transparently rebuilt by the next
|
|
87
|
+
* `applyEffectWrapper` after restore.
|
|
88
|
+
*
|
|
89
|
+
* Position attribute is enabled at location 0 — every effect's
|
|
90
|
+
* `createEffect` calls `gl.bindAttribLocation(program, 0, attributeNames[0])`
|
|
91
|
+
* BEFORE link, so the shared VAO is correct across all programs. */
|
|
92
|
+
function ensureQuad(engine) {
|
|
93
|
+
const s = engine._state;
|
|
94
|
+
const gl = engine.gl;
|
|
95
|
+
if (s.quadVao !== null) {
|
|
96
|
+
if (s.boundVao !== s.quadVao) {
|
|
97
|
+
gl.bindVertexArray(s.quadVao);
|
|
98
|
+
s.boundVao = s.quadVao;
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const vao = gl.createVertexArray();
|
|
103
|
+
if (vao === null) {
|
|
104
|
+
throw new Error("lite-gl: gl.createVertexArray returned null");
|
|
105
|
+
}
|
|
106
|
+
s.quadVao = vao;
|
|
107
|
+
gl.bindVertexArray(vao);
|
|
108
|
+
s.boundVao = vao;
|
|
109
|
+
const vbo = gl.createBuffer();
|
|
110
|
+
if (vbo === null) {
|
|
111
|
+
throw new Error("lite-gl: gl.createBuffer returned null (VBO)");
|
|
112
|
+
}
|
|
113
|
+
s.quadVbo = vbo;
|
|
114
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
115
|
+
s.boundArrayBuffer = vbo;
|
|
116
|
+
gl.bufferData(gl.ARRAY_BUFFER, QUAD_POSITIONS, gl.STATIC_DRAW);
|
|
117
|
+
const ibo = gl.createBuffer();
|
|
118
|
+
if (ibo === null) {
|
|
119
|
+
throw new Error("lite-gl: gl.createBuffer returned null (IBO)");
|
|
120
|
+
}
|
|
121
|
+
s.quadIbo = ibo;
|
|
122
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
|
|
123
|
+
s.boundElementBuffer = ibo;
|
|
124
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, QUAD_INDICES, gl.STATIC_DRAW);
|
|
125
|
+
gl.enableVertexAttribArray(0);
|
|
126
|
+
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
|
127
|
+
}
|
|
128
|
+
/** Typed-array literal — pure per bundler convention. Matches Babylon's
|
|
129
|
+
* `EffectRenderer` default geometry exactly. */
|
|
130
|
+
const QUAD_POSITIONS = new Float32Array([1, 1, -1, 1, -1, -1, 1, -1]);
|
|
131
|
+
const QUAD_INDICES = new Uint16Array([0, 1, 2, 0, 2, 3]);
|
|
132
|
+
//# sourceMappingURL=effect-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-renderer.js","sourceRoot":"","sources":["../src/effect-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { GLEngineContext } from \"./context.js\";\nimport { createEffect, disposeEffect, type GLEffect, useEffect } from \"./effect.js\";\nimport { applyGLStates } from \"./apply-states.js\";\n\n/** Built-in fullscreen-quad vertex shader, used when `GLEffectWrapperOptions`\n * omits `vertexSource`. Maps the package's fullscreen-quad positions\n * (attribute location 0) to clip space and forwards a 0..1 `vUv` varying —\n * the WebGL counterpart of lite's default `vertexWGSL`, so callers can pass\n * only `fragmentSource`. */\nconst DEFAULT_FULLSCREEN_VERTEX_SOURCE = `#version 300 es\nlayout(location = 0) in vec2 position;\nout vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n/** Inputs to `createEffectWrapper`. Mirrors lite's `EffectWrapperOptions`: the\n * wrapper compiles and OWNS the effect built from this shader source. */\nexport interface GLEffectWrapperOptions {\n /** Human-readable label for the wrapper and its effect. Defaults to\n * `\"effect-wrapper\"`. */\n name?: string;\n /** GLSL ES 3.00 vertex source. Defaults to a built-in fullscreen-quad\n * vertex shader (exposing a `vUv` varying), mirroring lite's default\n * `vertexWGSL`. */\n vertexSource?: string;\n /** GLSL ES 3.00 fragment source (≙ lite's `fragmentWGSL`). Required. */\n fragmentSource: string;\n /** Declared uniform names. Defaults to none. */\n uniformNames?: readonly string[];\n /** Declared sampler names, in unit-assignment order. Defaults to none. */\n samplerNames?: readonly string[];\n /** Attribute names; the first is bound to location 0. Defaults to\n * `[\"position\"]`. */\n attributeNames?: readonly string[];\n /** Optional `#define` block prepended to both shader stages. */\n defines?: string;\n}\n\n/** A reusable fullscreen effect that compiles and OWNS its `GLEffect` — the\n * WebGL counterpart of lite's `EffectWrapper`. The wrapper retains the engine\n * it was created for, so `disposeEffectWrapper` / `applyEffectWrapper` take\n * only the wrapper. */\nexport interface GLEffectWrapper {\n /** Name alias for the wrapper (and its effect). */\n readonly name: string;\n /** The compiled effect this wrapper owns. Exposed so the per-uniform\n * setters (`setEffectFloat`/`setEffectTexture`/…) can target it — the\n * WebGL divergence from lite's UBO-based `setEffectUniforms(wrapper, …)`. */\n readonly effect: GLEffect;\n /** @internal The engine the wrapper was created for. */\n _engine: GLEngineContext;\n /** @internal */\n _disposed: boolean;\n}\n\n/** Compile a fullscreen effect from shader source and wrap it; the wrapper OWNS\n * the resulting `GLEffect`. Mirrors lite's `createEffectWrapper(engine, options)`.\n * When `vertexSource` is omitted, a built-in fullscreen-quad vertex shader is\n * used, so callers can supply only `fragmentSource`. */\nexport function createEffectWrapper(engine: GLEngineContext, options: GLEffectWrapperOptions): GLEffectWrapper {\n const name = options.name ?? \"effect-wrapper\";\n const effect = createEffect(engine, {\n name,\n vertexSource: options.vertexSource ?? DEFAULT_FULLSCREEN_VERTEX_SOURCE,\n fragmentSource: options.fragmentSource,\n uniformNames: options.uniformNames ?? [],\n samplerNames: options.samplerNames ?? [],\n attributeNames: options.attributeNames,\n defines: options.defines,\n });\n return { name, effect, _engine: engine, _disposed: false };\n}\n\n/** Dispose the wrapper and the effect it owns (idempotent). Mirrors lite's\n * `disposeEffectWrapper(wrapper)`. */\nexport function disposeEffectWrapper(wrapper: GLEffectWrapper): void {\n if (wrapper._disposed) {\n return;\n }\n wrapper._disposed = true;\n disposeEffect(wrapper._engine, wrapper.effect);\n}\n\n/** Pixel-space viewport rectangle passed to `setViewport`. */\nexport interface GLViewport {\n /** Lower-left X origin in physical pixels. */\n x: number;\n /** Lower-left Y origin in physical pixels. */\n y: number;\n /** Width in physical pixels. */\n w: number;\n /** Height in physical pixels. */\n h: number;\n}\n\n/** Cached `gl.viewport`. Defaults to the full canvas in pixel coordinates. */\nexport function setViewport(engine: GLEngineContext, viewport?: GLViewport): void {\n if (engine._isLost || engine._disposed) {\n return;\n }\n const x = viewport?.x ?? 0;\n const y = viewport?.y ?? 0;\n const w = viewport?.w ?? engine.canvas.width;\n const h = viewport?.h ?? engine.canvas.height;\n const s = engine._state;\n if (s.viewportX === x && s.viewportY === y && s.viewportW === w && s.viewportH === h) {\n return;\n }\n s.viewportX = x;\n s.viewportY = y;\n s.viewportW = w;\n s.viewportH = h;\n engine.gl.viewport(x, y, w, h);\n}\n\n/** Make `wrapper.effect` current and ensure the shared fullscreen quad VAO\n * is bound. This MUST be called BEFORE any `setEffect*` call for the same\n * effect in the current frame (uniform setters write to the currently bound\n * program). */\nexport function applyEffectWrapper(wrapper: GLEffectWrapper): void {\n const engine = wrapper._engine;\n if (engine._isLost || engine._disposed || wrapper._disposed) {\n return;\n }\n ensureQuad(engine);\n useEffect(engine, wrapper.effect);\n}\n\n/** `gl.drawElements(TRIANGLES, 6, UNSIGNED_SHORT, 0)`. No-op when the\n * context is lost or there is no current program. */\nexport function drawEffect(engine: GLEngineContext): void {\n if (engine._isLost || engine._disposed) {\n return;\n }\n if (engine._state.currentProgram === null) {\n return;\n }\n applyGLStates(engine);\n engine.gl.drawElements(engine.gl.TRIANGLES, 6, engine.gl.UNSIGNED_SHORT, 0);\n}\n\n/** Lazy fullscreen quad. Built on first call; thereafter the VAO is cached on\n * `_state.quadVao` and rebinding is a single cached call. Cleared by\n * `webglcontextlost` and transparently rebuilt by the next\n * `applyEffectWrapper` after restore.\n *\n * Position attribute is enabled at location 0 — every effect's\n * `createEffect` calls `gl.bindAttribLocation(program, 0, attributeNames[0])`\n * BEFORE link, so the shared VAO is correct across all programs. */\nfunction ensureQuad(engine: GLEngineContext): void {\n const s = engine._state;\n const gl = engine.gl;\n if (s.quadVao !== null) {\n if (s.boundVao !== s.quadVao) {\n gl.bindVertexArray(s.quadVao);\n s.boundVao = s.quadVao;\n }\n return;\n }\n const vao = gl.createVertexArray();\n if (vao === null) {\n throw new Error(\"lite-gl: gl.createVertexArray returned null\");\n }\n s.quadVao = vao;\n gl.bindVertexArray(vao);\n s.boundVao = vao;\n\n const vbo = gl.createBuffer();\n if (vbo === null) {\n throw new Error(\"lite-gl: gl.createBuffer returned null (VBO)\");\n }\n s.quadVbo = vbo;\n gl.bindBuffer(gl.ARRAY_BUFFER, vbo);\n s.boundArrayBuffer = vbo;\n gl.bufferData(gl.ARRAY_BUFFER, QUAD_POSITIONS, gl.STATIC_DRAW);\n\n const ibo = gl.createBuffer();\n if (ibo === null) {\n throw new Error(\"lite-gl: gl.createBuffer returned null (IBO)\");\n }\n s.quadIbo = ibo;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);\n s.boundElementBuffer = ibo;\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, QUAD_INDICES, gl.STATIC_DRAW);\n\n gl.enableVertexAttribArray(0);\n gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n}\n\n/** Typed-array literal — pure per bundler convention. Matches Babylon's\n * `EffectRenderer` default geometry exactly. */\nconst QUAD_POSITIONS = new Float32Array([1, 1, -1, 1, -1, -1, 1, -1]);\nconst QUAD_INDICES = new Uint16Array([0, 1, 2, 0, 2, 3]);\n"]}
|
package/effect.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { GLEngineContext } from "./context.js";
|
|
2
|
+
import { type GLTexture } from "./texture.js";
|
|
3
|
+
/** Inputs to `createEffect`: shader sources plus the uniform, sampler and
|
|
4
|
+
* attribute names whose locations are resolved during readiness finalization. */
|
|
5
|
+
export interface GLEffectOptions {
|
|
6
|
+
/** Human-readable label, surfaced in compile/link error messages. */
|
|
7
|
+
name: string;
|
|
8
|
+
/** GLSL ES 3.00 source, ready for `gl.shaderSource`. */
|
|
9
|
+
vertexSource: string;
|
|
10
|
+
/** GLSL ES 3.00 source, ready for `gl.shaderSource`. */
|
|
11
|
+
fragmentSource: string;
|
|
12
|
+
/** Declared uniform names. Locations are resolved during readiness
|
|
13
|
+
* finalization. Names not declared here are legal but allocate cache
|
|
14
|
+
* slots lazily on first setter use. */
|
|
15
|
+
uniformNames: readonly string[];
|
|
16
|
+
/** Declared sampler names, in unit-assignment order. Each gets a fixed
|
|
17
|
+
* texture unit assigned during readiness finalization, and
|
|
18
|
+
* `gl.uniform1i(loc, unit)` is called exactly once per program lifetime
|
|
19
|
+
* (re-run after `webglcontextrestored`). */
|
|
20
|
+
samplerNames: readonly string[];
|
|
21
|
+
/** Default `["position"]`. The first attribute is bound to location 0 via
|
|
22
|
+
* `gl.bindAttribLocation(program, 0, name)` BEFORE link, so the shared
|
|
23
|
+
* fullscreen-quad VAO always feeds the same location. */
|
|
24
|
+
attributeNames?: readonly string[];
|
|
25
|
+
/** Optional `#define` block. Each unique `defines` string must be paired
|
|
26
|
+
* with the same vertex/fragment source via a separate `createEffect` call —
|
|
27
|
+
* the package does NOT cache compiled variants. */
|
|
28
|
+
defines?: string;
|
|
29
|
+
}
|
|
30
|
+
/** A compiled + linked shader program with cached uniform, sampler and
|
|
31
|
+
* attribute locations. Created by `createEffect`; most fields are managed
|
|
32
|
+
* internally — drive it via `isEffectReady` / `useEffect` / the `setEffect*`
|
|
33
|
+
* setters rather than mutating it directly. */
|
|
34
|
+
export interface GLEffect {
|
|
35
|
+
/** The `name` from the originating `GLEffectOptions`. */
|
|
36
|
+
readonly name: string;
|
|
37
|
+
/** The options this effect was created from (retained for context-restore). */
|
|
38
|
+
readonly options: GLEffectOptions;
|
|
39
|
+
/** The live `WebGLProgram`. Swapped for a fresh handle after context-restore. */
|
|
40
|
+
program: WebGLProgram;
|
|
41
|
+
/** Resolved during readiness finalization. Missing names map to `null` —
|
|
42
|
+
* setters with a `null` location are silent no-ops (matches Babylon). */
|
|
43
|
+
uniformLocations: {
|
|
44
|
+
[name: string]: WebGLUniformLocation | null;
|
|
45
|
+
};
|
|
46
|
+
/** Fixed unit assignment for declared samplers, index into
|
|
47
|
+
* `_state.boundTextures`. */
|
|
48
|
+
samplerUnits: {
|
|
49
|
+
[name: string]: number;
|
|
50
|
+
};
|
|
51
|
+
/** Resolved attribute locations, keyed by attribute name. */
|
|
52
|
+
attributeLocations: {
|
|
53
|
+
[name: string]: number;
|
|
54
|
+
};
|
|
55
|
+
/** True once the program has linked and finalization has run; the
|
|
56
|
+
* `setEffect*` setters are no-ops until then. Poll `isEffectReady` to advance it. */
|
|
57
|
+
isReady: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** Compile + link a new effect. Does NOT block on link completion — `isReady`
|
|
60
|
+
* starts false; consumers poll `isEffectReady` (typically from their render
|
|
61
|
+
* callback) to drive finalization. */
|
|
62
|
+
export declare function createEffect(engine: GLEngineContext, options: GLEffectOptions): GLEffect;
|
|
63
|
+
/** Poll the link state and, on first success, run finalization (uniform-
|
|
64
|
+
* location resolution + one-shot sampler-unit `uniform1i` assignment +
|
|
65
|
+
* `_onCompiled` callbacks). Returns `true` once the effect is usable. */
|
|
66
|
+
export declare function isEffectReady(engine: GLEngineContext, effect: GLEffect): boolean;
|
|
67
|
+
/** Fires `cb` synchronously if the effect is already ready; otherwise queues
|
|
68
|
+
* it for the next finalization. */
|
|
69
|
+
export declare function executeWhenCompiled(engine: GLEngineContext, effect: GLEffect, cb: (e: GLEffect) => void): void;
|
|
70
|
+
/** Decrement the share count and, on the last release, delete the effect's
|
|
71
|
+
* program + shaders, unregister it from the context + cache, and clear the
|
|
72
|
+
* cached current-program if it pointed at this effect. A shared effect (still
|
|
73
|
+
* referenced by another `createEffect` caller) is kept alive. Call exactly ONCE
|
|
74
|
+
* per `createEffect` (each call decrements the ref count); safe (no-op) once the
|
|
75
|
+
* effect is fully torn down. */
|
|
76
|
+
export declare function disposeEffect(engine: GLEngineContext, effect: GLEffect): void;
|
|
77
|
+
/** Cached `gl.useProgram`. No-op when the effect is not ready or already current. */
|
|
78
|
+
export declare function useEffect(engine: GLEngineContext, effect: GLEffect): void;
|
|
79
|
+
/** Cached `gl.uniform1f`. No-op when context-lost, the effect isn't ready, the
|
|
80
|
+
* uniform is absent, or the value is unchanged since last upload. */
|
|
81
|
+
export declare function setEffectFloat(engine: GLEngineContext, effect: GLEffect, name: string, x: number): void;
|
|
82
|
+
/** Cached `gl.uniform2f`. No-op when context-lost, the effect isn't ready, the
|
|
83
|
+
* uniform is absent, or the value is unchanged since last upload. */
|
|
84
|
+
export declare function setEffectFloat2(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number): void;
|
|
85
|
+
/** Cached `gl.uniform3f`. No-op when context-lost, the effect isn't ready, the
|
|
86
|
+
* uniform is absent, or the value is unchanged since last upload. */
|
|
87
|
+
export declare function setEffectFloat3(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number, z: number): void;
|
|
88
|
+
/** Cached `gl.uniform4f`. No-op when context-lost, the effect isn't ready, the
|
|
89
|
+
* uniform is absent, or the value is unchanged since last upload. */
|
|
90
|
+
export declare function setEffectFloat4(engine: GLEngineContext, effect: GLEffect, name: string, x: number, y: number, z: number, w: number): void;
|
|
91
|
+
/** Cached `gl.uniform3f` from an r/g/b color object. Delegates to `setEffectFloat3`. */
|
|
92
|
+
export declare function setEffectColor3(engine: GLEngineContext, effect: GLEffect, name: string, c: {
|
|
93
|
+
r: number;
|
|
94
|
+
g: number;
|
|
95
|
+
b: number;
|
|
96
|
+
}): void;
|
|
97
|
+
/** Cached `gl.uniform4f` from an r/g/b/a color object. Delegates to `setEffectFloat4`. */
|
|
98
|
+
export declare function setEffectColor4(engine: GLEngineContext, effect: GLEffect, name: string, c: {
|
|
99
|
+
r: number;
|
|
100
|
+
g: number;
|
|
101
|
+
b: number;
|
|
102
|
+
a: number;
|
|
103
|
+
}): void;
|
|
104
|
+
/** Cached `gl.uniform2f` from an `{x,y}` vector object — the lite-gl equivalent
|
|
105
|
+
* of Babylon's `Effect.setVector2`. Delegates to `setEffectFloat2`. */
|
|
106
|
+
export declare function setEffectVector2(engine: GLEngineContext, effect: GLEffect, name: string, v: {
|
|
107
|
+
x: number;
|
|
108
|
+
y: number;
|
|
109
|
+
}): void;
|
|
110
|
+
/** Cached `gl.uniform4f` from an r/g/b/a color WITHOUT premultiplication — the
|
|
111
|
+
* lite-gl equivalent of Babylon's `Effect.setDirectColor4`. Delegates to
|
|
112
|
+
* `setEffectFloat4` (lite-gl never premultiplies in the uniform setters, so
|
|
113
|
+
* this matches `setEffectColor4`; the distinct name eases the ShapeBuilder
|
|
114
|
+
* port). */
|
|
115
|
+
export declare function setEffectDirectColor4(engine: GLEngineContext, effect: GLEffect, name: string, c: {
|
|
116
|
+
r: number;
|
|
117
|
+
g: number;
|
|
118
|
+
b: number;
|
|
119
|
+
a: number;
|
|
120
|
+
}): void;
|
|
121
|
+
/** Cached `gl.uniform1i`. No-op when context-lost, the effect isn't ready, the
|
|
122
|
+
* uniform is absent, or the value is unchanged since last upload. */
|
|
123
|
+
export declare function setEffectInt(engine: GLEngineContext, effect: GLEffect, name: string, x: number): void;
|
|
124
|
+
/** `gl.uniformMatrix4fv` from a column-major 4×4 matrix — the lite-gl
|
|
125
|
+
* equivalent of Babylon's `Effect.setMatrix`. Not value-cached. */
|
|
126
|
+
export declare function setEffectMatrix(engine: GLEngineContext, effect: GLEffect, name: string, matrix: Float32Array | number[]): void;
|
|
127
|
+
/** `gl.uniformMatrix3fv` from a column-major 3×3 matrix — the lite-gl
|
|
128
|
+
* equivalent of Babylon's `Effect.setMatrix3x3`. Not value-cached. */
|
|
129
|
+
export declare function setEffectMatrix3x3(engine: GLEngineContext, effect: GLEffect, name: string, matrix: Float32Array | number[]): void;
|
|
130
|
+
/** `gl.uniform1fv` — a flat float array (`Effect.setFloatArray` / `setArray`).
|
|
131
|
+
* Not value-cached. */
|
|
132
|
+
export declare function setEffectFloatArray(engine: GLEngineContext, effect: GLEffect, name: string, array: Float32Array | number[]): void;
|
|
133
|
+
/** `gl.uniform4fv` — an array of `vec4`s (`Effect.setFloatArray4` / `setArray4`).
|
|
134
|
+
* Not value-cached. */
|
|
135
|
+
export declare function setEffectFloatArray4(engine: GLEngineContext, effect: GLEffect, name: string, array: Float32Array | number[]): void;
|
|
136
|
+
/** `gl.uniform1iv` — a flat int array (`Effect.setIntArray`). Not value-cached. */
|
|
137
|
+
export declare function setEffectIntArray(engine: GLEngineContext, effect: GLEffect, name: string, array: Int32Array | number[]): void;
|
|
138
|
+
/** Bind a texture to the sampler's pre-assigned unit (§4.4). NO `gl.uniform1i`
|
|
139
|
+
* is issued — that was done exactly once per program lifetime during
|
|
140
|
+
* finalization. This is the key win over Babylon's `Effect.setTexture` which
|
|
141
|
+
* re-issues the sampler binding on every call. */
|
|
142
|
+
export declare function setEffectTexture(engine: GLEngineContext, effect: GLEffect, samplerName: string, tex: GLTexture): void;
|