@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.
Files changed (61) hide show
  1. package/README.md +10 -34
  2. package/apply-states.d.ts +1 -0
  3. package/apply-states.js +30 -0
  4. package/apply-states.js.map +1 -0
  5. package/blend.d.ts +123 -0
  6. package/blend.js +194 -0
  7. package/blend.js.map +1 -0
  8. package/context.d.ts +130 -0
  9. package/context.js +354 -0
  10. package/context.js.map +1 -0
  11. package/depth-stencil.d.ts +155 -231
  12. package/depth-stencil.js +399 -262
  13. package/depth-stencil.js.map +1 -1
  14. package/dynamic-texture.d.ts +59 -149
  15. package/dynamic-texture.js +123 -69
  16. package/dynamic-texture.js.map +1 -1
  17. package/effect-renderer.d.ts +65 -0
  18. package/effect-renderer.js +132 -0
  19. package/effect-renderer.js.map +1 -0
  20. package/effect.d.ts +142 -0
  21. package/effect.js +465 -0
  22. package/effect.js.map +1 -0
  23. package/html-texture.d.ts +44 -143
  24. package/html-texture.js +87 -81
  25. package/html-texture.js.map +1 -1
  26. package/index.d.ts +23 -1482
  27. package/index.js +42 -263
  28. package/index.js.map +1 -1
  29. package/mesh.d.ts +210 -307
  30. package/mesh.js +436 -311
  31. package/mesh.js.map +1 -1
  32. package/package.json +5 -29
  33. package/render-loop.d.ts +8 -0
  34. package/render-loop.js +62 -0
  35. package/render-loop.js.map +1 -0
  36. package/render-target.d.ts +233 -290
  37. package/render-target.js +534 -335
  38. package/render-target.js.map +1 -1
  39. package/scissor.d.ts +30 -72
  40. package/scissor.js +47 -33
  41. package/scissor.js.map +1 -1
  42. package/shader.d.ts +22 -0
  43. package/shader.js +65 -0
  44. package/shader.js.map +1 -0
  45. package/sprites.d.ts +182 -263
  46. package/sprites.js +426 -10
  47. package/sprites.js.map +1 -1
  48. package/state.d.ts +126 -0
  49. package/state.js +153 -0
  50. package/state.js.map +1 -0
  51. package/texture.d.ts +142 -0
  52. package/texture.js +433 -0
  53. package/texture.js.map +1 -0
  54. package/effect-BxxwfB_O.js +0 -737
  55. package/effect-BxxwfB_O.js.map +0 -1
  56. package/sprites--1oyVtJ3.js +0 -437
  57. package/sprites--1oyVtJ3.js.map +0 -1
  58. package/state--j_ncWIi.js +0 -155
  59. package/state--j_ncWIi.js.map +0 -1
  60. package/texture-DaMd1gGm.js +0 -329
  61. package/texture-DaMd1gGm.js.map +0 -1
