@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
package/README.md
CHANGED
|
@@ -25,17 +25,7 @@ npm install @babylonjs/lite-gl
|
|
|
25
25
|
## Quick start — an animated fullscreen effect
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import {
|
|
29
|
-
createGLEngine,
|
|
30
|
-
createEffectWrapper,
|
|
31
|
-
isEffectReady,
|
|
32
|
-
applyEffectWrapper,
|
|
33
|
-
drawEffect,
|
|
34
|
-
setViewport,
|
|
35
|
-
setEffectFloat,
|
|
36
|
-
runRenderLoop,
|
|
37
|
-
resizeGLEngine,
|
|
38
|
-
} from "@babylonjs/lite-gl";
|
|
28
|
+
import { createGLEngine, createEffectWrapper, isEffectReady, applyEffectWrapper, drawEffect, setViewport, setEffectFloat, runRenderLoop, resizeGLEngine } from "@babylonjs/lite-gl";
|
|
39
29
|
|
|
40
30
|
const canvas = document.getElementById("renderCanvas") as HTMLCanvasElement;
|
|
41
31
|
const engine = createGLEngine(canvas, { alpha: false });
|
|
@@ -69,23 +59,13 @@ runRenderLoop(engine, () => {
|
|
|
69
59
|
|
|
70
60
|
## Entry points
|
|
71
61
|
|
|
72
|
-
The
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| Import | Provides |
|
|
80
|
-
| --- | --- |
|
|
81
|
-
| `@babylonjs/lite-gl` | Everything: engine + render loop, effects & uniform setters, textures (incl. float / HDR + dynamic), the `EffectWrapper` fullscreen-quad renderer, render targets, meshes / vertex-index buffers + instancing, depth / stencil / color-mask / clear, scissor, blend modes, the sprite renderer, and HTML-element textures. |
|
|
82
|
-
| `@babylonjs/lite-gl/sprites` | Just the sprite / instanced-quad renderer (`createSpriteRenderer`, `renderSprites`, `setSpriteRendererTexture`, `disposeSpriteRenderer`, `GLSprite`) — the lite-gl equivalent of Babylon's `SpriteRenderer`. |
|
|
83
|
-
| `@babylonjs/lite-gl/html-texture` | Just textures backed by a `<canvas>` / `<img>` / `<video>` element (`createHtmlElementTexture`, `updateHtmlElementTexture`, `GLSamplingMode`). |
|
|
84
|
-
| `@babylonjs/lite-gl/render-target` | Render-to-texture (FBO) + a ping-pong feedback helper (`createRenderTarget`, `createFloatRenderTarget`, `bindRenderTarget`, `resizeRenderTarget`, `generateRenderTargetMipMaps`, `readRenderTargetPixels`, `disposeRenderTarget`, `createPingPong`, `resizePingPong`, `disposePingPong`) — the lite-gl equivalent of Babylon's `RenderTargetTexture` / `createRenderTargetTexture`, for multi-pass and self-feedback effects. |
|
|
85
|
-
| `@babylonjs/lite-gl/mesh` | Vertex / index buffers, attribute binding and instanced `drawIndexed` (`createVertexBuffer`, `updateVertexBuffer`, `createIndexBuffer`, `bindAttributes`, `drawIndexed`, …) — the lite-gl equivalent of Babylon's `VertexBuffer` / `Geometry`. |
|
|
86
|
-
| `@babylonjs/lite-gl/depth-stencil` | Cached depth / stencil / cull / color-mask state + `clearEngine` (`setDepthState`, `setStencilState`, `setCullState`, `setColorMask`, `clearEngine`). |
|
|
87
|
-
| `@babylonjs/lite-gl/scissor` | The cached scissor-test rectangle (`setScissor`, `disableScissor`). |
|
|
88
|
-
| `@babylonjs/lite-gl/dynamic-texture` | Textures whose pixels are replayed from a retained source on context-restore (`createDynamicTexture`, `updateDynamicTexture`, `clearDynamicTextureSource`). |
|
|
62
|
+
The entire public API is available from the single `@babylonjs/lite-gl` entry:
|
|
63
|
+
engine + render loop, effects & uniform setters, textures (incl. float / HDR +
|
|
64
|
+
dynamic), the `EffectWrapper` fullscreen-quad renderer, render targets, meshes /
|
|
65
|
+
vertex-index buffers + instancing, depth / stencil / color-mask / clear, scissor,
|
|
66
|
+
blend modes, the sprite renderer, and HTML-element textures. The package is
|
|
67
|
+
`sideEffects: false`, so a bundler tree-shakes away whichever features you don't
|
|
68
|
+
use.
|
|
89
69
|
|
|
90
70
|
### Core API (`@babylonjs/lite-gl`)
|
|
91
71
|
|
|
@@ -107,20 +87,16 @@ path you import from.
|
|
|
107
87
|
`updateTextureWrapMode`, `createTextureFromHandle`.
|
|
108
88
|
- **Dynamic textures** — `createDynamicTexture`, `updateDynamicTexture`,
|
|
109
89
|
`clearDynamicTextureSource` (the retained source is replayed on context-restore).
|
|
110
|
-
Also at `@babylonjs/lite-gl/dynamic-texture`.
|
|
111
90
|
- **Render targets** — `createRenderTarget` (RGBA8 FBO with a sampleable color
|
|
112
91
|
`GLTexture` + optional depth / stencil renderbuffer), `createFloatRenderTarget`
|
|
113
92
|
(float / half-float HDR opt-in), `bindRenderTarget` (cached, null = the canvas),
|
|
114
93
|
`resizeRenderTarget`, `generateRenderTargetMipMaps`, `readRenderTargetPixels`,
|
|
115
94
|
`disposeRenderTarget`, plus the `createPingPong` / `resizePingPong` /
|
|
116
|
-
`disposePingPong` feedback helper.
|
|
95
|
+
`disposePingPong` feedback helper.
|
|
117
96
|
- **Meshes / buffers** — `createVertexBuffer`, `updateVertexBuffer`,
|
|
118
97
|
`createIndexBuffer`, `bindAttributes`, `drawIndexed` (instanced), `disposeBuffer`.
|
|
119
|
-
Also at `@babylonjs/lite-gl/mesh`.
|
|
120
98
|
- **Depth / stencil / scissor** — `setDepthState`, `setStencilState`,
|
|
121
|
-
`setCullState`, `setColorMask`, `clearEngine`
|
|
122
|
-
`@babylonjs/lite-gl/depth-stencil`); `setScissor`, `disableScissor` (also at
|
|
123
|
-
`@babylonjs/lite-gl/scissor`).
|
|
99
|
+
`setCullState`, `setColorMask`, `clearEngine`; `setScissor`, `disableScissor`.
|
|
124
100
|
- **Blend** — `setBlendMode` + `GLBlendMode` (`DISABLE` / `ADD` / `ALPHA` /
|
|
125
101
|
`PREMULTIPLIED`), matching Babylon's `setAlphaMode` parameters.
|
|
126
102
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/apply-states.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flush the deferred blend / depth+cull / stencil / color-mask state to GL by
|
|
3
|
+
* invoking each installed per-category reconciler in order. No-op on a
|
|
4
|
+
* lost/disposed context or when nothing has been marked dirty since the last
|
|
5
|
+
* flush. Reconcilers are installed lazily by their setters, so an uninstalled
|
|
6
|
+
* category is skipped at zero cost.
|
|
7
|
+
*
|
|
8
|
+
* @param engine - The engine whose deferred state is flushed.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export function applyGLStates(engine) {
|
|
12
|
+
const s = engine._state;
|
|
13
|
+
if (engine._isLost || engine._disposed || !s.statesDirty) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (s._flushBlend !== undefined) {
|
|
17
|
+
s._flushBlend(engine);
|
|
18
|
+
}
|
|
19
|
+
if (s._flushDepthCull !== undefined) {
|
|
20
|
+
s._flushDepthCull(engine);
|
|
21
|
+
}
|
|
22
|
+
if (s._flushStencil !== undefined) {
|
|
23
|
+
s._flushStencil(engine);
|
|
24
|
+
}
|
|
25
|
+
if (s._flushColorMask !== undefined) {
|
|
26
|
+
s._flushColorMask(engine);
|
|
27
|
+
}
|
|
28
|
+
s.statesDirty = false;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=apply-states.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-states.js","sourceRoot":"","sources":["../src/apply-states.ts"],"names":[],"mappings":"AAqCA;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,MAAuB;IACjD,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACxB,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACvD,OAAO;IACX,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,CAAC,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,CAAC,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,CAAC,CAAC,WAAW,GAAG,KAAK,CAAC;AAC1B,CAAC","sourcesContent":["/**\n * Deferred render-state flush dispatcher — the lite-gl counterpart of Babylon's\n * `Engine.applyStates()` (`_depthCullingState.apply` / `_alphaState.apply` /\n * `_stencilState.apply`).\n *\n * blend.ts and depth-stencil.ts setters record only the DESIRED state (the\n * `rs[RS_X + RS_DESIRED]` slots of {@link GLState.rs}), raise `statesDirty`, and\n * INSTALL their per-category reconciler onto a `_state._flush*` slot the first\n * time they run. {@link applyGLStates} then simply dispatches through whichever\n * slots are populated — it owns NO reconciliation code itself.\n *\n * Why a dispatcher (not a monolith): the reconcilers (`flushBlend` in blend.ts;\n * `flushDepthCull` / `flushStencil` / `flushColorMask` in depth-stencil.ts) are\n * reachable ONLY through the engine-state slots their setters populate, so a\n * category whose setter is absent from a scene tree-shakes its reconciler — and\n * its GL code — out of the bundle. A clear-only scene (e.g. `gl-scissor`) that\n * never touches blend/depth/stencil/color-mask therefore ships none of them;\n * `applyGLStates` collapses to four cheap \"is it installed?\" checks. The fixed\n * dispatch order (blend → depth+cull → stencil → color-mask) reproduces the\n * former monolith's GL call order exactly.\n *\n * Each reconciler still issues only the `gl.*` calls that actually change and\n * updates the actual slots in lock-step, so intra-frame churn collapses and\n * cross-frame elision is preserved, matching Babylon exactly.\n *\n * Flush sites (call `applyGLStates` immediately before the GPU op):\n * - effect-renderer.ts `drawEffect`\n * - sprites.ts `renderSprites`\n * - mesh.ts `drawIndexed`\n * - depth-stencil.ts `clearEngine` (clear respects the depth/stencil/color\n * write masks, so they must be current first — Babylon parity)\n *\n * Kept dependency-light (type-only import of {@link GLEngineContext}) so it never\n * introduces an import cycle.\n */\nimport type { GLEngineContext } from \"./context.js\";\n\n/**\n * Flush the deferred blend / depth+cull / stencil / color-mask state to GL by\n * invoking each installed per-category reconciler in order. No-op on a\n * lost/disposed context or when nothing has been marked dirty since the last\n * flush. Reconcilers are installed lazily by their setters, so an uninstalled\n * category is skipped at zero cost.\n *\n * @param engine - The engine whose deferred state is flushed.\n * @internal\n */\nexport function applyGLStates(engine: GLEngineContext): void {\n const s = engine._state;\n if (engine._isLost || engine._disposed || !s.statesDirty) {\n return;\n }\n if (s._flushBlend !== undefined) {\n s._flushBlend(engine);\n }\n if (s._flushDepthCull !== undefined) {\n s._flushDepthCull(engine);\n }\n if (s._flushStencil !== undefined) {\n s._flushStencil(engine);\n }\n if (s._flushColorMask !== undefined) {\n s._flushColorMask(engine);\n }\n s.statesDirty = false;\n}\n"]}
|
package/blend.d.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blend-mode state — the WebGL counterpart of Babylon's `Engine.setAlphaMode`
|
|
3
|
+
* (presets) and `AlphaState.setAlphaBlendFunctionParameters` /
|
|
4
|
+
* `setAlphaEquationParameters` (the arbitrary separate func + equation path).
|
|
5
|
+
*
|
|
6
|
+
* The numeric {@link GLBlendMode} values intentionally match Babylon's
|
|
7
|
+
* `Constants.ALPHA_*` (`ALPHA_DISABLE = 0`, `ALPHA_ADD = 1`, `ALPHA_COMBINE = 2`,
|
|
8
|
+
* `ALPHA_PREMULTIPLIED = 7`) so a consumer can forward raw Babylon constants
|
|
9
|
+
* without a translation table.
|
|
10
|
+
*
|
|
11
|
+
* DEFERRED MODEL (matches Babylon's `AlphaState`): these setters do NOT touch
|
|
12
|
+
* `gl.*`. They record only the DESIRED blend config into the `d*` mirror fields
|
|
13
|
+
* of `GLState` and raise `statesDirty`; `applyGLStates` (apply-states.ts) flushes
|
|
14
|
+
* the diff to GL right before each draw / clear. Setting blend A then B then A
|
|
15
|
+
* with no draw in between therefore applies exactly one blend state (A), and a
|
|
16
|
+
* blend left unchanged across frames re-issues nothing.
|
|
17
|
+
*
|
|
18
|
+
* Both {@link setBlendMode} and {@link setBlendState} feed the same desired
|
|
19
|
+
* fields, so the preset and arbitrary paths can never desync.
|
|
20
|
+
*/
|
|
21
|
+
import { type GLEngineContext } from "./context.js";
|
|
22
|
+
/**
|
|
23
|
+
* Supported blend presets. Values mirror Babylon's `Constants.ALPHA_*` so the
|
|
24
|
+
* raw Babylon integers can be passed straight through.
|
|
25
|
+
*/
|
|
26
|
+
export declare const GLBlendMode: {
|
|
27
|
+
/** No blending — `gl.disable(gl.BLEND)`. (`Constants.ALPHA_DISABLE`) */
|
|
28
|
+
readonly DISABLE: 0;
|
|
29
|
+
/** Additive — `blendFuncSeparate(SRC_ALPHA, ONE, ZERO, ONE)`. (`Constants.ALPHA_ADD`) */
|
|
30
|
+
readonly ADD: 1;
|
|
31
|
+
/** Standard (non-premultiplied) alpha — `blendFuncSeparate(SRC_ALPHA, ONE_MINUS_SRC_ALPHA, ONE, ONE)`. (`Constants.ALPHA_COMBINE`) */
|
|
32
|
+
readonly ALPHA: 2;
|
|
33
|
+
/** Premultiplied alpha — `blendFuncSeparate(ONE, ONE_MINUS_SRC_ALPHA, ONE, ONE)`. (`Constants.ALPHA_PREMULTIPLIED`) */
|
|
34
|
+
readonly PREMULTIPLIED: 7;
|
|
35
|
+
};
|
|
36
|
+
/** One of the {@link GLBlendMode} preset values (`0`, `1`, `2` or `7`). */
|
|
37
|
+
export type GLBlendMode = (typeof GLBlendMode)[keyof typeof GLBlendMode];
|
|
38
|
+
/**
|
|
39
|
+
* Blend equation presets — the values WebGL2 accepts for
|
|
40
|
+
* `gl.blendEquationSeparate`. Numeric values equal the GL enums so raw GL
|
|
41
|
+
* integers (or Babylon's identical `Constants.GL_ALPHA_EQUATION_*`) pass
|
|
42
|
+
* straight through.
|
|
43
|
+
*/
|
|
44
|
+
export declare const GLBlendEquation: {
|
|
45
|
+
/** `src + dst` (the GL default). */
|
|
46
|
+
readonly ADD: 32774;
|
|
47
|
+
/** `src - dst`. */
|
|
48
|
+
readonly SUBTRACT: 32778;
|
|
49
|
+
/** `dst - src`. */
|
|
50
|
+
readonly REVERSE_SUBTRACT: 32779;
|
|
51
|
+
/** `min(src, dst)`. */
|
|
52
|
+
readonly MIN: 32775;
|
|
53
|
+
/** `max(src, dst)`. */
|
|
54
|
+
readonly MAX: 32776;
|
|
55
|
+
};
|
|
56
|
+
/** One of the {@link GLBlendEquation} preset values. */
|
|
57
|
+
export type GLBlendEquation = (typeof GLBlendEquation)[keyof typeof GLBlendEquation];
|
|
58
|
+
/**
|
|
59
|
+
* Arbitrary separate-channel blend configuration — the lite-gl equivalent of
|
|
60
|
+
* Babylon's `AlphaState.setAlphaBlendFunctionParameters` +
|
|
61
|
+
* `setAlphaEquationParameters`. All factor / equation fields are raw WebGL2
|
|
62
|
+
* enums (`gl.ONE`, `gl.SRC_ALPHA`, `gl.MIN`, …); use {@link GLBlendEquation} for
|
|
63
|
+
* the equations if you prefer named presets.
|
|
64
|
+
*/
|
|
65
|
+
export interface GLBlendState {
|
|
66
|
+
/** RGB source factor (`gl.blendFuncSeparate` arg 1). */
|
|
67
|
+
srcRGB: GLenum;
|
|
68
|
+
/** RGB destination factor (`gl.blendFuncSeparate` arg 2). */
|
|
69
|
+
dstRGB: GLenum;
|
|
70
|
+
/** Alpha source factor (`gl.blendFuncSeparate` arg 3). */
|
|
71
|
+
srcAlpha: GLenum;
|
|
72
|
+
/** Alpha destination factor (`gl.blendFuncSeparate` arg 4). */
|
|
73
|
+
dstAlpha: GLenum;
|
|
74
|
+
/** RGB blend equation. Defaults to `FUNC_ADD`. */
|
|
75
|
+
equationRGB?: GLenum;
|
|
76
|
+
/** Alpha blend equation. Defaults to `FUNC_ADD`. */
|
|
77
|
+
equationAlpha?: GLenum;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Set the GL blend state to match Babylon's `setAlphaMode(mode)` exactly.
|
|
81
|
+
*
|
|
82
|
+
* | Mode | `gl.blendFuncSeparate(srcRGB, dstRGB, srcA, dstA)` |
|
|
83
|
+
* |--------------------|------------------------------------------------------------|
|
|
84
|
+
* | `DISABLE` (0) | — (`gl.disable(gl.BLEND)`) |
|
|
85
|
+
* | `ADD` (1) | `SRC_ALPHA, ONE, ZERO, ONE` |
|
|
86
|
+
* | `ALPHA` (2) | `SRC_ALPHA, ONE_MINUS_SRC_ALPHA, ONE, ONE` |
|
|
87
|
+
* | `PREMULTIPLIED` (7)| `ONE, ONE_MINUS_SRC_ALPHA, ONE, ONE` |
|
|
88
|
+
*
|
|
89
|
+
* No-op when the context is lost or disposed.
|
|
90
|
+
*
|
|
91
|
+
* @param engine - The engine whose GL blend state is updated.
|
|
92
|
+
* @param mode - The {@link GLBlendMode} preset to apply.
|
|
93
|
+
*/
|
|
94
|
+
export declare function setBlendMode(engine: GLEngineContext, mode: GLBlendMode): void;
|
|
95
|
+
/**
|
|
96
|
+
* Enable blending with an arbitrary separate-channel function and equation —
|
|
97
|
+
* the lite-gl equivalent of Babylon's `AlphaState` with
|
|
98
|
+
* `setAlphaBlendFunctionParameters` + `setAlphaEquationParameters`.
|
|
99
|
+
*
|
|
100
|
+
* Supports every WebGL2 blend equation, including `MIN`, `MAX`,
|
|
101
|
+
* `FUNC_SUBTRACT` and `FUNC_REVERSE_SUBTRACT` (used by ShapeBuilder's darken /
|
|
102
|
+
* cutout blend modes). Records the desired config (flushed by `applyGLStates`
|
|
103
|
+
* before the next draw); at flush time the enable flag, the equation and the func
|
|
104
|
+
* are each cached independently, so a redundant state is fully elided and only
|
|
105
|
+
* the call whose params changed is re-issued — mirroring Babylon's `AlphaState`
|
|
106
|
+
* dirty flags. Because GL keeps the equation + func across `gl.disable(BLEND)`,
|
|
107
|
+
* re-enabling with unchanged params re-issues neither.
|
|
108
|
+
*
|
|
109
|
+
* No-op when the context is lost or disposed.
|
|
110
|
+
*
|
|
111
|
+
* @param engine - The engine whose desired blend state is updated.
|
|
112
|
+
* @param state - The separate-channel blend factors + equations to apply.
|
|
113
|
+
*/
|
|
114
|
+
export declare function setBlendState(engine: GLEngineContext, state: GLBlendState): void;
|
|
115
|
+
/**
|
|
116
|
+
* Disable blending — the equivalent of Babylon's `AlphaState.alphaBlend = false`.
|
|
117
|
+
* Records the desired "blend off" state (flushed by `applyGLStates` before the
|
|
118
|
+
* next draw); the actual `gl.disable(gl.BLEND)` is elided when blending is
|
|
119
|
+
* already off at flush time. No-op when the context is lost or disposed.
|
|
120
|
+
*
|
|
121
|
+
* @param engine - The engine whose desired blend state is updated.
|
|
122
|
+
*/
|
|
123
|
+
export declare function disableBlend(engine: GLEngineContext): void;
|
package/blend.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { RS_BLEND_DST_A, RS_BLEND_DST_RGB, RS_BLEND_ENABLED, RS_BLEND_EQ_A, RS_BLEND_EQ_RGB, RS_BLEND_SRC_A, RS_BLEND_SRC_RGB, RS_DESIRED } from "./state.js";
|
|
2
|
+
/**
|
|
3
|
+
* Supported blend presets. Values mirror Babylon's `Constants.ALPHA_*` so the
|
|
4
|
+
* raw Babylon integers can be passed straight through.
|
|
5
|
+
*/
|
|
6
|
+
export const GLBlendMode = {
|
|
7
|
+
/** No blending — `gl.disable(gl.BLEND)`. (`Constants.ALPHA_DISABLE`) */
|
|
8
|
+
DISABLE: 0,
|
|
9
|
+
/** Additive — `blendFuncSeparate(SRC_ALPHA, ONE, ZERO, ONE)`. (`Constants.ALPHA_ADD`) */
|
|
10
|
+
ADD: 1,
|
|
11
|
+
/** Standard (non-premultiplied) alpha — `blendFuncSeparate(SRC_ALPHA, ONE_MINUS_SRC_ALPHA, ONE, ONE)`. (`Constants.ALPHA_COMBINE`) */
|
|
12
|
+
ALPHA: 2,
|
|
13
|
+
/** Premultiplied alpha — `blendFuncSeparate(ONE, ONE_MINUS_SRC_ALPHA, ONE, ONE)`. (`Constants.ALPHA_PREMULTIPLIED`) */
|
|
14
|
+
PREMULTIPLIED: 7,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Blend equation presets — the values WebGL2 accepts for
|
|
18
|
+
* `gl.blendEquationSeparate`. Numeric values equal the GL enums so raw GL
|
|
19
|
+
* integers (or Babylon's identical `Constants.GL_ALPHA_EQUATION_*`) pass
|
|
20
|
+
* straight through.
|
|
21
|
+
*/
|
|
22
|
+
export const GLBlendEquation = {
|
|
23
|
+
/** `src + dst` (the GL default). */
|
|
24
|
+
ADD: 0x8006,
|
|
25
|
+
/** `src - dst`. */
|
|
26
|
+
SUBTRACT: 0x800a,
|
|
27
|
+
/** `dst - src`. */
|
|
28
|
+
REVERSE_SUBTRACT: 0x800b,
|
|
29
|
+
/** `min(src, dst)`. */
|
|
30
|
+
MIN: 0x8007,
|
|
31
|
+
/** `max(src, dst)`. */
|
|
32
|
+
MAX: 0x8008,
|
|
33
|
+
};
|
|
34
|
+
/** GL `FUNC_ADD` — the implicit equation used by the {@link GLBlendMode}
|
|
35
|
+
* presets (matching Babylon's `setAlphaMode`, which leaves it at the default). */
|
|
36
|
+
const FUNC_ADD = 0x8006;
|
|
37
|
+
/** GL `gl.BLEND`. */
|
|
38
|
+
const BLEND = 0x0be2;
|
|
39
|
+
/**
|
|
40
|
+
* Set the GL blend state to match Babylon's `setAlphaMode(mode)` exactly.
|
|
41
|
+
*
|
|
42
|
+
* | Mode | `gl.blendFuncSeparate(srcRGB, dstRGB, srcA, dstA)` |
|
|
43
|
+
* |--------------------|------------------------------------------------------------|
|
|
44
|
+
* | `DISABLE` (0) | — (`gl.disable(gl.BLEND)`) |
|
|
45
|
+
* | `ADD` (1) | `SRC_ALPHA, ONE, ZERO, ONE` |
|
|
46
|
+
* | `ALPHA` (2) | `SRC_ALPHA, ONE_MINUS_SRC_ALPHA, ONE, ONE` |
|
|
47
|
+
* | `PREMULTIPLIED` (7)| `ONE, ONE_MINUS_SRC_ALPHA, ONE, ONE` |
|
|
48
|
+
*
|
|
49
|
+
* No-op when the context is lost or disposed.
|
|
50
|
+
*
|
|
51
|
+
* @param engine - The engine whose GL blend state is updated.
|
|
52
|
+
* @param mode - The {@link GLBlendMode} preset to apply.
|
|
53
|
+
*/
|
|
54
|
+
export function setBlendMode(engine, mode) {
|
|
55
|
+
if (engine._isLost || engine._disposed) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const gl = engine.gl;
|
|
59
|
+
switch (mode) {
|
|
60
|
+
case GLBlendMode.DISABLE:
|
|
61
|
+
disableBlend(engine);
|
|
62
|
+
return;
|
|
63
|
+
case GLBlendMode.ADD:
|
|
64
|
+
applyBlend(engine, gl.SRC_ALPHA, gl.ONE, gl.ZERO, gl.ONE, FUNC_ADD, FUNC_ADD);
|
|
65
|
+
return;
|
|
66
|
+
case GLBlendMode.ALPHA:
|
|
67
|
+
applyBlend(engine, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE, FUNC_ADD, FUNC_ADD);
|
|
68
|
+
return;
|
|
69
|
+
case GLBlendMode.PREMULTIPLIED:
|
|
70
|
+
applyBlend(engine, gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE, FUNC_ADD, FUNC_ADD);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Enable blending with an arbitrary separate-channel function and equation —
|
|
76
|
+
* the lite-gl equivalent of Babylon's `AlphaState` with
|
|
77
|
+
* `setAlphaBlendFunctionParameters` + `setAlphaEquationParameters`.
|
|
78
|
+
*
|
|
79
|
+
* Supports every WebGL2 blend equation, including `MIN`, `MAX`,
|
|
80
|
+
* `FUNC_SUBTRACT` and `FUNC_REVERSE_SUBTRACT` (used by ShapeBuilder's darken /
|
|
81
|
+
* cutout blend modes). Records the desired config (flushed by `applyGLStates`
|
|
82
|
+
* before the next draw); at flush time the enable flag, the equation and the func
|
|
83
|
+
* are each cached independently, so a redundant state is fully elided and only
|
|
84
|
+
* the call whose params changed is re-issued — mirroring Babylon's `AlphaState`
|
|
85
|
+
* dirty flags. Because GL keeps the equation + func across `gl.disable(BLEND)`,
|
|
86
|
+
* re-enabling with unchanged params re-issues neither.
|
|
87
|
+
*
|
|
88
|
+
* No-op when the context is lost or disposed.
|
|
89
|
+
*
|
|
90
|
+
* @param engine - The engine whose desired blend state is updated.
|
|
91
|
+
* @param state - The separate-channel blend factors + equations to apply.
|
|
92
|
+
*/
|
|
93
|
+
export function setBlendState(engine, state) {
|
|
94
|
+
if (engine._isLost || engine._disposed) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
applyBlend(engine, state.srcRGB, state.dstRGB, state.srcAlpha, state.dstAlpha, state.equationRGB ?? FUNC_ADD, state.equationAlpha ?? FUNC_ADD);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Disable blending — the equivalent of Babylon's `AlphaState.alphaBlend = false`.
|
|
101
|
+
* Records the desired "blend off" state (flushed by `applyGLStates` before the
|
|
102
|
+
* next draw); the actual `gl.disable(gl.BLEND)` is elided when blending is
|
|
103
|
+
* already off at flush time. No-op when the context is lost or disposed.
|
|
104
|
+
*
|
|
105
|
+
* @param engine - The engine whose desired blend state is updated.
|
|
106
|
+
*/
|
|
107
|
+
export function disableBlend(engine) {
|
|
108
|
+
if (engine._isLost || engine._disposed) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const s = engine._state;
|
|
112
|
+
s.rs[RS_BLEND_ENABLED + RS_DESIRED] = 0;
|
|
113
|
+
s._flushBlend = flushBlend;
|
|
114
|
+
s.statesDirty = true;
|
|
115
|
+
}
|
|
116
|
+
/* ──────────────────────────── internal apply ──────────────────────────── */
|
|
117
|
+
/** Record a granular blend config into the DESIRED (`rs[RS_* + RS_DESIRED]`)
|
|
118
|
+
* slots and mark it dirty. No `gl.*` here — `applyGLStates` reconciles
|
|
119
|
+
* desired→actual at the next flush, caching the enable flag, equation and func
|
|
120
|
+
* independently so each is re-issued only when its params change (and never on a
|
|
121
|
+
* bare re-enable). */
|
|
122
|
+
function applyBlend(engine, srcRGB, dstRGB, srcAlpha, dstAlpha, eqRGB, eqAlpha) {
|
|
123
|
+
const rs = engine._state.rs;
|
|
124
|
+
rs[RS_BLEND_ENABLED + RS_DESIRED] = 1;
|
|
125
|
+
rs[RS_BLEND_SRC_RGB + RS_DESIRED] = srcRGB;
|
|
126
|
+
rs[RS_BLEND_DST_RGB + RS_DESIRED] = dstRGB;
|
|
127
|
+
rs[RS_BLEND_SRC_A + RS_DESIRED] = srcAlpha;
|
|
128
|
+
rs[RS_BLEND_DST_A + RS_DESIRED] = dstAlpha;
|
|
129
|
+
rs[RS_BLEND_EQ_RGB + RS_DESIRED] = eqRGB;
|
|
130
|
+
rs[RS_BLEND_EQ_A + RS_DESIRED] = eqAlpha;
|
|
131
|
+
engine._state._flushBlend = flushBlend;
|
|
132
|
+
engine._state.statesDirty = true;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Reconcile the deferred blend state DESIRED → ACTUAL — the per-category half of
|
|
136
|
+
* Babylon's `_alphaState.apply`. Installed onto `_state._flushBlend` by the blend
|
|
137
|
+
* setters and dispatched by {@link applyGLStates}; co-located here so a scene that
|
|
138
|
+
* never sets a blend mode tree-shakes both this reconciler and its GL code out of
|
|
139
|
+
* the bundle.
|
|
140
|
+
*
|
|
141
|
+
* The enable flag, the equation and the func are reconciled as THREE independent
|
|
142
|
+
* cached sub-states (mirroring Babylon's `_AlphaState` `_isAlphaBlendDirty` /
|
|
143
|
+
* `_isBlendEquationParametersDirty` / `_isBlendFunctionParametersDirty`). GL
|
|
144
|
+
* retains the blend equation + func across `gl.disable(BLEND)`, so their cached
|
|
145
|
+
* actual values stay valid while blending is off — re-enabling with unchanged
|
|
146
|
+
* params therefore issues ONLY `gl.enable(BLEND)` and re-issues neither
|
|
147
|
+
* `blendEquationSeparate` nor `blendFuncSeparate`. A desired `-1` (never
|
|
148
|
+
* requested) leaves GL untouched. @internal
|
|
149
|
+
*/
|
|
150
|
+
function flushBlend(engine) {
|
|
151
|
+
const gl = engine.gl;
|
|
152
|
+
const rs = engine._state.rs;
|
|
153
|
+
const dBlend = rs[RS_BLEND_ENABLED + RS_DESIRED];
|
|
154
|
+
if (dBlend === -1) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// 1. enable / disable — independent of the func + equation cache below.
|
|
158
|
+
if (dBlend !== rs[RS_BLEND_ENABLED]) {
|
|
159
|
+
rs[RS_BLEND_ENABLED] = dBlend;
|
|
160
|
+
if (dBlend === 1) {
|
|
161
|
+
gl.enable(BLEND);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
gl.disable(BLEND);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// While blending is off the equation/func are not observable and GL keeps the
|
|
168
|
+
// last values, so leave their cache untouched (Babylon does the same) — the
|
|
169
|
+
// next enable with identical params then re-issues nothing.
|
|
170
|
+
if (dBlend !== 1) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// 2. equation — re-issued only when the params actually changed.
|
|
174
|
+
const eqRGB = rs[RS_BLEND_EQ_RGB + RS_DESIRED];
|
|
175
|
+
const eqA = rs[RS_BLEND_EQ_A + RS_DESIRED];
|
|
176
|
+
if (rs[RS_BLEND_EQ_RGB] !== eqRGB || rs[RS_BLEND_EQ_A] !== eqA) {
|
|
177
|
+
gl.blendEquationSeparate(eqRGB, eqA);
|
|
178
|
+
rs[RS_BLEND_EQ_RGB] = eqRGB;
|
|
179
|
+
rs[RS_BLEND_EQ_A] = eqA;
|
|
180
|
+
}
|
|
181
|
+
// 3. func — re-issued only when the params actually changed.
|
|
182
|
+
const srcRGB = rs[RS_BLEND_SRC_RGB + RS_DESIRED];
|
|
183
|
+
const dstRGB = rs[RS_BLEND_DST_RGB + RS_DESIRED];
|
|
184
|
+
const srcA = rs[RS_BLEND_SRC_A + RS_DESIRED];
|
|
185
|
+
const dstA = rs[RS_BLEND_DST_A + RS_DESIRED];
|
|
186
|
+
if (rs[RS_BLEND_SRC_RGB] !== srcRGB || rs[RS_BLEND_DST_RGB] !== dstRGB || rs[RS_BLEND_SRC_A] !== srcA || rs[RS_BLEND_DST_A] !== dstA) {
|
|
187
|
+
gl.blendFuncSeparate(srcRGB, dstRGB, srcA, dstA);
|
|
188
|
+
rs[RS_BLEND_SRC_RGB] = srcRGB;
|
|
189
|
+
rs[RS_BLEND_DST_RGB] = dstRGB;
|
|
190
|
+
rs[RS_BLEND_SRC_A] = srcA;
|
|
191
|
+
rs[RS_BLEND_DST_A] = dstA;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=blend.js.map
|
package/blend.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blend.js","sourceRoot":"","sources":["../src/blend.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Blend-mode state — the WebGL counterpart of Babylon's `Engine.setAlphaMode`\n * (presets) and `AlphaState.setAlphaBlendFunctionParameters` /\n * `setAlphaEquationParameters` (the arbitrary separate func + equation path).\n *\n * The numeric {@link GLBlendMode} values intentionally match Babylon's\n * `Constants.ALPHA_*` (`ALPHA_DISABLE = 0`, `ALPHA_ADD = 1`, `ALPHA_COMBINE = 2`,\n * `ALPHA_PREMULTIPLIED = 7`) so a consumer can forward raw Babylon constants\n * without a translation table.\n *\n * DEFERRED MODEL (matches Babylon's `AlphaState`): these setters do NOT touch\n * `gl.*`. They record only the DESIRED blend config into the `d*` mirror fields\n * of `GLState` and raise `statesDirty`; `applyGLStates` (apply-states.ts) flushes\n * the diff to GL right before each draw / clear. Setting blend A then B then A\n * with no draw in between therefore applies exactly one blend state (A), and a\n * blend left unchanged across frames re-issues nothing.\n *\n * Both {@link setBlendMode} and {@link setBlendState} feed the same desired\n * fields, so the preset and arbitrary paths can never desync.\n */\nimport { type GLEngineContext } from \"./context.js\";\nimport { RS_BLEND_DST_A, RS_BLEND_DST_RGB, RS_BLEND_ENABLED, RS_BLEND_EQ_A, RS_BLEND_EQ_RGB, RS_BLEND_SRC_A, RS_BLEND_SRC_RGB, RS_DESIRED } from \"./state.js\";\n\n/**\n * Supported blend presets. Values mirror Babylon's `Constants.ALPHA_*` so the\n * raw Babylon integers can be passed straight through.\n */\nexport const GLBlendMode = {\n /** No blending — `gl.disable(gl.BLEND)`. (`Constants.ALPHA_DISABLE`) */\n DISABLE: 0,\n /** Additive — `blendFuncSeparate(SRC_ALPHA, ONE, ZERO, ONE)`. (`Constants.ALPHA_ADD`) */\n ADD: 1,\n /** Standard (non-premultiplied) alpha — `blendFuncSeparate(SRC_ALPHA, ONE_MINUS_SRC_ALPHA, ONE, ONE)`. (`Constants.ALPHA_COMBINE`) */\n ALPHA: 2,\n /** Premultiplied alpha — `blendFuncSeparate(ONE, ONE_MINUS_SRC_ALPHA, ONE, ONE)`. (`Constants.ALPHA_PREMULTIPLIED`) */\n PREMULTIPLIED: 7,\n} as const;\n\n/** One of the {@link GLBlendMode} preset values (`0`, `1`, `2` or `7`). */\nexport type GLBlendMode = (typeof GLBlendMode)[keyof typeof GLBlendMode];\n\n/**\n * Blend equation presets — the values WebGL2 accepts for\n * `gl.blendEquationSeparate`. Numeric values equal the GL enums so raw GL\n * integers (or Babylon's identical `Constants.GL_ALPHA_EQUATION_*`) pass\n * straight through.\n */\nexport const GLBlendEquation = {\n /** `src + dst` (the GL default). */\n ADD: 0x8006,\n /** `src - dst`. */\n SUBTRACT: 0x800a,\n /** `dst - src`. */\n REVERSE_SUBTRACT: 0x800b,\n /** `min(src, dst)`. */\n MIN: 0x8007,\n /** `max(src, dst)`. */\n MAX: 0x8008,\n} as const;\n\n/** One of the {@link GLBlendEquation} preset values. */\nexport type GLBlendEquation = (typeof GLBlendEquation)[keyof typeof GLBlendEquation];\n\n/**\n * Arbitrary separate-channel blend configuration — the lite-gl equivalent of\n * Babylon's `AlphaState.setAlphaBlendFunctionParameters` +\n * `setAlphaEquationParameters`. All factor / equation fields are raw WebGL2\n * enums (`gl.ONE`, `gl.SRC_ALPHA`, `gl.MIN`, …); use {@link GLBlendEquation} for\n * the equations if you prefer named presets.\n */\nexport interface GLBlendState {\n /** RGB source factor (`gl.blendFuncSeparate` arg 1). */\n srcRGB: GLenum;\n /** RGB destination factor (`gl.blendFuncSeparate` arg 2). */\n dstRGB: GLenum;\n /** Alpha source factor (`gl.blendFuncSeparate` arg 3). */\n srcAlpha: GLenum;\n /** Alpha destination factor (`gl.blendFuncSeparate` arg 4). */\n dstAlpha: GLenum;\n /** RGB blend equation. Defaults to `FUNC_ADD`. */\n equationRGB?: GLenum;\n /** Alpha blend equation. Defaults to `FUNC_ADD`. */\n equationAlpha?: GLenum;\n}\n\n/** GL `FUNC_ADD` — the implicit equation used by the {@link GLBlendMode}\n * presets (matching Babylon's `setAlphaMode`, which leaves it at the default). */\nconst FUNC_ADD = 0x8006;\n/** GL `gl.BLEND`. */\nconst BLEND = 0x0be2;\n\n/**\n * Set the GL blend state to match Babylon's `setAlphaMode(mode)` exactly.\n *\n * | Mode | `gl.blendFuncSeparate(srcRGB, dstRGB, srcA, dstA)` |\n * |--------------------|------------------------------------------------------------|\n * | `DISABLE` (0) | — (`gl.disable(gl.BLEND)`) |\n * | `ADD` (1) | `SRC_ALPHA, ONE, ZERO, ONE` |\n * | `ALPHA` (2) | `SRC_ALPHA, ONE_MINUS_SRC_ALPHA, ONE, ONE` |\n * | `PREMULTIPLIED` (7)| `ONE, ONE_MINUS_SRC_ALPHA, ONE, ONE` |\n *\n * No-op when the context is lost or disposed.\n *\n * @param engine - The engine whose GL blend state is updated.\n * @param mode - The {@link GLBlendMode} preset to apply.\n */\nexport function setBlendMode(engine: GLEngineContext, mode: GLBlendMode): void {\n if (engine._isLost || engine._disposed) {\n return;\n }\n const gl = engine.gl;\n switch (mode) {\n case GLBlendMode.DISABLE:\n disableBlend(engine);\n return;\n case GLBlendMode.ADD:\n applyBlend(engine, gl.SRC_ALPHA, gl.ONE, gl.ZERO, gl.ONE, FUNC_ADD, FUNC_ADD);\n return;\n case GLBlendMode.ALPHA:\n applyBlend(engine, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE, FUNC_ADD, FUNC_ADD);\n return;\n case GLBlendMode.PREMULTIPLIED:\n applyBlend(engine, gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE, FUNC_ADD, FUNC_ADD);\n return;\n }\n}\n\n/**\n * Enable blending with an arbitrary separate-channel function and equation —\n * the lite-gl equivalent of Babylon's `AlphaState` with\n * `setAlphaBlendFunctionParameters` + `setAlphaEquationParameters`.\n *\n * Supports every WebGL2 blend equation, including `MIN`, `MAX`,\n * `FUNC_SUBTRACT` and `FUNC_REVERSE_SUBTRACT` (used by ShapeBuilder's darken /\n * cutout blend modes). Records the desired config (flushed by `applyGLStates`\n * before the next draw); at flush time the enable flag, the equation and the func\n * are each cached independently, so a redundant state is fully elided and only\n * the call whose params changed is re-issued — mirroring Babylon's `AlphaState`\n * dirty flags. Because GL keeps the equation + func across `gl.disable(BLEND)`,\n * re-enabling with unchanged params re-issues neither.\n *\n * No-op when the context is lost or disposed.\n *\n * @param engine - The engine whose desired blend state is updated.\n * @param state - The separate-channel blend factors + equations to apply.\n */\nexport function setBlendState(engine: GLEngineContext, state: GLBlendState): void {\n if (engine._isLost || engine._disposed) {\n return;\n }\n applyBlend(engine, state.srcRGB, state.dstRGB, state.srcAlpha, state.dstAlpha, state.equationRGB ?? FUNC_ADD, state.equationAlpha ?? FUNC_ADD);\n}\n\n/**\n * Disable blending — the equivalent of Babylon's `AlphaState.alphaBlend = false`.\n * Records the desired \"blend off\" state (flushed by `applyGLStates` before the\n * next draw); the actual `gl.disable(gl.BLEND)` is elided when blending is\n * already off at flush time. No-op when the context is lost or disposed.\n *\n * @param engine - The engine whose desired blend state is updated.\n */\nexport function disableBlend(engine: GLEngineContext): void {\n if (engine._isLost || engine._disposed) {\n return;\n }\n const s = engine._state;\n s.rs[RS_BLEND_ENABLED + RS_DESIRED] = 0;\n s._flushBlend = flushBlend;\n s.statesDirty = true;\n}\n\n/* ──────────────────────────── internal apply ──────────────────────────── */\n\n/** Record a granular blend config into the DESIRED (`rs[RS_* + RS_DESIRED]`)\n * slots and mark it dirty. No `gl.*` here — `applyGLStates` reconciles\n * desired→actual at the next flush, caching the enable flag, equation and func\n * independently so each is re-issued only when its params change (and never on a\n * bare re-enable). */\nfunction applyBlend(engine: GLEngineContext, srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number, eqRGB: number, eqAlpha: number): void {\n const rs = engine._state.rs;\n rs[RS_BLEND_ENABLED + RS_DESIRED] = 1;\n rs[RS_BLEND_SRC_RGB + RS_DESIRED] = srcRGB;\n rs[RS_BLEND_DST_RGB + RS_DESIRED] = dstRGB;\n rs[RS_BLEND_SRC_A + RS_DESIRED] = srcAlpha;\n rs[RS_BLEND_DST_A + RS_DESIRED] = dstAlpha;\n rs[RS_BLEND_EQ_RGB + RS_DESIRED] = eqRGB;\n rs[RS_BLEND_EQ_A + RS_DESIRED] = eqAlpha;\n engine._state._flushBlend = flushBlend;\n engine._state.statesDirty = true;\n}\n\n/**\n * Reconcile the deferred blend state DESIRED → ACTUAL — the per-category half of\n * Babylon's `_alphaState.apply`. Installed onto `_state._flushBlend` by the blend\n * setters and dispatched by {@link applyGLStates}; co-located here so a scene that\n * never sets a blend mode tree-shakes both this reconciler and its GL code out of\n * the bundle.\n *\n * The enable flag, the equation and the func are reconciled as THREE independent\n * cached sub-states (mirroring Babylon's `_AlphaState` `_isAlphaBlendDirty` /\n * `_isBlendEquationParametersDirty` / `_isBlendFunctionParametersDirty`). GL\n * retains the blend equation + func across `gl.disable(BLEND)`, so their cached\n * actual values stay valid while blending is off — re-enabling with unchanged\n * params therefore issues ONLY `gl.enable(BLEND)` and re-issues neither\n * `blendEquationSeparate` nor `blendFuncSeparate`. A desired `-1` (never\n * requested) leaves GL untouched. @internal\n */\nfunction flushBlend(engine: GLEngineContext): void {\n const gl = engine.gl;\n const rs = engine._state.rs;\n const dBlend = rs[RS_BLEND_ENABLED + RS_DESIRED]!;\n if (dBlend === -1) {\n return;\n }\n // 1. enable / disable — independent of the func + equation cache below.\n if (dBlend !== rs[RS_BLEND_ENABLED]) {\n rs[RS_BLEND_ENABLED] = dBlend;\n if (dBlend === 1) {\n gl.enable(BLEND);\n } else {\n gl.disable(BLEND);\n }\n }\n // While blending is off the equation/func are not observable and GL keeps the\n // last values, so leave their cache untouched (Babylon does the same) — the\n // next enable with identical params then re-issues nothing.\n if (dBlend !== 1) {\n return;\n }\n // 2. equation — re-issued only when the params actually changed.\n const eqRGB = rs[RS_BLEND_EQ_RGB + RS_DESIRED]!;\n const eqA = rs[RS_BLEND_EQ_A + RS_DESIRED]!;\n if (rs[RS_BLEND_EQ_RGB] !== eqRGB || rs[RS_BLEND_EQ_A] !== eqA) {\n gl.blendEquationSeparate(eqRGB, eqA);\n rs[RS_BLEND_EQ_RGB] = eqRGB;\n rs[RS_BLEND_EQ_A] = eqA;\n }\n // 3. func — re-issued only when the params actually changed.\n const srcRGB = rs[RS_BLEND_SRC_RGB + RS_DESIRED]!;\n const dstRGB = rs[RS_BLEND_DST_RGB + RS_DESIRED]!;\n const srcA = rs[RS_BLEND_SRC_A + RS_DESIRED]!;\n const dstA = rs[RS_BLEND_DST_A + RS_DESIRED]!;\n if (rs[RS_BLEND_SRC_RGB] !== srcRGB || rs[RS_BLEND_DST_RGB] !== dstRGB || rs[RS_BLEND_SRC_A] !== srcA || rs[RS_BLEND_DST_A] !== dstA) {\n gl.blendFuncSeparate(srcRGB, dstRGB, srcA, dstA);\n rs[RS_BLEND_SRC_RGB] = srcRGB;\n rs[RS_BLEND_DST_RGB] = dstRGB;\n rs[RS_BLEND_SRC_A] = srcA;\n rs[RS_BLEND_DST_A] = dstA;\n }\n}\n"]}
|
package/context.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/** Constructor options forwarded to `canvas.getContext('webgl2', …)`. */
|
|
2
|
+
export interface GLEngineOptions {
|
|
3
|
+
/** Default: true. */
|
|
4
|
+
alpha?: boolean;
|
|
5
|
+
/** Default: true. */
|
|
6
|
+
premultipliedAlpha?: boolean;
|
|
7
|
+
/** Default: false. */
|
|
8
|
+
antialias?: boolean;
|
|
9
|
+
/** Default: false. */
|
|
10
|
+
preserveDrawingBuffer?: boolean;
|
|
11
|
+
/** Default: false — disabled for fullscreen-quad workloads. */
|
|
12
|
+
depth?: boolean;
|
|
13
|
+
/** Default: false. */
|
|
14
|
+
stencil?: boolean;
|
|
15
|
+
/** Default: "default". */
|
|
16
|
+
powerPreference?: WebGLPowerPreference;
|
|
17
|
+
/** Default: false. */
|
|
18
|
+
failIfMajorPerformanceCaveat?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Read-only WebGL2 capability limits, queried once at context creation. */
|
|
21
|
+
export interface GLEngineCaps {
|
|
22
|
+
/** `gl.MAX_TEXTURE_SIZE` — largest supported texture dimension, in texels. */
|
|
23
|
+
readonly maxTextureSize: number;
|
|
24
|
+
/** `gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS` — number of sampler binding slots. */
|
|
25
|
+
readonly maxTextureUnits: number;
|
|
26
|
+
/** The `KHR_parallel_shader_compile` extension used for async link polling,
|
|
27
|
+
* or null when unsupported — linking is then treated as synchronous. */
|
|
28
|
+
readonly parallelShaderCompile: {
|
|
29
|
+
COMPLETION_STATUS_KHR: number;
|
|
30
|
+
} | null;
|
|
31
|
+
/** True when 32-bit float color attachments are renderable
|
|
32
|
+
* (`EXT_color_buffer_float`). Mirrors Babylon's `caps.textureFloatRender`. */
|
|
33
|
+
readonly textureFloatRender: boolean;
|
|
34
|
+
/** True when 32-bit float textures support linear filtering
|
|
35
|
+
* (`OES_texture_float_linear`). Mirrors `caps.textureFloatLinearFiltering`. */
|
|
36
|
+
readonly textureFloatLinearFiltering: boolean;
|
|
37
|
+
/** True when 16-bit half-float color attachments are renderable
|
|
38
|
+
* (`EXT_color_buffer_float` or `EXT_color_buffer_half_float`). Mirrors
|
|
39
|
+
* `caps.textureHalfFloatRender`. */
|
|
40
|
+
readonly textureHalfFloatRender: boolean;
|
|
41
|
+
/** Half-float linear filtering — always `true` in WebGL2 (it is core).
|
|
42
|
+
* Kept as a field to mirror Babylon's `caps.textureHalfFloatLinearFiltering`. */
|
|
43
|
+
readonly textureHalfFloatLinearFiltering: boolean;
|
|
44
|
+
/** Whether non-power-of-two textures need POT dimensions for mips / wrap.
|
|
45
|
+
* Always `false` in WebGL2 (NPOT is core). Mirrors `engine.needPOTTextures`. */
|
|
46
|
+
readonly needPOTTextures: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Pure-state handle for a WebGL2 canvas + its cached GL state.
|
|
50
|
+
*
|
|
51
|
+
* INVARIANT: consumers MUST NOT mutate GL state directly through `engine.gl`.
|
|
52
|
+
* Doing so silently corrupts the cache in `_state`. The package owns every
|
|
53
|
+
* GL call. (`engine.gl` is exposed only so downstream code that already has the
|
|
54
|
+
* pattern of poking `engine._gl.getExtension(...)` can do that, but must NOT
|
|
55
|
+
* call `bindTexture`/`useProgram`/`bindBuffer`/`viewport`/etc.)
|
|
56
|
+
*/
|
|
57
|
+
export interface GLEngineContext {
|
|
58
|
+
/** The canvas the WebGL2 context was acquired from. An `OffscreenCanvas` is
|
|
59
|
+
* supported for worker render paths (e.g. the Lottie player); it has no CSS
|
|
60
|
+
* box, so it must be sized explicitly via `setGLEngineSize` rather than the
|
|
61
|
+
* CSS-derived `resizeGLEngine`. */
|
|
62
|
+
readonly canvas: HTMLCanvasElement | OffscreenCanvas;
|
|
63
|
+
/** The raw WebGL2 context. Do NOT mutate GL state through it — see the
|
|
64
|
+
* type-level invariant above; the package owns every state-changing call. */
|
|
65
|
+
readonly gl: WebGL2RenderingContext;
|
|
66
|
+
/** Queried capability limits for this context. */
|
|
67
|
+
readonly caps: GLEngineCaps;
|
|
68
|
+
}
|
|
69
|
+
/** Acquire a WebGL2 context on the canvas and build the pure-state handle.
|
|
70
|
+
* Accepts an `HTMLCanvasElement` or an `OffscreenCanvas` (worker render paths —
|
|
71
|
+
* e.g. the Lottie player — which size the drawing buffer via `setGLEngineSize`).
|
|
72
|
+
* Throws if WebGL2 is unsupported. */
|
|
73
|
+
export declare function createGLEngine(canvas: HTMLCanvasElement | OffscreenCanvas, options?: GLEngineOptions): GLEngineContext;
|
|
74
|
+
/** Stops the render loop, removes DOM listeners, releases all known effects
|
|
75
|
+
* and textures, then marks the context disposed. The browser-owned canvas
|
|
76
|
+
* is left intact. */
|
|
77
|
+
export declare function disposeGLEngine(engine: GLEngineContext): void;
|
|
78
|
+
/** Match drawing-buffer size to (clientSize × devicePixelRatio / _hsl). No-op
|
|
79
|
+
* if size already matches. Never touches viewport — `setViewport` owns that. */
|
|
80
|
+
export declare function resizeGLEngine(engine: GLEngineContext): void;
|
|
81
|
+
/**
|
|
82
|
+
* Set the drawing-buffer size to an EXPLICIT width/height in physical pixels
|
|
83
|
+
* (each divided by `_hsl`), independent of the canvas client/CSS size — the
|
|
84
|
+
* counterpart of Babylon's `ThinEngine.setSize`. Use when the render resolution
|
|
85
|
+
* is computed directly (e.g. animation dimensions × scale × dpr) rather than
|
|
86
|
+
* derived from CSS layout via {@link resizeGLEngine}. No-op on a disposed
|
|
87
|
+
* engine. Never touches the viewport — `setViewport` owns that.
|
|
88
|
+
*
|
|
89
|
+
* @param engine - The engine to resize.
|
|
90
|
+
* @param width - Target drawing-buffer width in physical pixels.
|
|
91
|
+
* @param height - Target drawing-buffer height in physical pixels.
|
|
92
|
+
*/
|
|
93
|
+
export declare function setGLEngineSize(engine: GLEngineContext, width: number, height: number): void;
|
|
94
|
+
/**
|
|
95
|
+
* Invalidate lite-gl's cached GL state so the next state-setting call in each
|
|
96
|
+
* category (program / buffer / texture / VAO / framebuffer bindings, blend,
|
|
97
|
+
* depth, stencil, scissor, color-mask, viewport, unpack) is re-issued instead
|
|
98
|
+
* of elided.
|
|
99
|
+
*
|
|
100
|
+
* Use this when a host application that SHARES this WebGL2 context mutates raw
|
|
101
|
+
* `gl.*` state outside lite-gl — e.g. a save/restore wrapper that resets the
|
|
102
|
+
* context to GL defaults around each render scope, or any interop layer that
|
|
103
|
+
* issues GL calls directly. Without it, lite-gl's redundant-call elision would
|
|
104
|
+
* skip the state changes needed to re-establish the scope, producing corrupted
|
|
105
|
+
* output. Owned GPU resources (the shared quad, render targets, meshes,
|
|
106
|
+
* effects, textures) are preserved — only the cached "current GL state" is
|
|
107
|
+
* reset. Mirrors Babylon's `Engine.wipeCaches()`.
|
|
108
|
+
*
|
|
109
|
+
* No-op while the context is lost or the engine is disposed.
|
|
110
|
+
*/
|
|
111
|
+
export declare function wipeGLStateCache(engine: GLEngineContext): void;
|
|
112
|
+
/** Drawing-buffer width in physical pixels (`canvas.width`). */
|
|
113
|
+
export declare function getRenderWidth(engine: GLEngineContext): number;
|
|
114
|
+
/** Drawing-buffer height in physical pixels (`canvas.height`). */
|
|
115
|
+
export declare function getRenderHeight(engine: GLEngineContext): number;
|
|
116
|
+
/** Current hardware-scaling factor — drawing-buffer = clientSize × dpr / level. */
|
|
117
|
+
export declare function getHardwareScalingLevel(engine: GLEngineContext): number;
|
|
118
|
+
/** Updates the hardware-scaling factor and triggers a resize. */
|
|
119
|
+
export declare function setHardwareScalingLevel(engine: GLEngineContext, level: number): void;
|
|
120
|
+
/** The backing canvas element (an `HTMLCanvasElement`, or an `OffscreenCanvas`
|
|
121
|
+
* for worker render paths). */
|
|
122
|
+
export declare function getRenderingCanvas(engine: GLEngineContext): HTMLCanvasElement | OffscreenCanvas;
|
|
123
|
+
/** Register a `webglcontextlost` callback. Duplicate registrations are ignored. */
|
|
124
|
+
export declare function onContextLost(engine: GLEngineContext, cb: () => void): void;
|
|
125
|
+
/** Remove a previously-registered context-lost callback. */
|
|
126
|
+
export declare function offContextLost(engine: GLEngineContext, cb: () => void): void;
|
|
127
|
+
/** Register a `webglcontextrestored` callback. Duplicate registrations are ignored. */
|
|
128
|
+
export declare function onContextRestored(engine: GLEngineContext, cb: () => void): void;
|
|
129
|
+
/** Remove a previously-registered context-restored callback. */
|
|
130
|
+
export declare function offContextRestored(engine: GLEngineContext, cb: () => void): void;
|