@cosmos.gl/graph 2.6.2-rc.0 → 2.7.0-beta.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/.eslintrc +147 -0
- package/.github/SECURITY.md +13 -0
- package/.github/dco.yml +4 -0
- package/.github/workflows/github_pages.yml +54 -0
- package/.storybook/main.ts +26 -0
- package/.storybook/manager-head.html +1 -0
- package/.storybook/manager.ts +14 -0
- package/.storybook/preview.ts +29 -0
- package/.storybook/style.css +3 -0
- package/CHARTER.md +69 -0
- package/CODE_OF_CONDUCT.md +178 -0
- package/CONTRIBUTING.md +22 -0
- package/GOVERNANCE.md +21 -0
- package/cosmos-2-0-migration-notes.md +98 -0
- package/cosmos_awesome.md +96 -0
- package/dist/config.d.ts +5 -9
- package/dist/graph/utils/error-message.d.ts +1 -1
- package/dist/helper.d.ts +39 -2
- package/dist/index-FUIgayhu.js +19827 -0
- package/dist/index-FUIgayhu.js.map +1 -0
- package/dist/index.d.ts +17 -64
- package/dist/index.js +14 -14654
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1062 -475
- package/dist/index.min.js.map +1 -1
- package/dist/modules/Clusters/index.d.ts +11 -3
- package/dist/modules/ForceCenter/index.d.ts +10 -3
- package/dist/modules/ForceGravity/index.d.ts +5 -1
- package/dist/modules/ForceLink/index.d.ts +8 -5
- package/dist/modules/ForceManyBody/index.d.ts +16 -7
- package/dist/modules/ForceMouse/index.d.ts +5 -1
- package/dist/modules/GraphData/index.d.ts +0 -1
- package/dist/modules/Lines/index.d.ts +11 -5
- package/dist/modules/Points/index.d.ts +31 -13
- package/dist/modules/Store/index.d.ts +93 -0
- package/dist/modules/core-module.d.ts +3 -3
- package/dist/stories/beginners/basic-set-up/data-gen.d.ts +4 -0
- package/dist/stories/beginners/basic-set-up/index.d.ts +6 -0
- package/dist/stories/beginners/link-hovering/data-generator.d.ts +19 -0
- package/dist/stories/beginners/link-hovering/index.d.ts +6 -0
- package/dist/stories/beginners/point-labels/data.d.ts +13 -0
- package/dist/stories/beginners/point-labels/index.d.ts +10 -0
- package/dist/stories/beginners/point-labels/labels.d.ts +8 -0
- package/dist/stories/beginners/quick-start.d.ts +6 -0
- package/dist/stories/beginners/remove-points/config.d.ts +2 -0
- package/dist/stories/beginners/remove-points/data-gen.d.ts +4 -0
- package/dist/stories/beginners/remove-points/index.d.ts +6 -0
- package/dist/stories/beginners.stories.d.ts +10 -0
- package/dist/stories/clusters/polygon-selection/index.d.ts +6 -0
- package/dist/stories/clusters/polygon-selection/polygon.d.ts +20 -0
- package/dist/stories/clusters/radial.d.ts +6 -0
- package/dist/stories/clusters/with-labels.d.ts +6 -0
- package/dist/stories/clusters/worm.d.ts +6 -0
- package/dist/stories/clusters.stories.d.ts +9 -0
- package/dist/stories/create-cluster-labels.d.ts +4 -0
- package/dist/stories/create-cosmos.d.ts +17 -0
- package/dist/stories/create-story.d.ts +16 -0
- package/dist/stories/experiments/full-mesh.d.ts +6 -0
- package/dist/stories/experiments/mesh-with-holes.d.ts +6 -0
- package/dist/stories/experiments.stories.d.ts +7 -0
- package/dist/stories/generate-mesh-data.d.ts +12 -0
- package/dist/stories/geospatial/moscow-metro-stations/index.d.ts +16 -0
- package/dist/stories/geospatial/moscow-metro-stations/moscow-metro-coords.d.ts +1 -0
- package/dist/stories/geospatial/moscow-metro-stations/point-colors.d.ts +1 -0
- package/dist/stories/geospatial.stories.d.ts +6 -0
- package/dist/stories/shapes/all-shapes/index.d.ts +6 -0
- package/dist/stories/shapes/image-example/index.d.ts +6 -0
- package/dist/stories/shapes.stories.d.ts +7 -0
- package/dist/stories/test-luma-migration.d.ts +6 -0
- package/dist/stories/test.stories.d.ts +6 -0
- package/dist/webgl-device-B9ewDj5L.js +3923 -0
- package/dist/webgl-device-B9ewDj5L.js.map +1 -0
- package/logo.svg +3 -0
- package/package.json +5 -7
- package/rollup.config.js +70 -0
- package/src/config.ts +728 -0
- package/src/declaration.d.ts +12 -0
- package/src/graph/utils/error-message.ts +23 -0
- package/src/helper.ts +113 -0
- package/src/index.ts +1769 -0
- package/src/modules/Clusters/calculate-centermass.frag +12 -0
- package/src/modules/Clusters/calculate-centermass.vert +38 -0
- package/src/modules/Clusters/force-cluster.frag +55 -0
- package/src/modules/Clusters/index.ts +578 -0
- package/src/modules/Drag/index.ts +33 -0
- package/src/modules/FPSMonitor/css.ts +53 -0
- package/src/modules/FPSMonitor/index.ts +28 -0
- package/src/modules/ForceCenter/calculate-centermass.frag +9 -0
- package/src/modules/ForceCenter/calculate-centermass.vert +26 -0
- package/src/modules/ForceCenter/force-center.frag +37 -0
- package/src/modules/ForceCenter/index.ts +284 -0
- package/src/modules/ForceGravity/force-gravity.frag +40 -0
- package/src/modules/ForceGravity/index.ts +107 -0
- package/src/modules/ForceLink/force-spring.ts +89 -0
- package/src/modules/ForceLink/index.ts +293 -0
- package/src/modules/ForceManyBody/calculate-level.frag +9 -0
- package/src/modules/ForceManyBody/calculate-level.vert +37 -0
- package/src/modules/ForceManyBody/force-centermass.frag +61 -0
- package/src/modules/ForceManyBody/force-level.frag +138 -0
- package/src/modules/ForceManyBody/index.ts +525 -0
- package/src/modules/ForceManyBody/quadtree-frag-shader.ts +89 -0
- package/src/modules/ForceManyBodyQuadtree/calculate-level.frag +9 -0
- package/src/modules/ForceManyBodyQuadtree/calculate-level.vert +25 -0
- package/src/modules/ForceManyBodyQuadtree/index.ts +157 -0
- package/src/modules/ForceManyBodyQuadtree/quadtree-frag-shader.ts +93 -0
- package/src/modules/ForceMouse/force-mouse.frag +35 -0
- package/src/modules/ForceMouse/index.ts +102 -0
- package/src/modules/GraphData/index.ts +383 -0
- package/src/modules/Lines/draw-curve-line.frag +59 -0
- package/src/modules/Lines/draw-curve-line.vert +248 -0
- package/src/modules/Lines/geometry.ts +18 -0
- package/src/modules/Lines/hovered-line-index.frag +43 -0
- package/src/modules/Lines/hovered-line-index.vert +13 -0
- package/src/modules/Lines/index.ts +661 -0
- package/src/modules/Points/atlas-utils.ts +137 -0
- package/src/modules/Points/drag-point.frag +34 -0
- package/src/modules/Points/draw-highlighted.frag +44 -0
- package/src/modules/Points/draw-highlighted.vert +145 -0
- package/src/modules/Points/draw-points.frag +259 -0
- package/src/modules/Points/draw-points.vert +203 -0
- package/src/modules/Points/fill-sampled-points.frag +12 -0
- package/src/modules/Points/fill-sampled-points.vert +51 -0
- package/src/modules/Points/find-hovered-point.frag +15 -0
- package/src/modules/Points/find-hovered-point.vert +90 -0
- package/src/modules/Points/find-points-on-area-selection.frag +88 -0
- package/src/modules/Points/find-points-on-polygon-selection.frag +89 -0
- package/src/modules/Points/index.ts +2292 -0
- package/src/modules/Points/track-positions.frag +30 -0
- package/src/modules/Points/update-position.frag +39 -0
- package/src/modules/Shared/buffer.ts +39 -0
- package/src/modules/Shared/clear.frag +10 -0
- package/src/modules/Shared/quad.vert +13 -0
- package/src/modules/Store/index.ts +283 -0
- package/src/modules/Zoom/index.ts +148 -0
- package/src/modules/core-module.ts +28 -0
- package/src/stories/1. welcome.mdx +75 -0
- package/src/stories/2. configuration.mdx +111 -0
- package/src/stories/3. api-reference.mdx +591 -0
- package/src/stories/beginners/basic-set-up/data-gen.ts +33 -0
- package/src/stories/beginners/basic-set-up/index.ts +167 -0
- package/src/stories/beginners/basic-set-up/style.css +35 -0
- package/src/stories/beginners/link-hovering/data-generator.ts +198 -0
- package/src/stories/beginners/link-hovering/index.ts +65 -0
- package/src/stories/beginners/link-hovering/style.css +73 -0
- package/src/stories/beginners/point-labels/data.ts +73 -0
- package/src/stories/beginners/point-labels/index.ts +69 -0
- package/src/stories/beginners/point-labels/labels.ts +46 -0
- package/src/stories/beginners/point-labels/style.css +16 -0
- package/src/stories/beginners/quick-start.ts +54 -0
- package/src/stories/beginners/remove-points/config.ts +25 -0
- package/src/stories/beginners/remove-points/data-gen.ts +30 -0
- package/src/stories/beginners/remove-points/index.ts +96 -0
- package/src/stories/beginners/remove-points/style.css +31 -0
- package/src/stories/beginners.stories.ts +130 -0
- package/src/stories/clusters/polygon-selection/index.ts +52 -0
- package/src/stories/clusters/polygon-selection/polygon.ts +143 -0
- package/src/stories/clusters/polygon-selection/style.css +8 -0
- package/src/stories/clusters/radial.ts +24 -0
- package/src/stories/clusters/with-labels.ts +54 -0
- package/src/stories/clusters/worm.ts +40 -0
- package/src/stories/clusters.stories.ts +77 -0
- package/src/stories/create-cluster-labels.ts +50 -0
- package/src/stories/create-cosmos.ts +72 -0
- package/src/stories/create-story.ts +51 -0
- package/src/stories/experiments/full-mesh.ts +13 -0
- package/src/stories/experiments/mesh-with-holes.ts +13 -0
- package/src/stories/experiments.stories.ts +43 -0
- package/src/stories/generate-mesh-data.ts +125 -0
- package/src/stories/geospatial/moscow-metro-stations/index.ts +66 -0
- package/src/stories/geospatial/moscow-metro-stations/moscow-metro-coords.ts +1 -0
- package/src/stories/geospatial/moscow-metro-stations/point-colors.ts +46 -0
- package/src/stories/geospatial/moscow-metro-stations/style.css +30 -0
- package/src/stories/geospatial.stories.ts +30 -0
- package/src/stories/shapes/all-shapes/index.ts +73 -0
- package/src/stories/shapes/image-example/icons/box.png +0 -0
- package/src/stories/shapes/image-example/icons/lego.png +0 -0
- package/src/stories/shapes/image-example/icons/s.png +0 -0
- package/src/stories/shapes/image-example/icons/swift.png +0 -0
- package/src/stories/shapes/image-example/icons/toolbox.png +0 -0
- package/src/stories/shapes/image-example/index.ts +246 -0
- package/src/stories/shapes.stories.ts +37 -0
- package/src/stories/test-luma-migration.ts +195 -0
- package/src/stories/test.stories.ts +25 -0
- package/src/variables.ts +68 -0
- package/tsconfig.json +41 -0
- package/vite.config.ts +52 -0
|
@@ -0,0 +1,3923 @@
|
|
|
1
|
+
var je = Object.defineProperty;
|
|
2
|
+
var Qe = (r, t, e) => t in r ? je(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
|
|
3
|
+
var o = (r, t, e) => Qe(r, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { i as Me, a as Ye, n as Ke, u as Ze, R as S, l as b, T as L, g as Je, t as We, D as et, b as tt, B, S as rt, c as it, d as nt, e as st, f as at, h as ot, j as ct, k as lt, m as pe, o as ut, p as ht } from "./index-FUIgayhu.js";
|
|
5
|
+
function ft(r) {
|
|
6
|
+
return Me() ? Ye() ? "Electron" : (Ke.userAgent || "").indexOf("Edge") > -1 ? "Edge" : globalThis.chrome ? "Chrome" : globalThis.safari ? "Safari" : globalThis.mozInnerScreenX ? "Firefox" : "Unknown" : "Node";
|
|
7
|
+
}
|
|
8
|
+
function dt() {
|
|
9
|
+
let r, t;
|
|
10
|
+
return { promise: new Promise((i, n) => {
|
|
11
|
+
r = i, t = n;
|
|
12
|
+
}), resolve: r, reject: t };
|
|
13
|
+
}
|
|
14
|
+
const E = class E {
|
|
15
|
+
constructor(t) {
|
|
16
|
+
o(this, "id");
|
|
17
|
+
o(this, "props");
|
|
18
|
+
o(this, "canvas");
|
|
19
|
+
/** Handle to HTML canvas */
|
|
20
|
+
o(this, "htmlCanvas");
|
|
21
|
+
/** Handle to wrapped OffScreenCanvas */
|
|
22
|
+
o(this, "offscreenCanvas");
|
|
23
|
+
o(this, "type");
|
|
24
|
+
/** Promise that resolved once the resize observer has updated the pixel size */
|
|
25
|
+
o(this, "initialized");
|
|
26
|
+
o(this, "isInitialized", !1);
|
|
27
|
+
/** Visibility is automatically updated (via an IntersectionObserver) */
|
|
28
|
+
o(this, "isVisible", !0);
|
|
29
|
+
/** Width of canvas in CSS units (tracked by a ResizeObserver) */
|
|
30
|
+
o(this, "cssWidth");
|
|
31
|
+
/** Height of canvas in CSS units (tracked by a ResizeObserver) */
|
|
32
|
+
o(this, "cssHeight");
|
|
33
|
+
/** Device pixel ratio. Automatically updated via media queries */
|
|
34
|
+
o(this, "devicePixelRatio");
|
|
35
|
+
/** Exact width of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
36
|
+
o(this, "devicePixelWidth");
|
|
37
|
+
/** Exact height of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
38
|
+
o(this, "devicePixelHeight");
|
|
39
|
+
/** Width of drawing buffer: automatically tracks this.pixelWidth if props.autoResize is true */
|
|
40
|
+
o(this, "drawingBufferWidth");
|
|
41
|
+
/** Height of drawing buffer: automatically tracks this.pixelHeight if props.autoResize is true */
|
|
42
|
+
o(this, "drawingBufferHeight");
|
|
43
|
+
o(this, "_initializedResolvers", dt());
|
|
44
|
+
o(this, "_resizeObserver");
|
|
45
|
+
o(this, "_intersectionObserver");
|
|
46
|
+
o(this, "_position");
|
|
47
|
+
o(this, "destroyed", !1);
|
|
48
|
+
var e, i;
|
|
49
|
+
if (this.props = { ...E.defaultProps, ...t }, t = this.props, this.initialized = this._initializedResolvers.promise, Me() ? t.canvas ? typeof t.canvas == "string" ? this.canvas = bt(t.canvas) : this.canvas = t.canvas : this.canvas = mt(t) : this.canvas = { width: t.width || 1, height: t.height || 1 }, E.isHTMLCanvas(this.canvas) ? (this.id = t.id || this.canvas.id, this.type = "html-canvas", this.htmlCanvas = this.canvas) : E.isOffscreenCanvas(this.canvas) ? (this.id = t.id || "offscreen-canvas", this.type = "offscreen-canvas", this.offscreenCanvas = this.canvas) : (this.id = t.id || "node-canvas-context", this.type = "node"), this.cssWidth = ((e = this.htmlCanvas) == null ? void 0 : e.clientWidth) || this.canvas.width, this.cssHeight = ((i = this.htmlCanvas) == null ? void 0 : i.clientHeight) || this.canvas.height, this.devicePixelWidth = this.canvas.width, this.devicePixelHeight = this.canvas.height, this.drawingBufferWidth = this.canvas.width, this.drawingBufferHeight = this.canvas.height, this.devicePixelRatio = globalThis.devicePixelRatio || 1, this._position = [0, 0], E.isHTMLCanvas(this.canvas)) {
|
|
50
|
+
this._intersectionObserver = new IntersectionObserver((n) => this._handleIntersection(n)), this._intersectionObserver.observe(this.canvas), this._resizeObserver = new ResizeObserver((n) => this._handleResize(n));
|
|
51
|
+
try {
|
|
52
|
+
this._resizeObserver.observe(this.canvas, { box: "device-pixel-content-box" });
|
|
53
|
+
} catch {
|
|
54
|
+
this._resizeObserver.observe(this.canvas, { box: "content-box" });
|
|
55
|
+
}
|
|
56
|
+
setTimeout(() => this._observeDevicePixelRatio(), 0), this.props.trackPosition && this._trackPosition();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
static isHTMLCanvas(t) {
|
|
60
|
+
return typeof HTMLCanvasElement < "u" && t instanceof HTMLCanvasElement;
|
|
61
|
+
}
|
|
62
|
+
static isOffscreenCanvas(t) {
|
|
63
|
+
return typeof OffscreenCanvas < "u" && t instanceof OffscreenCanvas;
|
|
64
|
+
}
|
|
65
|
+
toString() {
|
|
66
|
+
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
67
|
+
}
|
|
68
|
+
destroy() {
|
|
69
|
+
this.destroyed = !0;
|
|
70
|
+
}
|
|
71
|
+
setProps(t) {
|
|
72
|
+
return "useDevicePixels" in t && (this.props.useDevicePixels = t.useDevicePixels || !1, this._updateDrawingBufferSize()), this;
|
|
73
|
+
}
|
|
74
|
+
// SIZE METHODS
|
|
75
|
+
/**
|
|
76
|
+
* Returns the size covered by the canvas in CSS pixels
|
|
77
|
+
* @note This can be different from the actual device pixel size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
78
|
+
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
79
|
+
*/
|
|
80
|
+
getCSSSize() {
|
|
81
|
+
return [this.cssWidth, this.cssHeight];
|
|
82
|
+
}
|
|
83
|
+
getPosition() {
|
|
84
|
+
return this._position;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns the size covered by the canvas in actual device pixels.
|
|
88
|
+
* @note This can be different from the 'CSS' size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
89
|
+
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
90
|
+
*/
|
|
91
|
+
getDevicePixelSize() {
|
|
92
|
+
return [this.devicePixelWidth, this.devicePixelHeight];
|
|
93
|
+
}
|
|
94
|
+
/** Get the drawing buffer size (number of pixels GPU is rendering into, can be different from CSS size) */
|
|
95
|
+
getDrawingBufferSize() {
|
|
96
|
+
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
97
|
+
}
|
|
98
|
+
/** Returns the biggest allowed framebuffer size. @todo Allow the application to limit this? */
|
|
99
|
+
getMaxDrawingBufferSize() {
|
|
100
|
+
const t = this.device.limits.maxTextureDimension2D;
|
|
101
|
+
return [t, t];
|
|
102
|
+
}
|
|
103
|
+
/** Update the canvas drawing buffer size. Called automatically if props.autoResize is true. */
|
|
104
|
+
setDrawingBufferSize(t, e) {
|
|
105
|
+
this.canvas.width = t, this.canvas.height = e, this.drawingBufferWidth = t, this.drawingBufferHeight = e;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
109
|
+
* @note This can be a fractional (non-integer) number, e.g. when the user zooms in the browser.
|
|
110
|
+
* @note This function handles the non-HTML canvas cases
|
|
111
|
+
*/
|
|
112
|
+
getDevicePixelRatio() {
|
|
113
|
+
return typeof window < "u" && window.devicePixelRatio || 1;
|
|
114
|
+
}
|
|
115
|
+
// DEPRECATED METHODS
|
|
116
|
+
/**
|
|
117
|
+
* Maps CSS pixel position to device pixel position
|
|
118
|
+
*/
|
|
119
|
+
cssToDevicePixels(t, e = !0) {
|
|
120
|
+
const i = this.cssToDeviceRatio(), [n, s] = this.getDrawingBufferSize();
|
|
121
|
+
return pt(t, i, n, s, e);
|
|
122
|
+
}
|
|
123
|
+
/** @deprecated - use .getDevicePixelSize() */
|
|
124
|
+
getPixelSize() {
|
|
125
|
+
return this.getDevicePixelSize();
|
|
126
|
+
}
|
|
127
|
+
/** @deprecated - TODO which values should we use for aspect */
|
|
128
|
+
getAspect() {
|
|
129
|
+
const [t, e] = this.getDevicePixelSize();
|
|
130
|
+
return t / e;
|
|
131
|
+
}
|
|
132
|
+
/** @deprecated Returns multiplier need to convert CSS size to Device size */
|
|
133
|
+
cssToDeviceRatio() {
|
|
134
|
+
try {
|
|
135
|
+
const [t] = this.getDrawingBufferSize(), [e] = this.getCSSSize();
|
|
136
|
+
return e ? t / e : 1;
|
|
137
|
+
} catch {
|
|
138
|
+
return 1;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** @deprecated Use canvasContext.setDrawingBufferSize() */
|
|
142
|
+
resize(t) {
|
|
143
|
+
this.setDrawingBufferSize(t.width, t.height);
|
|
144
|
+
}
|
|
145
|
+
// IMPLEMENTATION
|
|
146
|
+
/**
|
|
147
|
+
* Allows subclass constructor to override the canvas id for auto created canvases.
|
|
148
|
+
* This can really help when debugging DOM in apps that create multiple devices
|
|
149
|
+
*/
|
|
150
|
+
_setAutoCreatedCanvasId(t) {
|
|
151
|
+
var e;
|
|
152
|
+
((e = this.htmlCanvas) == null ? void 0 : e.id) === "lumagl-auto-created-canvas" && (this.htmlCanvas.id = t);
|
|
153
|
+
}
|
|
154
|
+
/** reacts to an observed intersection */
|
|
155
|
+
_handleIntersection(t) {
|
|
156
|
+
const e = t.find((n) => n.target === this.canvas);
|
|
157
|
+
if (!e)
|
|
158
|
+
return;
|
|
159
|
+
const i = e.isIntersecting;
|
|
160
|
+
this.isVisible !== i && (this.isVisible = i, this.device.props.onVisibilityChange(this));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Reacts to an observed resize by using the most accurate pixel size information the browser can provide
|
|
164
|
+
* @see https://web.dev/articles/device-pixel-content-box
|
|
165
|
+
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
166
|
+
*/
|
|
167
|
+
_handleResize(t) {
|
|
168
|
+
var l, u;
|
|
169
|
+
const e = t.find((h) => h.target === this.canvas);
|
|
170
|
+
if (!e)
|
|
171
|
+
return;
|
|
172
|
+
this.cssWidth = e.contentBoxSize[0].inlineSize, this.cssHeight = e.contentBoxSize[0].blockSize;
|
|
173
|
+
const i = this.getDevicePixelSize(), n = ((l = e.devicePixelContentBoxSize) == null ? void 0 : l[0].inlineSize) || e.contentBoxSize[0].inlineSize * devicePixelRatio, s = ((u = e.devicePixelContentBoxSize) == null ? void 0 : u[0].blockSize) || e.contentBoxSize[0].blockSize * devicePixelRatio, [a, c] = this.getMaxDrawingBufferSize();
|
|
174
|
+
this.devicePixelWidth = Math.max(1, Math.min(n, a)), this.devicePixelHeight = Math.max(1, Math.min(s, c)), this._updateDrawingBufferSize(), this.device.props.onResize(this, { oldPixelSize: i });
|
|
175
|
+
}
|
|
176
|
+
_updateDrawingBufferSize() {
|
|
177
|
+
if (this.props.autoResize) {
|
|
178
|
+
if (typeof this.props.useDevicePixels == "number") {
|
|
179
|
+
const t = this.props.useDevicePixels;
|
|
180
|
+
this.setDrawingBufferSize(this.cssWidth * t, this.cssHeight * t);
|
|
181
|
+
} else this.props.useDevicePixels ? this.setDrawingBufferSize(this.devicePixelWidth, this.devicePixelHeight) : this.setDrawingBufferSize(this.cssWidth, this.cssHeight);
|
|
182
|
+
this._updateDevice();
|
|
183
|
+
}
|
|
184
|
+
this._initializedResolvers.resolve(), this.isInitialized = !0, this.updatePosition();
|
|
185
|
+
}
|
|
186
|
+
/** Monitor DPR changes */
|
|
187
|
+
_observeDevicePixelRatio() {
|
|
188
|
+
const t = this.devicePixelRatio;
|
|
189
|
+
this.devicePixelRatio = window.devicePixelRatio, this.updatePosition(), this.device.props.onDevicePixelRatioChange(this, { oldRatio: t }), matchMedia(`(resolution: ${this.devicePixelRatio}dppx)`).addEventListener("change", () => this._observeDevicePixelRatio(), { once: !0 });
|
|
190
|
+
}
|
|
191
|
+
/** Start tracking positions with a timer */
|
|
192
|
+
_trackPosition(t = 100) {
|
|
193
|
+
const e = setInterval(() => {
|
|
194
|
+
this.destroyed ? clearInterval(e) : this.updatePosition();
|
|
195
|
+
}, t);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Calculated the absolute position of the canvas
|
|
199
|
+
* @note - getBoundingClientRect() is normally cheap but can be expensive
|
|
200
|
+
* if called before browser has finished a reflow. Should not be the case here.
|
|
201
|
+
*/
|
|
202
|
+
updatePosition() {
|
|
203
|
+
var e, i, n;
|
|
204
|
+
const t = (e = this.htmlCanvas) == null ? void 0 : e.getBoundingClientRect();
|
|
205
|
+
if (t) {
|
|
206
|
+
const s = [t.left, t.top];
|
|
207
|
+
if (this._position ?? (this._position = s), s[0] !== this._position[0] || s[1] !== this._position[1]) {
|
|
208
|
+
const c = this._position;
|
|
209
|
+
this._position = s, (n = (i = this.device.props).onPositionChange) == null || n.call(i, this, { oldPosition: c });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
o(E, "defaultProps", {
|
|
215
|
+
id: void 0,
|
|
216
|
+
canvas: null,
|
|
217
|
+
width: 800,
|
|
218
|
+
height: 600,
|
|
219
|
+
useDevicePixels: !0,
|
|
220
|
+
autoResize: !0,
|
|
221
|
+
container: null,
|
|
222
|
+
visible: !0,
|
|
223
|
+
alphaMode: "opaque",
|
|
224
|
+
colorSpace: "srgb",
|
|
225
|
+
trackPosition: !1
|
|
226
|
+
});
|
|
227
|
+
let X = E;
|
|
228
|
+
function gt(r) {
|
|
229
|
+
if (typeof r == "string") {
|
|
230
|
+
const t = document.getElementById(r);
|
|
231
|
+
if (!t)
|
|
232
|
+
throw new Error(`${r} is not an HTML element`);
|
|
233
|
+
return t;
|
|
234
|
+
}
|
|
235
|
+
return r || document.body;
|
|
236
|
+
}
|
|
237
|
+
function bt(r) {
|
|
238
|
+
const t = document.getElementById(r);
|
|
239
|
+
if (!X.isHTMLCanvas(t))
|
|
240
|
+
throw new Error("Object is not a canvas element");
|
|
241
|
+
return t;
|
|
242
|
+
}
|
|
243
|
+
function mt(r) {
|
|
244
|
+
const { width: t, height: e } = r, i = document.createElement("canvas");
|
|
245
|
+
i.id = Ze("lumagl-auto-created-canvas"), i.width = t || 1, i.height = e || 1, i.style.width = Number.isFinite(t) ? `${t}px` : "100%", i.style.height = Number.isFinite(e) ? `${e}px` : "100%", r != null && r.visible || (i.style.visibility = "hidden");
|
|
246
|
+
const n = gt((r == null ? void 0 : r.container) || null);
|
|
247
|
+
return n.insertBefore(i, n.firstChild), i;
|
|
248
|
+
}
|
|
249
|
+
function pt(r, t, e, i, n) {
|
|
250
|
+
const s = r, a = xe(s[0], t, e);
|
|
251
|
+
let c = ye(s[1], t, i, n), l = xe(s[0] + 1, t, e);
|
|
252
|
+
const u = l === e - 1 ? l : l - 1;
|
|
253
|
+
l = ye(s[1] + 1, t, i, n);
|
|
254
|
+
let h;
|
|
255
|
+
return n ? (l = l === 0 ? l : l + 1, h = c, c = l) : h = l === i - 1 ? l : l - 1, {
|
|
256
|
+
x: a,
|
|
257
|
+
y: c,
|
|
258
|
+
// when ratio < 1, current css pixel and next css pixel may point to same device pixel, set width/height to 1 in those cases.
|
|
259
|
+
width: Math.max(u - a + 1, 1),
|
|
260
|
+
height: Math.max(h - c + 1, 1)
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function xe(r, t, e) {
|
|
264
|
+
return Math.min(Math.round(r * t), e - 1);
|
|
265
|
+
}
|
|
266
|
+
function ye(r, t, e, i) {
|
|
267
|
+
return i ? Math.max(0, e - 1 - Math.round(r * t)) : Math.min(Math.round(r * t), e - 1);
|
|
268
|
+
}
|
|
269
|
+
const q = class q extends S {
|
|
270
|
+
constructor(e, i = {}) {
|
|
271
|
+
super(e, i, q.defaultProps);
|
|
272
|
+
/** Width of all attachments in this framebuffer */
|
|
273
|
+
o(this, "width");
|
|
274
|
+
/** Height of all attachments in this framebuffer */
|
|
275
|
+
o(this, "height");
|
|
276
|
+
this.width = this.props.width, this.height = this.props.height;
|
|
277
|
+
}
|
|
278
|
+
get [Symbol.toStringTag]() {
|
|
279
|
+
return "Framebuffer";
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Create a copy of this framebuffer with new attached textures, with same props but of the specified size.
|
|
283
|
+
* @note Does not copy contents of the attached textures.
|
|
284
|
+
*/
|
|
285
|
+
clone(e) {
|
|
286
|
+
const i = this.colorAttachments.map((s) => s.texture.clone(e)), n = this.depthStencilAttachment && this.depthStencilAttachment.texture.clone(e);
|
|
287
|
+
return this.device.createFramebuffer({ ...this.props, colorAttachments: i, depthStencilAttachment: n });
|
|
288
|
+
}
|
|
289
|
+
resize(e) {
|
|
290
|
+
let i = !e;
|
|
291
|
+
if (e) {
|
|
292
|
+
const [n, s] = Array.isArray(e) ? e : [e.width, e.height];
|
|
293
|
+
i = i || s !== this.height || n !== this.width, this.width = n, this.height = s;
|
|
294
|
+
}
|
|
295
|
+
i && (b.log(2, `Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)(), this.resizeAttachments(this.width, this.height));
|
|
296
|
+
}
|
|
297
|
+
/** Auto creates any textures */
|
|
298
|
+
autoCreateAttachmentTextures() {
|
|
299
|
+
if (this.props.colorAttachments.length === 0 && !this.props.depthStencilAttachment)
|
|
300
|
+
throw new Error("Framebuffer has noattachments");
|
|
301
|
+
this.colorAttachments = this.props.colorAttachments.map((i, n) => {
|
|
302
|
+
if (typeof i == "string") {
|
|
303
|
+
const s = this.createColorTexture(i, n);
|
|
304
|
+
return this.attachResource(s), s.view;
|
|
305
|
+
}
|
|
306
|
+
return i instanceof L ? i.view : i;
|
|
307
|
+
});
|
|
308
|
+
const e = this.props.depthStencilAttachment;
|
|
309
|
+
if (e)
|
|
310
|
+
if (typeof e == "string") {
|
|
311
|
+
const i = this.createDepthStencilTexture(e);
|
|
312
|
+
this.attachResource(i), this.depthStencilAttachment = i.view;
|
|
313
|
+
} else e instanceof L ? this.depthStencilAttachment = e.view : this.depthStencilAttachment = e;
|
|
314
|
+
}
|
|
315
|
+
/** Create a color texture */
|
|
316
|
+
createColorTexture(e, i) {
|
|
317
|
+
return this.device.createTexture({
|
|
318
|
+
id: `${this.id}-color-attachment-${i}`,
|
|
319
|
+
usage: L.RENDER_ATTACHMENT,
|
|
320
|
+
format: e,
|
|
321
|
+
width: this.width,
|
|
322
|
+
height: this.height,
|
|
323
|
+
// TODO deprecated? - luma.gl v8 compatibility
|
|
324
|
+
sampler: {
|
|
325
|
+
magFilter: "linear",
|
|
326
|
+
minFilter: "linear"
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
/** Create depth stencil texture */
|
|
331
|
+
createDepthStencilTexture(e) {
|
|
332
|
+
return this.device.createTexture({
|
|
333
|
+
id: `${this.id}-depth-stencil-attachment`,
|
|
334
|
+
usage: L.RENDER_ATTACHMENT,
|
|
335
|
+
format: e,
|
|
336
|
+
width: this.width,
|
|
337
|
+
height: this.height
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Default implementation of resize
|
|
342
|
+
* Creates new textures with correct size for all attachments.
|
|
343
|
+
* and destroys existing textures if owned
|
|
344
|
+
*/
|
|
345
|
+
resizeAttachments(e, i) {
|
|
346
|
+
for (let n = 0; n < this.colorAttachments.length; ++n)
|
|
347
|
+
if (this.colorAttachments[n]) {
|
|
348
|
+
const s = this.colorAttachments[n].texture.clone({
|
|
349
|
+
width: e,
|
|
350
|
+
height: i
|
|
351
|
+
});
|
|
352
|
+
this.destroyAttachedResource(this.colorAttachments[n]), this.colorAttachments[n] = s.view, this.attachResource(s.view);
|
|
353
|
+
}
|
|
354
|
+
if (this.depthStencilAttachment) {
|
|
355
|
+
const n = this.depthStencilAttachment.texture.clone({
|
|
356
|
+
width: e,
|
|
357
|
+
height: i
|
|
358
|
+
});
|
|
359
|
+
this.destroyAttachedResource(this.depthStencilAttachment), this.depthStencilAttachment = n.view, this.attachResource(n);
|
|
360
|
+
}
|
|
361
|
+
this.updateAttachments();
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
o(q, "defaultProps", {
|
|
365
|
+
...S.defaultProps,
|
|
366
|
+
width: 1,
|
|
367
|
+
height: 1,
|
|
368
|
+
colorAttachments: [],
|
|
369
|
+
// ['rgba8unorm'],
|
|
370
|
+
depthStencilAttachment: null
|
|
371
|
+
// 'depth24plus-stencil8'
|
|
372
|
+
});
|
|
373
|
+
let H = q;
|
|
374
|
+
const _ = class _ extends S {
|
|
375
|
+
get [Symbol.toStringTag]() {
|
|
376
|
+
return "RenderPass";
|
|
377
|
+
}
|
|
378
|
+
constructor(t, e) {
|
|
379
|
+
e = _.normalizeProps(t, e), super(t, e, _.defaultProps);
|
|
380
|
+
}
|
|
381
|
+
static normalizeProps(t, e) {
|
|
382
|
+
return e;
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
/** TODO - should be [0, 0, 0, 0], update once deck.gl tests run clean */
|
|
386
|
+
o(_, "defaultClearColor", [0, 0, 0, 1]), /** Depth 1.0 represents the far plance */
|
|
387
|
+
o(_, "defaultClearDepth", 1), /** Clears all stencil bits */
|
|
388
|
+
o(_, "defaultClearStencil", 0), /** Default properties for RenderPass */
|
|
389
|
+
o(_, "defaultProps", {
|
|
390
|
+
...S.defaultProps,
|
|
391
|
+
framebuffer: null,
|
|
392
|
+
parameters: void 0,
|
|
393
|
+
clearColor: _.defaultClearColor,
|
|
394
|
+
clearColors: void 0,
|
|
395
|
+
clearDepth: _.defaultClearDepth,
|
|
396
|
+
clearStencil: _.defaultClearStencil,
|
|
397
|
+
depthReadOnly: !1,
|
|
398
|
+
stencilReadOnly: !1,
|
|
399
|
+
discard: !1,
|
|
400
|
+
occlusionQuerySet: void 0,
|
|
401
|
+
timestampQuerySet: void 0,
|
|
402
|
+
beginTimestampIndex: void 0,
|
|
403
|
+
endTimestampIndex: void 0
|
|
404
|
+
});
|
|
405
|
+
let ie = _;
|
|
406
|
+
const j = class j extends S {
|
|
407
|
+
get [Symbol.toStringTag]() {
|
|
408
|
+
return "CommandEncoder";
|
|
409
|
+
}
|
|
410
|
+
constructor(t, e) {
|
|
411
|
+
super(t, e, j.defaultProps);
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
// TODO - luma.gl has these on the device, should we align with WebGPU API?
|
|
415
|
+
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
416
|
+
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
417
|
+
o(j, "defaultProps", {
|
|
418
|
+
...S.defaultProps,
|
|
419
|
+
measureExecutionTime: void 0
|
|
420
|
+
});
|
|
421
|
+
let ne = j;
|
|
422
|
+
const Q = class Q extends S {
|
|
423
|
+
get [Symbol.toStringTag]() {
|
|
424
|
+
return "CommandBuffer";
|
|
425
|
+
}
|
|
426
|
+
constructor(t, e) {
|
|
427
|
+
super(t, e, Q.defaultProps);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
o(Q, "defaultProps", {
|
|
431
|
+
...S.defaultProps
|
|
432
|
+
});
|
|
433
|
+
let se = Q;
|
|
434
|
+
const Y = class Y extends S {
|
|
435
|
+
constructor(e, i) {
|
|
436
|
+
super(e, i, Y.defaultProps);
|
|
437
|
+
/** Max number of vertex attributes */
|
|
438
|
+
o(this, "maxVertexAttributes");
|
|
439
|
+
/** Attribute infos indexed by location - TODO only needed by webgl module? */
|
|
440
|
+
o(this, "attributeInfos");
|
|
441
|
+
/** Index buffer */
|
|
442
|
+
o(this, "indexBuffer", null);
|
|
443
|
+
/** Attributes indexed by buffer slot */
|
|
444
|
+
o(this, "attributes");
|
|
445
|
+
this.maxVertexAttributes = e.limits.maxVertexAttributes, this.attributes = new Array(this.maxVertexAttributes).fill(null), this.attributeInfos = Je(i.shaderLayout, i.bufferLayout, this.maxVertexAttributes);
|
|
446
|
+
}
|
|
447
|
+
get [Symbol.toStringTag]() {
|
|
448
|
+
return "VertexArray";
|
|
449
|
+
}
|
|
450
|
+
// DEPRECATED METHODS
|
|
451
|
+
/** @deprecated Set constant attributes (WebGL only) */
|
|
452
|
+
setConstantWebGL(e, i) {
|
|
453
|
+
this.device.reportError(new Error("constant attributes not supported"), this)();
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
o(Y, "defaultProps", {
|
|
457
|
+
...S.defaultProps,
|
|
458
|
+
shaderLayout: void 0,
|
|
459
|
+
bufferLayout: []
|
|
460
|
+
});
|
|
461
|
+
let ae = Y;
|
|
462
|
+
const K = class K extends S {
|
|
463
|
+
get [Symbol.toStringTag]() {
|
|
464
|
+
return "TransformFeedback";
|
|
465
|
+
}
|
|
466
|
+
constructor(t, e) {
|
|
467
|
+
super(t, e, K.defaultProps);
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
o(K, "defaultProps", {
|
|
471
|
+
...S.defaultProps,
|
|
472
|
+
layout: void 0,
|
|
473
|
+
buffers: {}
|
|
474
|
+
});
|
|
475
|
+
let oe = K;
|
|
476
|
+
const Z = class Z extends S {
|
|
477
|
+
get [Symbol.toStringTag]() {
|
|
478
|
+
return "QuerySet";
|
|
479
|
+
}
|
|
480
|
+
constructor(t, e) {
|
|
481
|
+
super(t, e, Z.defaultProps);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
o(Z, "defaultProps", {
|
|
485
|
+
...S.defaultProps,
|
|
486
|
+
type: void 0,
|
|
487
|
+
count: void 0
|
|
488
|
+
});
|
|
489
|
+
let ce = Z;
|
|
490
|
+
const he = {
|
|
491
|
+
3042: !1,
|
|
492
|
+
32773: new Float32Array([0, 0, 0, 0]),
|
|
493
|
+
32777: 32774,
|
|
494
|
+
34877: 32774,
|
|
495
|
+
32969: 1,
|
|
496
|
+
32968: 0,
|
|
497
|
+
32971: 1,
|
|
498
|
+
32970: 0,
|
|
499
|
+
3106: new Float32Array([0, 0, 0, 0]),
|
|
500
|
+
// TBD
|
|
501
|
+
3107: [!0, !0, !0, !0],
|
|
502
|
+
2884: !1,
|
|
503
|
+
2885: 1029,
|
|
504
|
+
2929: !1,
|
|
505
|
+
2931: 1,
|
|
506
|
+
2932: 513,
|
|
507
|
+
2928: new Float32Array([0, 1]),
|
|
508
|
+
// TBD
|
|
509
|
+
2930: !0,
|
|
510
|
+
3024: !0,
|
|
511
|
+
35725: null,
|
|
512
|
+
// FRAMEBUFFER_BINDING and DRAW_FRAMEBUFFER_BINDING(WebGL2) refer same state.
|
|
513
|
+
36006: null,
|
|
514
|
+
36007: null,
|
|
515
|
+
34229: null,
|
|
516
|
+
34964: null,
|
|
517
|
+
2886: 2305,
|
|
518
|
+
33170: 4352,
|
|
519
|
+
2849: 1,
|
|
520
|
+
32823: !1,
|
|
521
|
+
32824: 0,
|
|
522
|
+
10752: 0,
|
|
523
|
+
32926: !1,
|
|
524
|
+
32928: !1,
|
|
525
|
+
32938: 1,
|
|
526
|
+
32939: !1,
|
|
527
|
+
3089: !1,
|
|
528
|
+
// Note: Dynamic value. If scissor test enabled we expect users to set correct scissor box
|
|
529
|
+
3088: new Int32Array([0, 0, 1024, 1024]),
|
|
530
|
+
2960: !1,
|
|
531
|
+
2961: 0,
|
|
532
|
+
2968: 4294967295,
|
|
533
|
+
36005: 4294967295,
|
|
534
|
+
2962: 519,
|
|
535
|
+
2967: 0,
|
|
536
|
+
2963: 4294967295,
|
|
537
|
+
34816: 519,
|
|
538
|
+
36003: 0,
|
|
539
|
+
36004: 4294967295,
|
|
540
|
+
2964: 7680,
|
|
541
|
+
2965: 7680,
|
|
542
|
+
2966: 7680,
|
|
543
|
+
34817: 7680,
|
|
544
|
+
34818: 7680,
|
|
545
|
+
34819: 7680,
|
|
546
|
+
// Dynamic value: We use [0, 0, 1024, 1024] as default, but usually this is updated in each frame.
|
|
547
|
+
2978: [0, 0, 1024, 1024],
|
|
548
|
+
36389: null,
|
|
549
|
+
36662: null,
|
|
550
|
+
36663: null,
|
|
551
|
+
35053: null,
|
|
552
|
+
35055: null,
|
|
553
|
+
35723: 4352,
|
|
554
|
+
36010: null,
|
|
555
|
+
35977: !1,
|
|
556
|
+
3333: 4,
|
|
557
|
+
3317: 4,
|
|
558
|
+
37440: !1,
|
|
559
|
+
37441: !1,
|
|
560
|
+
37443: 37444,
|
|
561
|
+
3330: 0,
|
|
562
|
+
3332: 0,
|
|
563
|
+
3331: 0,
|
|
564
|
+
3314: 0,
|
|
565
|
+
32878: 0,
|
|
566
|
+
3316: 0,
|
|
567
|
+
3315: 0,
|
|
568
|
+
32877: 0
|
|
569
|
+
}, y = (r, t, e) => t ? r.enable(e) : r.disable(e), we = (r, t, e) => r.hint(e, t), T = (r, t, e) => r.pixelStorei(e, t), ve = (r, t, e) => {
|
|
570
|
+
const i = e === 36006 ? 36009 : 36008;
|
|
571
|
+
return r.bindFramebuffer(i, t);
|
|
572
|
+
}, R = (r, t, e) => {
|
|
573
|
+
const n = {
|
|
574
|
+
34964: 34962,
|
|
575
|
+
36662: 36662,
|
|
576
|
+
36663: 36663,
|
|
577
|
+
35053: 35051,
|
|
578
|
+
35055: 35052
|
|
579
|
+
}[e];
|
|
580
|
+
r.bindBuffer(n, t);
|
|
581
|
+
};
|
|
582
|
+
function J(r) {
|
|
583
|
+
return Array.isArray(r) || ArrayBuffer.isView(r) && !(r instanceof DataView);
|
|
584
|
+
}
|
|
585
|
+
const xt = {
|
|
586
|
+
3042: y,
|
|
587
|
+
32773: (r, t) => r.blendColor(...t),
|
|
588
|
+
32777: "blendEquation",
|
|
589
|
+
34877: "blendEquation",
|
|
590
|
+
32969: "blendFunc",
|
|
591
|
+
32968: "blendFunc",
|
|
592
|
+
32971: "blendFunc",
|
|
593
|
+
32970: "blendFunc",
|
|
594
|
+
3106: (r, t) => r.clearColor(...t),
|
|
595
|
+
3107: (r, t) => r.colorMask(...t),
|
|
596
|
+
2884: y,
|
|
597
|
+
2885: (r, t) => r.cullFace(t),
|
|
598
|
+
2929: y,
|
|
599
|
+
2931: (r, t) => r.clearDepth(t),
|
|
600
|
+
2932: (r, t) => r.depthFunc(t),
|
|
601
|
+
2928: (r, t) => r.depthRange(...t),
|
|
602
|
+
2930: (r, t) => r.depthMask(t),
|
|
603
|
+
3024: y,
|
|
604
|
+
35723: we,
|
|
605
|
+
35725: (r, t) => r.useProgram(t),
|
|
606
|
+
36007: (r, t) => r.bindRenderbuffer(36161, t),
|
|
607
|
+
36389: (r, t) => {
|
|
608
|
+
var e;
|
|
609
|
+
return (e = r.bindTransformFeedback) == null ? void 0 : e.call(r, 36386, t);
|
|
610
|
+
},
|
|
611
|
+
34229: (r, t) => r.bindVertexArray(t),
|
|
612
|
+
// NOTE: FRAMEBUFFER_BINDING and DRAW_FRAMEBUFFER_BINDING(WebGL2) refer same state.
|
|
613
|
+
36006: ve,
|
|
614
|
+
36010: ve,
|
|
615
|
+
// Buffers
|
|
616
|
+
34964: R,
|
|
617
|
+
36662: R,
|
|
618
|
+
36663: R,
|
|
619
|
+
35053: R,
|
|
620
|
+
35055: R,
|
|
621
|
+
2886: (r, t) => r.frontFace(t),
|
|
622
|
+
33170: we,
|
|
623
|
+
2849: (r, t) => r.lineWidth(t),
|
|
624
|
+
32823: y,
|
|
625
|
+
32824: "polygonOffset",
|
|
626
|
+
10752: "polygonOffset",
|
|
627
|
+
35977: y,
|
|
628
|
+
32926: y,
|
|
629
|
+
32928: y,
|
|
630
|
+
32938: "sampleCoverage",
|
|
631
|
+
32939: "sampleCoverage",
|
|
632
|
+
3089: y,
|
|
633
|
+
3088: (r, t) => r.scissor(...t),
|
|
634
|
+
2960: y,
|
|
635
|
+
2961: (r, t) => r.clearStencil(t),
|
|
636
|
+
2968: (r, t) => r.stencilMaskSeparate(1028, t),
|
|
637
|
+
36005: (r, t) => r.stencilMaskSeparate(1029, t),
|
|
638
|
+
2962: "stencilFuncFront",
|
|
639
|
+
2967: "stencilFuncFront",
|
|
640
|
+
2963: "stencilFuncFront",
|
|
641
|
+
34816: "stencilFuncBack",
|
|
642
|
+
36003: "stencilFuncBack",
|
|
643
|
+
36004: "stencilFuncBack",
|
|
644
|
+
2964: "stencilOpFront",
|
|
645
|
+
2965: "stencilOpFront",
|
|
646
|
+
2966: "stencilOpFront",
|
|
647
|
+
34817: "stencilOpBack",
|
|
648
|
+
34818: "stencilOpBack",
|
|
649
|
+
34819: "stencilOpBack",
|
|
650
|
+
2978: (r, t) => r.viewport(...t),
|
|
651
|
+
// WEBGL2 EXTENSIONS
|
|
652
|
+
// EXT_depth_clamp https://registry.khronos.org/webgl/extensions/EXT_depth_clamp/
|
|
653
|
+
34383: y,
|
|
654
|
+
// WEBGL_provoking_vertex https://registry.khronos.org/webgl/extensions/WEBGL_provoking_vertex/
|
|
655
|
+
// [GL.PROVOKING_VERTEX_WEBL]: TODO - extension function needed
|
|
656
|
+
// WEBGL_polygon_mode https://registry.khronos.org/webgl/extensions/WEBGL_polygon_mode/
|
|
657
|
+
// POLYGON_MODE_WEBGL TODO - extension function needed
|
|
658
|
+
10754: y,
|
|
659
|
+
// WEBGL_clip_cull_distance https://registry.khronos.org/webgl/extensions/WEBGL_clip_cull_distance/
|
|
660
|
+
12288: y,
|
|
661
|
+
12289: y,
|
|
662
|
+
12290: y,
|
|
663
|
+
12291: y,
|
|
664
|
+
12292: y,
|
|
665
|
+
12293: y,
|
|
666
|
+
12294: y,
|
|
667
|
+
12295: y,
|
|
668
|
+
// PIXEL PACK/UNPACK MODES
|
|
669
|
+
3333: T,
|
|
670
|
+
3317: T,
|
|
671
|
+
37440: T,
|
|
672
|
+
37441: T,
|
|
673
|
+
37443: T,
|
|
674
|
+
3330: T,
|
|
675
|
+
3332: T,
|
|
676
|
+
3331: T,
|
|
677
|
+
3314: T,
|
|
678
|
+
32878: T,
|
|
679
|
+
3316: T,
|
|
680
|
+
3315: T,
|
|
681
|
+
32877: T,
|
|
682
|
+
// Function-style setters
|
|
683
|
+
framebuffer: (r, t) => {
|
|
684
|
+
const e = t && "handle" in t ? t.handle : t;
|
|
685
|
+
return r.bindFramebuffer(36160, e);
|
|
686
|
+
},
|
|
687
|
+
blend: (r, t) => t ? r.enable(3042) : r.disable(3042),
|
|
688
|
+
blendColor: (r, t) => r.blendColor(...t),
|
|
689
|
+
blendEquation: (r, t) => {
|
|
690
|
+
const e = typeof t == "number" ? [t, t] : t;
|
|
691
|
+
r.blendEquationSeparate(...e);
|
|
692
|
+
},
|
|
693
|
+
blendFunc: (r, t) => {
|
|
694
|
+
const e = (t == null ? void 0 : t.length) === 2 ? [...t, ...t] : t;
|
|
695
|
+
r.blendFuncSeparate(...e);
|
|
696
|
+
},
|
|
697
|
+
clearColor: (r, t) => r.clearColor(...t),
|
|
698
|
+
clearDepth: (r, t) => r.clearDepth(t),
|
|
699
|
+
clearStencil: (r, t) => r.clearStencil(t),
|
|
700
|
+
colorMask: (r, t) => r.colorMask(...t),
|
|
701
|
+
cull: (r, t) => t ? r.enable(2884) : r.disable(2884),
|
|
702
|
+
cullFace: (r, t) => r.cullFace(t),
|
|
703
|
+
depthTest: (r, t) => t ? r.enable(2929) : r.disable(2929),
|
|
704
|
+
depthFunc: (r, t) => r.depthFunc(t),
|
|
705
|
+
depthMask: (r, t) => r.depthMask(t),
|
|
706
|
+
depthRange: (r, t) => r.depthRange(...t),
|
|
707
|
+
dither: (r, t) => t ? r.enable(3024) : r.disable(3024),
|
|
708
|
+
derivativeHint: (r, t) => {
|
|
709
|
+
r.hint(35723, t);
|
|
710
|
+
},
|
|
711
|
+
frontFace: (r, t) => r.frontFace(t),
|
|
712
|
+
mipmapHint: (r, t) => r.hint(33170, t),
|
|
713
|
+
lineWidth: (r, t) => r.lineWidth(t),
|
|
714
|
+
polygonOffsetFill: (r, t) => t ? r.enable(32823) : r.disable(32823),
|
|
715
|
+
polygonOffset: (r, t) => r.polygonOffset(...t),
|
|
716
|
+
sampleCoverage: (r, t) => r.sampleCoverage(t[0], t[1] || !1),
|
|
717
|
+
scissorTest: (r, t) => t ? r.enable(3089) : r.disable(3089),
|
|
718
|
+
scissor: (r, t) => r.scissor(...t),
|
|
719
|
+
stencilTest: (r, t) => t ? r.enable(2960) : r.disable(2960),
|
|
720
|
+
stencilMask: (r, t) => {
|
|
721
|
+
t = J(t) ? t : [t, t];
|
|
722
|
+
const [e, i] = t;
|
|
723
|
+
r.stencilMaskSeparate(1028, e), r.stencilMaskSeparate(1029, i);
|
|
724
|
+
},
|
|
725
|
+
stencilFunc: (r, t) => {
|
|
726
|
+
t = J(t) && t.length === 3 ? [...t, ...t] : t;
|
|
727
|
+
const [e, i, n, s, a, c] = t;
|
|
728
|
+
r.stencilFuncSeparate(1028, e, i, n), r.stencilFuncSeparate(1029, s, a, c);
|
|
729
|
+
},
|
|
730
|
+
stencilOp: (r, t) => {
|
|
731
|
+
t = J(t) && t.length === 3 ? [...t, ...t] : t;
|
|
732
|
+
const [e, i, n, s, a, c] = t;
|
|
733
|
+
r.stencilOpSeparate(1028, e, i, n), r.stencilOpSeparate(1029, s, a, c);
|
|
734
|
+
},
|
|
735
|
+
viewport: (r, t) => r.viewport(...t)
|
|
736
|
+
};
|
|
737
|
+
function x(r, t, e) {
|
|
738
|
+
return t[r] !== void 0 ? t[r] : e[r];
|
|
739
|
+
}
|
|
740
|
+
const yt = {
|
|
741
|
+
blendEquation: (r, t, e) => r.blendEquationSeparate(x(32777, t, e), x(34877, t, e)),
|
|
742
|
+
blendFunc: (r, t, e) => r.blendFuncSeparate(x(32969, t, e), x(32968, t, e), x(32971, t, e), x(32970, t, e)),
|
|
743
|
+
polygonOffset: (r, t, e) => r.polygonOffset(x(32824, t, e), x(10752, t, e)),
|
|
744
|
+
sampleCoverage: (r, t, e) => r.sampleCoverage(x(32938, t, e), x(32939, t, e)),
|
|
745
|
+
stencilFuncFront: (r, t, e) => r.stencilFuncSeparate(1028, x(2962, t, e), x(2967, t, e), x(2963, t, e)),
|
|
746
|
+
stencilFuncBack: (r, t, e) => r.stencilFuncSeparate(1029, x(34816, t, e), x(36003, t, e), x(36004, t, e)),
|
|
747
|
+
stencilOpFront: (r, t, e) => r.stencilOpSeparate(1028, x(2964, t, e), x(2965, t, e), x(2966, t, e)),
|
|
748
|
+
stencilOpBack: (r, t, e) => r.stencilOpSeparate(1029, x(34817, t, e), x(34818, t, e), x(34819, t, e))
|
|
749
|
+
}, Se = {
|
|
750
|
+
// GENERIC SETTERS
|
|
751
|
+
enable: (r, t) => r({
|
|
752
|
+
[t]: !0
|
|
753
|
+
}),
|
|
754
|
+
disable: (r, t) => r({
|
|
755
|
+
[t]: !1
|
|
756
|
+
}),
|
|
757
|
+
pixelStorei: (r, t, e) => r({
|
|
758
|
+
[t]: e
|
|
759
|
+
}),
|
|
760
|
+
hint: (r, t, e) => r({
|
|
761
|
+
[t]: e
|
|
762
|
+
}),
|
|
763
|
+
// SPECIFIC SETTERS
|
|
764
|
+
useProgram: (r, t) => r({
|
|
765
|
+
35725: t
|
|
766
|
+
}),
|
|
767
|
+
bindRenderbuffer: (r, t, e) => r({
|
|
768
|
+
36007: e
|
|
769
|
+
}),
|
|
770
|
+
bindTransformFeedback: (r, t, e) => r({
|
|
771
|
+
36389: e
|
|
772
|
+
}),
|
|
773
|
+
bindVertexArray: (r, t) => r({
|
|
774
|
+
34229: t
|
|
775
|
+
}),
|
|
776
|
+
bindFramebuffer: (r, t, e) => {
|
|
777
|
+
switch (t) {
|
|
778
|
+
case 36160:
|
|
779
|
+
return r({
|
|
780
|
+
36006: e,
|
|
781
|
+
36010: e
|
|
782
|
+
});
|
|
783
|
+
case 36009:
|
|
784
|
+
return r({ 36006: e });
|
|
785
|
+
case 36008:
|
|
786
|
+
return r({ 36010: e });
|
|
787
|
+
default:
|
|
788
|
+
return null;
|
|
789
|
+
}
|
|
790
|
+
},
|
|
791
|
+
bindBuffer: (r, t, e) => {
|
|
792
|
+
const i = {
|
|
793
|
+
34962: [34964],
|
|
794
|
+
36662: [36662],
|
|
795
|
+
36663: [36663],
|
|
796
|
+
35051: [35053],
|
|
797
|
+
35052: [35055]
|
|
798
|
+
}[t];
|
|
799
|
+
return i ? r({ [i]: e }) : { valueChanged: !0 };
|
|
800
|
+
},
|
|
801
|
+
blendColor: (r, t, e, i, n) => r({
|
|
802
|
+
32773: new Float32Array([t, e, i, n])
|
|
803
|
+
}),
|
|
804
|
+
blendEquation: (r, t) => r({
|
|
805
|
+
32777: t,
|
|
806
|
+
34877: t
|
|
807
|
+
}),
|
|
808
|
+
blendEquationSeparate: (r, t, e) => r({
|
|
809
|
+
32777: t,
|
|
810
|
+
34877: e
|
|
811
|
+
}),
|
|
812
|
+
blendFunc: (r, t, e) => r({
|
|
813
|
+
32969: t,
|
|
814
|
+
32968: e,
|
|
815
|
+
32971: t,
|
|
816
|
+
32970: e
|
|
817
|
+
}),
|
|
818
|
+
blendFuncSeparate: (r, t, e, i, n) => r({
|
|
819
|
+
32969: t,
|
|
820
|
+
32968: e,
|
|
821
|
+
32971: i,
|
|
822
|
+
32970: n
|
|
823
|
+
}),
|
|
824
|
+
clearColor: (r, t, e, i, n) => r({
|
|
825
|
+
3106: new Float32Array([t, e, i, n])
|
|
826
|
+
}),
|
|
827
|
+
clearDepth: (r, t) => r({
|
|
828
|
+
2931: t
|
|
829
|
+
}),
|
|
830
|
+
clearStencil: (r, t) => r({
|
|
831
|
+
2961: t
|
|
832
|
+
}),
|
|
833
|
+
colorMask: (r, t, e, i, n) => r({
|
|
834
|
+
3107: [t, e, i, n]
|
|
835
|
+
}),
|
|
836
|
+
cullFace: (r, t) => r({
|
|
837
|
+
2885: t
|
|
838
|
+
}),
|
|
839
|
+
depthFunc: (r, t) => r({
|
|
840
|
+
2932: t
|
|
841
|
+
}),
|
|
842
|
+
depthRange: (r, t, e) => r({
|
|
843
|
+
2928: new Float32Array([t, e])
|
|
844
|
+
}),
|
|
845
|
+
depthMask: (r, t) => r({
|
|
846
|
+
2930: t
|
|
847
|
+
}),
|
|
848
|
+
frontFace: (r, t) => r({
|
|
849
|
+
2886: t
|
|
850
|
+
}),
|
|
851
|
+
lineWidth: (r, t) => r({
|
|
852
|
+
2849: t
|
|
853
|
+
}),
|
|
854
|
+
polygonOffset: (r, t, e) => r({
|
|
855
|
+
32824: t,
|
|
856
|
+
10752: e
|
|
857
|
+
}),
|
|
858
|
+
sampleCoverage: (r, t, e) => r({
|
|
859
|
+
32938: t,
|
|
860
|
+
32939: e
|
|
861
|
+
}),
|
|
862
|
+
scissor: (r, t, e, i, n) => r({
|
|
863
|
+
3088: new Int32Array([t, e, i, n])
|
|
864
|
+
}),
|
|
865
|
+
stencilMask: (r, t) => r({
|
|
866
|
+
2968: t,
|
|
867
|
+
36005: t
|
|
868
|
+
}),
|
|
869
|
+
stencilMaskSeparate: (r, t, e) => r({
|
|
870
|
+
[t === 1028 ? 2968 : 36005]: e
|
|
871
|
+
}),
|
|
872
|
+
stencilFunc: (r, t, e, i) => r({
|
|
873
|
+
2962: t,
|
|
874
|
+
2967: e,
|
|
875
|
+
2963: i,
|
|
876
|
+
34816: t,
|
|
877
|
+
36003: e,
|
|
878
|
+
36004: i
|
|
879
|
+
}),
|
|
880
|
+
stencilFuncSeparate: (r, t, e, i, n) => r({
|
|
881
|
+
[t === 1028 ? 2962 : 34816]: e,
|
|
882
|
+
[t === 1028 ? 2967 : 36003]: i,
|
|
883
|
+
[t === 1028 ? 2963 : 36004]: n
|
|
884
|
+
}),
|
|
885
|
+
stencilOp: (r, t, e, i) => r({
|
|
886
|
+
2964: t,
|
|
887
|
+
2965: e,
|
|
888
|
+
2966: i,
|
|
889
|
+
34817: t,
|
|
890
|
+
34818: e,
|
|
891
|
+
34819: i
|
|
892
|
+
}),
|
|
893
|
+
stencilOpSeparate: (r, t, e, i, n) => r({
|
|
894
|
+
[t === 1028 ? 2964 : 34817]: e,
|
|
895
|
+
[t === 1028 ? 2965 : 34818]: i,
|
|
896
|
+
[t === 1028 ? 2966 : 34819]: n
|
|
897
|
+
}),
|
|
898
|
+
viewport: (r, t, e, i, n) => r({
|
|
899
|
+
2978: [t, e, i, n]
|
|
900
|
+
})
|
|
901
|
+
}, P = (r, t) => r.isEnabled(t), Te = {
|
|
902
|
+
3042: P,
|
|
903
|
+
2884: P,
|
|
904
|
+
2929: P,
|
|
905
|
+
3024: P,
|
|
906
|
+
32823: P,
|
|
907
|
+
32926: P,
|
|
908
|
+
32928: P,
|
|
909
|
+
3089: P,
|
|
910
|
+
2960: P,
|
|
911
|
+
35977: P
|
|
912
|
+
}, wt = /* @__PURE__ */ new Set([
|
|
913
|
+
34016,
|
|
914
|
+
36388,
|
|
915
|
+
36387,
|
|
916
|
+
35983,
|
|
917
|
+
35368,
|
|
918
|
+
34965,
|
|
919
|
+
35739,
|
|
920
|
+
35738,
|
|
921
|
+
3074,
|
|
922
|
+
34853,
|
|
923
|
+
34854,
|
|
924
|
+
34855,
|
|
925
|
+
34856,
|
|
926
|
+
34857,
|
|
927
|
+
34858,
|
|
928
|
+
34859,
|
|
929
|
+
34860,
|
|
930
|
+
34861,
|
|
931
|
+
34862,
|
|
932
|
+
34863,
|
|
933
|
+
34864,
|
|
934
|
+
34865,
|
|
935
|
+
34866,
|
|
936
|
+
34867,
|
|
937
|
+
34868,
|
|
938
|
+
35097,
|
|
939
|
+
32873,
|
|
940
|
+
35869,
|
|
941
|
+
32874,
|
|
942
|
+
34068
|
|
943
|
+
]);
|
|
944
|
+
function W(r, t) {
|
|
945
|
+
if (St(t))
|
|
946
|
+
return;
|
|
947
|
+
const e = {};
|
|
948
|
+
for (const n in t) {
|
|
949
|
+
const s = Number(n), a = xt[n];
|
|
950
|
+
a && (typeof a == "string" ? e[a] = !0 : a(r, t[n], s));
|
|
951
|
+
}
|
|
952
|
+
const i = r.state && r.state.cache;
|
|
953
|
+
if (i)
|
|
954
|
+
for (const n in e) {
|
|
955
|
+
const s = yt[n];
|
|
956
|
+
s(r, t, i);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
function Re(r, t = he) {
|
|
960
|
+
if (typeof t == "number") {
|
|
961
|
+
const n = t, s = Te[n];
|
|
962
|
+
return s ? s(r, n) : r.getParameter(n);
|
|
963
|
+
}
|
|
964
|
+
const e = Array.isArray(t) ? t : Object.keys(t), i = {};
|
|
965
|
+
for (const n of e) {
|
|
966
|
+
const s = Te[n];
|
|
967
|
+
i[n] = s ? s(r, Number(n)) : r.getParameter(Number(n));
|
|
968
|
+
}
|
|
969
|
+
return i;
|
|
970
|
+
}
|
|
971
|
+
function vt(r) {
|
|
972
|
+
W(r, he);
|
|
973
|
+
}
|
|
974
|
+
function St(r) {
|
|
975
|
+
for (const t in r)
|
|
976
|
+
return !1;
|
|
977
|
+
return !0;
|
|
978
|
+
}
|
|
979
|
+
function Tt(r, t) {
|
|
980
|
+
if (r === t)
|
|
981
|
+
return !0;
|
|
982
|
+
if (_e(r) && _e(t) && r.length === t.length) {
|
|
983
|
+
for (let e = 0; e < r.length; ++e)
|
|
984
|
+
if (r[e] !== t[e])
|
|
985
|
+
return !1;
|
|
986
|
+
return !0;
|
|
987
|
+
}
|
|
988
|
+
return !1;
|
|
989
|
+
}
|
|
990
|
+
function _e(r) {
|
|
991
|
+
return Array.isArray(r) || ArrayBuffer.isView(r);
|
|
992
|
+
}
|
|
993
|
+
class C {
|
|
994
|
+
constructor(t, e) {
|
|
995
|
+
o(this, "gl");
|
|
996
|
+
o(this, "program", null);
|
|
997
|
+
o(this, "stateStack", []);
|
|
998
|
+
o(this, "enable", !0);
|
|
999
|
+
o(this, "cache", null);
|
|
1000
|
+
o(this, "log");
|
|
1001
|
+
o(this, "initialized", !1);
|
|
1002
|
+
this.gl = t, this.log = (e == null ? void 0 : e.log) || (() => {
|
|
1003
|
+
}), this._updateCache = this._updateCache.bind(this), Object.seal(this);
|
|
1004
|
+
}
|
|
1005
|
+
static get(t) {
|
|
1006
|
+
return t.state;
|
|
1007
|
+
}
|
|
1008
|
+
push(t = {}) {
|
|
1009
|
+
this.stateStack.push({});
|
|
1010
|
+
}
|
|
1011
|
+
pop() {
|
|
1012
|
+
const t = this.stateStack[this.stateStack.length - 1];
|
|
1013
|
+
W(this.gl, t), this.stateStack.pop();
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Initialize WebGL state caching on a context
|
|
1017
|
+
* can be called multiple times to enable/disable
|
|
1018
|
+
*
|
|
1019
|
+
* @note After calling this function, context state will be cached
|
|
1020
|
+
* .push() and .pop() will be available for saving,
|
|
1021
|
+
* temporarily modifying, and then restoring state.
|
|
1022
|
+
*/
|
|
1023
|
+
trackState(t, e) {
|
|
1024
|
+
if (this.cache = e != null && e.copyState ? Re(t) : Object.assign({}, he), this.initialized)
|
|
1025
|
+
throw new Error("WebGLStateTracker");
|
|
1026
|
+
this.initialized = !0, this.gl.state = this, Pt(t);
|
|
1027
|
+
for (const i in Se) {
|
|
1028
|
+
const n = Se[i];
|
|
1029
|
+
_t(t, i, n);
|
|
1030
|
+
}
|
|
1031
|
+
Pe(t, "getParameter"), Pe(t, "isEnabled");
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
// interceptor for context set functions - update our cache and our stack
|
|
1035
|
+
// values (Object) - the key values for this setter
|
|
1036
|
+
* @param values
|
|
1037
|
+
* @returns
|
|
1038
|
+
*/
|
|
1039
|
+
_updateCache(t) {
|
|
1040
|
+
let e = !1, i;
|
|
1041
|
+
const n = this.stateStack.length > 0 ? this.stateStack[this.stateStack.length - 1] : null;
|
|
1042
|
+
for (const s in t) {
|
|
1043
|
+
const a = t[s], c = this.cache[s];
|
|
1044
|
+
Tt(a, c) || (e = !0, i = c, n && !(s in n) && (n[s] = c), this.cache[s] = a);
|
|
1045
|
+
}
|
|
1046
|
+
return { valueChanged: e, oldValue: i };
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
function Pe(r, t) {
|
|
1050
|
+
const e = r[t].bind(r);
|
|
1051
|
+
r[t] = function(n) {
|
|
1052
|
+
if (n === void 0 || wt.has(n))
|
|
1053
|
+
return e(n);
|
|
1054
|
+
const s = C.get(r);
|
|
1055
|
+
return n in s.cache || (s.cache[n] = e(n)), s.enable ? (
|
|
1056
|
+
// Call the getter the params so that it can e.g. serve from a cache
|
|
1057
|
+
s.cache[n]
|
|
1058
|
+
) : (
|
|
1059
|
+
// Optionally call the original function to do a "hard" query from the WebGL2RenderingContext
|
|
1060
|
+
e(n)
|
|
1061
|
+
);
|
|
1062
|
+
}, Object.defineProperty(r[t], "name", {
|
|
1063
|
+
value: `${t}-from-cache`,
|
|
1064
|
+
configurable: !1
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
function _t(r, t, e) {
|
|
1068
|
+
if (!r[t])
|
|
1069
|
+
return;
|
|
1070
|
+
const i = r[t].bind(r);
|
|
1071
|
+
r[t] = function(...s) {
|
|
1072
|
+
const a = C.get(r), { valueChanged: c, oldValue: l } = e(a._updateCache, ...s);
|
|
1073
|
+
return c && i(...s), l;
|
|
1074
|
+
}, Object.defineProperty(r[t], "name", {
|
|
1075
|
+
value: `${t}-to-cache`,
|
|
1076
|
+
configurable: !1
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
function Pt(r) {
|
|
1080
|
+
const t = r.useProgram.bind(r);
|
|
1081
|
+
r.useProgram = function(i) {
|
|
1082
|
+
const n = C.get(r);
|
|
1083
|
+
n.program !== i && (t(i), n.program = i);
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
function At(r, t, e) {
|
|
1087
|
+
let i = "";
|
|
1088
|
+
const n = {
|
|
1089
|
+
preserveDrawingBuffer: !0,
|
|
1090
|
+
// failIfMajorPerformanceCaveat: true,
|
|
1091
|
+
...e
|
|
1092
|
+
};
|
|
1093
|
+
let s = null;
|
|
1094
|
+
if (s || (s = r.getContext("webgl2", n)), n.failIfMajorPerformanceCaveat && (i || (i = "Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.")), !s && !e.failIfMajorPerformanceCaveat && (n.failIfMajorPerformanceCaveat = !1, s = r.getContext("webgl2", n), s.luma || (s.luma = {}), s.luma.softwareRenderer = !0), s || (s = r.getContext("webgl", {}), s && (s = null, i || (i = "Your browser only supports WebGL1"))), !s)
|
|
1095
|
+
throw i || (i = "Your browser does not support WebGL"), new Error(`Failed to create WebGL context: ${i}`);
|
|
1096
|
+
const { onContextLost: a, onContextRestored: c } = t;
|
|
1097
|
+
return r.addEventListener("webglcontextlost", (l) => a(l), !1), r.addEventListener("webglcontextrestored", (l) => c(l), !1), s.luma || (s.luma = {}), s;
|
|
1098
|
+
}
|
|
1099
|
+
function M(r, t, e) {
|
|
1100
|
+
return e[t] === void 0 && (e[t] = r.getExtension(t) || null), e[t];
|
|
1101
|
+
}
|
|
1102
|
+
function Et(r, t) {
|
|
1103
|
+
const e = r.getParameter(7936), i = r.getParameter(7937);
|
|
1104
|
+
M(r, "WEBGL_debug_renderer_info", t);
|
|
1105
|
+
const n = t.WEBGL_debug_renderer_info, s = r.getParameter(n ? n.UNMASKED_VENDOR_WEBGL : 7936), a = r.getParameter(n ? n.UNMASKED_RENDERER_WEBGL : 7937), c = s || e, l = a || i, u = r.getParameter(7938), h = Ie(c, l), f = Lt(c, l), g = Bt(c, l);
|
|
1106
|
+
return {
|
|
1107
|
+
type: "webgl",
|
|
1108
|
+
gpu: h,
|
|
1109
|
+
gpuType: g,
|
|
1110
|
+
gpuBackend: f,
|
|
1111
|
+
vendor: c,
|
|
1112
|
+
renderer: l,
|
|
1113
|
+
version: u,
|
|
1114
|
+
shadingLanguage: "glsl",
|
|
1115
|
+
shadingLanguageVersion: 300
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
function Ie(r, t) {
|
|
1119
|
+
return /NVIDIA/i.exec(r) || /NVIDIA/i.exec(t) ? "nvidia" : /INTEL/i.exec(r) || /INTEL/i.exec(t) ? "intel" : /Apple/i.exec(r) || /Apple/i.exec(t) ? "apple" : /AMD/i.exec(r) || /AMD/i.exec(t) || /ATI/i.exec(r) || /ATI/i.exec(t) ? "amd" : /SwiftShader/i.exec(r) || /SwiftShader/i.exec(t) ? "software" : "unknown";
|
|
1120
|
+
}
|
|
1121
|
+
function Lt(r, t) {
|
|
1122
|
+
return /Metal/i.exec(r) || /Metal/i.exec(t) ? "metal" : /ANGLE/i.exec(r) || /ANGLE/i.exec(t) ? "opengl" : "unknown";
|
|
1123
|
+
}
|
|
1124
|
+
function Bt(r, t) {
|
|
1125
|
+
if (/SwiftShader/i.exec(r) || /SwiftShader/i.exec(t))
|
|
1126
|
+
return "cpu";
|
|
1127
|
+
switch (Ie(r, t)) {
|
|
1128
|
+
case "intel":
|
|
1129
|
+
return "integrated";
|
|
1130
|
+
case "software":
|
|
1131
|
+
return "cpu";
|
|
1132
|
+
case "unknown":
|
|
1133
|
+
return "unknown";
|
|
1134
|
+
default:
|
|
1135
|
+
return "discrete";
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
function Oe(r) {
|
|
1139
|
+
switch (r) {
|
|
1140
|
+
case "uint8":
|
|
1141
|
+
return 5121;
|
|
1142
|
+
case "sint8":
|
|
1143
|
+
return 5120;
|
|
1144
|
+
case "unorm8":
|
|
1145
|
+
return 5121;
|
|
1146
|
+
case "snorm8":
|
|
1147
|
+
return 5120;
|
|
1148
|
+
case "uint16":
|
|
1149
|
+
return 5123;
|
|
1150
|
+
case "sint16":
|
|
1151
|
+
return 5122;
|
|
1152
|
+
case "unorm16":
|
|
1153
|
+
return 5123;
|
|
1154
|
+
case "snorm16":
|
|
1155
|
+
return 5122;
|
|
1156
|
+
case "uint32":
|
|
1157
|
+
return 5125;
|
|
1158
|
+
case "sint32":
|
|
1159
|
+
return 5124;
|
|
1160
|
+
// WebGPU does not support normalized 32 bit integer attributes
|
|
1161
|
+
// case 'unorm32': return GL.UNSIGNED_INT;
|
|
1162
|
+
// case 'snorm32': return GL.INT;
|
|
1163
|
+
case "float16":
|
|
1164
|
+
return 5131;
|
|
1165
|
+
case "float32":
|
|
1166
|
+
return 5126;
|
|
1167
|
+
}
|
|
1168
|
+
throw new Error(String(r));
|
|
1169
|
+
}
|
|
1170
|
+
const I = "WEBGL_compressed_texture_s3tc", O = "WEBGL_compressed_texture_s3tc_srgb", k = "EXT_texture_compression_rgtc", D = "EXT_texture_compression_bptc", Ct = "WEBGL_compressed_texture_etc", Ft = "WEBGL_compressed_texture_astc", kt = "WEBGL_compressed_texture_etc1", Dt = "WEBGL_compressed_texture_pvrtc", Gt = "WEBGL_compressed_texture_atc", Ae = "EXT_texture_norm16", Ee = "EXT_render_snorm", Mt = "EXT_color_buffer_float", fe = {
|
|
1171
|
+
"float32-renderable-webgl": ["EXT_color_buffer_float"],
|
|
1172
|
+
"float16-renderable-webgl": ["EXT_color_buffer_half_float"],
|
|
1173
|
+
"rgb9e5ufloat-renderable-webgl": ["WEBGL_render_shared_exponent"],
|
|
1174
|
+
"snorm8-renderable-webgl": [Ee],
|
|
1175
|
+
"norm16-renderable-webgl": [Ae],
|
|
1176
|
+
"snorm16-renderable-webgl": [Ae, Ee],
|
|
1177
|
+
"float32-filterable": ["OES_texture_float_linear"],
|
|
1178
|
+
"float16-filterable-webgl": ["OES_texture_half_float_linear"],
|
|
1179
|
+
"texture-filterable-anisotropic-webgl": ["EXT_texture_filter_anisotropic"],
|
|
1180
|
+
"texture-blend-float-webgl": ["EXT_float_blend"],
|
|
1181
|
+
"texture-compression-bc": [I, O, k, D],
|
|
1182
|
+
// 'texture-compression-bc3-srgb-webgl': [X_S3TC_SRGB],
|
|
1183
|
+
// 'texture-compression-bc3-webgl': [X_S3TC],
|
|
1184
|
+
"texture-compression-bc5-webgl": [k],
|
|
1185
|
+
"texture-compression-bc7-webgl": [D],
|
|
1186
|
+
"texture-compression-etc2": [Ct],
|
|
1187
|
+
"texture-compression-astc": [Ft],
|
|
1188
|
+
"texture-compression-etc1-webgl": [kt],
|
|
1189
|
+
"texture-compression-pvrtc-webgl": [Dt],
|
|
1190
|
+
"texture-compression-atc-webgl": [Gt]
|
|
1191
|
+
};
|
|
1192
|
+
function Wt(r) {
|
|
1193
|
+
return r in fe;
|
|
1194
|
+
}
|
|
1195
|
+
function Rt(r, t, e) {
|
|
1196
|
+
return (fe[t] || []).every((n) => M(r, n, e));
|
|
1197
|
+
}
|
|
1198
|
+
const de = {
|
|
1199
|
+
// 8-bit formats
|
|
1200
|
+
r8unorm: { gl: 33321, rb: !0 },
|
|
1201
|
+
r8snorm: { gl: 36756 },
|
|
1202
|
+
r8uint: { gl: 33330, rb: !0 },
|
|
1203
|
+
r8sint: { gl: 33329, rb: !0 },
|
|
1204
|
+
// 16-bit formats
|
|
1205
|
+
rg8unorm: { gl: 33323, rb: !0 },
|
|
1206
|
+
rg8snorm: { gl: 36757 },
|
|
1207
|
+
rg8uint: { gl: 33336, rb: !0 },
|
|
1208
|
+
rg8sint: { gl: 33335, rb: !0 },
|
|
1209
|
+
r16uint: { gl: 33332, rb: !0 },
|
|
1210
|
+
r16sint: { gl: 33331, rb: !0 },
|
|
1211
|
+
r16float: { gl: 33325, rb: !0 },
|
|
1212
|
+
r16unorm: { gl: 33322, rb: !0 },
|
|
1213
|
+
r16snorm: { gl: 36760 },
|
|
1214
|
+
// Packed 16-bit formats
|
|
1215
|
+
"rgba4unorm-webgl": { gl: 32854, rb: !0 },
|
|
1216
|
+
"rgb565unorm-webgl": { gl: 36194, rb: !0 },
|
|
1217
|
+
"rgb5a1unorm-webgl": { gl: 32855, rb: !0 },
|
|
1218
|
+
// 24-bit formats
|
|
1219
|
+
"rgb8unorm-webgl": { gl: 32849 },
|
|
1220
|
+
"rgb8snorm-webgl": { gl: 36758 },
|
|
1221
|
+
// 32-bit formats
|
|
1222
|
+
rgba8unorm: { gl: 32856 },
|
|
1223
|
+
"rgba8unorm-srgb": { gl: 35907 },
|
|
1224
|
+
rgba8snorm: { gl: 36759 },
|
|
1225
|
+
rgba8uint: { gl: 36220 },
|
|
1226
|
+
rgba8sint: { gl: 36238 },
|
|
1227
|
+
// reverse colors, webgpu only
|
|
1228
|
+
bgra8unorm: {},
|
|
1229
|
+
"bgra8unorm-srgb": {},
|
|
1230
|
+
rg16uint: { gl: 33338 },
|
|
1231
|
+
rg16sint: { gl: 33337 },
|
|
1232
|
+
rg16float: { gl: 33327, rb: !0 },
|
|
1233
|
+
rg16unorm: { gl: 33324 },
|
|
1234
|
+
rg16snorm: { gl: 36761 },
|
|
1235
|
+
r32uint: { gl: 33334, rb: !0 },
|
|
1236
|
+
r32sint: { gl: 33333, rb: !0 },
|
|
1237
|
+
r32float: { gl: 33326 },
|
|
1238
|
+
// Packed 32-bit formats
|
|
1239
|
+
rgb9e5ufloat: { gl: 35901 },
|
|
1240
|
+
// , filter: true},
|
|
1241
|
+
rg11b10ufloat: { gl: 35898, rb: !0 },
|
|
1242
|
+
rgb10a2unorm: { gl: 32857, rb: !0 },
|
|
1243
|
+
rgb10a2uint: { gl: 36975, rb: !0 },
|
|
1244
|
+
// 48-bit formats
|
|
1245
|
+
"rgb16unorm-webgl": { gl: 32852 },
|
|
1246
|
+
// rgb not renderable
|
|
1247
|
+
"rgb16snorm-webgl": { gl: 36762 },
|
|
1248
|
+
// rgb not renderable
|
|
1249
|
+
// 64-bit formats
|
|
1250
|
+
rg32uint: { gl: 33340, rb: !0 },
|
|
1251
|
+
rg32sint: { gl: 33339, rb: !0 },
|
|
1252
|
+
rg32float: { gl: 33328, rb: !0 },
|
|
1253
|
+
rgba16uint: { gl: 36214, rb: !0 },
|
|
1254
|
+
rgba16sint: { gl: 36232, rb: !0 },
|
|
1255
|
+
rgba16float: { gl: 34842 },
|
|
1256
|
+
rgba16unorm: { gl: 32859, rb: !0 },
|
|
1257
|
+
rgba16snorm: { gl: 36763 },
|
|
1258
|
+
// 96-bit formats (deprecated!)
|
|
1259
|
+
"rgb32float-webgl": { gl: 34837, x: Mt, dataFormat: 6407, types: [5126] },
|
|
1260
|
+
// 128-bit formats
|
|
1261
|
+
rgba32uint: { gl: 36208, rb: !0 },
|
|
1262
|
+
rgba32sint: { gl: 36226, rb: !0 },
|
|
1263
|
+
rgba32float: { gl: 34836, rb: !0 },
|
|
1264
|
+
// Depth and stencil formats
|
|
1265
|
+
stencil8: { gl: 36168, rb: !0 },
|
|
1266
|
+
// 8 stencil bits
|
|
1267
|
+
depth16unorm: { gl: 33189, dataFormat: 6402, types: [5123], rb: !0 },
|
|
1268
|
+
// 16 depth bits
|
|
1269
|
+
depth24plus: { gl: 33190, dataFormat: 6402, types: [5125] },
|
|
1270
|
+
depth32float: { gl: 36012, dataFormat: 6402, types: [5126], rb: !0 },
|
|
1271
|
+
// The depth component of the "depth24plus" and "depth24plus-stencil8" formats may be implemented as either a 24-bit depth value or a "depth32float" value.
|
|
1272
|
+
"depth24plus-stencil8": { gl: 35056, rb: !0, depthTexture: !0, dataFormat: 34041, types: [34042] },
|
|
1273
|
+
// "depth32float-stencil8" feature - TODO below is render buffer only?
|
|
1274
|
+
"depth32float-stencil8": { gl: 36013, dataFormat: 34041, types: [36269], rb: !0 },
|
|
1275
|
+
// BC compressed formats: check device.features.has("texture-compression-bc");
|
|
1276
|
+
"bc1-rgb-unorm-webgl": { gl: 33776, x: I },
|
|
1277
|
+
"bc1-rgb-unorm-srgb-webgl": { gl: 35916, x: O },
|
|
1278
|
+
"bc1-rgba-unorm": { gl: 33777, x: I },
|
|
1279
|
+
"bc1-rgba-unorm-srgb": { gl: 35916, x: O },
|
|
1280
|
+
"bc2-rgba-unorm": { gl: 33778, x: I },
|
|
1281
|
+
"bc2-rgba-unorm-srgb": { gl: 35918, x: O },
|
|
1282
|
+
"bc3-rgba-unorm": { gl: 33779, x: I },
|
|
1283
|
+
"bc3-rgba-unorm-srgb": { gl: 35919, x: O },
|
|
1284
|
+
"bc4-r-unorm": { gl: 36283, x: k },
|
|
1285
|
+
"bc4-r-snorm": { gl: 36284, x: k },
|
|
1286
|
+
"bc5-rg-unorm": { gl: 36285, x: k },
|
|
1287
|
+
"bc5-rg-snorm": { gl: 36286, x: k },
|
|
1288
|
+
"bc6h-rgb-ufloat": { gl: 36495, x: D },
|
|
1289
|
+
"bc6h-rgb-float": { gl: 36494, x: D },
|
|
1290
|
+
"bc7-rgba-unorm": { gl: 36492, x: D },
|
|
1291
|
+
"bc7-rgba-unorm-srgb": { gl: 36493, x: D },
|
|
1292
|
+
// WEBGL_compressed_texture_etc: device.features.has("texture-compression-etc2")
|
|
1293
|
+
// Note: Supposedly guaranteed availability compressed formats in WebGL2, but through CPU decompression
|
|
1294
|
+
"etc2-rgb8unorm": { gl: 37492 },
|
|
1295
|
+
"etc2-rgb8unorm-srgb": { gl: 37494 },
|
|
1296
|
+
"etc2-rgb8a1unorm": { gl: 37496 },
|
|
1297
|
+
"etc2-rgb8a1unorm-srgb": { gl: 37497 },
|
|
1298
|
+
"etc2-rgba8unorm": { gl: 37493 },
|
|
1299
|
+
"etc2-rgba8unorm-srgb": { gl: 37495 },
|
|
1300
|
+
"eac-r11unorm": { gl: 37488 },
|
|
1301
|
+
"eac-r11snorm": { gl: 37489 },
|
|
1302
|
+
"eac-rg11unorm": { gl: 37490 },
|
|
1303
|
+
"eac-rg11snorm": { gl: 37491 },
|
|
1304
|
+
// X_ASTC compressed formats: device.features.has("texture-compression-astc")
|
|
1305
|
+
"astc-4x4-unorm": { gl: 37808 },
|
|
1306
|
+
"astc-4x4-unorm-srgb": { gl: 37840 },
|
|
1307
|
+
"astc-5x4-unorm": { gl: 37809 },
|
|
1308
|
+
"astc-5x4-unorm-srgb": { gl: 37841 },
|
|
1309
|
+
"astc-5x5-unorm": { gl: 37810 },
|
|
1310
|
+
"astc-5x5-unorm-srgb": { gl: 37842 },
|
|
1311
|
+
"astc-6x5-unorm": { gl: 37811 },
|
|
1312
|
+
"astc-6x5-unorm-srgb": { gl: 37843 },
|
|
1313
|
+
"astc-6x6-unorm": { gl: 37812 },
|
|
1314
|
+
"astc-6x6-unorm-srgb": { gl: 37844 },
|
|
1315
|
+
"astc-8x5-unorm": { gl: 37813 },
|
|
1316
|
+
"astc-8x5-unorm-srgb": { gl: 37845 },
|
|
1317
|
+
"astc-8x6-unorm": { gl: 37814 },
|
|
1318
|
+
"astc-8x6-unorm-srgb": { gl: 37846 },
|
|
1319
|
+
"astc-8x8-unorm": { gl: 37815 },
|
|
1320
|
+
"astc-8x8-unorm-srgb": { gl: 37847 },
|
|
1321
|
+
"astc-10x5-unorm": { gl: 37819 },
|
|
1322
|
+
"astc-10x5-unorm-srgb": { gl: 37851 },
|
|
1323
|
+
"astc-10x6-unorm": { gl: 37817 },
|
|
1324
|
+
"astc-10x6-unorm-srgb": { gl: 37849 },
|
|
1325
|
+
"astc-10x8-unorm": { gl: 37818 },
|
|
1326
|
+
"astc-10x8-unorm-srgb": { gl: 37850 },
|
|
1327
|
+
"astc-10x10-unorm": { gl: 37819 },
|
|
1328
|
+
"astc-10x10-unorm-srgb": { gl: 37851 },
|
|
1329
|
+
"astc-12x10-unorm": { gl: 37820 },
|
|
1330
|
+
"astc-12x10-unorm-srgb": { gl: 37852 },
|
|
1331
|
+
"astc-12x12-unorm": { gl: 37821 },
|
|
1332
|
+
"astc-12x12-unorm-srgb": { gl: 37853 },
|
|
1333
|
+
// WEBGL_compressed_texture_pvrtc
|
|
1334
|
+
"pvrtc-rgb4unorm-webgl": { gl: 35840 },
|
|
1335
|
+
"pvrtc-rgba4unorm-webgl": { gl: 35842 },
|
|
1336
|
+
"pvrtc-rbg2unorm-webgl": { gl: 35841 },
|
|
1337
|
+
"pvrtc-rgba2unorm-webgl": { gl: 35843 },
|
|
1338
|
+
// WEBGL_compressed_texture_etc1
|
|
1339
|
+
"etc1-rbg-unorm-webgl": { gl: 36196 },
|
|
1340
|
+
// WEBGL_compressed_texture_atc
|
|
1341
|
+
"atc-rgb-unorm-webgl": { gl: 35986 },
|
|
1342
|
+
"atc-rgba-unorm-webgl": { gl: 35986 },
|
|
1343
|
+
"atc-rgbai-unorm-webgl": { gl: 34798 }
|
|
1344
|
+
};
|
|
1345
|
+
function It(r, t, e) {
|
|
1346
|
+
let i = t.create;
|
|
1347
|
+
const n = de[t.format];
|
|
1348
|
+
return (n == null ? void 0 : n.gl) === void 0 && (i = !1), n != null && n.x && (i = i && !!M(r, n.x, e)), {
|
|
1349
|
+
format: t.format,
|
|
1350
|
+
// @ts-ignore
|
|
1351
|
+
create: i && t.create,
|
|
1352
|
+
// @ts-ignore
|
|
1353
|
+
render: i && t.render,
|
|
1354
|
+
// @ts-ignore
|
|
1355
|
+
filter: i && t.filter,
|
|
1356
|
+
// @ts-ignore
|
|
1357
|
+
blend: i && t.blend,
|
|
1358
|
+
// @ts-ignore
|
|
1359
|
+
store: i && t.store
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
function $e(r) {
|
|
1363
|
+
var n;
|
|
1364
|
+
const t = de[r], e = zt(r), i = We.getInfo(r);
|
|
1365
|
+
return i.compressed && (t.dataFormat = e), {
|
|
1366
|
+
internalFormat: e,
|
|
1367
|
+
format: (t == null ? void 0 : t.dataFormat) || $t(i.channels, i.integer, i.normalized, e),
|
|
1368
|
+
// depth formats don't have a type
|
|
1369
|
+
type: i.dataType ? Oe(i.dataType) : ((n = t == null ? void 0 : t.types) == null ? void 0 : n[0]) || 5121,
|
|
1370
|
+
compressed: i.compressed || !1
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
function Ot(r) {
|
|
1374
|
+
switch (We.getInfo(r).attachment) {
|
|
1375
|
+
case "depth":
|
|
1376
|
+
return 36096;
|
|
1377
|
+
case "stencil":
|
|
1378
|
+
return 36128;
|
|
1379
|
+
case "depth-stencil":
|
|
1380
|
+
return 33306;
|
|
1381
|
+
default:
|
|
1382
|
+
throw new Error(`Not a depth stencil format: ${r}`);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
function $t(r, t, e, i) {
|
|
1386
|
+
if (i === 6408 || i === 6407)
|
|
1387
|
+
return i;
|
|
1388
|
+
switch (r) {
|
|
1389
|
+
case "r":
|
|
1390
|
+
return t && !e ? 36244 : 6403;
|
|
1391
|
+
case "rg":
|
|
1392
|
+
return t && !e ? 33320 : 33319;
|
|
1393
|
+
case "rgb":
|
|
1394
|
+
return t && !e ? 36248 : 6407;
|
|
1395
|
+
case "rgba":
|
|
1396
|
+
return t && !e ? 36249 : 6408;
|
|
1397
|
+
case "bgra":
|
|
1398
|
+
throw new Error("bgra pixels not supported by WebGL");
|
|
1399
|
+
default:
|
|
1400
|
+
return 6408;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
function zt(r) {
|
|
1404
|
+
const t = de[r], e = t == null ? void 0 : t.gl;
|
|
1405
|
+
if (e === void 0)
|
|
1406
|
+
throw new Error(`Unsupported texture format ${r}`);
|
|
1407
|
+
return e;
|
|
1408
|
+
}
|
|
1409
|
+
const Le = {
|
|
1410
|
+
// optional WebGPU features
|
|
1411
|
+
"depth-clip-control": "EXT_depth_clamp",
|
|
1412
|
+
// TODO these seem subtly different
|
|
1413
|
+
// 'timestamp-query' // GPUQueryType "timestamp-query"
|
|
1414
|
+
// "indirect-first-instance"
|
|
1415
|
+
// Textures are handled by getTextureFeatures()
|
|
1416
|
+
// 'depth32float-stencil8' // GPUTextureFormat 'depth32float-stencil8'
|
|
1417
|
+
// optional WebGL features
|
|
1418
|
+
"timer-query-webgl": "EXT_disjoint_timer_query_webgl2",
|
|
1419
|
+
"compilation-status-async-webgl": "KHR_parallel_shader_compile",
|
|
1420
|
+
"polygon-mode-webgl": "WEBGL_polygon_mode",
|
|
1421
|
+
"provoking-vertex-webgl": "WEBGL_provoking_vertex",
|
|
1422
|
+
"shader-clip-cull-distance-webgl": "WEBGL_clip_cull_distance",
|
|
1423
|
+
"shader-noperspective-interpolation-webgl": "NV_shader_noperspective_interpolation",
|
|
1424
|
+
"shader-conservative-depth-webgl": "EXT_conservative_depth"
|
|
1425
|
+
// Textures are handled by getTextureFeatures()
|
|
1426
|
+
};
|
|
1427
|
+
class Vt extends et {
|
|
1428
|
+
constructor(e, i, n) {
|
|
1429
|
+
super([], n);
|
|
1430
|
+
o(this, "gl");
|
|
1431
|
+
o(this, "extensions");
|
|
1432
|
+
o(this, "testedFeatures", /* @__PURE__ */ new Set());
|
|
1433
|
+
this.gl = e, this.extensions = i, M(e, "EXT_color_buffer_float", i);
|
|
1434
|
+
}
|
|
1435
|
+
*[Symbol.iterator]() {
|
|
1436
|
+
const e = this.getFeatures();
|
|
1437
|
+
for (const i of e)
|
|
1438
|
+
this.has(i) && (yield i);
|
|
1439
|
+
return [];
|
|
1440
|
+
}
|
|
1441
|
+
has(e) {
|
|
1442
|
+
var i;
|
|
1443
|
+
return (i = this.disabledFeatures) != null && i[e] ? !1 : (this.testedFeatures.has(e) || (this.testedFeatures.add(e), Wt(e) && Rt(this.gl, e, this.extensions) && this.features.add(e), this.getWebGLFeature(e) && this.features.add(e)), this.features.has(e));
|
|
1444
|
+
}
|
|
1445
|
+
// FOR DEVICE
|
|
1446
|
+
initializeFeatures() {
|
|
1447
|
+
const e = this.getFeatures().filter((i) => i !== "polygon-mode-webgl");
|
|
1448
|
+
for (const i of e)
|
|
1449
|
+
this.has(i);
|
|
1450
|
+
}
|
|
1451
|
+
// IMPLEMENTATION
|
|
1452
|
+
getFeatures() {
|
|
1453
|
+
return [...Object.keys(Le), ...Object.keys(fe)];
|
|
1454
|
+
}
|
|
1455
|
+
/** Extract all WebGL features */
|
|
1456
|
+
getWebGLFeature(e) {
|
|
1457
|
+
const i = Le[e];
|
|
1458
|
+
return typeof i == "string" ? !!M(this.gl, i, this.extensions) : !!i;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
class Ut extends tt {
|
|
1462
|
+
constructor(e) {
|
|
1463
|
+
super();
|
|
1464
|
+
// WebGL does not support compute shaders
|
|
1465
|
+
// PRIVATE
|
|
1466
|
+
o(this, "gl");
|
|
1467
|
+
o(this, "limits", {});
|
|
1468
|
+
this.gl = e;
|
|
1469
|
+
}
|
|
1470
|
+
get maxTextureDimension1D() {
|
|
1471
|
+
return 0;
|
|
1472
|
+
}
|
|
1473
|
+
// WebGL does not support 1D textures
|
|
1474
|
+
get maxTextureDimension2D() {
|
|
1475
|
+
return this.getParameter(3379);
|
|
1476
|
+
}
|
|
1477
|
+
get maxTextureDimension3D() {
|
|
1478
|
+
return this.getParameter(32883);
|
|
1479
|
+
}
|
|
1480
|
+
get maxTextureArrayLayers() {
|
|
1481
|
+
return this.getParameter(35071);
|
|
1482
|
+
}
|
|
1483
|
+
get maxBindGroups() {
|
|
1484
|
+
return 0;
|
|
1485
|
+
}
|
|
1486
|
+
get maxDynamicUniformBuffersPerPipelineLayout() {
|
|
1487
|
+
return 0;
|
|
1488
|
+
}
|
|
1489
|
+
// TBD
|
|
1490
|
+
get maxDynamicStorageBuffersPerPipelineLayout() {
|
|
1491
|
+
return 0;
|
|
1492
|
+
}
|
|
1493
|
+
// TBD
|
|
1494
|
+
get maxSampledTexturesPerShaderStage() {
|
|
1495
|
+
return this.getParameter(35660);
|
|
1496
|
+
}
|
|
1497
|
+
// ) TBD
|
|
1498
|
+
get maxSamplersPerShaderStage() {
|
|
1499
|
+
return this.getParameter(35661);
|
|
1500
|
+
}
|
|
1501
|
+
get maxStorageBuffersPerShaderStage() {
|
|
1502
|
+
return 0;
|
|
1503
|
+
}
|
|
1504
|
+
// TBD
|
|
1505
|
+
get maxStorageTexturesPerShaderStage() {
|
|
1506
|
+
return 0;
|
|
1507
|
+
}
|
|
1508
|
+
// TBD
|
|
1509
|
+
get maxUniformBuffersPerShaderStage() {
|
|
1510
|
+
return this.getParameter(35375);
|
|
1511
|
+
}
|
|
1512
|
+
get maxUniformBufferBindingSize() {
|
|
1513
|
+
return this.getParameter(35376);
|
|
1514
|
+
}
|
|
1515
|
+
get maxStorageBufferBindingSize() {
|
|
1516
|
+
return 0;
|
|
1517
|
+
}
|
|
1518
|
+
get minUniformBufferOffsetAlignment() {
|
|
1519
|
+
return this.getParameter(35380);
|
|
1520
|
+
}
|
|
1521
|
+
get minStorageBufferOffsetAlignment() {
|
|
1522
|
+
return 0;
|
|
1523
|
+
}
|
|
1524
|
+
get maxVertexBuffers() {
|
|
1525
|
+
return 16;
|
|
1526
|
+
}
|
|
1527
|
+
// WebGL 2 supports 16 buffers, see https://github.com/gpuweb/gpuweb/issues/4284
|
|
1528
|
+
get maxVertexAttributes() {
|
|
1529
|
+
return this.getParameter(34921);
|
|
1530
|
+
}
|
|
1531
|
+
get maxVertexBufferArrayStride() {
|
|
1532
|
+
return 2048;
|
|
1533
|
+
}
|
|
1534
|
+
// TBD, this is just the default value from WebGPU
|
|
1535
|
+
get maxInterStageShaderVariables() {
|
|
1536
|
+
return this.getParameter(35659);
|
|
1537
|
+
}
|
|
1538
|
+
get maxComputeWorkgroupStorageSize() {
|
|
1539
|
+
return 0;
|
|
1540
|
+
}
|
|
1541
|
+
// WebGL does not support compute shaders
|
|
1542
|
+
get maxComputeInvocationsPerWorkgroup() {
|
|
1543
|
+
return 0;
|
|
1544
|
+
}
|
|
1545
|
+
// WebGL does not support compute shaders
|
|
1546
|
+
get maxComputeWorkgroupSizeX() {
|
|
1547
|
+
return 0;
|
|
1548
|
+
}
|
|
1549
|
+
// WebGL does not support compute shaders
|
|
1550
|
+
get maxComputeWorkgroupSizeY() {
|
|
1551
|
+
return 0;
|
|
1552
|
+
}
|
|
1553
|
+
// WebGL does not support compute shaders
|
|
1554
|
+
get maxComputeWorkgroupSizeZ() {
|
|
1555
|
+
return 0;
|
|
1556
|
+
}
|
|
1557
|
+
// WebGL does not support compute shaders
|
|
1558
|
+
get maxComputeWorkgroupsPerDimension() {
|
|
1559
|
+
return 0;
|
|
1560
|
+
}
|
|
1561
|
+
getParameter(e) {
|
|
1562
|
+
return this.limits[e] === void 0 && (this.limits[e] = this.gl.getParameter(e)), this.limits[e] || 0;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
class $ extends H {
|
|
1566
|
+
constructor(e, i) {
|
|
1567
|
+
super(e, i);
|
|
1568
|
+
o(this, "device");
|
|
1569
|
+
o(this, "gl");
|
|
1570
|
+
o(this, "handle");
|
|
1571
|
+
o(this, "colorAttachments", []);
|
|
1572
|
+
o(this, "depthStencilAttachment", null);
|
|
1573
|
+
const n = i.handle === null;
|
|
1574
|
+
this.device = e, this.gl = e.gl, this.handle = this.props.handle || n ? this.props.handle : this.gl.createFramebuffer(), n || (e._setWebGLDebugMetadata(this.handle, this, { spector: this.props }), this.autoCreateAttachmentTextures(), this.updateAttachments());
|
|
1575
|
+
}
|
|
1576
|
+
/** destroys any auto created resources etc. */
|
|
1577
|
+
destroy() {
|
|
1578
|
+
super.destroy(), !this.destroyed && this.handle !== null && this.gl.deleteFramebuffer(this.handle);
|
|
1579
|
+
}
|
|
1580
|
+
updateAttachments() {
|
|
1581
|
+
const e = this.gl.bindFramebuffer(36160, this.handle);
|
|
1582
|
+
for (let i = 0; i < this.colorAttachments.length; ++i) {
|
|
1583
|
+
const n = this.colorAttachments[i];
|
|
1584
|
+
if (n) {
|
|
1585
|
+
const s = 36064 + i;
|
|
1586
|
+
this._attachTextureView(s, n);
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
if (this.depthStencilAttachment) {
|
|
1590
|
+
const i = Ot(this.depthStencilAttachment.props.format);
|
|
1591
|
+
this._attachTextureView(i, this.depthStencilAttachment);
|
|
1592
|
+
}
|
|
1593
|
+
if (this.device.props.debug) {
|
|
1594
|
+
const i = this.gl.checkFramebufferStatus(36160);
|
|
1595
|
+
if (i !== 36053)
|
|
1596
|
+
throw new Error(`Framebuffer ${Xt(i)}`);
|
|
1597
|
+
}
|
|
1598
|
+
this.gl.bindFramebuffer(36160, e);
|
|
1599
|
+
}
|
|
1600
|
+
// PRIVATE
|
|
1601
|
+
/** In WebGL we must use renderbuffers for depth/stencil attachments (unless we have extensions) */
|
|
1602
|
+
// protected override createDepthStencilTexture(format: TextureFormat): Texture {
|
|
1603
|
+
// // return new WEBGLRenderbuffer(this.device, {
|
|
1604
|
+
// return new WEBGLTexture(this.device, {
|
|
1605
|
+
// id: `${this.id}-depth-stencil`,
|
|
1606
|
+
// format,
|
|
1607
|
+
// width: this.width,
|
|
1608
|
+
// height: this.height,
|
|
1609
|
+
// mipmaps: false
|
|
1610
|
+
// });
|
|
1611
|
+
// }
|
|
1612
|
+
/**
|
|
1613
|
+
* @param attachment
|
|
1614
|
+
* @param texture
|
|
1615
|
+
* @param layer = 0 - index into WEBGLTextureArray and Texture3D or face for `TextureCubeMap`
|
|
1616
|
+
* @param level = 0 - mipmapLevel
|
|
1617
|
+
*/
|
|
1618
|
+
_attachTextureView(e, i) {
|
|
1619
|
+
const { gl: n } = this.device, { texture: s } = i, a = i.props.baseMipLevel, c = i.props.baseArrayLayer;
|
|
1620
|
+
switch (n.bindTexture(s.glTarget, s.handle), s.glTarget) {
|
|
1621
|
+
case 35866:
|
|
1622
|
+
case 32879:
|
|
1623
|
+
n.framebufferTextureLayer(36160, e, s.handle, a, c);
|
|
1624
|
+
break;
|
|
1625
|
+
case 34067:
|
|
1626
|
+
const l = Nt(c);
|
|
1627
|
+
n.framebufferTexture2D(36160, e, l, s.handle, a);
|
|
1628
|
+
break;
|
|
1629
|
+
case 3553:
|
|
1630
|
+
n.framebufferTexture2D(36160, e, 3553, s.handle, a);
|
|
1631
|
+
break;
|
|
1632
|
+
default:
|
|
1633
|
+
throw new Error("Illegal texture type");
|
|
1634
|
+
}
|
|
1635
|
+
n.bindTexture(s.glTarget, null);
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
function Nt(r) {
|
|
1639
|
+
return r < 34069 ? r + 34069 : r;
|
|
1640
|
+
}
|
|
1641
|
+
function Xt(r) {
|
|
1642
|
+
switch (r) {
|
|
1643
|
+
case 36053:
|
|
1644
|
+
return "success";
|
|
1645
|
+
case 36054:
|
|
1646
|
+
return "Mismatched attachments";
|
|
1647
|
+
case 36055:
|
|
1648
|
+
return "No attachments";
|
|
1649
|
+
case 36057:
|
|
1650
|
+
return "Height/width mismatch";
|
|
1651
|
+
case 36061:
|
|
1652
|
+
return "Unsupported or split attachments";
|
|
1653
|
+
// WebGL2
|
|
1654
|
+
case 36182:
|
|
1655
|
+
return "Samples mismatch";
|
|
1656
|
+
// OVR_multiview2 extension
|
|
1657
|
+
// case GL.FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR: return 'baseViewIndex mismatch';
|
|
1658
|
+
default:
|
|
1659
|
+
return `${r}`;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
class Ht extends X {
|
|
1663
|
+
constructor(e, i) {
|
|
1664
|
+
super(i);
|
|
1665
|
+
o(this, "device");
|
|
1666
|
+
o(this, "handle", null);
|
|
1667
|
+
o(this, "_framebuffer", null);
|
|
1668
|
+
this.device = e, this._setAutoCreatedCanvasId(`${this.device.id}-canvas`), this._updateDevice();
|
|
1669
|
+
}
|
|
1670
|
+
get [Symbol.toStringTag]() {
|
|
1671
|
+
return "WebGLCanvasContext";
|
|
1672
|
+
}
|
|
1673
|
+
getCurrentFramebuffer() {
|
|
1674
|
+
return this._framebuffer = this._framebuffer || new $(this.device, { handle: null }), this._framebuffer;
|
|
1675
|
+
}
|
|
1676
|
+
// IMPLEMENTATION OF ABSTRACT METHODS
|
|
1677
|
+
_updateDevice() {
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
const ee = {};
|
|
1681
|
+
function qt(r = "id") {
|
|
1682
|
+
ee[r] = ee[r] || 1;
|
|
1683
|
+
const t = ee[r]++;
|
|
1684
|
+
return `${r}-${t}`;
|
|
1685
|
+
}
|
|
1686
|
+
class z extends B {
|
|
1687
|
+
constructor(e, i = {}) {
|
|
1688
|
+
super(e, i);
|
|
1689
|
+
o(this, "device");
|
|
1690
|
+
o(this, "gl");
|
|
1691
|
+
o(this, "handle");
|
|
1692
|
+
/** Target in OpenGL defines the type of buffer */
|
|
1693
|
+
o(this, "glTarget");
|
|
1694
|
+
/** Usage is a hint on how frequently the buffer will be updates */
|
|
1695
|
+
o(this, "glUsage");
|
|
1696
|
+
/** Index type is needed when issuing draw calls, so we pre-compute it */
|
|
1697
|
+
o(this, "glIndexType", 5123);
|
|
1698
|
+
/** Number of bytes allocated on the GPU for this buffer */
|
|
1699
|
+
o(this, "byteLength", 0);
|
|
1700
|
+
/** Number of bytes used */
|
|
1701
|
+
o(this, "bytesUsed", 0);
|
|
1702
|
+
this.device = e, this.gl = this.device.gl;
|
|
1703
|
+
const n = typeof i == "object" ? i.handle : void 0;
|
|
1704
|
+
this.handle = n || this.gl.createBuffer(), e._setWebGLDebugMetadata(this.handle, this, {
|
|
1705
|
+
spector: { ...this.props, data: typeof this.props.data }
|
|
1706
|
+
}), this.glTarget = jt(this.props.usage), this.glUsage = Qt(this.props.usage), this.glIndexType = this.props.indexType === "uint32" ? 5125 : 5123, i.data ? this._initWithData(i.data, i.byteOffset, i.byteLength) : this._initWithByteLength(i.byteLength || 0);
|
|
1707
|
+
}
|
|
1708
|
+
destroy() {
|
|
1709
|
+
!this.destroyed && this.handle && (this.removeStats(), this.trackDeallocatedMemory(), this.gl.deleteBuffer(this.handle), this.destroyed = !0, this.handle = null);
|
|
1710
|
+
}
|
|
1711
|
+
/** Allocate a new buffer and initialize to contents of typed array */
|
|
1712
|
+
_initWithData(e, i = 0, n = e.byteLength + i) {
|
|
1713
|
+
const s = this.glTarget;
|
|
1714
|
+
this.gl.bindBuffer(s, this.handle), this.gl.bufferData(s, n, this.glUsage), this.gl.bufferSubData(s, i, e), this.gl.bindBuffer(s, null), this.bytesUsed = n, this.byteLength = n, this._setDebugData(e, i, n), this.trackAllocatedMemory(n);
|
|
1715
|
+
}
|
|
1716
|
+
// Allocate a GPU buffer of specified size.
|
|
1717
|
+
_initWithByteLength(e) {
|
|
1718
|
+
let i = e;
|
|
1719
|
+
e === 0 && (i = new Float32Array(0));
|
|
1720
|
+
const n = this.glTarget;
|
|
1721
|
+
return this.gl.bindBuffer(n, this.handle), this.gl.bufferData(n, i, this.glUsage), this.gl.bindBuffer(n, null), this.bytesUsed = e, this.byteLength = e, this._setDebugData(null, 0, e), this.trackAllocatedMemory(e), this;
|
|
1722
|
+
}
|
|
1723
|
+
write(e, i = 0) {
|
|
1724
|
+
const n = ArrayBuffer.isView(e) ? e : new Uint8Array(e), s = 36663;
|
|
1725
|
+
this.gl.bindBuffer(s, this.handle), this.gl.bufferSubData(s, i, n), this.gl.bindBuffer(s, null), this._setDebugData(e, i, e.byteLength);
|
|
1726
|
+
}
|
|
1727
|
+
async mapAndWriteAsync(e, i = 0, n = this.byteLength - i) {
|
|
1728
|
+
const s = new ArrayBuffer(n);
|
|
1729
|
+
await e(s, "copied"), this.write(s, i);
|
|
1730
|
+
}
|
|
1731
|
+
async readAsync(e = 0, i) {
|
|
1732
|
+
return this.readSyncWebGL(e, i);
|
|
1733
|
+
}
|
|
1734
|
+
async mapAndReadAsync(e, i = 0, n) {
|
|
1735
|
+
const s = await this.readAsync(i, n);
|
|
1736
|
+
return await e(s.buffer, "copied");
|
|
1737
|
+
}
|
|
1738
|
+
readSyncWebGL(e = 0, i) {
|
|
1739
|
+
i = i ?? this.byteLength - e;
|
|
1740
|
+
const n = new Uint8Array(i), s = 0;
|
|
1741
|
+
return this.gl.bindBuffer(36662, this.handle), this.gl.getBufferSubData(36662, e, n, s, i), this.gl.bindBuffer(36662, null), this._setDebugData(n, e, i), n;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
function jt(r) {
|
|
1745
|
+
return r & B.INDEX ? 34963 : r & B.VERTEX ? 34962 : r & B.UNIFORM ? 35345 : 34962;
|
|
1746
|
+
}
|
|
1747
|
+
function Qt(r) {
|
|
1748
|
+
return r & B.INDEX || r & B.VERTEX ? 35044 : r & B.UNIFORM ? 35048 : 35044;
|
|
1749
|
+
}
|
|
1750
|
+
function Yt(r) {
|
|
1751
|
+
const t = r.split(/\r?\n/), e = [];
|
|
1752
|
+
for (const i of t) {
|
|
1753
|
+
if (i.length <= 1)
|
|
1754
|
+
continue;
|
|
1755
|
+
const n = i.split(":");
|
|
1756
|
+
if (n.length === 2) {
|
|
1757
|
+
const [f, g] = n;
|
|
1758
|
+
e.push({
|
|
1759
|
+
message: g.trim(),
|
|
1760
|
+
type: Be(f),
|
|
1761
|
+
lineNum: 0,
|
|
1762
|
+
linePos: 0
|
|
1763
|
+
});
|
|
1764
|
+
continue;
|
|
1765
|
+
}
|
|
1766
|
+
const [s, a, c, ...l] = n;
|
|
1767
|
+
let u = parseInt(c, 10);
|
|
1768
|
+
isNaN(u) && (u = 0);
|
|
1769
|
+
let h = parseInt(a, 10);
|
|
1770
|
+
isNaN(h) && (h = 0), e.push({
|
|
1771
|
+
message: l.join(":").trim(),
|
|
1772
|
+
type: Be(s),
|
|
1773
|
+
lineNum: u,
|
|
1774
|
+
linePos: h
|
|
1775
|
+
// TODO
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
return e;
|
|
1779
|
+
}
|
|
1780
|
+
function Be(r) {
|
|
1781
|
+
const t = ["warning", "error", "info"], e = r.toLowerCase();
|
|
1782
|
+
return t.includes(e) ? e : "info";
|
|
1783
|
+
}
|
|
1784
|
+
class Kt extends rt {
|
|
1785
|
+
constructor(e, i) {
|
|
1786
|
+
super(e, i);
|
|
1787
|
+
o(this, "device");
|
|
1788
|
+
o(this, "handle");
|
|
1789
|
+
switch (this.device = e, this.props.stage) {
|
|
1790
|
+
case "vertex":
|
|
1791
|
+
this.handle = this.props.handle || this.device.gl.createShader(35633);
|
|
1792
|
+
break;
|
|
1793
|
+
case "fragment":
|
|
1794
|
+
this.handle = this.props.handle || this.device.gl.createShader(35632);
|
|
1795
|
+
break;
|
|
1796
|
+
default:
|
|
1797
|
+
throw new Error(this.props.stage);
|
|
1798
|
+
}
|
|
1799
|
+
e._setWebGLDebugMetadata(this.handle, this, { spector: this.props }), this._compile(this.source);
|
|
1800
|
+
}
|
|
1801
|
+
destroy() {
|
|
1802
|
+
this.handle && (this.removeStats(), this.device.gl.deleteShader(this.handle), this.destroyed = !0, this.handle.destroyed = !0);
|
|
1803
|
+
}
|
|
1804
|
+
get asyncCompilationStatus() {
|
|
1805
|
+
return this._waitForCompilationComplete().then(() => (this._getCompilationStatus(), this.compilationStatus));
|
|
1806
|
+
}
|
|
1807
|
+
async getCompilationInfo() {
|
|
1808
|
+
return await this._waitForCompilationComplete(), this.getCompilationInfoSync();
|
|
1809
|
+
}
|
|
1810
|
+
getCompilationInfoSync() {
|
|
1811
|
+
const e = this.device.gl.getShaderInfoLog(this.handle);
|
|
1812
|
+
return e ? Yt(e) : [];
|
|
1813
|
+
}
|
|
1814
|
+
getTranslatedSource() {
|
|
1815
|
+
const i = this.device.getExtension("WEBGL_debug_shaders").WEBGL_debug_shaders;
|
|
1816
|
+
return (i == null ? void 0 : i.getTranslatedShaderSource(this.handle)) || null;
|
|
1817
|
+
}
|
|
1818
|
+
// PRIVATE METHODS
|
|
1819
|
+
/** Compile a shader and get compilation status */
|
|
1820
|
+
async _compile(e) {
|
|
1821
|
+
e = e.startsWith("#version ") ? e : `#version 300 es
|
|
1822
|
+
${e}`;
|
|
1823
|
+
const { gl: i } = this.device;
|
|
1824
|
+
if (i.shaderSource(this.handle, e), i.compileShader(this.handle), !this.device.props.debug) {
|
|
1825
|
+
this.compilationStatus = "pending";
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1828
|
+
if (!this.device.features.has("compilation-status-async-webgl")) {
|
|
1829
|
+
if (this._getCompilationStatus(), this.debugShader(), this.compilationStatus === "error")
|
|
1830
|
+
throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`);
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1833
|
+
b.once(1, "Shader compilation is asynchronous")(), await this._waitForCompilationComplete(), b.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)(), this._getCompilationStatus(), this.debugShader();
|
|
1834
|
+
}
|
|
1835
|
+
/** Use KHR_parallel_shader_compile extension if available */
|
|
1836
|
+
async _waitForCompilationComplete() {
|
|
1837
|
+
const e = async (s) => await new Promise((a) => setTimeout(a, s));
|
|
1838
|
+
if (!this.device.features.has("compilation-status-async-webgl")) {
|
|
1839
|
+
await e(10);
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
const { gl: n } = this.device;
|
|
1843
|
+
for (; ; ) {
|
|
1844
|
+
if (n.getShaderParameter(this.handle, 37297))
|
|
1845
|
+
return;
|
|
1846
|
+
await e(10);
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
/**
|
|
1850
|
+
* Get the shader compilation status
|
|
1851
|
+
* TODO - Load log even when no error reported, to catch warnings?
|
|
1852
|
+
* https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
|
|
1853
|
+
*/
|
|
1854
|
+
_getCompilationStatus() {
|
|
1855
|
+
this.compilationStatus = this.device.gl.getShaderParameter(this.handle, 35713) ? "success" : "error";
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
function Zt(r, t, e, i) {
|
|
1859
|
+
if (rr(t))
|
|
1860
|
+
return i(r);
|
|
1861
|
+
const n = r;
|
|
1862
|
+
n.pushState();
|
|
1863
|
+
try {
|
|
1864
|
+
return Jt(r, t), W(n.gl, e), i(r);
|
|
1865
|
+
} finally {
|
|
1866
|
+
n.popState();
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
function Jt(r, t) {
|
|
1870
|
+
const e = r, { gl: i } = e;
|
|
1871
|
+
if (t.cullMode)
|
|
1872
|
+
switch (t.cullMode) {
|
|
1873
|
+
case "none":
|
|
1874
|
+
i.disable(2884);
|
|
1875
|
+
break;
|
|
1876
|
+
case "front":
|
|
1877
|
+
i.enable(2884), i.cullFace(1028);
|
|
1878
|
+
break;
|
|
1879
|
+
case "back":
|
|
1880
|
+
i.enable(2884), i.cullFace(1029);
|
|
1881
|
+
break;
|
|
1882
|
+
}
|
|
1883
|
+
if (t.frontFace && i.frontFace(F("frontFace", t.frontFace, {
|
|
1884
|
+
ccw: 2305,
|
|
1885
|
+
cw: 2304
|
|
1886
|
+
})), t.unclippedDepth && r.features.has("depth-clip-control") && i.enable(34383), t.depthBias !== void 0 && (i.enable(32823), i.polygonOffset(t.depthBias, t.depthBiasSlopeScale || 0)), t.provokingVertex && r.features.has("provoking-vertex-webgl")) {
|
|
1887
|
+
const s = e.getExtension("WEBGL_provoking_vertex").WEBGL_provoking_vertex, a = F("provokingVertex", t.provokingVertex, {
|
|
1888
|
+
first: 36429,
|
|
1889
|
+
last: 36430
|
|
1890
|
+
});
|
|
1891
|
+
s == null || s.provokingVertexWEBGL(a);
|
|
1892
|
+
}
|
|
1893
|
+
if ((t.polygonMode || t.polygonOffsetLine) && r.features.has("polygon-mode-webgl")) {
|
|
1894
|
+
if (t.polygonMode) {
|
|
1895
|
+
const s = e.getExtension("WEBGL_polygon_mode").WEBGL_polygon_mode, a = F("polygonMode", t.polygonMode, {
|
|
1896
|
+
fill: 6914,
|
|
1897
|
+
line: 6913
|
|
1898
|
+
});
|
|
1899
|
+
s == null || s.polygonModeWEBGL(1028, a), s == null || s.polygonModeWEBGL(1029, a);
|
|
1900
|
+
}
|
|
1901
|
+
t.polygonOffsetLine && i.enable(10754);
|
|
1902
|
+
}
|
|
1903
|
+
if (r.features.has("shader-clip-cull-distance-webgl") && (t.clipDistance0 && i.enable(12288), t.clipDistance1 && i.enable(12289), t.clipDistance2 && i.enable(12290), t.clipDistance3 && i.enable(12291), t.clipDistance4 && i.enable(12292), t.clipDistance5 && i.enable(12293), t.clipDistance6 && i.enable(12294), t.clipDistance7 && i.enable(12295)), t.depthWriteEnabled !== void 0 && i.depthMask(tr("depthWriteEnabled", t.depthWriteEnabled)), t.depthCompare && (t.depthCompare !== "always" ? i.enable(2929) : i.disable(2929), i.depthFunc(le("depthCompare", t.depthCompare))), t.stencilWriteMask) {
|
|
1904
|
+
const n = t.stencilWriteMask;
|
|
1905
|
+
i.stencilMaskSeparate(1028, n), i.stencilMaskSeparate(1029, n);
|
|
1906
|
+
}
|
|
1907
|
+
if (t.stencilReadMask && b.warn("stencilReadMask not supported under WebGL"), t.stencilCompare) {
|
|
1908
|
+
const n = t.stencilReadMask || 4294967295, s = le("depthCompare", t.stencilCompare);
|
|
1909
|
+
t.stencilCompare !== "always" ? i.enable(2960) : i.disable(2960), i.stencilFuncSeparate(1028, s, 0, n), i.stencilFuncSeparate(1029, s, 0, n);
|
|
1910
|
+
}
|
|
1911
|
+
if (t.stencilPassOperation && t.stencilFailOperation && t.stencilDepthFailOperation) {
|
|
1912
|
+
const n = te("stencilPassOperation", t.stencilPassOperation), s = te("stencilFailOperation", t.stencilFailOperation), a = te("stencilDepthFailOperation", t.stencilDepthFailOperation);
|
|
1913
|
+
i.stencilOpSeparate(1028, s, a, n), i.stencilOpSeparate(1029, s, a, n);
|
|
1914
|
+
}
|
|
1915
|
+
switch (t.blend) {
|
|
1916
|
+
case !0:
|
|
1917
|
+
i.enable(3042);
|
|
1918
|
+
break;
|
|
1919
|
+
case !1:
|
|
1920
|
+
i.disable(3042);
|
|
1921
|
+
break;
|
|
1922
|
+
}
|
|
1923
|
+
if (t.blendColorOperation || t.blendAlphaOperation) {
|
|
1924
|
+
const n = Ce("blendColorOperation", t.blendColorOperation || "add"), s = Ce("blendAlphaOperation", t.blendAlphaOperation || "add");
|
|
1925
|
+
i.blendEquationSeparate(n, s);
|
|
1926
|
+
const a = N("blendColorSrcFactor", t.blendColorSrcFactor || "one"), c = N("blendColorDstFactor", t.blendColorDstFactor || "zero"), l = N("blendAlphaSrcFactor", t.blendAlphaSrcFactor || "one"), u = N("blendAlphaDstFactor", t.blendAlphaDstFactor || "zero");
|
|
1927
|
+
i.blendFuncSeparate(a, c, l, u);
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
function le(r, t) {
|
|
1931
|
+
return F(r, t, {
|
|
1932
|
+
never: 512,
|
|
1933
|
+
less: 513,
|
|
1934
|
+
equal: 514,
|
|
1935
|
+
"less-equal": 515,
|
|
1936
|
+
greater: 516,
|
|
1937
|
+
"not-equal": 517,
|
|
1938
|
+
"greater-equal": 518,
|
|
1939
|
+
always: 519
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
function te(r, t) {
|
|
1943
|
+
return F(r, t, {
|
|
1944
|
+
keep: 7680,
|
|
1945
|
+
zero: 0,
|
|
1946
|
+
replace: 7681,
|
|
1947
|
+
invert: 5386,
|
|
1948
|
+
"increment-clamp": 7682,
|
|
1949
|
+
"decrement-clamp": 7683,
|
|
1950
|
+
"increment-wrap": 34055,
|
|
1951
|
+
"decrement-wrap": 34056
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1954
|
+
function Ce(r, t) {
|
|
1955
|
+
return F(r, t, {
|
|
1956
|
+
add: 32774,
|
|
1957
|
+
subtract: 32778,
|
|
1958
|
+
"reverse-subtract": 32779,
|
|
1959
|
+
min: 32775,
|
|
1960
|
+
max: 32776
|
|
1961
|
+
});
|
|
1962
|
+
}
|
|
1963
|
+
function N(r, t, e = "color") {
|
|
1964
|
+
return F(r, t, {
|
|
1965
|
+
one: 1,
|
|
1966
|
+
zero: 0,
|
|
1967
|
+
src: 768,
|
|
1968
|
+
"one-minus-src": 769,
|
|
1969
|
+
dst: 774,
|
|
1970
|
+
"one-minus-dst": 775,
|
|
1971
|
+
"src-alpha": 770,
|
|
1972
|
+
"one-minus-src-alpha": 771,
|
|
1973
|
+
"dst-alpha": 772,
|
|
1974
|
+
"one-minus-dst-alpha": 773,
|
|
1975
|
+
"src-alpha-saturated": 776,
|
|
1976
|
+
constant: e === "color" ? 32769 : 32771,
|
|
1977
|
+
"one-minus-constant": e === "color" ? 32770 : 32772,
|
|
1978
|
+
// 'constant-alpha': GL.CONSTANT_ALPHA,
|
|
1979
|
+
// 'one-minus-constant-alpha': GL.ONE_MINUS_CONSTANT_ALPHA,
|
|
1980
|
+
// TODO not supported in WebGL2
|
|
1981
|
+
src1: 768,
|
|
1982
|
+
"one-minus-src1": 769,
|
|
1983
|
+
"src1-alpha": 770,
|
|
1984
|
+
"one-minus-src1-alpha": 771
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
function er(r, t) {
|
|
1988
|
+
return `Illegal parameter ${t} for ${r}`;
|
|
1989
|
+
}
|
|
1990
|
+
function F(r, t, e) {
|
|
1991
|
+
if (!(t in e))
|
|
1992
|
+
throw new Error(er(r, t));
|
|
1993
|
+
return e[t];
|
|
1994
|
+
}
|
|
1995
|
+
function tr(r, t) {
|
|
1996
|
+
return t;
|
|
1997
|
+
}
|
|
1998
|
+
function rr(r) {
|
|
1999
|
+
let t = !0;
|
|
2000
|
+
for (const e in r) {
|
|
2001
|
+
t = !1;
|
|
2002
|
+
break;
|
|
2003
|
+
}
|
|
2004
|
+
return t;
|
|
2005
|
+
}
|
|
2006
|
+
function ze(r) {
|
|
2007
|
+
const t = {};
|
|
2008
|
+
return r.addressModeU && (t[10242] = re(r.addressModeU)), r.addressModeV && (t[10243] = re(r.addressModeV)), r.addressModeW && (t[32882] = re(r.addressModeW)), r.magFilter && (t[10240] = ue(r.magFilter)), (r.minFilter || r.mipmapFilter) && (t[10241] = ir(r.minFilter || "linear", r.mipmapFilter)), r.lodMinClamp !== void 0 && (t[33082] = r.lodMinClamp), r.lodMaxClamp !== void 0 && (t[33083] = r.lodMaxClamp), r.type === "comparison-sampler" && (t[34892] = 34894), r.compare && (t[34893] = le("compare", r.compare)), r.maxAnisotropy && (t[34046] = r.maxAnisotropy), t;
|
|
2009
|
+
}
|
|
2010
|
+
function re(r) {
|
|
2011
|
+
switch (r) {
|
|
2012
|
+
case "clamp-to-edge":
|
|
2013
|
+
return 33071;
|
|
2014
|
+
case "repeat":
|
|
2015
|
+
return 10497;
|
|
2016
|
+
case "mirror-repeat":
|
|
2017
|
+
return 33648;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
function ue(r) {
|
|
2021
|
+
switch (r) {
|
|
2022
|
+
case "nearest":
|
|
2023
|
+
return 9728;
|
|
2024
|
+
case "linear":
|
|
2025
|
+
return 9729;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
function ir(r, t = "none") {
|
|
2029
|
+
if (!t)
|
|
2030
|
+
return ue(r);
|
|
2031
|
+
switch (t) {
|
|
2032
|
+
case "none":
|
|
2033
|
+
return ue(r);
|
|
2034
|
+
case "nearest":
|
|
2035
|
+
switch (r) {
|
|
2036
|
+
case "nearest":
|
|
2037
|
+
return 9984;
|
|
2038
|
+
case "linear":
|
|
2039
|
+
return 9985;
|
|
2040
|
+
}
|
|
2041
|
+
break;
|
|
2042
|
+
case "linear":
|
|
2043
|
+
switch (r) {
|
|
2044
|
+
case "nearest":
|
|
2045
|
+
return 9986;
|
|
2046
|
+
case "linear":
|
|
2047
|
+
return 9987;
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
class nr extends it {
|
|
2052
|
+
constructor(e, i) {
|
|
2053
|
+
super(e, i);
|
|
2054
|
+
o(this, "device");
|
|
2055
|
+
o(this, "handle");
|
|
2056
|
+
o(this, "parameters");
|
|
2057
|
+
this.device = e, this.parameters = ze(i), this.handle = i.handle || this.device.gl.createSampler(), this._setSamplerParameters(this.parameters);
|
|
2058
|
+
}
|
|
2059
|
+
destroy() {
|
|
2060
|
+
this.handle && (this.device.gl.deleteSampler(this.handle), this.handle = void 0);
|
|
2061
|
+
}
|
|
2062
|
+
toString() {
|
|
2063
|
+
return `Sampler(${this.id},${JSON.stringify(this.props)})`;
|
|
2064
|
+
}
|
|
2065
|
+
/** Set sampler parameters on the sampler */
|
|
2066
|
+
_setSamplerParameters(e) {
|
|
2067
|
+
for (const [i, n] of Object.entries(e)) {
|
|
2068
|
+
const s = Number(i);
|
|
2069
|
+
switch (s) {
|
|
2070
|
+
case 33082:
|
|
2071
|
+
case 33083:
|
|
2072
|
+
this.device.gl.samplerParameterf(this.handle, s, n);
|
|
2073
|
+
break;
|
|
2074
|
+
default:
|
|
2075
|
+
this.device.gl.samplerParameteri(this.handle, s, n);
|
|
2076
|
+
break;
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
function U(r, t, e) {
|
|
2082
|
+
if (sr(t))
|
|
2083
|
+
return e(r);
|
|
2084
|
+
const { nocatch: i = !0 } = t, n = C.get(r);
|
|
2085
|
+
n.push(), W(r, t);
|
|
2086
|
+
let s;
|
|
2087
|
+
if (i)
|
|
2088
|
+
s = e(r), n.pop();
|
|
2089
|
+
else
|
|
2090
|
+
try {
|
|
2091
|
+
s = e(r);
|
|
2092
|
+
} finally {
|
|
2093
|
+
n.pop();
|
|
2094
|
+
}
|
|
2095
|
+
return s;
|
|
2096
|
+
}
|
|
2097
|
+
function sr(r) {
|
|
2098
|
+
for (const t in r)
|
|
2099
|
+
return !1;
|
|
2100
|
+
return !0;
|
|
2101
|
+
}
|
|
2102
|
+
class G extends nt {
|
|
2103
|
+
constructor(e, i) {
|
|
2104
|
+
super(e, { ...L.defaultProps, ...i });
|
|
2105
|
+
o(this, "device");
|
|
2106
|
+
o(this, "gl");
|
|
2107
|
+
o(this, "handle");
|
|
2108
|
+
// Does not have a WebGL representation
|
|
2109
|
+
o(this, "texture");
|
|
2110
|
+
this.device = e, this.gl = this.device.gl, this.handle = null, this.texture = i.texture;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
class V extends L {
|
|
2114
|
+
constructor(e, i) {
|
|
2115
|
+
super(e, i);
|
|
2116
|
+
// readonly MAX_ATTRIBUTES: number;
|
|
2117
|
+
o(this, "device");
|
|
2118
|
+
o(this, "gl");
|
|
2119
|
+
o(this, "handle");
|
|
2120
|
+
// @ts-ignore TODO - currently unused in WebGL. Create dummy sampler?
|
|
2121
|
+
o(this, "sampler");
|
|
2122
|
+
o(this, "view");
|
|
2123
|
+
/**
|
|
2124
|
+
* The WebGL target corresponding to the texture type
|
|
2125
|
+
* @note `target` cannot be modified by bind:
|
|
2126
|
+
* textures are special because when you first bind them to a target,
|
|
2127
|
+
* When you first bind a texture as a GL_TEXTURE_2D, you are saying that this texture is a 2D texture.
|
|
2128
|
+
* And it will always be a 2D texture; this state cannot be changed ever.
|
|
2129
|
+
* A texture that was first bound as a GL_TEXTURE_2D, must always be bound as a GL_TEXTURE_2D;
|
|
2130
|
+
* attempting to bind it as GL_TEXTURE_3D will give rise to a run-time error
|
|
2131
|
+
*/
|
|
2132
|
+
o(this, "glTarget");
|
|
2133
|
+
/** The WebGL format - essentially channel structure */
|
|
2134
|
+
o(this, "glFormat");
|
|
2135
|
+
/** The WebGL data format - the type of each channel */
|
|
2136
|
+
o(this, "glType");
|
|
2137
|
+
/** The WebGL constant corresponding to the WebGPU style constant in format */
|
|
2138
|
+
o(this, "glInternalFormat");
|
|
2139
|
+
/** Whether the internal format is compressed */
|
|
2140
|
+
o(this, "compressed");
|
|
2141
|
+
// state
|
|
2142
|
+
/** Texture binding slot - TODO - move to texture view? */
|
|
2143
|
+
o(this, "_textureUnit", 0);
|
|
2144
|
+
this.device = e, this.gl = this.device.gl;
|
|
2145
|
+
const n = $e(this.props.format);
|
|
2146
|
+
this.glTarget = ar(this.props.dimension), this.glInternalFormat = n.internalFormat, this.glFormat = n.format, this.glType = n.type, this.compressed = n.compressed, this.handle = this.props.handle || this.gl.createTexture(), this.device._setWebGLDebugMetadata(this.handle, this, { spector: this.props }), this.gl.bindTexture(this.glTarget, this.handle);
|
|
2147
|
+
const { dimension: s, width: a, height: c, depth: l, mipLevels: u, glTarget: h, glInternalFormat: f } = this;
|
|
2148
|
+
switch (s) {
|
|
2149
|
+
case "2d":
|
|
2150
|
+
case "cube":
|
|
2151
|
+
this.gl.texStorage2D(h, u, f, a, c);
|
|
2152
|
+
break;
|
|
2153
|
+
case "2d-array":
|
|
2154
|
+
case "3d":
|
|
2155
|
+
this.gl.texStorage3D(h, u, f, a, c, l);
|
|
2156
|
+
break;
|
|
2157
|
+
default:
|
|
2158
|
+
throw new Error(s);
|
|
2159
|
+
}
|
|
2160
|
+
this.gl.bindTexture(this.glTarget, null), this._initializeData(i.data), this.setSampler(this.props.sampler), this.view = new G(this.device, { ...this.props, texture: this }), Object.seal(this);
|
|
2161
|
+
}
|
|
2162
|
+
destroy() {
|
|
2163
|
+
this.handle && (this.gl.deleteTexture(this.handle), this.removeStats(), this.trackDeallocatedMemory("Texture"), this.destroyed = !0);
|
|
2164
|
+
}
|
|
2165
|
+
createView(e) {
|
|
2166
|
+
return new G(this.device, { ...e, texture: this });
|
|
2167
|
+
}
|
|
2168
|
+
setSampler(e = {}) {
|
|
2169
|
+
super.setSampler(e);
|
|
2170
|
+
const i = ze(this.sampler.props);
|
|
2171
|
+
this._setSamplerParameters(i);
|
|
2172
|
+
}
|
|
2173
|
+
copyImageData(e) {
|
|
2174
|
+
const i = this._normalizeCopyImageDataOptions(e), n = i.data, { width: s, height: a, depth: c } = this, { mipLevel: l = 0, byteOffset: u = 0, x: h = 0, y: f = 0, z: g = 0 } = i, { glFormat: d, glType: m, compressed: p } = this, w = Fe(this.glTarget, this.dimension, c), v = this.compressed ? {} : {
|
|
2175
|
+
3314: i.bytesPerRow,
|
|
2176
|
+
32878: i.rowsPerImage
|
|
2177
|
+
};
|
|
2178
|
+
this.gl.bindTexture(w, this.handle), U(this.gl, v, () => {
|
|
2179
|
+
switch (this.dimension) {
|
|
2180
|
+
case "2d":
|
|
2181
|
+
case "cube":
|
|
2182
|
+
p ? this.gl.compressedTexSubImage2D(w, l, h, f, s, a, d, n, u) : this.gl.texSubImage2D(w, l, h, f, s, a, d, m, n, u);
|
|
2183
|
+
break;
|
|
2184
|
+
case "2d-array":
|
|
2185
|
+
case "3d":
|
|
2186
|
+
p ? this.gl.compressedTexSubImage3D(w, l, h, f, g, s, a, c, d, n, u) : this.gl.texSubImage3D(w, l, h, f, g, s, a, c, d, m, n, u);
|
|
2187
|
+
break;
|
|
2188
|
+
default:
|
|
2189
|
+
}
|
|
2190
|
+
}), this.gl.bindTexture(w, null);
|
|
2191
|
+
}
|
|
2192
|
+
copyExternalImage(e) {
|
|
2193
|
+
const i = this._normalizeCopyExternalImageOptions(e);
|
|
2194
|
+
if (i.sourceX || i.sourceY)
|
|
2195
|
+
throw new Error("WebGL does not support sourceX/sourceY)");
|
|
2196
|
+
const { glFormat: n, glType: s } = this, { image: a, depth: c, mipLevel: l, x: u, y: h, z: f, width: g, height: d } = i, m = Fe(this.glTarget, this.dimension, c), p = i.flipY ? { 37440: !0 } : {};
|
|
2197
|
+
return this.gl.bindTexture(this.glTarget, this.handle), U(this.gl, p, () => {
|
|
2198
|
+
switch (this.dimension) {
|
|
2199
|
+
case "2d":
|
|
2200
|
+
case "cube":
|
|
2201
|
+
this.gl.texSubImage2D(m, l, u, h, g, d, n, s, a);
|
|
2202
|
+
break;
|
|
2203
|
+
case "2d-array":
|
|
2204
|
+
case "3d":
|
|
2205
|
+
this.gl.texSubImage3D(m, l, u, h, f, g, d, c, n, s, a);
|
|
2206
|
+
break;
|
|
2207
|
+
default:
|
|
2208
|
+
}
|
|
2209
|
+
}), this.gl.bindTexture(this.glTarget, null), { width: i.width, height: i.height };
|
|
2210
|
+
}
|
|
2211
|
+
// WEBGL SPECIFIC
|
|
2212
|
+
generateMipmapsWebGL(e) {
|
|
2213
|
+
if (!(!(this.device.isTextureFormatRenderable(this.props.format) && this.device.isTextureFormatFilterable(this.props.format)) && (b.warn(`${this} is not renderable or filterable, may not be able to generate mipmaps`)(), !(e != null && e.force))))
|
|
2214
|
+
try {
|
|
2215
|
+
this.gl.bindTexture(this.glTarget, this.handle), this.gl.generateMipmap(this.glTarget);
|
|
2216
|
+
} catch (n) {
|
|
2217
|
+
b.warn(`Error generating mipmap for ${this}: ${n.message}`)();
|
|
2218
|
+
} finally {
|
|
2219
|
+
this.gl.bindTexture(this.glTarget, null);
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
// INTERNAL
|
|
2223
|
+
/**
|
|
2224
|
+
* Sets sampler parameters on texture
|
|
2225
|
+
*/
|
|
2226
|
+
_setSamplerParameters(e) {
|
|
2227
|
+
b.log(2, `${this.id} sampler parameters`, this.device.getGLKeys(e))(), this.gl.bindTexture(this.glTarget, this.handle);
|
|
2228
|
+
for (const [i, n] of Object.entries(e)) {
|
|
2229
|
+
const s = Number(i), a = n;
|
|
2230
|
+
switch (s) {
|
|
2231
|
+
case 33082:
|
|
2232
|
+
case 33083:
|
|
2233
|
+
this.gl.texParameterf(this.glTarget, s, a);
|
|
2234
|
+
break;
|
|
2235
|
+
case 10240:
|
|
2236
|
+
case 10241:
|
|
2237
|
+
this.gl.texParameteri(this.glTarget, s, a);
|
|
2238
|
+
break;
|
|
2239
|
+
case 10242:
|
|
2240
|
+
case 10243:
|
|
2241
|
+
case 32882:
|
|
2242
|
+
this.gl.texParameteri(this.glTarget, s, a);
|
|
2243
|
+
break;
|
|
2244
|
+
case 34046:
|
|
2245
|
+
this.device.features.has("texture-filterable-anisotropic-webgl") && this.gl.texParameteri(this.glTarget, s, a);
|
|
2246
|
+
break;
|
|
2247
|
+
case 34892:
|
|
2248
|
+
case 34893:
|
|
2249
|
+
this.gl.texParameteri(this.glTarget, s, a);
|
|
2250
|
+
break;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
this.gl.bindTexture(this.glTarget, null);
|
|
2254
|
+
}
|
|
2255
|
+
_getActiveUnit() {
|
|
2256
|
+
return this.gl.getParameter(34016) - 33984;
|
|
2257
|
+
}
|
|
2258
|
+
_bind(e) {
|
|
2259
|
+
const { gl: i } = this;
|
|
2260
|
+
return e !== void 0 && (this._textureUnit = e, i.activeTexture(33984 + e)), i.bindTexture(this.glTarget, this.handle), e;
|
|
2261
|
+
}
|
|
2262
|
+
_unbind(e) {
|
|
2263
|
+
const { gl: i } = this;
|
|
2264
|
+
return e !== void 0 && (this._textureUnit = e, i.activeTexture(33984 + e)), i.bindTexture(this.glTarget, null), e;
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
function ar(r) {
|
|
2268
|
+
switch (r) {
|
|
2269
|
+
case "1d":
|
|
2270
|
+
break;
|
|
2271
|
+
// not supported in any WebGL version
|
|
2272
|
+
case "2d":
|
|
2273
|
+
return 3553;
|
|
2274
|
+
// supported in WebGL1
|
|
2275
|
+
case "3d":
|
|
2276
|
+
return 32879;
|
|
2277
|
+
// supported in WebGL2
|
|
2278
|
+
case "cube":
|
|
2279
|
+
return 34067;
|
|
2280
|
+
// supported in WebGL1
|
|
2281
|
+
case "2d-array":
|
|
2282
|
+
return 35866;
|
|
2283
|
+
}
|
|
2284
|
+
throw new Error(r);
|
|
2285
|
+
}
|
|
2286
|
+
function Fe(r, t, e) {
|
|
2287
|
+
return t === "cube" ? 34069 + e : r;
|
|
2288
|
+
}
|
|
2289
|
+
function or(r) {
|
|
2290
|
+
return hr[r];
|
|
2291
|
+
}
|
|
2292
|
+
function ge(r) {
|
|
2293
|
+
return ur[r];
|
|
2294
|
+
}
|
|
2295
|
+
function cr(r) {
|
|
2296
|
+
return !!Ve[r];
|
|
2297
|
+
}
|
|
2298
|
+
function lr(r) {
|
|
2299
|
+
return Ve[r];
|
|
2300
|
+
}
|
|
2301
|
+
const ur = {
|
|
2302
|
+
5126: "f32",
|
|
2303
|
+
35664: "vec2<f32>",
|
|
2304
|
+
35665: "vec3<f32>",
|
|
2305
|
+
35666: "vec4<f32>",
|
|
2306
|
+
5124: "i32",
|
|
2307
|
+
35667: "vec2<i32>",
|
|
2308
|
+
35668: "vec3<i32>",
|
|
2309
|
+
35669: "vec4<i32>",
|
|
2310
|
+
5125: "u32",
|
|
2311
|
+
36294: "vec2<u32>",
|
|
2312
|
+
36295: "vec3<u32>",
|
|
2313
|
+
36296: "vec4<u32>",
|
|
2314
|
+
35670: "f32",
|
|
2315
|
+
35671: "vec2<f32>",
|
|
2316
|
+
35672: "vec3<f32>",
|
|
2317
|
+
35673: "vec4<f32>",
|
|
2318
|
+
// TODO - are sizes/components below correct?
|
|
2319
|
+
35674: "mat2x2<f32>",
|
|
2320
|
+
35685: "mat2x3<f32>",
|
|
2321
|
+
35686: "mat2x4<f32>",
|
|
2322
|
+
35687: "mat3x2<f32>",
|
|
2323
|
+
35675: "mat3x3<f32>",
|
|
2324
|
+
35688: "mat3x4<f32>",
|
|
2325
|
+
35689: "mat4x2<f32>",
|
|
2326
|
+
35690: "mat4x3<f32>",
|
|
2327
|
+
35676: "mat4x4<f32>"
|
|
2328
|
+
}, Ve = {
|
|
2329
|
+
35678: { viewDimension: "2d", sampleType: "float" },
|
|
2330
|
+
35680: { viewDimension: "cube", sampleType: "float" },
|
|
2331
|
+
35679: { viewDimension: "3d", sampleType: "float" },
|
|
2332
|
+
35682: { viewDimension: "3d", sampleType: "depth" },
|
|
2333
|
+
36289: { viewDimension: "2d-array", sampleType: "float" },
|
|
2334
|
+
36292: { viewDimension: "2d-array", sampleType: "depth" },
|
|
2335
|
+
36293: { viewDimension: "cube", sampleType: "float" },
|
|
2336
|
+
36298: { viewDimension: "2d", sampleType: "sint" },
|
|
2337
|
+
36299: { viewDimension: "3d", sampleType: "sint" },
|
|
2338
|
+
36300: { viewDimension: "cube", sampleType: "sint" },
|
|
2339
|
+
36303: { viewDimension: "2d-array", sampleType: "uint" },
|
|
2340
|
+
36306: { viewDimension: "2d", sampleType: "uint" },
|
|
2341
|
+
36307: { viewDimension: "3d", sampleType: "uint" },
|
|
2342
|
+
36308: { viewDimension: "cube", sampleType: "uint" },
|
|
2343
|
+
36311: { viewDimension: "2d-array", sampleType: "uint" }
|
|
2344
|
+
}, hr = {
|
|
2345
|
+
uint8: 5121,
|
|
2346
|
+
sint8: 5120,
|
|
2347
|
+
unorm8: 5121,
|
|
2348
|
+
snorm8: 5120,
|
|
2349
|
+
uint16: 5123,
|
|
2350
|
+
sint16: 5122,
|
|
2351
|
+
unorm16: 5123,
|
|
2352
|
+
snorm16: 5122,
|
|
2353
|
+
uint32: 5125,
|
|
2354
|
+
sint32: 5124,
|
|
2355
|
+
// WebGPU does not support normalized 32 bit integer attributes
|
|
2356
|
+
// 'unorm32': GL.UNSIGNED_INT,
|
|
2357
|
+
// 'snorm32': GL.INT,
|
|
2358
|
+
float16: 5131,
|
|
2359
|
+
float32: 5126
|
|
2360
|
+
};
|
|
2361
|
+
function fr(r, t) {
|
|
2362
|
+
const e = {
|
|
2363
|
+
attributes: [],
|
|
2364
|
+
bindings: []
|
|
2365
|
+
};
|
|
2366
|
+
e.attributes = dr(r, t);
|
|
2367
|
+
const i = mr(r, t);
|
|
2368
|
+
for (const c of i) {
|
|
2369
|
+
const l = c.uniforms.map((u) => ({
|
|
2370
|
+
name: u.name,
|
|
2371
|
+
format: u.format,
|
|
2372
|
+
byteOffset: u.byteOffset,
|
|
2373
|
+
byteStride: u.byteStride,
|
|
2374
|
+
arrayLength: u.arrayLength
|
|
2375
|
+
}));
|
|
2376
|
+
e.bindings.push({
|
|
2377
|
+
type: "uniform",
|
|
2378
|
+
name: c.name,
|
|
2379
|
+
group: 0,
|
|
2380
|
+
location: c.location,
|
|
2381
|
+
visibility: (c.vertex ? 1 : 0) & (c.fragment ? 2 : 0),
|
|
2382
|
+
minBindingSize: c.byteLength,
|
|
2383
|
+
uniforms: l
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
const n = br(r, t);
|
|
2387
|
+
let s = 0;
|
|
2388
|
+
for (const c of n)
|
|
2389
|
+
if (cr(c.type)) {
|
|
2390
|
+
const { viewDimension: l, sampleType: u } = lr(c.type);
|
|
2391
|
+
e.bindings.push({
|
|
2392
|
+
type: "texture",
|
|
2393
|
+
name: c.name,
|
|
2394
|
+
group: 0,
|
|
2395
|
+
location: s,
|
|
2396
|
+
viewDimension: l,
|
|
2397
|
+
sampleType: u
|
|
2398
|
+
}), c.textureUnit = s, s += 1;
|
|
2399
|
+
}
|
|
2400
|
+
n.length && (e.uniforms = n);
|
|
2401
|
+
const a = gr(r, t);
|
|
2402
|
+
return a != null && a.length && (e.varyings = a), e;
|
|
2403
|
+
}
|
|
2404
|
+
function dr(r, t) {
|
|
2405
|
+
const e = [], i = r.getProgramParameter(t, 35721);
|
|
2406
|
+
for (let n = 0; n < i; n++) {
|
|
2407
|
+
const s = r.getActiveAttrib(t, n);
|
|
2408
|
+
if (!s)
|
|
2409
|
+
throw new Error("activeInfo");
|
|
2410
|
+
const {
|
|
2411
|
+
name: a,
|
|
2412
|
+
type: c
|
|
2413
|
+
/* , size*/
|
|
2414
|
+
} = s, l = r.getAttribLocation(t, a);
|
|
2415
|
+
if (l >= 0) {
|
|
2416
|
+
const u = ge(c), h = /instance/i.test(a) ? "instance" : "vertex";
|
|
2417
|
+
e.push({
|
|
2418
|
+
name: a,
|
|
2419
|
+
location: l,
|
|
2420
|
+
stepMode: h,
|
|
2421
|
+
type: u
|
|
2422
|
+
// size - for arrays, size is the number of elements in the array
|
|
2423
|
+
});
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
return e.sort((n, s) => n.location - s.location), e;
|
|
2427
|
+
}
|
|
2428
|
+
function gr(r, t) {
|
|
2429
|
+
const e = [], i = r.getProgramParameter(t, 35971);
|
|
2430
|
+
for (let n = 0; n < i; n++) {
|
|
2431
|
+
const s = r.getTransformFeedbackVarying(t, n);
|
|
2432
|
+
if (!s)
|
|
2433
|
+
throw new Error("activeInfo");
|
|
2434
|
+
const { name: a, type: c, size: l } = s, u = ge(c), { type: h, components: f } = st(u);
|
|
2435
|
+
e.push({ location: n, name: a, type: h, size: l * f });
|
|
2436
|
+
}
|
|
2437
|
+
return e.sort((n, s) => n.location - s.location), e;
|
|
2438
|
+
}
|
|
2439
|
+
function br(r, t) {
|
|
2440
|
+
const e = [], i = r.getProgramParameter(t, 35718);
|
|
2441
|
+
for (let n = 0; n < i; n++) {
|
|
2442
|
+
const s = r.getActiveUniform(t, n);
|
|
2443
|
+
if (!s)
|
|
2444
|
+
throw new Error("activeInfo");
|
|
2445
|
+
const { name: a, size: c, type: l } = s, { name: u, isArray: h } = pr(a);
|
|
2446
|
+
let f = r.getUniformLocation(t, u);
|
|
2447
|
+
const g = {
|
|
2448
|
+
// WebGL locations are uniquely typed but just numbers
|
|
2449
|
+
location: f,
|
|
2450
|
+
name: u,
|
|
2451
|
+
size: c,
|
|
2452
|
+
type: l,
|
|
2453
|
+
isArray: h
|
|
2454
|
+
};
|
|
2455
|
+
if (e.push(g), g.size > 1)
|
|
2456
|
+
for (let d = 0; d < g.size; d++) {
|
|
2457
|
+
const m = `${u}[${d}]`;
|
|
2458
|
+
f = r.getUniformLocation(t, m);
|
|
2459
|
+
const p = {
|
|
2460
|
+
...g,
|
|
2461
|
+
name: m,
|
|
2462
|
+
location: f
|
|
2463
|
+
};
|
|
2464
|
+
e.push(p);
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
return e;
|
|
2468
|
+
}
|
|
2469
|
+
function mr(r, t) {
|
|
2470
|
+
const e = (s, a) => r.getActiveUniformBlockParameter(t, s, a), i = [], n = r.getProgramParameter(t, 35382);
|
|
2471
|
+
for (let s = 0; s < n; s++) {
|
|
2472
|
+
const a = {
|
|
2473
|
+
name: r.getActiveUniformBlockName(t, s) || "",
|
|
2474
|
+
location: e(s, 35391),
|
|
2475
|
+
byteLength: e(s, 35392),
|
|
2476
|
+
vertex: e(s, 35396),
|
|
2477
|
+
fragment: e(s, 35398),
|
|
2478
|
+
uniformCount: e(s, 35394),
|
|
2479
|
+
uniforms: []
|
|
2480
|
+
}, c = e(s, 35395) || [], l = r.getActiveUniforms(t, c, 35383), u = r.getActiveUniforms(t, c, 35384), h = r.getActiveUniforms(t, c, 35387), f = r.getActiveUniforms(t, c, 35388);
|
|
2481
|
+
for (let g = 0; g < a.uniformCount; ++g) {
|
|
2482
|
+
const d = r.getActiveUniform(t, c[g]);
|
|
2483
|
+
if (!d)
|
|
2484
|
+
throw new Error("activeInfo");
|
|
2485
|
+
const m = ge(l[g]);
|
|
2486
|
+
a.uniforms.push({
|
|
2487
|
+
name: d.name,
|
|
2488
|
+
format: m,
|
|
2489
|
+
type: l[g],
|
|
2490
|
+
arrayLength: u[g],
|
|
2491
|
+
byteOffset: h[g],
|
|
2492
|
+
byteStride: f[g]
|
|
2493
|
+
// matrixStride: uniformStride[i],
|
|
2494
|
+
// rowMajor: uniformRowMajor[i]
|
|
2495
|
+
});
|
|
2496
|
+
}
|
|
2497
|
+
i.push(a);
|
|
2498
|
+
}
|
|
2499
|
+
return i.sort((s, a) => s.location - a.location), i;
|
|
2500
|
+
}
|
|
2501
|
+
function pr(r) {
|
|
2502
|
+
if (r[r.length - 1] !== "]")
|
|
2503
|
+
return {
|
|
2504
|
+
name: r,
|
|
2505
|
+
length: 1,
|
|
2506
|
+
isArray: !1
|
|
2507
|
+
};
|
|
2508
|
+
const e = /([^[]*)(\[[0-9]+\])?/.exec(r);
|
|
2509
|
+
if (!e || e.length < 2)
|
|
2510
|
+
throw new Error(`Failed to parse GLSL uniform name ${r}`);
|
|
2511
|
+
return {
|
|
2512
|
+
name: e[1],
|
|
2513
|
+
length: e[2] ? 1 : 0,
|
|
2514
|
+
isArray: !!e[2]
|
|
2515
|
+
};
|
|
2516
|
+
}
|
|
2517
|
+
function xr(r, t, e, i) {
|
|
2518
|
+
const n = r;
|
|
2519
|
+
let s = i;
|
|
2520
|
+
s === !0 && (s = 1), s === !1 && (s = 0);
|
|
2521
|
+
const a = typeof s == "number" ? [s] : s;
|
|
2522
|
+
switch (e) {
|
|
2523
|
+
case 35678:
|
|
2524
|
+
case 35680:
|
|
2525
|
+
case 35679:
|
|
2526
|
+
case 35682:
|
|
2527
|
+
case 36289:
|
|
2528
|
+
case 36292:
|
|
2529
|
+
case 36293:
|
|
2530
|
+
case 36298:
|
|
2531
|
+
case 36299:
|
|
2532
|
+
case 36300:
|
|
2533
|
+
case 36303:
|
|
2534
|
+
case 36306:
|
|
2535
|
+
case 36307:
|
|
2536
|
+
case 36308:
|
|
2537
|
+
case 36311:
|
|
2538
|
+
if (typeof i != "number")
|
|
2539
|
+
throw new Error("samplers must be set to integers");
|
|
2540
|
+
return r.uniform1i(t, i);
|
|
2541
|
+
case 5126:
|
|
2542
|
+
return r.uniform1fv(t, a);
|
|
2543
|
+
case 35664:
|
|
2544
|
+
return r.uniform2fv(t, a);
|
|
2545
|
+
case 35665:
|
|
2546
|
+
return r.uniform3fv(t, a);
|
|
2547
|
+
case 35666:
|
|
2548
|
+
return r.uniform4fv(t, a);
|
|
2549
|
+
case 5124:
|
|
2550
|
+
return r.uniform1iv(t, a);
|
|
2551
|
+
case 35667:
|
|
2552
|
+
return r.uniform2iv(t, a);
|
|
2553
|
+
case 35668:
|
|
2554
|
+
return r.uniform3iv(t, a);
|
|
2555
|
+
case 35669:
|
|
2556
|
+
return r.uniform4iv(t, a);
|
|
2557
|
+
case 35670:
|
|
2558
|
+
return r.uniform1iv(t, a);
|
|
2559
|
+
case 35671:
|
|
2560
|
+
return r.uniform2iv(t, a);
|
|
2561
|
+
case 35672:
|
|
2562
|
+
return r.uniform3iv(t, a);
|
|
2563
|
+
case 35673:
|
|
2564
|
+
return r.uniform4iv(t, a);
|
|
2565
|
+
// WEBGL2 - unsigned integers
|
|
2566
|
+
case 5125:
|
|
2567
|
+
return n.uniform1uiv(t, a, 1);
|
|
2568
|
+
case 36294:
|
|
2569
|
+
return n.uniform2uiv(t, a, 2);
|
|
2570
|
+
case 36295:
|
|
2571
|
+
return n.uniform3uiv(t, a, 3);
|
|
2572
|
+
case 36296:
|
|
2573
|
+
return n.uniform4uiv(t, a, 4);
|
|
2574
|
+
// WebGL2 - quadratic matrices
|
|
2575
|
+
// false: don't transpose the matrix
|
|
2576
|
+
case 35674:
|
|
2577
|
+
return r.uniformMatrix2fv(t, !1, a);
|
|
2578
|
+
case 35675:
|
|
2579
|
+
return r.uniformMatrix3fv(t, !1, a);
|
|
2580
|
+
case 35676:
|
|
2581
|
+
return r.uniformMatrix4fv(t, !1, a);
|
|
2582
|
+
// WebGL2 - rectangular matrices
|
|
2583
|
+
case 35685:
|
|
2584
|
+
return n.uniformMatrix2x3fv(t, !1, a);
|
|
2585
|
+
case 35686:
|
|
2586
|
+
return n.uniformMatrix2x4fv(t, !1, a);
|
|
2587
|
+
case 35687:
|
|
2588
|
+
return n.uniformMatrix3x2fv(t, !1, a);
|
|
2589
|
+
case 35688:
|
|
2590
|
+
return n.uniformMatrix3x4fv(t, !1, a);
|
|
2591
|
+
case 35689:
|
|
2592
|
+
return n.uniformMatrix4x2fv(t, !1, a);
|
|
2593
|
+
case 35690:
|
|
2594
|
+
return n.uniformMatrix4x3fv(t, !1, a);
|
|
2595
|
+
}
|
|
2596
|
+
throw new Error("Illegal uniform");
|
|
2597
|
+
}
|
|
2598
|
+
function yr(r) {
|
|
2599
|
+
switch (r) {
|
|
2600
|
+
case "point-list":
|
|
2601
|
+
return 0;
|
|
2602
|
+
case "line-list":
|
|
2603
|
+
return 1;
|
|
2604
|
+
case "line-strip":
|
|
2605
|
+
return 3;
|
|
2606
|
+
case "triangle-list":
|
|
2607
|
+
return 4;
|
|
2608
|
+
case "triangle-strip":
|
|
2609
|
+
return 5;
|
|
2610
|
+
default:
|
|
2611
|
+
throw new Error(r);
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
function wr(r) {
|
|
2615
|
+
switch (r) {
|
|
2616
|
+
case "point-list":
|
|
2617
|
+
return 0;
|
|
2618
|
+
case "line-list":
|
|
2619
|
+
return 1;
|
|
2620
|
+
case "line-strip":
|
|
2621
|
+
return 1;
|
|
2622
|
+
case "triangle-list":
|
|
2623
|
+
return 4;
|
|
2624
|
+
case "triangle-strip":
|
|
2625
|
+
return 4;
|
|
2626
|
+
default:
|
|
2627
|
+
throw new Error(r);
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
const ke = 4;
|
|
2631
|
+
class vr extends at {
|
|
2632
|
+
constructor(e, i) {
|
|
2633
|
+
super(e, i);
|
|
2634
|
+
/** The WebGL device that created this render pipeline */
|
|
2635
|
+
o(this, "device");
|
|
2636
|
+
/** Handle to underlying WebGL program */
|
|
2637
|
+
o(this, "handle");
|
|
2638
|
+
/** vertex shader */
|
|
2639
|
+
o(this, "vs");
|
|
2640
|
+
/** fragment shader */
|
|
2641
|
+
o(this, "fs");
|
|
2642
|
+
/** The layout extracted from shader by WebGL introspection APIs */
|
|
2643
|
+
o(this, "introspectedLayout");
|
|
2644
|
+
/** Uniforms set on this model */
|
|
2645
|
+
o(this, "uniforms", {});
|
|
2646
|
+
/** Bindings set on this model */
|
|
2647
|
+
o(this, "bindings", {});
|
|
2648
|
+
/** WebGL varyings */
|
|
2649
|
+
o(this, "varyings", null);
|
|
2650
|
+
o(this, "_uniformCount", 0);
|
|
2651
|
+
o(this, "_uniformSetters", {});
|
|
2652
|
+
this.device = e, this.handle = this.props.handle || this.device.gl.createProgram(), this.device._setWebGLDebugMetadata(this.handle, this, { spector: { id: this.props.id } }), this.vs = i.vs, this.fs = i.fs;
|
|
2653
|
+
const { varyings: n, bufferMode: s = 35981 } = i;
|
|
2654
|
+
n && n.length > 0 && (this.varyings = n, this.device.gl.transformFeedbackVaryings(this.handle, n, s)), this._linkShaders(), b.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)(), this.introspectedLayout = fr(this.device.gl, this.handle), b.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)(), this.shaderLayout = i.shaderLayout ? Sr(this.introspectedLayout, i.shaderLayout) : this.introspectedLayout;
|
|
2655
|
+
}
|
|
2656
|
+
// TODO are these used?
|
|
2657
|
+
get [Symbol.toStringTag]() {
|
|
2658
|
+
return "WEBGLRenderPipeline";
|
|
2659
|
+
}
|
|
2660
|
+
destroy() {
|
|
2661
|
+
this.handle && (this.device.gl.useProgram(null), this.device.gl.deleteProgram(this.handle), this.destroyed = !0, this.handle.destroyed = !0, this.handle = null);
|
|
2662
|
+
}
|
|
2663
|
+
/**
|
|
2664
|
+
* Bindings include: textures, samplers and uniform buffers
|
|
2665
|
+
* @todo needed for portable model
|
|
2666
|
+
*/
|
|
2667
|
+
setBindings(e, i) {
|
|
2668
|
+
for (const [n, s] of Object.entries(e)) {
|
|
2669
|
+
const a = this.shaderLayout.bindings.find((c) => c.name === n) || this.shaderLayout.bindings.find((c) => c.name === `${n}Uniforms`);
|
|
2670
|
+
if (!a) {
|
|
2671
|
+
const c = this.shaderLayout.bindings.map((l) => `"${l.name}"`).join(", ");
|
|
2672
|
+
i != null && i.disableWarnings || b.warn(`No binding "${n}" in render pipeline "${this.id}", expected one of ${c}`, s)();
|
|
2673
|
+
continue;
|
|
2674
|
+
}
|
|
2675
|
+
switch (s || b.warn(`Unsetting binding "${n}" in render pipeline "${this.id}"`)(), a.type) {
|
|
2676
|
+
case "uniform":
|
|
2677
|
+
if (!(s instanceof z) && !(s.buffer instanceof z))
|
|
2678
|
+
throw new Error("buffer value");
|
|
2679
|
+
break;
|
|
2680
|
+
case "texture":
|
|
2681
|
+
if (!(s instanceof G || s instanceof V || s instanceof $))
|
|
2682
|
+
throw new Error(`${this} Bad texture binding for ${n}`);
|
|
2683
|
+
break;
|
|
2684
|
+
case "sampler":
|
|
2685
|
+
b.warn(`Ignoring sampler ${n}`)();
|
|
2686
|
+
break;
|
|
2687
|
+
default:
|
|
2688
|
+
throw new Error(a.type);
|
|
2689
|
+
}
|
|
2690
|
+
this.bindings[n] = s;
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
/** @todo needed for portable model
|
|
2694
|
+
* @note The WebGL API is offers many ways to draw things
|
|
2695
|
+
* This function unifies those ways into a single call using common parameters with sane defaults
|
|
2696
|
+
*/
|
|
2697
|
+
draw(e) {
|
|
2698
|
+
var w;
|
|
2699
|
+
const {
|
|
2700
|
+
renderPass: i,
|
|
2701
|
+
parameters: n = this.props.parameters,
|
|
2702
|
+
topology: s = this.props.topology,
|
|
2703
|
+
vertexArray: a,
|
|
2704
|
+
vertexCount: c,
|
|
2705
|
+
// indexCount,
|
|
2706
|
+
instanceCount: l,
|
|
2707
|
+
isInstanced: u = !1,
|
|
2708
|
+
firstVertex: h = 0,
|
|
2709
|
+
// firstIndex,
|
|
2710
|
+
// firstInstance,
|
|
2711
|
+
// baseVertex,
|
|
2712
|
+
transformFeedback: f
|
|
2713
|
+
} = e, g = yr(s), d = !!a.indexBuffer, m = (w = a.indexBuffer) == null ? void 0 : w.glIndexType;
|
|
2714
|
+
if (this.linkStatus !== "success")
|
|
2715
|
+
return b.info(2, `RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)(), !1;
|
|
2716
|
+
if (!this._areTexturesRenderable())
|
|
2717
|
+
return b.info(2, `RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)(), !1;
|
|
2718
|
+
this.device.gl.useProgram(this.handle), a.bindBeforeRender(i), f && f.begin(this.props.topology), this._applyBindings(), this._applyUniforms();
|
|
2719
|
+
const p = i;
|
|
2720
|
+
return Zt(this.device, n, p.glParameters, () => {
|
|
2721
|
+
d && u ? this.device.gl.drawElementsInstanced(
|
|
2722
|
+
g,
|
|
2723
|
+
c || 0,
|
|
2724
|
+
// indexCount?
|
|
2725
|
+
m,
|
|
2726
|
+
h,
|
|
2727
|
+
l || 0
|
|
2728
|
+
) : d ? this.device.gl.drawElements(g, c || 0, m, h) : u ? this.device.gl.drawArraysInstanced(g, h, c || 0, l || 0) : this.device.gl.drawArrays(g, h, c || 0), f && f.end();
|
|
2729
|
+
}), a.unbindAfterRender(i), !0;
|
|
2730
|
+
}
|
|
2731
|
+
// PRIVATE METHODS
|
|
2732
|
+
// setAttributes(attributes: Record<string, Buffer>): void {}
|
|
2733
|
+
// setBindings(bindings: Record<string, Binding>): void {}
|
|
2734
|
+
async _linkShaders() {
|
|
2735
|
+
const { gl: e } = this.device;
|
|
2736
|
+
if (e.attachShader(this.handle, this.vs.handle), e.attachShader(this.handle, this.fs.handle), b.time(ke, `linkProgram for ${this.id}`)(), e.linkProgram(this.handle), b.timeEnd(ke, `linkProgram for ${this.id}`)(), b.level, !this.device.features.has("compilation-status-async-webgl")) {
|
|
2737
|
+
const n = this._getLinkStatus();
|
|
2738
|
+
this._reportLinkStatus(n);
|
|
2739
|
+
return;
|
|
2740
|
+
}
|
|
2741
|
+
b.once(1, "RenderPipeline linking is asynchronous")(), await this._waitForLinkComplete(), b.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();
|
|
2742
|
+
const i = this._getLinkStatus();
|
|
2743
|
+
this._reportLinkStatus(i);
|
|
2744
|
+
}
|
|
2745
|
+
/** Report link status. First, check for shader compilation failures if linking fails */
|
|
2746
|
+
async _reportLinkStatus(e) {
|
|
2747
|
+
var i;
|
|
2748
|
+
switch (e) {
|
|
2749
|
+
case "success":
|
|
2750
|
+
return;
|
|
2751
|
+
default:
|
|
2752
|
+
const n = e === "link-error" ? "Link error" : "Validation error";
|
|
2753
|
+
switch (this.vs.compilationStatus) {
|
|
2754
|
+
case "error":
|
|
2755
|
+
throw this.vs.debugShader(), new Error(`${this} ${n} during compilation of ${this.vs}`);
|
|
2756
|
+
case "pending":
|
|
2757
|
+
await this.vs.asyncCompilationStatus, this.vs.debugShader();
|
|
2758
|
+
break;
|
|
2759
|
+
}
|
|
2760
|
+
switch ((i = this.fs) == null ? void 0 : i.compilationStatus) {
|
|
2761
|
+
case "error":
|
|
2762
|
+
throw this.fs.debugShader(), new Error(`${this} ${n} during compilation of ${this.fs}`);
|
|
2763
|
+
case "pending":
|
|
2764
|
+
await this.fs.asyncCompilationStatus, this.fs.debugShader();
|
|
2765
|
+
break;
|
|
2766
|
+
}
|
|
2767
|
+
const s = this.device.gl.getProgramInfoLog(this.handle);
|
|
2768
|
+
this.device.reportError(new Error(`${n} during ${e}: ${s}`), this)(), this.device.debug();
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
/**
|
|
2772
|
+
* Get the shader compilation status
|
|
2773
|
+
* TODO - Load log even when no error reported, to catch warnings?
|
|
2774
|
+
* https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
|
|
2775
|
+
*/
|
|
2776
|
+
_getLinkStatus() {
|
|
2777
|
+
const { gl: e } = this.device;
|
|
2778
|
+
return e.getProgramParameter(this.handle, 35714) ? (e.validateProgram(this.handle), e.getProgramParameter(this.handle, 35715) ? (this.linkStatus = "success", "success") : (this.linkStatus = "error", "validation-error")) : (this.linkStatus = "error", "link-error");
|
|
2779
|
+
}
|
|
2780
|
+
/** Use KHR_parallel_shader_compile extension if available */
|
|
2781
|
+
async _waitForLinkComplete() {
|
|
2782
|
+
const e = async (s) => await new Promise((a) => setTimeout(a, s));
|
|
2783
|
+
if (!this.device.features.has("compilation-status-async-webgl")) {
|
|
2784
|
+
await e(10);
|
|
2785
|
+
return;
|
|
2786
|
+
}
|
|
2787
|
+
const { gl: n } = this.device;
|
|
2788
|
+
for (; ; ) {
|
|
2789
|
+
if (n.getProgramParameter(this.handle, 37297))
|
|
2790
|
+
return;
|
|
2791
|
+
await e(10);
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Checks if all texture-values uniforms are renderable (i.e. loaded)
|
|
2796
|
+
* Update a texture if needed (e.g. from video)
|
|
2797
|
+
* Note: This is currently done before every draw call
|
|
2798
|
+
*/
|
|
2799
|
+
_areTexturesRenderable() {
|
|
2800
|
+
let e = !0;
|
|
2801
|
+
for (const i of this.shaderLayout.bindings)
|
|
2802
|
+
!this.bindings[i.name] && !this.bindings[i.name.replace(/Uniforms$/, "")] && (b.warn(`Binding ${i.name} not found in ${this.id}`)(), e = !1);
|
|
2803
|
+
return e;
|
|
2804
|
+
}
|
|
2805
|
+
/** Apply any bindings (before each draw call) */
|
|
2806
|
+
_applyBindings() {
|
|
2807
|
+
if (this.linkStatus !== "success")
|
|
2808
|
+
return;
|
|
2809
|
+
const { gl: e } = this.device;
|
|
2810
|
+
e.useProgram(this.handle);
|
|
2811
|
+
let i = 0, n = 0;
|
|
2812
|
+
for (const s of this.shaderLayout.bindings) {
|
|
2813
|
+
const a = this.bindings[s.name] || this.bindings[s.name.replace(/Uniforms$/, "")];
|
|
2814
|
+
if (!a)
|
|
2815
|
+
throw new Error(`No value for binding ${s.name} in ${this.id}`);
|
|
2816
|
+
switch (s.type) {
|
|
2817
|
+
case "uniform":
|
|
2818
|
+
const { name: c } = s, l = e.getUniformBlockIndex(this.handle, c);
|
|
2819
|
+
if (l === 4294967295)
|
|
2820
|
+
throw new Error(`Invalid uniform block name ${c}`);
|
|
2821
|
+
e.uniformBlockBinding(this.handle, n, l), a instanceof z ? e.bindBufferBase(35345, n, a.handle) : e.bindBufferRange(
|
|
2822
|
+
35345,
|
|
2823
|
+
n,
|
|
2824
|
+
// @ts-expect-error
|
|
2825
|
+
a.buffer.handle,
|
|
2826
|
+
// @ts-expect-error
|
|
2827
|
+
a.offset || 0,
|
|
2828
|
+
// @ts-expect-error
|
|
2829
|
+
a.size || a.buffer.byteLength - a.offset
|
|
2830
|
+
), n += 1;
|
|
2831
|
+
break;
|
|
2832
|
+
case "texture":
|
|
2833
|
+
if (!(a instanceof G || a instanceof V || a instanceof $))
|
|
2834
|
+
throw new Error("texture");
|
|
2835
|
+
let u;
|
|
2836
|
+
if (a instanceof G)
|
|
2837
|
+
u = a.texture;
|
|
2838
|
+
else if (a instanceof V)
|
|
2839
|
+
u = a;
|
|
2840
|
+
else if (a instanceof $ && a.colorAttachments[0] instanceof G)
|
|
2841
|
+
b.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")(), u = a.colorAttachments[0].texture;
|
|
2842
|
+
else
|
|
2843
|
+
throw new Error("No texture");
|
|
2844
|
+
e.activeTexture(33984 + i), e.bindTexture(u.glTarget, u.handle), i += 1;
|
|
2845
|
+
break;
|
|
2846
|
+
case "sampler":
|
|
2847
|
+
break;
|
|
2848
|
+
case "storage":
|
|
2849
|
+
case "read-only-storage":
|
|
2850
|
+
throw new Error(`binding type '${s.type}' not supported in WebGL`);
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
/**
|
|
2855
|
+
* Due to program sharing, uniforms need to be reset before every draw call
|
|
2856
|
+
* (though caching will avoid redundant WebGL calls)
|
|
2857
|
+
*/
|
|
2858
|
+
_applyUniforms() {
|
|
2859
|
+
for (const e of this.shaderLayout.uniforms || []) {
|
|
2860
|
+
const { name: i, location: n, type: s, textureUnit: a } = e, c = this.uniforms[i] ?? a;
|
|
2861
|
+
c !== void 0 && xr(this.device.gl, n, s, c);
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
function Sr(r, t) {
|
|
2866
|
+
const e = {
|
|
2867
|
+
...r,
|
|
2868
|
+
attributes: r.attributes.map((i) => ({ ...i }))
|
|
2869
|
+
};
|
|
2870
|
+
for (const i of (t == null ? void 0 : t.attributes) || []) {
|
|
2871
|
+
const n = e.attributes.find((s) => s.name === i.name);
|
|
2872
|
+
n ? (n.type = i.type || n.type, n.stepMode = i.stepMode || n.stepMode) : b.warn(`shader layout attribute ${i.name} not present in shader`);
|
|
2873
|
+
}
|
|
2874
|
+
return e;
|
|
2875
|
+
}
|
|
2876
|
+
class Tr extends se {
|
|
2877
|
+
constructor(e) {
|
|
2878
|
+
super(e, {});
|
|
2879
|
+
o(this, "device");
|
|
2880
|
+
o(this, "handle", null);
|
|
2881
|
+
o(this, "commands", []);
|
|
2882
|
+
this.device = e;
|
|
2883
|
+
}
|
|
2884
|
+
_executeCommands(e = this.commands) {
|
|
2885
|
+
for (const i of e)
|
|
2886
|
+
switch (i.name) {
|
|
2887
|
+
case "copy-buffer-to-buffer":
|
|
2888
|
+
_r(this.device, i.options);
|
|
2889
|
+
break;
|
|
2890
|
+
case "copy-buffer-to-texture":
|
|
2891
|
+
Pr(this.device, i.options);
|
|
2892
|
+
break;
|
|
2893
|
+
case "copy-texture-to-buffer":
|
|
2894
|
+
Ar(this.device, i.options);
|
|
2895
|
+
break;
|
|
2896
|
+
case "copy-texture-to-texture":
|
|
2897
|
+
Er(this.device, i.options);
|
|
2898
|
+
break;
|
|
2899
|
+
// case 'clear-texture':
|
|
2900
|
+
// _clearTexture(this.device, command.options);
|
|
2901
|
+
// break;
|
|
2902
|
+
default:
|
|
2903
|
+
throw new Error(i.name);
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
function _r(r, t) {
|
|
2908
|
+
const e = t.sourceBuffer, i = t.destinationBuffer;
|
|
2909
|
+
r.gl.bindBuffer(36662, e.handle), r.gl.bindBuffer(36663, i.handle), r.gl.copyBufferSubData(36662, 36663, t.sourceOffset ?? 0, t.destinationOffset ?? 0, t.size), r.gl.bindBuffer(36662, null), r.gl.bindBuffer(36663, null);
|
|
2910
|
+
}
|
|
2911
|
+
function Pr(r, t) {
|
|
2912
|
+
throw new Error("Not implemented");
|
|
2913
|
+
}
|
|
2914
|
+
function Ar(r, t) {
|
|
2915
|
+
const {
|
|
2916
|
+
/** Texture to copy to/from. */
|
|
2917
|
+
sourceTexture: e,
|
|
2918
|
+
/** Mip-map level of the texture to copy to/from. (Default 0) */
|
|
2919
|
+
mipLevel: i = 0,
|
|
2920
|
+
/** Defines which aspects of the texture to copy to/from. */
|
|
2921
|
+
aspect: n = "all",
|
|
2922
|
+
/** Width to copy */
|
|
2923
|
+
width: s = t.sourceTexture.width,
|
|
2924
|
+
/** Height to copy */
|
|
2925
|
+
height: a = t.sourceTexture.height,
|
|
2926
|
+
depthOrArrayLayers: c = 0,
|
|
2927
|
+
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
|
|
2928
|
+
origin: l = [0, 0],
|
|
2929
|
+
/** Destination buffer */
|
|
2930
|
+
destinationBuffer: u,
|
|
2931
|
+
/** Offset, in bytes, from the beginning of the buffer to the start of the image data (default 0) */
|
|
2932
|
+
byteOffset: h = 0,
|
|
2933
|
+
/**
|
|
2934
|
+
* The stride, in bytes, between the beginning of each block row and the subsequent block row.
|
|
2935
|
+
* Required if there are multiple block rows (i.e. the copy height or depth is more than one block).
|
|
2936
|
+
*/
|
|
2937
|
+
bytesPerRow: f,
|
|
2938
|
+
/**
|
|
2939
|
+
* Number of block rows per single image of the texture.
|
|
2940
|
+
* rowsPerImage × bytesPerRow is the stride, in bytes, between the beginning of each image of data and the subsequent image.
|
|
2941
|
+
* Required if there are multiple images (i.e. the copy depth is more than one).
|
|
2942
|
+
*/
|
|
2943
|
+
rowsPerImage: g
|
|
2944
|
+
} = t;
|
|
2945
|
+
if (n !== "all")
|
|
2946
|
+
throw new Error("aspect not supported in WebGL");
|
|
2947
|
+
if (i !== 0 || c !== 0 || f || g)
|
|
2948
|
+
throw new Error("not implemented");
|
|
2949
|
+
const { framebuffer: d, destroyFramebuffer: m } = Ue(e);
|
|
2950
|
+
let p;
|
|
2951
|
+
try {
|
|
2952
|
+
const w = u, v = s || d.width, A = a || d.height, me = $e(d.colorAttachments[0].texture.props.format), He = me.format, qe = me.type;
|
|
2953
|
+
r.gl.bindBuffer(35051, w.handle), p = r.gl.bindFramebuffer(36160, d.handle), r.gl.readPixels(l[0], l[1], v, A, He, qe, h);
|
|
2954
|
+
} finally {
|
|
2955
|
+
r.gl.bindBuffer(35051, null), p !== void 0 && r.gl.bindFramebuffer(36160, p), m && d.destroy();
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
function Er(r, t) {
|
|
2959
|
+
const {
|
|
2960
|
+
/** Texture to copy to/from. */
|
|
2961
|
+
sourceTexture: e,
|
|
2962
|
+
/** Mip-map level of the texture to copy to (Default 0) */
|
|
2963
|
+
destinationMipLevel: i = 0,
|
|
2964
|
+
/** Defines which aspects of the texture to copy to/from. */
|
|
2965
|
+
// aspect = 'all',
|
|
2966
|
+
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy from. */
|
|
2967
|
+
origin: n = [0, 0],
|
|
2968
|
+
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to. */
|
|
2969
|
+
destinationOrigin: s = [0, 0],
|
|
2970
|
+
/** Texture to copy to/from. */
|
|
2971
|
+
destinationTexture: a
|
|
2972
|
+
/** Mip-map level of the texture to copy to/from. (Default 0) */
|
|
2973
|
+
// destinationMipLevel = options.mipLevel,
|
|
2974
|
+
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
|
|
2975
|
+
// destinationOrigin = [0, 0],
|
|
2976
|
+
/** Defines which aspects of the texture to copy to/from. */
|
|
2977
|
+
// destinationAspect = options.aspect,
|
|
2978
|
+
} = t;
|
|
2979
|
+
let {
|
|
2980
|
+
width: c = t.destinationTexture.width,
|
|
2981
|
+
height: l = t.destinationTexture.height
|
|
2982
|
+
// depthOrArrayLayers = 0
|
|
2983
|
+
} = t;
|
|
2984
|
+
const { framebuffer: u, destroyFramebuffer: h } = Ue(e), [f, g] = n, [d, m, p] = s, w = r.gl.bindFramebuffer(36160, u.handle);
|
|
2985
|
+
let v, A;
|
|
2986
|
+
if (a instanceof V)
|
|
2987
|
+
v = a, c = Number.isFinite(c) ? c : v.width, l = Number.isFinite(l) ? l : v.height, v._bind(0), A = v.glTarget;
|
|
2988
|
+
else
|
|
2989
|
+
throw new Error("invalid destination");
|
|
2990
|
+
switch (A) {
|
|
2991
|
+
case 3553:
|
|
2992
|
+
case 34067:
|
|
2993
|
+
r.gl.copyTexSubImage2D(A, i, d, m, f, g, c, l);
|
|
2994
|
+
break;
|
|
2995
|
+
case 35866:
|
|
2996
|
+
case 32879:
|
|
2997
|
+
r.gl.copyTexSubImage3D(A, i, d, m, p, f, g, c, l);
|
|
2998
|
+
break;
|
|
2999
|
+
}
|
|
3000
|
+
v && v._unbind(), r.gl.bindFramebuffer(36160, w), h && u.destroy();
|
|
3001
|
+
}
|
|
3002
|
+
function Ue(r) {
|
|
3003
|
+
if (r instanceof L) {
|
|
3004
|
+
const { width: t, height: e, id: i } = r;
|
|
3005
|
+
return { framebuffer: r.device.createFramebuffer({
|
|
3006
|
+
id: `framebuffer-for-${i}`,
|
|
3007
|
+
width: t,
|
|
3008
|
+
height: e,
|
|
3009
|
+
colorAttachments: [r]
|
|
3010
|
+
}), destroyFramebuffer: !0 };
|
|
3011
|
+
}
|
|
3012
|
+
return { framebuffer: r, destroyFramebuffer: !1 };
|
|
3013
|
+
}
|
|
3014
|
+
const Lr = [1, 2, 4, 8];
|
|
3015
|
+
class Br extends ie {
|
|
3016
|
+
constructor(e, i) {
|
|
3017
|
+
var a;
|
|
3018
|
+
super(e, i);
|
|
3019
|
+
o(this, "device");
|
|
3020
|
+
o(this, "handle", null);
|
|
3021
|
+
/** Parameters that should be applied before each draw call */
|
|
3022
|
+
o(this, "glParameters", {});
|
|
3023
|
+
this.device = e;
|
|
3024
|
+
let n;
|
|
3025
|
+
if (!((a = i == null ? void 0 : i.parameters) != null && a.viewport))
|
|
3026
|
+
if (i != null && i.framebuffer) {
|
|
3027
|
+
const { width: c, height: l } = i.framebuffer;
|
|
3028
|
+
n = [0, 0, c, l];
|
|
3029
|
+
} else {
|
|
3030
|
+
const [c, l] = e.getDefaultCanvasContext().getDrawingBufferSize();
|
|
3031
|
+
n = [0, 0, c, l];
|
|
3032
|
+
}
|
|
3033
|
+
this.device.pushState(), this.setParameters({ viewport: n, ...this.props.parameters });
|
|
3034
|
+
const s = this.props.framebuffer;
|
|
3035
|
+
if (this.props.framebuffer && (s != null && s.handle)) {
|
|
3036
|
+
const c = this.props.framebuffer.colorAttachments.map((l, u) => 36064 + u);
|
|
3037
|
+
this.device.gl.drawBuffers(c);
|
|
3038
|
+
} else
|
|
3039
|
+
this.device.gl.drawBuffers([1029]);
|
|
3040
|
+
this.clear();
|
|
3041
|
+
}
|
|
3042
|
+
end() {
|
|
3043
|
+
this.device.popState();
|
|
3044
|
+
}
|
|
3045
|
+
pushDebugGroup(e) {
|
|
3046
|
+
}
|
|
3047
|
+
popDebugGroup() {
|
|
3048
|
+
}
|
|
3049
|
+
insertDebugMarker(e) {
|
|
3050
|
+
}
|
|
3051
|
+
// beginOcclusionQuery(queryIndex: number): void;
|
|
3052
|
+
// endOcclusionQuery(): void;
|
|
3053
|
+
// executeBundles(bundles: Iterable<GPURenderBundle>): void;
|
|
3054
|
+
/**
|
|
3055
|
+
* Maps RenderPass parameters to GL parameters
|
|
3056
|
+
*/
|
|
3057
|
+
setParameters(e = {}) {
|
|
3058
|
+
const i = { ...this.glParameters };
|
|
3059
|
+
i.framebuffer = this.props.framebuffer || null, this.props.depthReadOnly && (i.depthMask = !this.props.depthReadOnly), i.stencilMask = this.props.stencilReadOnly ? 0 : 1, i[35977] = this.props.discard, e.viewport && (e.viewport.length >= 6 ? (i.viewport = e.viewport.slice(0, 4), i.depthRange = [
|
|
3060
|
+
e.viewport[4],
|
|
3061
|
+
e.viewport[5]
|
|
3062
|
+
]) : i.viewport = e.viewport), e.scissorRect && (i.scissorTest = !0, i.scissor = e.scissorRect), e.blendConstant && (i.blendColor = e.blendConstant), e.stencilReference && (console.warn("RenderPassParameters.stencilReference not yet implemented in WebGL"), i[2967] = e.stencilReference), "colorMask" in e && (i.colorMask = Lr.map((n) => !!(n & e.colorMask))), this.glParameters = i, W(this.device.gl, i);
|
|
3063
|
+
}
|
|
3064
|
+
beginOcclusionQuery(e) {
|
|
3065
|
+
const i = this.props.occlusionQuerySet;
|
|
3066
|
+
i == null || i.beginOcclusionQuery();
|
|
3067
|
+
}
|
|
3068
|
+
endOcclusionQuery() {
|
|
3069
|
+
const e = this.props.occlusionQuerySet;
|
|
3070
|
+
e == null || e.endOcclusionQuery();
|
|
3071
|
+
}
|
|
3072
|
+
// PRIVATE
|
|
3073
|
+
/**
|
|
3074
|
+
* Optionally clears depth, color and stencil buffers based on parameters
|
|
3075
|
+
*/
|
|
3076
|
+
clear() {
|
|
3077
|
+
const e = { ...this.glParameters };
|
|
3078
|
+
let i = 0;
|
|
3079
|
+
this.props.clearColors && this.props.clearColors.forEach((n, s) => {
|
|
3080
|
+
n && this.clearColorBuffer(s, n);
|
|
3081
|
+
}), this.props.clearColor !== !1 && this.props.clearColors === void 0 && (i |= 16384, e.clearColor = this.props.clearColor), this.props.clearDepth !== !1 && (i |= 256, e.clearDepth = this.props.clearDepth), this.props.clearStencil !== !1 && (i |= 1024, e.clearStencil = this.props.clearStencil), i !== 0 && U(this.device.gl, e, () => {
|
|
3082
|
+
this.device.gl.clear(i);
|
|
3083
|
+
});
|
|
3084
|
+
}
|
|
3085
|
+
/**
|
|
3086
|
+
* WebGL2 - clear a specific color buffer
|
|
3087
|
+
*/
|
|
3088
|
+
clearColorBuffer(e = 0, i = [0, 0, 0, 0]) {
|
|
3089
|
+
U(this.device.gl, { framebuffer: this.props.framebuffer }, () => {
|
|
3090
|
+
switch (i.constructor) {
|
|
3091
|
+
case Int8Array:
|
|
3092
|
+
case Int16Array:
|
|
3093
|
+
case Int32Array:
|
|
3094
|
+
this.device.gl.clearBufferiv(6144, e, i);
|
|
3095
|
+
break;
|
|
3096
|
+
case Uint8Array:
|
|
3097
|
+
case Uint8ClampedArray:
|
|
3098
|
+
case Uint16Array:
|
|
3099
|
+
case Uint32Array:
|
|
3100
|
+
this.device.gl.clearBufferuiv(6144, e, i);
|
|
3101
|
+
break;
|
|
3102
|
+
case Float32Array:
|
|
3103
|
+
this.device.gl.clearBufferfv(6144, e, i);
|
|
3104
|
+
break;
|
|
3105
|
+
default:
|
|
3106
|
+
throw new Error("clearColorBuffer: color must be typed array");
|
|
3107
|
+
}
|
|
3108
|
+
});
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
class De extends ne {
|
|
3112
|
+
constructor(e, i) {
|
|
3113
|
+
super(e, i);
|
|
3114
|
+
o(this, "device");
|
|
3115
|
+
o(this, "handle", null);
|
|
3116
|
+
o(this, "commandBuffer");
|
|
3117
|
+
this.device = e, this.commandBuffer = new Tr(e);
|
|
3118
|
+
}
|
|
3119
|
+
destroy() {
|
|
3120
|
+
}
|
|
3121
|
+
finish() {
|
|
3122
|
+
return this.commandBuffer;
|
|
3123
|
+
}
|
|
3124
|
+
beginRenderPass(e) {
|
|
3125
|
+
return new Br(this.device, e);
|
|
3126
|
+
}
|
|
3127
|
+
beginComputePass(e) {
|
|
3128
|
+
throw new Error("ComputePass not supported in WebGL");
|
|
3129
|
+
}
|
|
3130
|
+
copyBufferToBuffer(e) {
|
|
3131
|
+
this.commandBuffer.commands.push({ name: "copy-buffer-to-buffer", options: e });
|
|
3132
|
+
}
|
|
3133
|
+
copyBufferToTexture(e) {
|
|
3134
|
+
this.commandBuffer.commands.push({ name: "copy-buffer-to-texture", options: e });
|
|
3135
|
+
}
|
|
3136
|
+
copyTextureToBuffer(e) {
|
|
3137
|
+
this.commandBuffer.commands.push({ name: "copy-texture-to-buffer", options: e });
|
|
3138
|
+
}
|
|
3139
|
+
copyTextureToTexture(e) {
|
|
3140
|
+
this.commandBuffer.commands.push({ name: "copy-texture-to-texture", options: e });
|
|
3141
|
+
}
|
|
3142
|
+
// clearTexture(options: ClearTextureOptions): void {
|
|
3143
|
+
// this.commandBuffer.commands.push({name: 'copy-texture-to-texture', options});
|
|
3144
|
+
// }
|
|
3145
|
+
pushDebugGroup(e) {
|
|
3146
|
+
}
|
|
3147
|
+
popDebugGroup() {
|
|
3148
|
+
}
|
|
3149
|
+
insertDebugMarker(e) {
|
|
3150
|
+
}
|
|
3151
|
+
resolveQuerySet(e, i, n) {
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
function Cr(r) {
|
|
3155
|
+
const { target: t, source: e, start: i = 0, count: n = 1 } = r, s = e.length, a = n * s;
|
|
3156
|
+
let c = 0;
|
|
3157
|
+
for (let l = i; c < s; c++)
|
|
3158
|
+
t[l++] = e[c];
|
|
3159
|
+
for (; c < a; )
|
|
3160
|
+
c < a - c ? (t.copyWithin(i + c, i, i + c), c *= 2) : (t.copyWithin(i + c, i, i + a - c), c = a);
|
|
3161
|
+
return r.target;
|
|
3162
|
+
}
|
|
3163
|
+
class be extends ae {
|
|
3164
|
+
// Create a VertexArray
|
|
3165
|
+
constructor(e, i) {
|
|
3166
|
+
super(e, i);
|
|
3167
|
+
o(this, "device");
|
|
3168
|
+
o(this, "handle");
|
|
3169
|
+
/** Attribute 0 buffer constant */
|
|
3170
|
+
o(this, "buffer", null);
|
|
3171
|
+
o(this, "bufferValue", null);
|
|
3172
|
+
this.device = e, this.handle = this.device.gl.createVertexArray();
|
|
3173
|
+
}
|
|
3174
|
+
get [Symbol.toStringTag]() {
|
|
3175
|
+
return "VertexArray";
|
|
3176
|
+
}
|
|
3177
|
+
/** * Attribute 0 can not be disable on most desktop OpenGL based browsers */
|
|
3178
|
+
static isConstantAttributeZeroSupported(e) {
|
|
3179
|
+
return ft() === "Chrome";
|
|
3180
|
+
}
|
|
3181
|
+
destroy() {
|
|
3182
|
+
var e;
|
|
3183
|
+
super.destroy(), this.buffer && ((e = this.buffer) == null || e.destroy()), this.handle && (this.device.gl.deleteVertexArray(this.handle), this.handle = void 0);
|
|
3184
|
+
}
|
|
3185
|
+
/**
|
|
3186
|
+
// Set (bind/unbind) an elements buffer, for indexed rendering.
|
|
3187
|
+
// Must be a Buffer bound to GL.ELEMENT_ARRAY_BUFFER or null. Constants not supported
|
|
3188
|
+
*
|
|
3189
|
+
* @param elementBuffer
|
|
3190
|
+
*/
|
|
3191
|
+
setIndexBuffer(e) {
|
|
3192
|
+
const i = e;
|
|
3193
|
+
if (i && i.glTarget !== 34963)
|
|
3194
|
+
throw new Error("Use .setBuffer()");
|
|
3195
|
+
this.device.gl.bindVertexArray(this.handle), this.device.gl.bindBuffer(34963, i ? i.handle : null), this.indexBuffer = i, this.device.gl.bindVertexArray(null);
|
|
3196
|
+
}
|
|
3197
|
+
/** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
|
|
3198
|
+
setBuffer(e, i) {
|
|
3199
|
+
const n = i;
|
|
3200
|
+
if (n.glTarget === 34963)
|
|
3201
|
+
throw new Error("Use .setIndexBuffer()");
|
|
3202
|
+
const { size: s, type: a, stride: c, offset: l, normalized: u, integer: h, divisor: f } = this._getAccessor(e);
|
|
3203
|
+
this.device.gl.bindVertexArray(this.handle), this.device.gl.bindBuffer(34962, n.handle), h ? this.device.gl.vertexAttribIPointer(e, s, a, c, l) : this.device.gl.vertexAttribPointer(e, s, a, u, c, l), this.device.gl.bindBuffer(34962, null), this.device.gl.enableVertexAttribArray(e), this.device.gl.vertexAttribDivisor(e, f || 0), this.attributes[e] = n, this.device.gl.bindVertexArray(null);
|
|
3204
|
+
}
|
|
3205
|
+
/** Set a location in vertex attributes array to a constant value, disables the location */
|
|
3206
|
+
setConstantWebGL(e, i) {
|
|
3207
|
+
this._enable(e, !1), this.attributes[e] = i;
|
|
3208
|
+
}
|
|
3209
|
+
bindBeforeRender() {
|
|
3210
|
+
this.device.gl.bindVertexArray(this.handle), this._applyConstantAttributes();
|
|
3211
|
+
}
|
|
3212
|
+
unbindAfterRender() {
|
|
3213
|
+
this.device.gl.bindVertexArray(null);
|
|
3214
|
+
}
|
|
3215
|
+
// Internal methods
|
|
3216
|
+
/**
|
|
3217
|
+
* Constant attributes need to be reset before every draw call
|
|
3218
|
+
* Any attribute that is disabled in the current vertex array object
|
|
3219
|
+
* is read from the context's global constant value for that attribute location.
|
|
3220
|
+
* @note Constant attributes are only supported in WebGL, not in WebGPU
|
|
3221
|
+
*/
|
|
3222
|
+
_applyConstantAttributes() {
|
|
3223
|
+
for (let e = 0; e < this.maxVertexAttributes; ++e) {
|
|
3224
|
+
const i = this.attributes[e];
|
|
3225
|
+
ArrayBuffer.isView(i) && this.device.setConstantAttributeWebGL(e, i);
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
/**
|
|
3229
|
+
* Set a location in vertex attributes array to a buffer, enables the location, sets divisor
|
|
3230
|
+
* @note requires vertex array to be bound
|
|
3231
|
+
*/
|
|
3232
|
+
// protected _setAttributeLayout(location: number): void {
|
|
3233
|
+
// const {size, type, stride, offset, normalized, integer, divisor} = this._getAccessor(location);
|
|
3234
|
+
// // WebGL2 supports *integer* data formats, i.e. GPU will see integer values
|
|
3235
|
+
// if (integer) {
|
|
3236
|
+
// this.device.gl.vertexAttribIPointer(location, size, type, stride, offset);
|
|
3237
|
+
// } else {
|
|
3238
|
+
// // Attaches ARRAY_BUFFER with specified buffer format to location
|
|
3239
|
+
// this.device.gl.vertexAttribPointer(location, size, type, normalized, stride, offset);
|
|
3240
|
+
// }
|
|
3241
|
+
// this.device.gl.vertexAttribDivisor(location, divisor || 0);
|
|
3242
|
+
// }
|
|
3243
|
+
/** Get an accessor from the */
|
|
3244
|
+
_getAccessor(e) {
|
|
3245
|
+
const i = this.attributeInfos[e];
|
|
3246
|
+
if (!i)
|
|
3247
|
+
throw new Error(`Unknown attribute location ${e}`);
|
|
3248
|
+
const n = Oe(i.bufferDataType);
|
|
3249
|
+
return {
|
|
3250
|
+
size: i.bufferComponents,
|
|
3251
|
+
type: n,
|
|
3252
|
+
stride: i.byteStride,
|
|
3253
|
+
offset: i.byteOffset,
|
|
3254
|
+
normalized: i.normalized,
|
|
3255
|
+
// it is the shader attribute declaration, not the vertex memory format,
|
|
3256
|
+
// that determines if the data in the buffer will be treated as integers.
|
|
3257
|
+
//
|
|
3258
|
+
// Also note that WebGL supports assigning non-normalized integer data to floating point attributes,
|
|
3259
|
+
// but as far as we can tell, WebGPU does not.
|
|
3260
|
+
integer: i.integer,
|
|
3261
|
+
divisor: i.stepMode === "instance" ? 1 : 0
|
|
3262
|
+
};
|
|
3263
|
+
}
|
|
3264
|
+
/**
|
|
3265
|
+
* Enabling an attribute location makes it reference the currently bound buffer
|
|
3266
|
+
* Disabling an attribute location makes it reference the global constant value
|
|
3267
|
+
* TODO - handle single values for size 1 attributes?
|
|
3268
|
+
* TODO - convert classic arrays based on known type?
|
|
3269
|
+
*/
|
|
3270
|
+
_enable(e, i = !0) {
|
|
3271
|
+
const s = be.isConstantAttributeZeroSupported(this.device) || e !== 0;
|
|
3272
|
+
(i || s) && (e = Number(e), this.device.gl.bindVertexArray(this.handle), i ? this.device.gl.enableVertexAttribArray(e) : this.device.gl.disableVertexAttribArray(e), this.device.gl.bindVertexArray(null));
|
|
3273
|
+
}
|
|
3274
|
+
/**
|
|
3275
|
+
* Provide a means to create a buffer that is equivalent to a constant.
|
|
3276
|
+
* NOTE: Desktop OpenGL cannot disable attribute 0.
|
|
3277
|
+
* https://stackoverflow.com/questions/20305231/webgl-warning-attribute-0-is-disabled-
|
|
3278
|
+
* this-has-significant-performance-penalty
|
|
3279
|
+
*/
|
|
3280
|
+
getConstantBuffer(e, i) {
|
|
3281
|
+
const n = Fr(i), s = n.byteLength * e, a = n.length * e;
|
|
3282
|
+
if (this.buffer && s !== this.buffer.byteLength)
|
|
3283
|
+
throw new Error(`Buffer size is immutable, byte length ${s} !== ${this.buffer.byteLength}.`);
|
|
3284
|
+
let c = !this.buffer;
|
|
3285
|
+
if (this.buffer = this.buffer || this.device.createBuffer({ byteLength: s }), c || (c = !kr(n, this.bufferValue)), c) {
|
|
3286
|
+
const l = ot(i.constructor, a);
|
|
3287
|
+
Cr({ target: l, source: n, start: 0, count: a }), this.buffer.write(l), this.bufferValue = i;
|
|
3288
|
+
}
|
|
3289
|
+
return this.buffer;
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
function Fr(r) {
|
|
3293
|
+
return Array.isArray(r) ? new Float32Array(r) : r;
|
|
3294
|
+
}
|
|
3295
|
+
function kr(r, t) {
|
|
3296
|
+
if (!r || !t || r.length !== t.length || r.constructor !== t.constructor)
|
|
3297
|
+
return !1;
|
|
3298
|
+
for (let e = 0; e < r.length; ++e)
|
|
3299
|
+
if (r[e] !== t[e])
|
|
3300
|
+
return !1;
|
|
3301
|
+
return !0;
|
|
3302
|
+
}
|
|
3303
|
+
class Dr extends oe {
|
|
3304
|
+
constructor(e, i) {
|
|
3305
|
+
super(e, i);
|
|
3306
|
+
o(this, "device");
|
|
3307
|
+
o(this, "gl");
|
|
3308
|
+
o(this, "handle");
|
|
3309
|
+
/**
|
|
3310
|
+
* NOTE: The Model already has this information while drawing, but
|
|
3311
|
+
* TransformFeedback currently needs it internally, to look up
|
|
3312
|
+
* varying information outside of a draw() call.
|
|
3313
|
+
*/
|
|
3314
|
+
o(this, "layout");
|
|
3315
|
+
o(this, "buffers", {});
|
|
3316
|
+
o(this, "unusedBuffers", {});
|
|
3317
|
+
/**
|
|
3318
|
+
* Allows us to avoid a Chrome bug where a buffer that is already bound to a
|
|
3319
|
+
* different target cannot be bound to 'TRANSFORM_FEEDBACK_BUFFER' target.
|
|
3320
|
+
* This a major workaround, see: https://github.com/KhronosGroup/WebGL/issues/2346
|
|
3321
|
+
*/
|
|
3322
|
+
o(this, "bindOnUse", !0);
|
|
3323
|
+
o(this, "_bound", !1);
|
|
3324
|
+
this.device = e, this.gl = e.gl, this.handle = this.props.handle || this.gl.createTransformFeedback(), this.layout = this.props.layout, i.buffers && this.setBuffers(i.buffers), Object.seal(this);
|
|
3325
|
+
}
|
|
3326
|
+
destroy() {
|
|
3327
|
+
this.gl.deleteTransformFeedback(this.handle), super.destroy();
|
|
3328
|
+
}
|
|
3329
|
+
begin(e = "point-list") {
|
|
3330
|
+
this.gl.bindTransformFeedback(36386, this.handle), this.bindOnUse && this._bindBuffers(), this.gl.beginTransformFeedback(wr(e));
|
|
3331
|
+
}
|
|
3332
|
+
end() {
|
|
3333
|
+
this.gl.endTransformFeedback(), this.bindOnUse && this._unbindBuffers(), this.gl.bindTransformFeedback(36386, null);
|
|
3334
|
+
}
|
|
3335
|
+
// SUBCLASS
|
|
3336
|
+
setBuffers(e) {
|
|
3337
|
+
this.buffers = {}, this.unusedBuffers = {}, this.bind(() => {
|
|
3338
|
+
for (const i in e)
|
|
3339
|
+
this.setBuffer(i, e[i]);
|
|
3340
|
+
});
|
|
3341
|
+
}
|
|
3342
|
+
setBuffer(e, i) {
|
|
3343
|
+
const n = this._getVaryingIndex(e), { buffer: s, byteLength: a, byteOffset: c } = this._getBufferRange(i);
|
|
3344
|
+
if (n < 0) {
|
|
3345
|
+
this.unusedBuffers[e] = s, b.warn(`${this.id} unusedBuffers varying buffer ${e}`)();
|
|
3346
|
+
return;
|
|
3347
|
+
}
|
|
3348
|
+
this.buffers[n] = { buffer: s, byteLength: a, byteOffset: c }, this.bindOnUse || this._bindBuffer(n, s, c, a);
|
|
3349
|
+
}
|
|
3350
|
+
getBuffer(e) {
|
|
3351
|
+
if (Ge(e))
|
|
3352
|
+
return this.buffers[e] || null;
|
|
3353
|
+
const i = this._getVaryingIndex(e);
|
|
3354
|
+
return i >= 0 ? this.buffers[i] : null;
|
|
3355
|
+
}
|
|
3356
|
+
bind(e = this.handle) {
|
|
3357
|
+
if (typeof e != "function")
|
|
3358
|
+
return this.gl.bindTransformFeedback(36386, e), this;
|
|
3359
|
+
let i;
|
|
3360
|
+
return this._bound ? i = e() : (this.gl.bindTransformFeedback(36386, this.handle), this._bound = !0, i = e(), this._bound = !1, this.gl.bindTransformFeedback(36386, null)), i;
|
|
3361
|
+
}
|
|
3362
|
+
unbind() {
|
|
3363
|
+
this.bind(null);
|
|
3364
|
+
}
|
|
3365
|
+
// PRIVATE METHODS
|
|
3366
|
+
/** Extract offsets for bindBufferRange */
|
|
3367
|
+
_getBufferRange(e) {
|
|
3368
|
+
if (e instanceof z)
|
|
3369
|
+
return { buffer: e, byteOffset: 0, byteLength: e.byteLength };
|
|
3370
|
+
const { buffer: i, byteOffset: n = 0, byteLength: s = e.buffer.byteLength } = e;
|
|
3371
|
+
return { buffer: i, byteOffset: n, byteLength: s };
|
|
3372
|
+
}
|
|
3373
|
+
_getVaryingIndex(e) {
|
|
3374
|
+
if (Ge(e))
|
|
3375
|
+
return Number(e);
|
|
3376
|
+
for (const i of this.layout.varyings || [])
|
|
3377
|
+
if (e === i.name)
|
|
3378
|
+
return i.location;
|
|
3379
|
+
return -1;
|
|
3380
|
+
}
|
|
3381
|
+
/**
|
|
3382
|
+
* Need to avoid chrome bug where buffer that is already bound to a different target
|
|
3383
|
+
* cannot be bound to 'TRANSFORM_FEEDBACK_BUFFER' target.
|
|
3384
|
+
*/
|
|
3385
|
+
_bindBuffers() {
|
|
3386
|
+
for (const e in this.buffers) {
|
|
3387
|
+
const { buffer: i, byteLength: n, byteOffset: s } = this._getBufferRange(this.buffers[e]);
|
|
3388
|
+
this._bindBuffer(Number(e), i, s, n);
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
_unbindBuffers() {
|
|
3392
|
+
for (const e in this.buffers)
|
|
3393
|
+
this.gl.bindBufferBase(35982, Number(e), null);
|
|
3394
|
+
}
|
|
3395
|
+
_bindBuffer(e, i, n = 0, s) {
|
|
3396
|
+
const a = i && i.handle;
|
|
3397
|
+
!a || s === void 0 ? this.gl.bindBufferBase(35982, e, a) : this.gl.bindBufferRange(35982, e, a, n, s);
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
function Ge(r) {
|
|
3401
|
+
return typeof r == "number" ? Number.isInteger(r) : /^\d+$/.test(r);
|
|
3402
|
+
}
|
|
3403
|
+
class Gr extends ce {
|
|
3404
|
+
// Create a query class
|
|
3405
|
+
constructor(e, i) {
|
|
3406
|
+
super(e, i);
|
|
3407
|
+
o(this, "device");
|
|
3408
|
+
o(this, "handle");
|
|
3409
|
+
o(this, "target", null);
|
|
3410
|
+
o(this, "_queryPending", !1);
|
|
3411
|
+
o(this, "_pollingPromise", null);
|
|
3412
|
+
if (this.device = e, i.count > 1)
|
|
3413
|
+
throw new Error("WebGL QuerySet can only have one value");
|
|
3414
|
+
const n = this.device.gl.createQuery();
|
|
3415
|
+
if (!n)
|
|
3416
|
+
throw new Error("WebGL query not supported");
|
|
3417
|
+
this.handle = n, Object.seal(this);
|
|
3418
|
+
}
|
|
3419
|
+
get [Symbol.toStringTag]() {
|
|
3420
|
+
return "Query";
|
|
3421
|
+
}
|
|
3422
|
+
destroy() {
|
|
3423
|
+
this.device.gl.deleteQuery(this.handle);
|
|
3424
|
+
}
|
|
3425
|
+
// FOR RENDER PASS AND COMMAND ENCODER
|
|
3426
|
+
/**
|
|
3427
|
+
* Shortcut for timer query (dependent on extension in both WebGL1 and 2)
|
|
3428
|
+
* Measures GPU time delta between this call and a matching `end` call in the
|
|
3429
|
+
* GPU instruction stream.
|
|
3430
|
+
*/
|
|
3431
|
+
beginTimestampQuery() {
|
|
3432
|
+
return this._begin(35007);
|
|
3433
|
+
}
|
|
3434
|
+
endTimestampQuery() {
|
|
3435
|
+
this._end();
|
|
3436
|
+
}
|
|
3437
|
+
// Shortcut for occlusion queries
|
|
3438
|
+
beginOcclusionQuery(e) {
|
|
3439
|
+
return this._begin(e != null && e.conservative ? 36202 : 35887);
|
|
3440
|
+
}
|
|
3441
|
+
endOcclusionQuery() {
|
|
3442
|
+
this._end();
|
|
3443
|
+
}
|
|
3444
|
+
// Shortcut for transformFeedbackQuery
|
|
3445
|
+
beginTransformFeedbackQuery() {
|
|
3446
|
+
return this._begin(35976);
|
|
3447
|
+
}
|
|
3448
|
+
endTransformFeedbackQuery() {
|
|
3449
|
+
this._end();
|
|
3450
|
+
}
|
|
3451
|
+
async resolveQuery() {
|
|
3452
|
+
return [await this.pollQuery()];
|
|
3453
|
+
}
|
|
3454
|
+
// PRIVATE METHODS
|
|
3455
|
+
/**
|
|
3456
|
+
* Due to OpenGL API limitations, after calling `begin()` on one Query
|
|
3457
|
+
* instance, `end()` must be called on that same instance before
|
|
3458
|
+
* calling `begin()` on another query. While there can be multiple
|
|
3459
|
+
* outstanding queries representing disjoint `begin()`/`end()` intervals.
|
|
3460
|
+
* It is not possible to interleave or overlap `begin` and `end` calls.
|
|
3461
|
+
*/
|
|
3462
|
+
_begin(e) {
|
|
3463
|
+
this._queryPending || (this.target = e, this.device.gl.beginQuery(this.target, this.handle));
|
|
3464
|
+
}
|
|
3465
|
+
// ends the current query
|
|
3466
|
+
_end() {
|
|
3467
|
+
this._queryPending || this.target && (this.device.gl.endQuery(this.target), this.target = null, this._queryPending = !0);
|
|
3468
|
+
}
|
|
3469
|
+
// Returns true if the query result is available
|
|
3470
|
+
isResultAvailable() {
|
|
3471
|
+
if (!this._queryPending)
|
|
3472
|
+
return !1;
|
|
3473
|
+
const e = this.device.gl.getQueryParameter(this.handle, 34919);
|
|
3474
|
+
return e && (this._queryPending = !1), e;
|
|
3475
|
+
}
|
|
3476
|
+
// Timing query is disjoint, i.e. results are invalid
|
|
3477
|
+
isTimerDisjoint() {
|
|
3478
|
+
return this.device.gl.getParameter(36795);
|
|
3479
|
+
}
|
|
3480
|
+
// Returns query result.
|
|
3481
|
+
getResult() {
|
|
3482
|
+
return this.device.gl.getQueryParameter(this.handle, 34918);
|
|
3483
|
+
}
|
|
3484
|
+
// Returns the query result, converted to milliseconds to match JavaScript conventions.
|
|
3485
|
+
getTimerMilliseconds() {
|
|
3486
|
+
return this.getResult() / 1e6;
|
|
3487
|
+
}
|
|
3488
|
+
// Polls the query
|
|
3489
|
+
pollQuery(e = Number.POSITIVE_INFINITY) {
|
|
3490
|
+
if (this._pollingPromise)
|
|
3491
|
+
return this._pollingPromise;
|
|
3492
|
+
let i = 0;
|
|
3493
|
+
return this._pollingPromise = new Promise((n, s) => {
|
|
3494
|
+
const a = () => {
|
|
3495
|
+
this.isResultAvailable() ? (n(this.getResult()), this._pollingPromise = null) : i++ > e ? (s("Timed out"), this._pollingPromise = null) : requestAnimationFrame(a);
|
|
3496
|
+
};
|
|
3497
|
+
requestAnimationFrame(a);
|
|
3498
|
+
}), this._pollingPromise;
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
function Ne(r) {
|
|
3502
|
+
switch (r) {
|
|
3503
|
+
case 6406:
|
|
3504
|
+
case 33326:
|
|
3505
|
+
case 6403:
|
|
3506
|
+
case 36244:
|
|
3507
|
+
return 1;
|
|
3508
|
+
case 33339:
|
|
3509
|
+
case 33340:
|
|
3510
|
+
case 33328:
|
|
3511
|
+
case 33320:
|
|
3512
|
+
case 33319:
|
|
3513
|
+
return 2;
|
|
3514
|
+
case 6407:
|
|
3515
|
+
case 36248:
|
|
3516
|
+
case 34837:
|
|
3517
|
+
return 3;
|
|
3518
|
+
case 6408:
|
|
3519
|
+
case 36249:
|
|
3520
|
+
case 34836:
|
|
3521
|
+
return 4;
|
|
3522
|
+
// TODO: Add support for additional WebGL2 formats
|
|
3523
|
+
default:
|
|
3524
|
+
return 0;
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
function Mr(r) {
|
|
3528
|
+
switch (r) {
|
|
3529
|
+
case 5121:
|
|
3530
|
+
return 1;
|
|
3531
|
+
case 33635:
|
|
3532
|
+
case 32819:
|
|
3533
|
+
case 32820:
|
|
3534
|
+
return 2;
|
|
3535
|
+
case 5126:
|
|
3536
|
+
return 4;
|
|
3537
|
+
// TODO: Add support for additional WebGL2 types
|
|
3538
|
+
default:
|
|
3539
|
+
return 0;
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
function Wr(r) {
|
|
3543
|
+
return Rr[r];
|
|
3544
|
+
}
|
|
3545
|
+
const Rr = {
|
|
3546
|
+
5124: "sint32",
|
|
3547
|
+
5125: "uint32",
|
|
3548
|
+
5122: "sint16",
|
|
3549
|
+
5123: "uint16",
|
|
3550
|
+
5120: "sint8",
|
|
3551
|
+
5121: "uint8",
|
|
3552
|
+
5126: "float32",
|
|
3553
|
+
5131: "float16",
|
|
3554
|
+
33635: "uint16",
|
|
3555
|
+
32819: "uint16",
|
|
3556
|
+
32820: "uint16",
|
|
3557
|
+
33640: "uint32",
|
|
3558
|
+
35899: "uint32",
|
|
3559
|
+
35902: "uint32",
|
|
3560
|
+
34042: "uint32",
|
|
3561
|
+
36269: "uint32"
|
|
3562
|
+
};
|
|
3563
|
+
function Ir(r, t) {
|
|
3564
|
+
var A;
|
|
3565
|
+
const {
|
|
3566
|
+
sourceX: e = 0,
|
|
3567
|
+
sourceY: i = 0,
|
|
3568
|
+
sourceAttachment: n = 0
|
|
3569
|
+
// TODO - support gl.readBuffer
|
|
3570
|
+
} = t || {};
|
|
3571
|
+
let {
|
|
3572
|
+
target: s = null,
|
|
3573
|
+
// following parameters are auto deduced if not provided
|
|
3574
|
+
sourceWidth: a,
|
|
3575
|
+
sourceHeight: c,
|
|
3576
|
+
sourceDepth: l,
|
|
3577
|
+
sourceFormat: u,
|
|
3578
|
+
sourceType: h
|
|
3579
|
+
} = t || {};
|
|
3580
|
+
const { framebuffer: f, deleteFramebuffer: g } = Xe(r), { gl: d, handle: m } = f;
|
|
3581
|
+
a || (a = f.width), c || (c = f.height);
|
|
3582
|
+
const p = (A = f.colorAttachments[n]) == null ? void 0 : A.texture;
|
|
3583
|
+
if (!p)
|
|
3584
|
+
throw new Error(`Invalid framebuffer attachment ${n}`);
|
|
3585
|
+
l = (p == null ? void 0 : p.depth) || 1, u || (u = (p == null ? void 0 : p.glFormat) || 6408), h || (h = (p == null ? void 0 : p.glType) || 5121), s = zr(s, h, u, a, c);
|
|
3586
|
+
const w = ct(s);
|
|
3587
|
+
h = h || or(w);
|
|
3588
|
+
const v = d.bindFramebuffer(36160, m);
|
|
3589
|
+
return d.readBuffer(36064 + n), d.readPixels(e, i, a, c, u, h, s), d.readBuffer(36064), d.bindFramebuffer(36160, v || null), g && f.destroy(), s;
|
|
3590
|
+
}
|
|
3591
|
+
function Or(r, t) {
|
|
3592
|
+
const { target: e, sourceX: i = 0, sourceY: n = 0, sourceFormat: s = 6408, targetByteOffset: a = 0 } = t || {};
|
|
3593
|
+
let { sourceWidth: c, sourceHeight: l, sourceType: u } = t || {};
|
|
3594
|
+
const { framebuffer: h, deleteFramebuffer: f } = Xe(r);
|
|
3595
|
+
c = c || h.width, l = l || h.height;
|
|
3596
|
+
const g = h;
|
|
3597
|
+
u = u || 5121;
|
|
3598
|
+
let d = e;
|
|
3599
|
+
if (!d) {
|
|
3600
|
+
const p = Ne(s), w = Mr(u), v = a + c * l * p * w;
|
|
3601
|
+
d = g.device.createBuffer({ byteLength: v });
|
|
3602
|
+
}
|
|
3603
|
+
const m = r.device.createCommandEncoder();
|
|
3604
|
+
return m.copyTextureToBuffer({
|
|
3605
|
+
sourceTexture: r,
|
|
3606
|
+
width: c,
|
|
3607
|
+
height: l,
|
|
3608
|
+
origin: [i, n],
|
|
3609
|
+
destinationBuffer: d,
|
|
3610
|
+
byteOffset: a
|
|
3611
|
+
}), m.destroy(), f && h.destroy(), d;
|
|
3612
|
+
}
|
|
3613
|
+
function Xe(r) {
|
|
3614
|
+
return r instanceof H ? { framebuffer: r, deleteFramebuffer: !1 } : { framebuffer: $r(r), deleteFramebuffer: !0 };
|
|
3615
|
+
}
|
|
3616
|
+
function $r(r, t) {
|
|
3617
|
+
const { device: e, width: i, height: n, id: s } = r;
|
|
3618
|
+
return e.createFramebuffer({
|
|
3619
|
+
...t,
|
|
3620
|
+
id: `framebuffer-for-${s}`,
|
|
3621
|
+
width: i,
|
|
3622
|
+
height: n,
|
|
3623
|
+
colorAttachments: [r]
|
|
3624
|
+
});
|
|
3625
|
+
}
|
|
3626
|
+
function zr(r, t, e, i, n, s) {
|
|
3627
|
+
if (r)
|
|
3628
|
+
return r;
|
|
3629
|
+
t || (t = 5121);
|
|
3630
|
+
const a = Wr(t), c = lt(a), l = Ne(e);
|
|
3631
|
+
return new c(i * n * l);
|
|
3632
|
+
}
|
|
3633
|
+
class jr extends pe {
|
|
3634
|
+
constructor(e) {
|
|
3635
|
+
var f, g;
|
|
3636
|
+
super({ ...e, id: e.id || qt("webgl-device") });
|
|
3637
|
+
// Public `Device` API
|
|
3638
|
+
/** type of this device */
|
|
3639
|
+
o(this, "type", "webgl");
|
|
3640
|
+
// Use the ! assertion to handle the case where _reuseDevices causes the constructor to return early
|
|
3641
|
+
/** The underlying WebGL context */
|
|
3642
|
+
o(this, "handle");
|
|
3643
|
+
o(this, "features");
|
|
3644
|
+
o(this, "limits");
|
|
3645
|
+
o(this, "info");
|
|
3646
|
+
o(this, "canvasContext");
|
|
3647
|
+
o(this, "preferredColorFormat", "rgba8unorm");
|
|
3648
|
+
o(this, "preferredDepthFormat", "depth24plus");
|
|
3649
|
+
o(this, "commandEncoder");
|
|
3650
|
+
o(this, "lost");
|
|
3651
|
+
o(this, "_resolveContextLost");
|
|
3652
|
+
/** WebGL2 context. */
|
|
3653
|
+
o(this, "gl");
|
|
3654
|
+
/** Store constants */
|
|
3655
|
+
// @ts-ignore TODO fix
|
|
3656
|
+
o(this, "_constants");
|
|
3657
|
+
/** State used by luma.gl classes - TODO - not used? */
|
|
3658
|
+
o(this, "_extensions", {});
|
|
3659
|
+
o(this, "_polyfilled", !1);
|
|
3660
|
+
/** Instance of Spector.js (if initialized) */
|
|
3661
|
+
o(this, "spectorJS");
|
|
3662
|
+
const i = pe._getCanvasContextProps(e);
|
|
3663
|
+
if (!i)
|
|
3664
|
+
throw new Error("WebGLDevice requires props.createCanvasContext to be set");
|
|
3665
|
+
let n = (g = (f = i.canvas) == null ? void 0 : f.gl) == null ? void 0 : g.device;
|
|
3666
|
+
if (n)
|
|
3667
|
+
throw new Error(`WebGL context already attached to device ${n.id}`);
|
|
3668
|
+
this.canvasContext = new Ht(this, i), this.lost = new Promise((d) => {
|
|
3669
|
+
this._resolveContextLost = d;
|
|
3670
|
+
});
|
|
3671
|
+
const s = { ...e.webgl };
|
|
3672
|
+
i.alphaMode === "premultiplied" && (s.premultipliedAlpha = !0), e.powerPreference !== void 0 && (s.powerPreference = e.powerPreference);
|
|
3673
|
+
const c = this.props._handle || At(this.canvasContext.canvas, {
|
|
3674
|
+
onContextLost: (d) => {
|
|
3675
|
+
var m;
|
|
3676
|
+
return (m = this._resolveContextLost) == null ? void 0 : m.call(this, {
|
|
3677
|
+
reason: "destroyed",
|
|
3678
|
+
message: "Entered sleep mode, or too many apps or browser tabs are using the GPU."
|
|
3679
|
+
});
|
|
3680
|
+
},
|
|
3681
|
+
// eslint-disable-next-line no-console
|
|
3682
|
+
onContextRestored: (d) => console.log("WebGL context restored")
|
|
3683
|
+
}, s);
|
|
3684
|
+
if (!c)
|
|
3685
|
+
throw new Error("WebGL context creation failed");
|
|
3686
|
+
if (n = c.device, n) {
|
|
3687
|
+
if (e._reuseDevices)
|
|
3688
|
+
return b.log(1, `Not creating a new Device, instead returning a reference to Device ${n.id} already attached to WebGL context`, n)(), n._reused = !0, n;
|
|
3689
|
+
throw new Error(`WebGL context already attached to device ${n.id}`);
|
|
3690
|
+
}
|
|
3691
|
+
this.handle = c, this.gl = c, this.spectorJS = ut({ ...this.props, gl: this.handle }), this.gl.device = this, this.gl._version = 2, this.info = Et(this.gl, this._extensions), this.limits = new Ut(this.gl), this.features = new Vt(this.gl, this._extensions, this.props._disabledFeatures), this.props._initializeFeatures && this.features.initializeFeatures(), new C(this.gl, {
|
|
3692
|
+
log: (...d) => b.log(1, ...d)()
|
|
3693
|
+
}).trackState(this.gl, { copyState: !1 });
|
|
3694
|
+
const u = e.debugWebGL || e.debug, h = e.debugWebGL;
|
|
3695
|
+
u && (this.gl = ht(this.gl, { debugWebGL: u, traceWebGL: h }), b.warn("WebGL debug mode activated. Performance reduced.")(), e.debugWebGL && (b.level = Math.max(b.level, 1))), this.commandEncoder = new De(this, { id: `${this}-command-encoder` });
|
|
3696
|
+
}
|
|
3697
|
+
//
|
|
3698
|
+
// Public API
|
|
3699
|
+
//
|
|
3700
|
+
get [Symbol.toStringTag]() {
|
|
3701
|
+
return "WebGLDevice";
|
|
3702
|
+
}
|
|
3703
|
+
toString() {
|
|
3704
|
+
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
3705
|
+
}
|
|
3706
|
+
isVertexFormatSupported(e) {
|
|
3707
|
+
switch (e) {
|
|
3708
|
+
case "unorm8x4-bgra":
|
|
3709
|
+
return !1;
|
|
3710
|
+
default:
|
|
3711
|
+
return !0;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
/**
|
|
3715
|
+
* Destroys the device
|
|
3716
|
+
*
|
|
3717
|
+
* @note "Detaches" from the WebGL context unless _reuseDevices is true.
|
|
3718
|
+
*
|
|
3719
|
+
* @note The underlying WebGL context is not immediately destroyed,
|
|
3720
|
+
* but may be destroyed later through normal JavaScript garbage collection.
|
|
3721
|
+
* This is a fundamental limitation since WebGL does not offer any
|
|
3722
|
+
* browser API for destroying WebGL contexts.
|
|
3723
|
+
*/
|
|
3724
|
+
destroy() {
|
|
3725
|
+
!this.props._reuseDevices && !this._reused && delete this.gl.device;
|
|
3726
|
+
}
|
|
3727
|
+
get isLost() {
|
|
3728
|
+
return this.gl.isContextLost();
|
|
3729
|
+
}
|
|
3730
|
+
// IMPLEMENTATION OF ABSTRACT DEVICE
|
|
3731
|
+
getTextureByteAlignment() {
|
|
3732
|
+
return 4;
|
|
3733
|
+
}
|
|
3734
|
+
createCanvasContext(e) {
|
|
3735
|
+
throw new Error("WebGL only supports a single canvas");
|
|
3736
|
+
}
|
|
3737
|
+
createBuffer(e) {
|
|
3738
|
+
const i = this._normalizeBufferProps(e);
|
|
3739
|
+
return new z(this, i);
|
|
3740
|
+
}
|
|
3741
|
+
createTexture(e) {
|
|
3742
|
+
return new V(this, e);
|
|
3743
|
+
}
|
|
3744
|
+
createExternalTexture(e) {
|
|
3745
|
+
throw new Error("createExternalTexture() not implemented");
|
|
3746
|
+
}
|
|
3747
|
+
createSampler(e) {
|
|
3748
|
+
return new nr(this, e);
|
|
3749
|
+
}
|
|
3750
|
+
createShader(e) {
|
|
3751
|
+
return new Kt(this, e);
|
|
3752
|
+
}
|
|
3753
|
+
createFramebuffer(e) {
|
|
3754
|
+
return new $(this, e);
|
|
3755
|
+
}
|
|
3756
|
+
createVertexArray(e) {
|
|
3757
|
+
return new be(this, e);
|
|
3758
|
+
}
|
|
3759
|
+
createTransformFeedback(e) {
|
|
3760
|
+
return new Dr(this, e);
|
|
3761
|
+
}
|
|
3762
|
+
createQuerySet(e) {
|
|
3763
|
+
return new Gr(this, e);
|
|
3764
|
+
}
|
|
3765
|
+
createRenderPipeline(e) {
|
|
3766
|
+
return new vr(this, e);
|
|
3767
|
+
}
|
|
3768
|
+
createComputePipeline(e) {
|
|
3769
|
+
throw new Error("ComputePipeline not supported in WebGL");
|
|
3770
|
+
}
|
|
3771
|
+
createCommandEncoder(e = {}) {
|
|
3772
|
+
return new De(this, e);
|
|
3773
|
+
}
|
|
3774
|
+
/**
|
|
3775
|
+
* Offscreen Canvas Support: Commit the frame
|
|
3776
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/commit
|
|
3777
|
+
* Chrome's offscreen canvas does not require gl.commit
|
|
3778
|
+
*/
|
|
3779
|
+
submit(e) {
|
|
3780
|
+
e || (e = this.commandEncoder.finish(), this.commandEncoder.destroy(), this.commandEncoder = this.createCommandEncoder({ id: `${this.id}-default-encoder` })), e._executeCommands();
|
|
3781
|
+
}
|
|
3782
|
+
//
|
|
3783
|
+
// TEMPORARY HACKS - will be removed in v9.1
|
|
3784
|
+
//
|
|
3785
|
+
/** @deprecated - should use command encoder */
|
|
3786
|
+
readPixelsToArrayWebGL(e, i) {
|
|
3787
|
+
return Ir(e, i);
|
|
3788
|
+
}
|
|
3789
|
+
/** @deprecated - should use command encoder */
|
|
3790
|
+
readPixelsToBufferWebGL(e, i) {
|
|
3791
|
+
return Or(e, i);
|
|
3792
|
+
}
|
|
3793
|
+
setParametersWebGL(e) {
|
|
3794
|
+
W(this.gl, e);
|
|
3795
|
+
}
|
|
3796
|
+
getParametersWebGL(e) {
|
|
3797
|
+
return Re(this.gl, e);
|
|
3798
|
+
}
|
|
3799
|
+
withParametersWebGL(e, i) {
|
|
3800
|
+
return U(this.gl, e, i);
|
|
3801
|
+
}
|
|
3802
|
+
resetWebGL() {
|
|
3803
|
+
b.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")(), vt(this.gl);
|
|
3804
|
+
}
|
|
3805
|
+
_getDeviceSpecificTextureFormatCapabilities(e) {
|
|
3806
|
+
return It(this.gl, e, this._extensions);
|
|
3807
|
+
}
|
|
3808
|
+
//
|
|
3809
|
+
// WebGL-only API (not part of `Device` API)
|
|
3810
|
+
//
|
|
3811
|
+
/**
|
|
3812
|
+
* Triggers device (or WebGL context) loss.
|
|
3813
|
+
* @note primarily intended for testing how application reacts to device loss
|
|
3814
|
+
*/
|
|
3815
|
+
loseDevice() {
|
|
3816
|
+
var s;
|
|
3817
|
+
let e = !1;
|
|
3818
|
+
const n = this.getExtension("WEBGL_lose_context").WEBGL_lose_context;
|
|
3819
|
+
return n && (e = !0, n.loseContext()), (s = this._resolveContextLost) == null || s.call(this, {
|
|
3820
|
+
reason: "destroyed",
|
|
3821
|
+
message: "Application triggered context loss"
|
|
3822
|
+
}), e;
|
|
3823
|
+
}
|
|
3824
|
+
/** Save current WebGL context state onto an internal stack */
|
|
3825
|
+
pushState() {
|
|
3826
|
+
C.get(this.gl).push();
|
|
3827
|
+
}
|
|
3828
|
+
/** Restores previously saved context state */
|
|
3829
|
+
popState() {
|
|
3830
|
+
C.get(this.gl).pop();
|
|
3831
|
+
}
|
|
3832
|
+
/**
|
|
3833
|
+
* Returns the GL.<KEY> constant that corresponds to a numeric value of a GL constant
|
|
3834
|
+
* Be aware that there are some duplicates especially for constants that are 0,
|
|
3835
|
+
* so this isn't guaranteed to return the right key in all cases.
|
|
3836
|
+
*/
|
|
3837
|
+
getGLKey(e, i) {
|
|
3838
|
+
const n = Number(e);
|
|
3839
|
+
for (const s in this.gl)
|
|
3840
|
+
if (this.gl[s] === n)
|
|
3841
|
+
return `GL.${s}`;
|
|
3842
|
+
return i != null && i.emptyIfUnknown ? "" : String(e);
|
|
3843
|
+
}
|
|
3844
|
+
/**
|
|
3845
|
+
* Returns a map with any GL.<KEY> constants mapped to strings, both for keys and values
|
|
3846
|
+
*/
|
|
3847
|
+
getGLKeys(e) {
|
|
3848
|
+
const i = { emptyIfUnknown: !0 };
|
|
3849
|
+
return Object.entries(e).reduce((n, [s, a]) => (n[`${s}:${this.getGLKey(s, i)}`] = `${a}:${this.getGLKey(a, i)}`, n), {});
|
|
3850
|
+
}
|
|
3851
|
+
/**
|
|
3852
|
+
* Set a constant value for a location. Disabled attributes at that location will read from this value
|
|
3853
|
+
* @note WebGL constants are stored globally on the WebGL context, not the VertexArray
|
|
3854
|
+
* so they need to be updated before every render
|
|
3855
|
+
* @todo - remember/cache values to avoid setting them unnecessarily?
|
|
3856
|
+
*/
|
|
3857
|
+
setConstantAttributeWebGL(e, i) {
|
|
3858
|
+
const n = this.limits.maxVertexAttributes;
|
|
3859
|
+
this._constants = this._constants || new Array(n).fill(null);
|
|
3860
|
+
const s = this._constants[e];
|
|
3861
|
+
switch (s && Xr(s, i) && b.info(1, `setConstantAttributeWebGL(${e}) could have been skipped, value unchanged`)(), this._constants[e] = i, i.constructor) {
|
|
3862
|
+
case Float32Array:
|
|
3863
|
+
Vr(this, e, i);
|
|
3864
|
+
break;
|
|
3865
|
+
case Int32Array:
|
|
3866
|
+
Ur(this, e, i);
|
|
3867
|
+
break;
|
|
3868
|
+
case Uint32Array:
|
|
3869
|
+
Nr(this, e, i);
|
|
3870
|
+
break;
|
|
3871
|
+
default:
|
|
3872
|
+
throw new Error("constant");
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
/** Ensure extensions are only requested once */
|
|
3876
|
+
getExtension(e) {
|
|
3877
|
+
return M(this.gl, e, this._extensions), this._extensions;
|
|
3878
|
+
}
|
|
3879
|
+
// INTERNAL SUPPORT METHODS FOR WEBGL RESOURCES
|
|
3880
|
+
/**
|
|
3881
|
+
* Storing data on a special field on WebGLObjects makes that data visible in SPECTOR chrome debug extension
|
|
3882
|
+
* luma.gl ids and props can be inspected
|
|
3883
|
+
*/
|
|
3884
|
+
_setWebGLDebugMetadata(e, i, n) {
|
|
3885
|
+
e.luma = i;
|
|
3886
|
+
const s = { props: n.spector, id: n.spector.id };
|
|
3887
|
+
e.__SPECTOR_Metadata = s;
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
function Vr(r, t, e) {
|
|
3891
|
+
switch (e.length) {
|
|
3892
|
+
case 1:
|
|
3893
|
+
r.gl.vertexAttrib1fv(t, e);
|
|
3894
|
+
break;
|
|
3895
|
+
case 2:
|
|
3896
|
+
r.gl.vertexAttrib2fv(t, e);
|
|
3897
|
+
break;
|
|
3898
|
+
case 3:
|
|
3899
|
+
r.gl.vertexAttrib3fv(t, e);
|
|
3900
|
+
break;
|
|
3901
|
+
case 4:
|
|
3902
|
+
r.gl.vertexAttrib4fv(t, e);
|
|
3903
|
+
break;
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
function Ur(r, t, e) {
|
|
3907
|
+
r.gl.vertexAttribI4iv(t, e);
|
|
3908
|
+
}
|
|
3909
|
+
function Nr(r, t, e) {
|
|
3910
|
+
r.gl.vertexAttribI4uiv(t, e);
|
|
3911
|
+
}
|
|
3912
|
+
function Xr(r, t) {
|
|
3913
|
+
if (!r || !t || r.length !== t.length || r.constructor !== t.constructor)
|
|
3914
|
+
return !1;
|
|
3915
|
+
for (let e = 0; e < r.length; ++e)
|
|
3916
|
+
if (r[e] !== t[e])
|
|
3917
|
+
return !1;
|
|
3918
|
+
return !0;
|
|
3919
|
+
}
|
|
3920
|
+
export {
|
|
3921
|
+
jr as WebGLDevice
|
|
3922
|
+
};
|
|
3923
|
+
//# sourceMappingURL=webgl-device-B9ewDj5L.js.map
|