package/html-texture.d.ts CHANGED
@@ -1,143 +1,44 @@
1
- /** Create a texture backed by an `<canvas>` / `<img>` / `<video>` element.
2
- * The initial upload is performed immediately; call `updateHtmlElementTexture`
3
- * to re-upload after the source has changed. */
4
- export declare function createHtmlElementTexture(engine: GLEngineContext, element: HTMLCanvasElement | HTMLImageElement | HTMLVideoElement, options?: GLHtmlElementTextureOptions): GLTexture;
5
-
6
- /** Read-only WebGL2 capability limits, queried once at context creation. */
7
- declare interface GLEngineCaps {
8
- /** `gl.MAX_TEXTURE_SIZE` largest supported texture dimension, in texels. */
9
- readonly maxTextureSize: number;
10
- /** `gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS` number of sampler binding slots. */
11
- readonly maxTextureUnits: number;
12
- /** The `KHR_parallel_shader_compile` extension used for async link polling,
13
- * or null when unsupported — linking is then treated as synchronous. */
14
- readonly parallelShaderCompile: {
15
- COMPLETION_STATUS_KHR: number;
16
- } | null;
17
- /** True when 32-bit float color attachments are renderable
18
- * (`EXT_color_buffer_float`). Mirrors Babylon's `caps.textureFloatRender`. */
19
- readonly textureFloatRender: boolean;
20
- /** True when 32-bit float textures support linear filtering
21
- * (`OES_texture_float_linear`). Mirrors `caps.textureFloatLinearFiltering`. */
22
- readonly textureFloatLinearFiltering: boolean;
23
- /** True when 16-bit half-float color attachments are renderable
24
- * (`EXT_color_buffer_float` or `EXT_color_buffer_half_float`). Mirrors
25
- * `caps.textureHalfFloatRender`. */
26
- readonly textureHalfFloatRender: boolean;
27
- /** Half-float linear filtering always `true` in WebGL2 (it is core).
28
- * Kept as a field to mirror Babylon's `caps.textureHalfFloatLinearFiltering`. */
29
- readonly textureHalfFloatLinearFiltering: boolean;
30
- /** Whether non-power-of-two textures need POT dimensions for mips / wrap.
31
- * Always `false` in WebGL2 (NPOT is core). Mirrors `engine.needPOTTextures`. */
32
- readonly needPOTTextures: boolean;
33
- }
34
-
35
- /**
36
- * Pure-state handle for a WebGL2 canvas + its cached GL state.
37
- *
38
- * INVARIANT: consumers MUST NOT mutate GL state directly through `engine.gl`.
39
- * Doing so silently corrupts the cache in `_state`. The package owns every
40
- * GL call. (`engine.gl` is exposed only so downstream code that already has the
41
- * pattern of poking `engine._gl.getExtension(...)` can do that, but must NOT
42
- * call `bindTexture`/`useProgram`/`bindBuffer`/`viewport`/etc.)
43
- */
44
- declare interface GLEngineContext {
45
- /** The canvas the WebGL2 context was acquired from. An `OffscreenCanvas` is
46
- * supported for worker render paths (e.g. the Lottie player); it has no CSS
47
- * box, so it must be sized explicitly via `setGLEngineSize` rather than the
48
- * CSS-derived `resizeGLEngine`. */
49
- readonly canvas: HTMLCanvasElement | OffscreenCanvas;
50
- /** The raw WebGL2 context. Do NOT mutate GL state through it — see the
51
- * type-level invariant above; the package owns every state-changing call. */
52
- readonly gl: WebGL2RenderingContext;
53
- /** Queried capability limits for this context. */
54
- readonly caps: GLEngineCaps;
55
-
56
- /** Options for `createHtmlElementTexture` — the base texture options plus
57
- * HTML-source-specific settings. */
58
- export declare interface GLHtmlElementTextureOptions extends GLTextureOptions {
59
- /** High-level sampling preset. When set, derives `minFilter`/`magFilter`
60
- * (and `generateMipMaps` for `TRILINEAR`). Explicit `minFilter` /
61
- * `magFilter` / `generateMipMaps` options still take precedence. Omit for
62
- * the GL defaults (linear min + mag, no mipmaps). */
63
- samplingMode?: GLSamplingMode;
64
- /** Build a full mip chain after each upload. Independent of the core
65
- * texture options (this factory's mip behavior is sampling-mode-driven):
66
- * defaults to `true` only when `samplingMode` is `TRILINEAR`, otherwise
67
- * `false`. */
68
- generateMipMaps?: boolean;
69
- }
70
-
71
- /** High-level sampling presets, mirroring Babylon's `Texture.*_SAMPLINGMODE`
72
- * numeric constants. Each resolves to GL min/mag filters (and mip generation
73
- * for `TRILINEAR`). */
74
- export declare const GLSamplingMode: {
75
- /** Nearest min + mag, no mipmaps. (`Texture.NEAREST_SAMPLINGMODE`) */
76
- readonly NEAREST: 1;
77
- /** Linear min + mag, no mipmaps. (`Texture.BILINEAR_SAMPLINGMODE`) */
78
- readonly BILINEAR: 2;
79
- /** Linear mag + linear-mipmap-linear min, mipmaps generated.
80
- * (`Texture.TRILINEAR_SAMPLINGMODE`) */
81
- readonly TRILINEAR: 3;
82
- };
83
-
84
- /** One of the {@link GLSamplingMode} preset values (`1`, `2` or `3`). */
85
- export declare type GLSamplingMode = (typeof GLSamplingMode)[keyof typeof GLSamplingMode];
86
-
87
- /**
88
- * Pure-state texture handle. The `handle` field is MUTABLE so the same logical
89
- * texture survives a `webglcontextrestored` event — every consumer keeps the
90
- * same `GLTexture` reference; only the internal `WebGLTexture` is swapped.
91
- *
92
- * `loadTexture2D` also uses the same handle for the 1×1 placeholder upload AND
93
- * the final image upload — so a `bindTexture(engine, unit, tex)` made before the
94
- * image has decoded remains valid once the image arrives.
95
- */
96
- declare interface GLTexture {
97
- /** The live `WebGLTexture`. MUTABLE — swapped for a fresh handle on
98
- * `webglcontextrestored` while consumers keep the same `GLTexture` reference. */
99
- handle: WebGLTexture;
100
- /** GL texture target (always `gl.TEXTURE_2D` for this package). */
101
- readonly target: GLenum;
102
- /** Texture width in texels. Updated once an async upload resolves. */
103
- width: number;
104
- /** Texture height in texels. Updated once an async upload resolves. */
105
- height: number;
106
- /** True when the texture is safe to sample with final content (placeholders
107
- * read as not-ready until their image/upload completes). */
108
- isReady: boolean;
109
-
110
- /** Texture sampling / wrap options. All have GL-spec defaults. Mipmaps are NOT
111
- * a create option — generate the chain explicitly via {@link generateTextureMipMaps}. */
112
- declare interface GLTextureOptions {
113
- /** Default: false (matches Babylon's default raw-texture behaviour). */
114
- invertY?: boolean;
115
- /** Default: gl.LINEAR. */
116
- minFilter?: GLenum;
117
- /** Default: gl.LINEAR. */
118
- magFilter?: GLenum;
119
- /** Default: gl.CLAMP_TO_EDGE. May be `gl.REPEAT` / `gl.MIRRORED_REPEAT`
120
- * (NPOT-safe in WebGL2). */
121
- wrapS?: GLenum;
122
- /** Default: gl.CLAMP_TO_EDGE. May be `gl.REPEAT` / `gl.MIRRORED_REPEAT`. */
123
- wrapT?: GLenum;
124
- /** `gl.pixelStorei(UNPACK_ALIGNMENT)` for the upload (1/2/4/8). Default 4.
125
- * Use 1 for tightly-packed non-RGBA rows. */
126
- unpackAlignment?: number;
127
- /** Premultiply alpha at upload (`UNPACK_PREMULTIPLY_ALPHA_WEBGL`). Default
128
- * false. */
129
- premultiplyAlpha?: boolean;
130
- /** Explicit sized internalFormat for `texImage2D`. When provided it is used
131
- * verbatim and the inline LDR resolver is bypassed — this is how
132
- * {@link createFloatTexture} injects its `RGBA16F` / `RGBA32F` choice
133
- * without the byte path ever referencing the float-format table (keeping it
134
- * tree-shakeable out of RGBA8-only bundles). Default: derived from
135
- * `format`/`type` via the LDR resolver. */
136
- internalFormat?: GLenum;
137
- }
138
-
139
- /** Re-upload the texture from its source element. No-op when the context is
140
- * lost/disposed or the texture is disposed. */
141
- export declare function updateHtmlElementTexture(engine: GLEngineContext, tex: GLTexture): void;
142
-
143
- export { }
1
+ /**
2
+ * HTML element textures.
3
+ *
4
+ * Part of the public API via the `@babylonjs/lite-gl` barrel. The package is
5
+ * `sideEffects: false`, so consumers that don't need it (everything except
6
+ * NeonBrush's `InputGlow`) tree-shake it out.
7
+ */
8
+ import type { GLEngineContext } from "./context.js";
9
+ import { type GLTexture, type GLTextureOptions } from "./texture.js";
10
+ /** High-level sampling presets, mirroring Babylon's `Texture.*_SAMPLINGMODE`
11
+ * numeric constants. Each resolves to GL min/mag filters (and mip generation
12
+ * for `TRILINEAR`). */
13
+ export declare const GLSamplingMode: {
14
+ /** Nearest min + mag, no mipmaps. (`Texture.NEAREST_SAMPLINGMODE`) */
15
+ readonly NEAREST: 1;
16
+ /** Linear min + mag, no mipmaps. (`Texture.BILINEAR_SAMPLINGMODE`) */
17
+ readonly BILINEAR: 2;
18
+ /** Linear mag + linear-mipmap-linear min, mipmaps generated.
19
+ * (`Texture.TRILINEAR_SAMPLINGMODE`) */
20
+ readonly TRILINEAR: 3;
21
+ };
22
+ /** One of the {@link GLSamplingMode} preset values (`1`, `2` or `3`). */
23
+ export type GLSamplingMode = (typeof GLSamplingMode)[keyof typeof GLSamplingMode];
24
+ /** Options for `createHtmlElementTexture` — the base texture options plus
25
+ * HTML-source-specific settings. */
26
+ export interface GLHtmlElementTextureOptions extends GLTextureOptions {
27
+ /** High-level sampling preset. When set, derives `minFilter`/`magFilter`
28
+ * (and `generateMipMaps` for `TRILINEAR`). Explicit `minFilter` /
29
+ * `magFilter` / `generateMipMaps` options still take precedence. Omit for
30
+ * the GL defaults (linear min + mag, no mipmaps). */
31
+ samplingMode?: GLSamplingMode;
32
+ /** Build a full mip chain after each upload. Independent of the core
33
+ * texture options (this factory's mip behavior is sampling-mode-driven):
34
+ * defaults to `true` only when `samplingMode` is `TRILINEAR`, otherwise
35
+ * `false`. */
36
+ generateMipMaps?: boolean;
37
+ }
38
+ /** Create a texture backed by an `<canvas>` / `<img>` / `<video>` element.
39
+ * The initial upload is performed immediately; call `updateHtmlElementTexture`
40
+ * to re-upload after the source has changed. */
41
+ export declare function createHtmlElementTexture(engine: GLEngineContext, element: HTMLCanvasElement | HTMLImageElement | HTMLVideoElement, options?: GLHtmlElementTextureOptions): GLTexture;
42
+ /** Re-upload the texture from its source element. No-op when the context is
43
+ * lost/disposed or the texture is disposed. */
44
+ export declare function updateHtmlElementTexture(engine: GLEngineContext, tex: GLTexture): void;
package/html-texture.js CHANGED
@@ -1,89 +1,95 @@
1
- import { s as setUnpackState, i as bindTextureForUpload } from "./texture-DaMd1gGm.js";
2
- const GLSamplingMode = {
3
- /** Nearest min + mag, no mipmaps. (`Texture.NEAREST_SAMPLINGMODE`) */
4
- NEAREST: 1,
5
- /** Linear min + mag, no mipmaps. (`Texture.BILINEAR_SAMPLINGMODE`) */
6
- BILINEAR: 2,
7
- /** Linear mag + linear-mipmap-linear min, mipmaps generated.
8
- * (`Texture.TRILINEAR_SAMPLINGMODE`) */
9
- TRILINEAR: 3
1
+ import { bindTextureForUpload, setUnpackState } from "./texture.js";
2
+ /** High-level sampling presets, mirroring Babylon's `Texture.*_SAMPLINGMODE`
3
+ * numeric constants. Each resolves to GL min/mag filters (and mip generation
4
+ * for `TRILINEAR`). */
5
+ export const GLSamplingMode = {
6
+ /** Nearest min + mag, no mipmaps. (`Texture.NEAREST_SAMPLINGMODE`) */
7
+ NEAREST: 1,
8
+ /** Linear min + mag, no mipmaps. (`Texture.BILINEAR_SAMPLINGMODE`) */
9
+ BILINEAR: 2,
10
+ /** Linear mag + linear-mipmap-linear min, mipmaps generated.
11
+ * (`Texture.TRILINEAR_SAMPLINGMODE`) */
12
+ TRILINEAR: 3,
10
13
  };
11
- function createHtmlElementTexture(engine, element, options) {
12
- const gl = engine.gl;
13
- const handle = gl.createTexture();
14
- if (handle === null) {
15
- throw new Error("lite-gl: gl.createTexture returned null");
16
- }
17
- const opts = options ?? {};
18
- const sm = opts.samplingMode;
19
- const minFilter = opts.minFilter ?? samplingMinFilter(gl, sm);
20
- const magFilter = opts.magFilter ?? samplingMagFilter(gl, sm);
21
- const wrapS = opts.wrapS ?? gl.CLAMP_TO_EDGE;
22
- const wrapT = opts.wrapT ?? gl.CLAMP_TO_EDGE;
23
- const invertY = opts.invertY ?? false;
24
- const generateMipMaps = opts.generateMipMaps ?? sm === GLSamplingMode.TRILINEAR;
25
- const sizeOf = () => {
26
- if (element instanceof HTMLVideoElement) {
27
- return [element.videoWidth || 1, element.videoHeight || 1];
14
+ /** Create a texture backed by an `<canvas>` / `<img>` / `<video>` element.
15
+ * The initial upload is performed immediately; call `updateHtmlElementTexture`
16
+ * to re-upload after the source has changed. */
17
+ export function createHtmlElementTexture(engine, element, options) {
18
+ const gl = engine.gl;
19
+ const handle = gl.createTexture();
20
+ if (handle === null) {
21
+ throw new Error("lite-gl: gl.createTexture returned null");
28
22
  }
29
- if (element instanceof HTMLImageElement) {
30
- return [element.naturalWidth || 1, element.naturalHeight || 1];
31
- }
32
- return [element.width || 1, element.height || 1];
33
- };
34
- const upload = (target) => {
35
- const g = target.gl;
36
- setUnpackState(target, invertY, false);
37
- bindTextureForUpload(target, tex.handle);
38
- g.texImage2D(g.TEXTURE_2D, 0, g.RGBA, g.RGBA, g.UNSIGNED_BYTE, element);
39
- const [w, h] = sizeOf();
40
- tex.width = w;
41
- tex.height = h;
42
- g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MIN_FILTER, minFilter);
43
- g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MAG_FILTER, magFilter);
44
- g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_S, wrapS);
45
- g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_T, wrapT);
46
- if (generateMipMaps) {
47
- g.generateMipmap(g.TEXTURE_2D);
48
- }
49
- };
50
- const [w0, h0] = sizeOf();
51
- const tex = {
52
- handle,
53
- target: gl.TEXTURE_2D,
54
- width: w0,
55
- height: h0,
56
- isReady: true,
57
- _disposed: false,
58
- _refCount: 1,
59
- _upload: upload,
60
- _wasReady: true
61
- };
62
- upload(engine);
63
- engine._textures.push(tex);
64
- return tex;
23
+ const opts = options ?? {};
24
+ const sm = opts.samplingMode;
25
+ const minFilter = opts.minFilter ?? samplingMinFilter(gl, sm);
26
+ const magFilter = opts.magFilter ?? samplingMagFilter(gl, sm);
27
+ const wrapS = opts.wrapS ?? gl.CLAMP_TO_EDGE;
28
+ const wrapT = opts.wrapT ?? gl.CLAMP_TO_EDGE;
29
+ const invertY = opts.invertY ?? false;
30
+ const generateMipMaps = opts.generateMipMaps ?? sm === GLSamplingMode.TRILINEAR;
31
+ const sizeOf = () => {
32
+ if (element instanceof HTMLVideoElement) {
33
+ return [element.videoWidth || 1, element.videoHeight || 1];
34
+ }
35
+ if (element instanceof HTMLImageElement) {
36
+ return [element.naturalWidth || 1, element.naturalHeight || 1];
37
+ }
38
+ return [element.width || 1, element.height || 1];
39
+ };
40
+ const upload = (target) => {
41
+ const g = target.gl;
42
+ setUnpackState(target, invertY, false);
43
+ bindTextureForUpload(target, tex.handle);
44
+ g.texImage2D(g.TEXTURE_2D, 0, g.RGBA, g.RGBA, g.UNSIGNED_BYTE, element);
45
+ const [w, h] = sizeOf();
46
+ tex.width = w;
47
+ tex.height = h;
48
+ g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MIN_FILTER, minFilter);
49
+ g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MAG_FILTER, magFilter);
50
+ g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_S, wrapS);
51
+ g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_T, wrapT);
52
+ if (generateMipMaps) {
53
+ g.generateMipmap(g.TEXTURE_2D);
54
+ }
55
+ };
56
+ const [w0, h0] = sizeOf();
57
+ const tex = {
58
+ handle,
59
+ target: gl.TEXTURE_2D,
60
+ width: w0,
61
+ height: h0,
62
+ isReady: true,
63
+ _disposed: false,
64
+ _refCount: 1,
65
+ _upload: upload,
66
+ _wasReady: true,
67
+ };
68
+ upload(engine);
69
+ engine._textures.push(tex);
70
+ return tex;
65
71
  }
66
- function updateHtmlElementTexture(engine, tex) {
67
- if (engine._isLost || engine._disposed || tex._disposed) {
68
- return;
69
- }
70
- tex._upload(engine);
72
+ /** Re-upload the texture from its source element. No-op when the context is
73
+ * lost/disposed or the texture is disposed. */
74
+ export function updateHtmlElementTexture(engine, tex) {
75
+ if (engine._isLost || engine._disposed || tex._disposed) {
76
+ return;
77
+ }
78
+ tex._upload(engine);
71
79
  }
80
+ /* ──────────────────────────── internal helpers ──────────────────────────── */
81
+ /** Resolve a sampling preset to a GL min filter. Defaults to `gl.LINEAR`. */
72
82
  function samplingMinFilter(gl, mode) {
73
- if (mode === GLSamplingMode.NEAREST) {
74
- return gl.NEAREST;
75
- }
76
- if (mode === GLSamplingMode.TRILINEAR) {
77
- return gl.LINEAR_MIPMAP_LINEAR;
78
- }
79
- return gl.LINEAR;
83
+ if (mode === GLSamplingMode.NEAREST) {
84
+ return gl.NEAREST;
85
+ }
86
+ if (mode === GLSamplingMode.TRILINEAR) {
87
+ return gl.LINEAR_MIPMAP_LINEAR;
88
+ }
89
+ return gl.LINEAR;
80
90
  }
91
+ /** Resolve a sampling preset to a GL mag filter. Defaults to `gl.LINEAR`. */
81
92
  function samplingMagFilter(gl, mode) {
82
- return mode === GLSamplingMode.NEAREST ? gl.NEAREST : gl.LINEAR;
93
+ return mode === GLSamplingMode.NEAREST ? gl.NEAREST : gl.LINEAR;
83
94
  }
84
- export {
85
- GLSamplingMode,
86
- createHtmlElementTexture,
87
- updateHtmlElementTexture
88
- };
89
- //# sourceMappingURL=html-texture.js.map
95
+ //# sourceMappingURL=html-texture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"html-texture.js","sources":["../src/html-texture.ts"],"sourcesContent":["/**\n * Sub-entry: HTML element textures.\n *\n * Dynamic-importable via `import { ... } from \"@babylonjs/lite-gl/html-texture\"`\n * so consumers that don't need it (everything except NeonBrush's `InputGlow`)\n * don't pull it into their bundles.\n */\nimport type { GLEngineContext } from \"./context.js\";\nimport { bindTextureForUpload, setUnpackState, type GLTexture, type GLTextureOptions } from \"./texture.js\";\n\n/** High-level sampling presets, mirroring Babylon's `Texture.*_SAMPLINGMODE`\n * numeric constants. Each resolves to GL min/mag filters (and mip generation\n * for `TRILINEAR`). */\nexport const GLSamplingMode = {\n /** Nearest min + mag, no mipmaps. (`Texture.NEAREST_SAMPLINGMODE`) */\n NEAREST: 1,\n /** Linear min + mag, no mipmaps. (`Texture.BILINEAR_SAMPLINGMODE`) */\n BILINEAR: 2,\n /** Linear mag + linear-mipmap-linear min, mipmaps generated.\n * (`Texture.TRILINEAR_SAMPLINGMODE`) */\n TRILINEAR: 3,\n} as const;\n\n/** One of the {@link GLSamplingMode} preset values (`1`, `2` or `3`). */\nexport type GLSamplingMode = (typeof GLSamplingMode)[keyof typeof GLSamplingMode];\n\n/** Options for `createHtmlElementTexture` — the base texture options plus\n * HTML-source-specific settings. */\nexport interface GLHtmlElementTextureOptions extends GLTextureOptions {\n /** High-level sampling preset. When set, derives `minFilter`/`magFilter`\n * (and `generateMipMaps` for `TRILINEAR`). Explicit `minFilter` /\n * `magFilter` / `generateMipMaps` options still take precedence. Omit for\n * the GL defaults (linear min + mag, no mipmaps). */\n samplingMode?: GLSamplingMode;\n /** Build a full mip chain after each upload. Independent of the core\n * texture options (this factory's mip behavior is sampling-mode-driven):\n * defaults to `true` only when `samplingMode` is `TRILINEAR`, otherwise\n * `false`. */\n generateMipMaps?: boolean;\n}\n\n/** Create a texture backed by an `<canvas>` / `<img>` / `<video>` element.\n * The initial upload is performed immediately; call `updateHtmlElementTexture`\n * to re-upload after the source has changed. */\nexport function createHtmlElementTexture(\n engine: GLEngineContext,\n element: HTMLCanvasElement | HTMLImageElement | HTMLVideoElement,\n options?: GLHtmlElementTextureOptions\n): GLTexture {\n const gl = engine.gl;\n const handle = gl.createTexture();\n if (handle === null) {\n throw new Error(\"lite-gl: gl.createTexture returned null\");\n }\n const opts = options ?? {};\n const sm = opts.samplingMode;\n const minFilter = opts.minFilter ?? samplingMinFilter(gl, sm);\n const magFilter = opts.magFilter ?? samplingMagFilter(gl, sm);\n const wrapS = opts.wrapS ?? gl.CLAMP_TO_EDGE;\n const wrapT = opts.wrapT ?? gl.CLAMP_TO_EDGE;\n const invertY = opts.invertY ?? false;\n const generateMipMaps = opts.generateMipMaps ?? sm === GLSamplingMode.TRILINEAR;\n\n const sizeOf = (): [number, number] => {\n if (element instanceof HTMLVideoElement) {\n return [element.videoWidth || 1, element.videoHeight || 1];\n }\n if (element instanceof HTMLImageElement) {\n return [element.naturalWidth || 1, element.naturalHeight || 1];\n }\n return [element.width || 1, element.height || 1];\n };\n\n const upload = (target: GLEngineContext): void => {\n const g = target.gl;\n setUnpackState(target, invertY, false);\n bindTextureForUpload(target, tex.handle);\n g.texImage2D(g.TEXTURE_2D, 0, g.RGBA, g.RGBA, g.UNSIGNED_BYTE, element);\n const [w, h] = sizeOf();\n tex.width = w;\n tex.height = h;\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MIN_FILTER, minFilter);\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MAG_FILTER, magFilter);\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_S, wrapS);\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_T, wrapT);\n if (generateMipMaps) {\n g.generateMipmap(g.TEXTURE_2D);\n }\n };\n\n const [w0, h0] = sizeOf();\n const tex: GLTexture = {\n handle,\n target: gl.TEXTURE_2D,\n width: w0,\n height: h0,\n isReady: true,\n _disposed: false,\n _refCount: 1,\n _upload: upload,\n _wasReady: true,\n };\n upload(engine);\n engine._textures.push(tex);\n return tex;\n}\n\n/** Re-upload the texture from its source element. No-op when the context is\n * lost/disposed or the texture is disposed. */\nexport function updateHtmlElementTexture(engine: GLEngineContext, tex: GLTexture): void {\n if (engine._isLost || engine._disposed || tex._disposed) {\n return;\n }\n tex._upload(engine);\n}\n\n/* ──────────────────────────── internal helpers ──────────────────────────── */\n\n/** Resolve a sampling preset to a GL min filter. Defaults to `gl.LINEAR`. */\nfunction samplingMinFilter(gl: WebGL2RenderingContext, mode: GLSamplingMode | undefined): GLenum {\n if (mode === GLSamplingMode.NEAREST) {\n return gl.NEAREST;\n }\n if (mode === GLSamplingMode.TRILINEAR) {\n return gl.LINEAR_MIPMAP_LINEAR;\n }\n return gl.LINEAR;\n}\n\n/** Resolve a sampling preset to a GL mag filter. Defaults to `gl.LINEAR`. */\nfunction samplingMagFilter(gl: WebGL2RenderingContext, mode: GLSamplingMode | undefined): GLenum {\n return mode === GLSamplingMode.NEAREST ? gl.NEAREST : gl.LINEAR;\n}\n"],"names":[],"mappings":";AAaO,MAAM,iBAAiB;AAAA;AAAA,EAE1B,SAAS;AAAA;AAAA,EAET,UAAU;AAAA;AAAA;AAAA,EAGV,WAAW;AACf;AAuBO,SAAS,yBACZ,QACA,SACA,SACS;AACT,QAAM,KAAK,OAAO;AAClB,QAAM,SAAS,GAAG,cAAA;AAClB,MAAI,WAAW,MAAM;AACjB,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC7D;AACA,QAAM,OAAO,WAAW,CAAA;AACxB,QAAM,KAAK,KAAK;AAChB,QAAM,YAAY,KAAK,aAAa,kBAAkB,IAAI,EAAE;AAC5D,QAAM,YAAY,KAAK,aAAa,kBAAkB,IAAI,EAAE;AAC5D,QAAM,QAAQ,KAAK,SAAS,GAAG;AAC/B,QAAM,QAAQ,KAAK,SAAS,GAAG;AAC/B,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,kBAAkB,KAAK,mBAAmB,OAAO,eAAe;AAEtE,QAAM,SAAS,MAAwB;AACnC,QAAI,mBAAmB,kBAAkB;AACrC,aAAO,CAAC,QAAQ,cAAc,GAAG,QAAQ,eAAe,CAAC;AAAA,IAC7D;AACA,QAAI,mBAAmB,kBAAkB;AACrC,aAAO,CAAC,QAAQ,gBAAgB,GAAG,QAAQ,iBAAiB,CAAC;AAAA,IACjE;AACA,WAAO,CAAC,QAAQ,SAAS,GAAG,QAAQ,UAAU,CAAC;AAAA,EACnD;AAEA,QAAM,SAAS,CAAC,WAAkC;AAC9C,UAAM,IAAI,OAAO;AACjB,mBAAe,QAAQ,SAAS,KAAK;AACrC,yBAAqB,QAAQ,IAAI,MAAM;AACvC,MAAE,WAAW,EAAE,YAAY,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,OAAO;AACtE,UAAM,CAAC,GAAG,CAAC,IAAI,OAAA;AACf,QAAI,QAAQ;AACZ,QAAI,SAAS;AACb,MAAE,cAAc,EAAE,YAAY,EAAE,oBAAoB,SAAS;AAC7D,MAAE,cAAc,EAAE,YAAY,EAAE,oBAAoB,SAAS;AAC7D,MAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,KAAK;AACrD,MAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,KAAK;AACrD,QAAI,iBAAiB;AACjB,QAAE,eAAe,EAAE,UAAU;AAAA,IACjC;AAAA,EACJ;AAEA,QAAM,CAAC,IAAI,EAAE,IAAI,OAAA;AACjB,QAAM,MAAiB;AAAA,IACnB;AAAA,IACA,QAAQ,GAAG;AAAA,IACX,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,EAAA;AAEf,SAAO,MAAM;AACb,SAAO,UAAU,KAAK,GAAG;AACzB,SAAO;AACX;AAIO,SAAS,yBAAyB,QAAyB,KAAsB;AACpF,MAAI,OAAO,WAAW,OAAO,aAAa,IAAI,WAAW;AACrD;AAAA,EACJ;AACA,MAAI,QAAQ,MAAM;AACtB;AAKA,SAAS,kBAAkB,IAA4B,MAA0C;AAC7F,MAAI,SAAS,eAAe,SAAS;AACjC,WAAO,GAAG;AAAA,EACd;AACA,MAAI,SAAS,eAAe,WAAW;AACnC,WAAO,GAAG;AAAA,EACd;AACA,SAAO,GAAG;AACd;AAGA,SAAS,kBAAkB,IAA4B,MAA0C;AAC7F,SAAO,SAAS,eAAe,UAAU,GAAG,UAAU,GAAG;AAC7D;"}
1
+ {"version":3,"file":"html-texture.js","sourceRoot":"","sources":["../src/html-texture.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTML element textures.\n *\n * Part of the public API via the `@babylonjs/lite-gl` barrel. The package is\n * `sideEffects: false`, so consumers that don't need it (everything except\n * NeonBrush's `InputGlow`) tree-shake it out.\n */\nimport type { GLEngineContext } from \"./context.js\";\nimport { bindTextureForUpload, setUnpackState, type GLTexture, type GLTextureOptions } from \"./texture.js\";\n\n/** High-level sampling presets, mirroring Babylon's `Texture.*_SAMPLINGMODE`\n * numeric constants. Each resolves to GL min/mag filters (and mip generation\n * for `TRILINEAR`). */\nexport const GLSamplingMode = {\n /** Nearest min + mag, no mipmaps. (`Texture.NEAREST_SAMPLINGMODE`) */\n NEAREST: 1,\n /** Linear min + mag, no mipmaps. (`Texture.BILINEAR_SAMPLINGMODE`) */\n BILINEAR: 2,\n /** Linear mag + linear-mipmap-linear min, mipmaps generated.\n * (`Texture.TRILINEAR_SAMPLINGMODE`) */\n TRILINEAR: 3,\n} as const;\n\n/** One of the {@link GLSamplingMode} preset values (`1`, `2` or `3`). */\nexport type GLSamplingMode = (typeof GLSamplingMode)[keyof typeof GLSamplingMode];\n\n/** Options for `createHtmlElementTexture` — the base texture options plus\n * HTML-source-specific settings. */\nexport interface GLHtmlElementTextureOptions extends GLTextureOptions {\n /** High-level sampling preset. When set, derives `minFilter`/`magFilter`\n * (and `generateMipMaps` for `TRILINEAR`). Explicit `minFilter` /\n * `magFilter` / `generateMipMaps` options still take precedence. Omit for\n * the GL defaults (linear min + mag, no mipmaps). */\n samplingMode?: GLSamplingMode;\n /** Build a full mip chain after each upload. Independent of the core\n * texture options (this factory's mip behavior is sampling-mode-driven):\n * defaults to `true` only when `samplingMode` is `TRILINEAR`, otherwise\n * `false`. */\n generateMipMaps?: boolean;\n}\n\n/** Create a texture backed by an `<canvas>` / `<img>` / `<video>` element.\n * The initial upload is performed immediately; call `updateHtmlElementTexture`\n * to re-upload after the source has changed. */\nexport function createHtmlElementTexture(\n engine: GLEngineContext,\n element: HTMLCanvasElement | HTMLImageElement | HTMLVideoElement,\n options?: GLHtmlElementTextureOptions\n): GLTexture {\n const gl = engine.gl;\n const handle = gl.createTexture();\n if (handle === null) {\n throw new Error(\"lite-gl: gl.createTexture returned null\");\n }\n const opts = options ?? {};\n const sm = opts.samplingMode;\n const minFilter = opts.minFilter ?? samplingMinFilter(gl, sm);\n const magFilter = opts.magFilter ?? samplingMagFilter(gl, sm);\n const wrapS = opts.wrapS ?? gl.CLAMP_TO_EDGE;\n const wrapT = opts.wrapT ?? gl.CLAMP_TO_EDGE;\n const invertY = opts.invertY ?? false;\n const generateMipMaps = opts.generateMipMaps ?? sm === GLSamplingMode.TRILINEAR;\n\n const sizeOf = (): [number, number] => {\n if (element instanceof HTMLVideoElement) {\n return [element.videoWidth || 1, element.videoHeight || 1];\n }\n if (element instanceof HTMLImageElement) {\n return [element.naturalWidth || 1, element.naturalHeight || 1];\n }\n return [element.width || 1, element.height || 1];\n };\n\n const upload = (target: GLEngineContext): void => {\n const g = target.gl;\n setUnpackState(target, invertY, false);\n bindTextureForUpload(target, tex.handle);\n g.texImage2D(g.TEXTURE_2D, 0, g.RGBA, g.RGBA, g.UNSIGNED_BYTE, element);\n const [w, h] = sizeOf();\n tex.width = w;\n tex.height = h;\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MIN_FILTER, minFilter);\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_MAG_FILTER, magFilter);\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_S, wrapS);\n g.texParameteri(g.TEXTURE_2D, g.TEXTURE_WRAP_T, wrapT);\n if (generateMipMaps) {\n g.generateMipmap(g.TEXTURE_2D);\n }\n };\n\n const [w0, h0] = sizeOf();\n const tex: GLTexture = {\n handle,\n target: gl.TEXTURE_2D,\n width: w0,\n height: h0,\n isReady: true,\n _disposed: false,\n _refCount: 1,\n _upload: upload,\n _wasReady: true,\n };\n upload(engine);\n engine._textures.push(tex);\n return tex;\n}\n\n/** Re-upload the texture from its source element. No-op when the context is\n * lost/disposed or the texture is disposed. */\nexport function updateHtmlElementTexture(engine: GLEngineContext, tex: GLTexture): void {\n if (engine._isLost || engine._disposed || tex._disposed) {\n return;\n }\n tex._upload(engine);\n}\n\n/* ──────────────────────────── internal helpers ──────────────────────────── */\n\n/** Resolve a sampling preset to a GL min filter. Defaults to `gl.LINEAR`. */\nfunction samplingMinFilter(gl: WebGL2RenderingContext, mode: GLSamplingMode | undefined): GLenum {\n if (mode === GLSamplingMode.NEAREST) {\n return gl.NEAREST;\n }\n if (mode === GLSamplingMode.TRILINEAR) {\n return gl.LINEAR_MIPMAP_LINEAR;\n }\n return gl.LINEAR;\n}\n\n/** Resolve a sampling preset to a GL mag filter. Defaults to `gl.LINEAR`. */\nfunction samplingMagFilter(gl: WebGL2RenderingContext, mode: GLSamplingMode | undefined): GLenum {\n return mode === GLSamplingMode.NEAREST ? gl.NEAREST : gl.LINEAR;\n}\n"]}