@luma.gl/engine 9.0.0-alpha.20 → 9.0.0-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  2. package/dist/animation-loop/animation-loop.js +3 -1
  3. package/dist/animation-loop/animation-loop.js.map +1 -1
  4. package/dist/animation-loop/animation-props.d.ts +2 -1
  5. package/dist/animation-loop/animation-props.d.ts.map +1 -1
  6. package/dist/animation-loop/animation-props.js.map +1 -1
  7. package/dist/dist.dev.js +1435 -748
  8. package/dist/geometries/cube-geometry.d.ts +1 -1
  9. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  10. package/dist/geometries/cube-geometry.js +1 -1
  11. package/dist/geometries/cube-geometry.js.map +1 -1
  12. package/dist/geometries/ico-sphere-geometry.d.ts +1 -1
  13. package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
  14. package/dist/geometries/ico-sphere-geometry.js +1 -1
  15. package/dist/geometries/ico-sphere-geometry.js.map +1 -1
  16. package/dist/geometries/plane-geometry.d.ts +1 -1
  17. package/dist/geometries/plane-geometry.d.ts.map +1 -1
  18. package/dist/geometries/plane-geometry.js +1 -1
  19. package/dist/geometries/plane-geometry.js.map +1 -1
  20. package/dist/geometries/sphere-geometry.d.ts +1 -1
  21. package/dist/geometries/sphere-geometry.d.ts.map +1 -1
  22. package/dist/geometries/sphere-geometry.js +1 -1
  23. package/dist/geometries/sphere-geometry.js.map +1 -1
  24. package/dist/geometries/truncated-cone-geometry.d.ts +1 -1
  25. package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
  26. package/dist/geometries/truncated-cone-geometry.js +1 -1
  27. package/dist/geometries/truncated-cone-geometry.js.map +1 -1
  28. package/dist/geometry/geometry-utils.js.map +1 -1
  29. package/dist/geometry/geometry.d.ts +1 -1
  30. package/dist/geometry/geometry.d.ts.map +1 -1
  31. package/dist/geometry/geometry.js +1 -1
  32. package/dist/geometry/geometry.js.map +1 -1
  33. package/dist/index.cjs +110 -29
  34. package/dist/index.d.ts +4 -3
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +3 -2
  37. package/dist/index.js.map +1 -1
  38. package/dist/lib/clip-space.d.ts +1 -1
  39. package/dist/lib/clip-space.d.ts.map +1 -1
  40. package/dist/lib/clip-space.js +3 -3
  41. package/dist/lib/clip-space.js.map +1 -1
  42. package/dist/lib/pipeline-factory.d.ts +1 -1
  43. package/dist/lib/pipeline-factory.d.ts.map +1 -1
  44. package/dist/lib/pipeline-factory.js.map +1 -1
  45. package/dist/{lib → model}/model-utils.d.ts +1 -1
  46. package/dist/model/model-utils.d.ts.map +1 -0
  47. package/dist/model/model-utils.js.map +1 -0
  48. package/dist/{lib → model}/model.d.ts +8 -3
  49. package/dist/model/model.d.ts.map +1 -0
  50. package/dist/{lib → model}/model.js +10 -6
  51. package/dist/model/model.js.map +1 -0
  52. package/dist/transform/transform.d.ts +98 -0
  53. package/dist/transform/transform.d.ts.map +1 -0
  54. package/dist/transform/transform.js +67 -0
  55. package/dist/transform/transform.js.map +1 -0
  56. package/dist.min.js +83 -65
  57. package/package.json +6 -6
  58. package/src/animation-loop/animation-loop.ts +5 -1
  59. package/src/animation-loop/animation-props.ts +2 -1
  60. package/src/geometries/cube-geometry.ts +1 -1
  61. package/src/geometries/ico-sphere-geometry.ts +1 -1
  62. package/src/geometries/plane-geometry.ts +1 -1
  63. package/src/geometries/sphere-geometry.ts +1 -1
  64. package/src/geometries/truncated-cone-geometry.ts +1 -1
  65. package/src/geometry/geometry-utils.ts +1 -1
  66. package/src/geometry/geometry.ts +1 -1
  67. package/src/index.ts +5 -3
  68. package/src/lib/clip-space.ts +3 -3
  69. package/src/lib/pipeline-factory.ts +1 -1
  70. package/src/{lib → model}/model-utils.ts +1 -1
  71. package/src/{lib → model}/model.ts +17 -8
  72. package/src/transform/transform.ts +246 -0
  73. package/dist/lib/model-utils.d.ts.map +0 -1
  74. package/dist/lib/model-utils.js.map +0 -1
  75. package/dist/lib/model.d.ts.map +0 -1
  76. package/dist/lib/model.js.map +0 -1
  77. /package/dist/{lib → model}/model-utils.js +0 -0
package/dist/dist.dev.js CHANGED
@@ -46,6 +46,7 @@ var __exports__ = (() => {
46
46
  PlaneGeometry: () => PlaneGeometry,
47
47
  SphereGeometry: () => SphereGeometry,
48
48
  Timeline: () => Timeline,
49
+ Transform: () => Transform,
49
50
  TruncatedConeGeometry: () => TruncatedConeGeometry,
50
51
  makeAnimationLoop: () => makeAnimationLoop
51
52
  });
@@ -1047,7 +1048,7 @@ var __exports__ = (() => {
1047
1048
  var lumaStats = new StatsManager();
1048
1049
 
1049
1050
  // ../api/src/init.ts
1050
- function init() {
1051
+ function initializeLuma() {
1051
1052
  const VERSION3 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "untranspiled source";
1052
1053
  const STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
1053
1054
  if (globalThis.luma && globalThis.luma.VERSION !== VERSION3) {
@@ -1068,8 +1069,7 @@ var __exports__ = (() => {
1068
1069
  }
1069
1070
  return VERSION3;
1070
1071
  }
1071
- var VERSION2 = init();
1072
- var init_default = globalThis.luma;
1072
+ var VERSION2 = initializeLuma();
1073
1073
 
1074
1074
  // ../api/src/lib/utils/utils.ts
1075
1075
  var uidCounters = {};
@@ -1094,14 +1094,17 @@ var __exports__ = (() => {
1094
1094
  var DEFAULT_RESOURCE_PROPS = {
1095
1095
  id: "undefined",
1096
1096
  handle: void 0,
1097
- userData: {}
1097
+ userData: void 0
1098
1098
  };
1099
1099
  var Resource = class {
1100
1100
  /** props.id, for debugging. */
1101
1101
  userData = {};
1102
+ /** Whether this resource has been destroyed */
1102
1103
  destroyed = false;
1103
1104
  /** For resources that allocate GPU memory */
1104
1105
  allocatedBytes = 0;
1106
+ /** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
1107
+ _attachedResources = /* @__PURE__ */ new Set();
1105
1108
  /**
1106
1109
  * Create a new Resource. Called from Subclass
1107
1110
  */
@@ -1121,7 +1124,7 @@ var __exports__ = (() => {
1121
1124
  * destroy can be called on any resource to release it before it is garbage collected.
1122
1125
  */
1123
1126
  destroy() {
1124
- this.removeStats();
1127
+ this.destroyResource();
1125
1128
  }
1126
1129
  /** @deprecated Use destroy() */
1127
1130
  delete() {
@@ -1138,14 +1141,41 @@ var __exports__ = (() => {
1138
1141
  getProps() {
1139
1142
  return this.props;
1140
1143
  }
1144
+ // ATTACHED RESOURCES
1145
+ /**
1146
+ * Attaches a resource. Attached resources are auto destroyed when this resource is destroyed
1147
+ * Called automatically when sub resources are auto created but can be called by application
1148
+ */
1149
+ attachResource(resource) {
1150
+ this._attachedResources.add(resource);
1151
+ }
1152
+ /**
1153
+ * Detach an attached resource. The resource will no longer be auto-destroyed when this resource is destroyed.
1154
+ */
1155
+ detachResource(resource) {
1156
+ this._attachedResources.delete(resource);
1157
+ }
1158
+ /**
1159
+ * Destroys a resource (only if owned), and removes from the owned (auto-destroy) list for this resource.
1160
+ */
1161
+ destroyAttachedResource(resource) {
1162
+ if (this._attachedResources.delete(resource)) {
1163
+ resource.destroy();
1164
+ }
1165
+ }
1166
+ /** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
1167
+ destroyAttachedResources() {
1168
+ for (const resource of Object.values(this._attachedResources)) {
1169
+ resource.destroy();
1170
+ }
1171
+ this._attachedResources = /* @__PURE__ */ new Set();
1172
+ }
1141
1173
  // PROTECTED METHODS
1142
- /** Called by resource constructor to track object creation */
1143
- addStats() {
1144
- const stats = this._device.statsManager.getStats("Resource Counts");
1145
- const name = this[Symbol.toStringTag];
1146
- stats.get("Resources Created").incrementCount();
1147
- stats.get(`${name}s Created`).incrementCount();
1148
- stats.get(`${name}s Active`).incrementCount();
1174
+ /** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
1175
+ destroyResource() {
1176
+ this.destroyAttachedResources();
1177
+ this.removeStats();
1178
+ this.destroyed = true;
1149
1179
  }
1150
1180
  /** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
1151
1181
  removeStats() {
@@ -1167,7 +1197,17 @@ var __exports__ = (() => {
1167
1197
  stats.get(`${name} Memory`).subtractCount(this.allocatedBytes);
1168
1198
  this.allocatedBytes = 0;
1169
1199
  }
1200
+ /** Called by resource constructor to track object creation */
1201
+ addStats() {
1202
+ const stats = this._device.statsManager.getStats("Resource Counts");
1203
+ const name = this[Symbol.toStringTag];
1204
+ stats.get("Resources Created").incrementCount();
1205
+ stats.get(`${name}s Created`).incrementCount();
1206
+ stats.get(`${name}s Active`).incrementCount();
1207
+ }
1170
1208
  };
1209
+ /** Default properties for resource */
1210
+ __publicField(Resource, "defaultProps", DEFAULT_RESOURCE_PROPS);
1171
1211
  function selectivelyMerge(props, defaultProps) {
1172
1212
  const mergedProps = {
1173
1213
  ...defaultProps
@@ -1195,6 +1235,7 @@ var __exports__ = (() => {
1195
1235
  get [Symbol.toStringTag]() {
1196
1236
  return "Buffer";
1197
1237
  }
1238
+ /** Length of buffer in bytes */
1198
1239
  constructor(device, props) {
1199
1240
  const deducedProps = {
1200
1241
  ...props
@@ -1315,34 +1356,30 @@ var __exports__ = (() => {
1315
1356
  }
1316
1357
  statsManager = lumaStats;
1317
1358
  userData = {};
1359
+ // Capabilities
1318
1360
  /** Information about the device (vendor, versions etc) */
1319
1361
  /** Optional capability discovery */
1320
1362
  /** WebGPU style device limits */
1321
1363
  /** Check if device supports a specific texture format (creation and `nearest` sampling) */
1322
1364
  /** Check if linear filtering (sampler interpolation) is supported for a specific texture format */
1323
1365
  /** Check if device supports rendering to a specific texture format */
1324
- /** True context is already lost */
1325
- /** Promise that resolves when context is lost */
1326
- /** default canvas context */
1366
+ // Device loss
1367
+ /** `true` if device is already lost */
1368
+ /** Promise that resolves when device is lost */
1369
+ /**
1370
+ * Trigger device loss.
1371
+ * @returns `true` if context loss could actually be triggered.
1372
+ * @note primarily intended for testing how application reacts to device loss
1373
+ */
1374
+ loseDevice() {
1375
+ return false;
1376
+ }
1377
+ // Canvas context
1378
+ /** Default / primary canvas context. Can be null as WebGPU devices can be created without a CanvasContext */
1327
1379
  /** Creates a new CanvasContext (WebGPU only) */
1328
1380
  /** Call after rendering a frame (necessary e.g. on WebGL OffscreenCanvas) */
1329
1381
  // Resource creation
1330
1382
  /** Create a buffer */
1331
- createBuffer(props) {
1332
- if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
1333
- return this._createBuffer({
1334
- data: props
1335
- });
1336
- }
1337
- if ((props.usage || 0) & Buffer2.INDEX && !props.indexType) {
1338
- if (props.data instanceof Uint32Array) {
1339
- props.indexType = "uint32";
1340
- } else if (props.data instanceof Uint16Array) {
1341
- props.indexType = "uint16";
1342
- }
1343
- }
1344
- return this._createBuffer(props);
1345
- }
1346
1383
  /** Create a texture */
1347
1384
  createTexture(props) {
1348
1385
  if (props instanceof Promise || typeof props === "string") {
@@ -1357,9 +1394,31 @@ var __exports__ = (() => {
1357
1394
  /** Create a shader */
1358
1395
  /** Create a render pipeline (aka program) */
1359
1396
  /** Create a compute pipeline (aka program) */
1397
+ createCommandEncoder(props = {}) {
1398
+ throw new Error("not implemented");
1399
+ }
1360
1400
  /** Create a RenderPass */
1361
1401
  /** Create a ComputePass */
1362
- // Implementation
1402
+ /** Get a renderpass that is set up to render to the primary CanvasContext */
1403
+ // Resource creation helpers
1404
+ _getBufferProps(props) {
1405
+ if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
1406
+ return {
1407
+ data: props
1408
+ };
1409
+ }
1410
+ const newProps = {
1411
+ ...props
1412
+ };
1413
+ if ((props.usage || 0) & Buffer2.INDEX && !props.indexType) {
1414
+ if (props.data instanceof Uint32Array) {
1415
+ props.indexType = "uint32";
1416
+ } else if (props.data instanceof Uint16Array) {
1417
+ props.indexType = "uint16";
1418
+ }
1419
+ }
1420
+ return newProps;
1421
+ }
1363
1422
  };
1364
1423
  __publicField(Device, "VERSION", VERSION2);
1365
1424
 
@@ -1505,13 +1564,15 @@ var __exports__ = (() => {
1505
1564
  if (typeof OffscreenCanvas !== "undefined" && this.canvas instanceof OffscreenCanvas) {
1506
1565
  return 1;
1507
1566
  }
1508
- if (typeof useDevicePixels === "number") {
1509
- return useDevicePixels > 0 ? useDevicePixels : 1;
1567
+ useDevicePixels = useDevicePixels === void 0 ? this.props.useDevicePixels : useDevicePixels;
1568
+ if (!useDevicePixels || useDevicePixels <= 0) {
1569
+ return 1;
1510
1570
  }
1511
- if (typeof this.props.useDevicePixels === "number") {
1512
- return this.props.useDevicePixels > 0 ? this.props.useDevicePixels : 1;
1571
+ if (useDevicePixels === true) {
1572
+ const dpr = typeof window !== "undefined" && window.devicePixelRatio;
1573
+ return dpr || 1;
1513
1574
  }
1514
- return useDevicePixels || this.props.useDevicePixels ? typeof window !== "undefined" && window.devicePixelRatio || 1 : 1;
1575
+ return useDevicePixels;
1515
1576
  }
1516
1577
  /**
1517
1578
  * Returns the size of drawing buffer in device pixels.
@@ -1704,8 +1765,8 @@ var __exports__ = (() => {
1704
1765
  data: null,
1705
1766
  dimension: "2d",
1706
1767
  format: "rgba8unorm",
1707
- // width: undefined,
1708
- // height: undefined,
1768
+ width: void 0,
1769
+ height: void 0,
1709
1770
  depth: 1,
1710
1771
  mipmaps: true,
1711
1772
  sampler: {},
@@ -1713,20 +1774,28 @@ var __exports__ = (() => {
1713
1774
  compressed: false,
1714
1775
  // mipLevels: 1,
1715
1776
  usage: 0,
1716
- parameters: {},
1717
- pixelStore: {},
1718
- pixels: null,
1719
- border: 0,
1720
- recreate: false
1777
+ mipLevels: void 0,
1778
+ samples: void 0,
1779
+ type: void 0
1721
1780
  };
1722
1781
  var Texture = class extends Resource {
1723
1782
  get [Symbol.toStringTag]() {
1724
1783
  return "Texture";
1725
1784
  }
1726
- constructor(device, props) {
1727
- super(device, props, DEFAULT_TEXTURE_PROPS);
1785
+ /** dimension of this texture */
1786
+ /** format of this texture */
1787
+ /** width in pixels of this texture */
1788
+ /** height in pixels of this texture */
1789
+ /** depth of this texture */
1790
+ /** Default sampler for this texture */
1791
+ constructor(device, props, defaultProps = DEFAULT_TEXTURE_PROPS) {
1792
+ super(device, props, defaultProps);
1793
+ this.dimension = this.props.dimension;
1794
+ this.format = this.props.format;
1795
+ this.width = this.props.width;
1796
+ this.height = this.props.height;
1797
+ this.depth = this.props.depth;
1728
1798
  }
1729
- /** Default sampler for this device */
1730
1799
  };
1731
1800
  __publicField(Texture, "COPY_SRC", 1);
1732
1801
  __publicField(Texture, "COPY_DST", 2);
@@ -1795,6 +1864,10 @@ var __exports__ = (() => {
1795
1864
  }
1796
1865
  /** Width of all attachments in this framebuffer */
1797
1866
  /** Height of all attachments in this framebuffer */
1867
+ /** Color attachments */
1868
+ colorAttachments = [];
1869
+ /** Depth-stencil attachment, if provided */
1870
+ depthStencilAttachment = null;
1798
1871
  constructor(device, props = {}) {
1799
1872
  super(device, props, DEFAULT_FRAMEBUFFER_PROPS);
1800
1873
  this.width = this.props.width;
@@ -1805,16 +1878,162 @@ var __exports__ = (() => {
1805
1878
  * @note resize() destroys existing textures (if size has changed).
1806
1879
  */
1807
1880
  resize(size) {
1808
- const updateSize = !size || size.height !== this.height || size.width !== this.width;
1881
+ let updateSize = !size;
1809
1882
  if (size) {
1810
- this.width = size?.width;
1811
- this.height = size?.height;
1883
+ const [width, height] = Array.isArray(size) ? size : [size.width, size.height];
1884
+ updateSize = updateSize || height !== this.height || width !== this.width;
1885
+ this.width = width;
1886
+ this.height = height;
1812
1887
  }
1813
1888
  if (updateSize) {
1814
- this._resizeAttachments(this.width, this.height);
1889
+ log.log(2, `Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)();
1890
+ this.resizeAttachments(this.width, this.height);
1891
+ }
1892
+ }
1893
+ // /** Returns fully populated attachment object. */
1894
+ // protected normalizeColorAttachment(
1895
+ // attachment: Texture | ColorTextureFormat
1896
+ // ): Required<ColorAttachment> {
1897
+ // const COLOR_ATTACHMENT_DEFAULTS: Required<ColorAttachment> = {
1898
+ // texture: undefined!,
1899
+ // format: undefined!,
1900
+ // clearValue: [0.0, 0.0, 0.0, 0.0],
1901
+ // loadOp: 'clear',
1902
+ // storeOp: 'store'
1903
+ // };
1904
+ // if (attachment instanceof Texture) {
1905
+ // return {...COLOR_ATTACHMENT_DEFAULTS, texture: attachment};
1906
+ // }
1907
+ // if (typeof attachment === 'string') {
1908
+ // return {...COLOR_ATTACHMENT_DEFAULTS, format: attachment};
1909
+ // }
1910
+ // return {...COLOR_ATTACHMENT_DEFAULTS, ...attachment};
1911
+ // }
1912
+ // /** Wraps texture inside fully populated attachment object. */
1913
+ // protected normalizeDepthStencilAttachment(
1914
+ // attachment: DepthStencilAttachment | Texture | DepthStencilTextureFormat
1915
+ // ): Required<DepthStencilAttachment> {
1916
+ // const DEPTH_STENCIL_ATTACHMENT_DEFAULTS: Required<DepthStencilAttachment> = {
1917
+ // texture: undefined!,
1918
+ // format: undefined!,
1919
+ // depthClearValue: 1.0,
1920
+ // depthLoadOp: 'clear',
1921
+ // depthStoreOp: 'store',
1922
+ // depthReadOnly: false,
1923
+ // stencilClearValue: 0,
1924
+ // stencilLoadOp: 'clear',
1925
+ // stencilStoreOp: 'store',
1926
+ // stencilReadOnly: false
1927
+ // };
1928
+ // if (typeof attachment === 'string') {
1929
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, format: attachment};
1930
+ // }
1931
+ // // @ts-expect-error attachment instanceof Texture doesn't cover Renderbuffer
1932
+ // if (attachment.handle || attachment instanceof Texture) {
1933
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, texture: attachment as Texture};
1934
+ // }
1935
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, ...attachment};
1936
+ // }
1937
+ /** Auto creates any textures */
1938
+ autoCreateAttachmentTextures() {
1939
+ this.colorAttachments = this.props.colorAttachments.map((attachment) => {
1940
+ if (typeof attachment === "string") {
1941
+ const texture = this.createColorTexture(attachment);
1942
+ this.attachResource(texture);
1943
+ return texture;
1944
+ }
1945
+ return attachment;
1946
+ });
1947
+ if (this.props.depthStencilAttachment) {
1948
+ if (typeof this.props.depthStencilAttachment === "string") {
1949
+ const texture = this.createDepthStencilTexture(this.props.depthStencilAttachment);
1950
+ this.attachResource(texture);
1951
+ this.depthStencilAttachment = texture;
1952
+ } else {
1953
+ this.depthStencilAttachment = this.props.depthStencilAttachment;
1954
+ }
1815
1955
  }
1816
1956
  }
1817
- /** Implementation of resize */
1957
+ /** Create a color texture */
1958
+ createColorTexture(format) {
1959
+ return this.device.createTexture({
1960
+ id: "color-attachment",
1961
+ usage: Texture.RENDER_ATTACHMENT,
1962
+ format,
1963
+ width: this.width,
1964
+ height: this.height
1965
+ });
1966
+ }
1967
+ /** Create depth stencil texture */
1968
+ createDepthStencilTexture(format) {
1969
+ return this.device.createTexture({
1970
+ id: "depth-stencil-attachment",
1971
+ usage: Texture.RENDER_ATTACHMENT,
1972
+ format,
1973
+ width: this.width,
1974
+ height: this.height
1975
+ });
1976
+ }
1977
+ /**
1978
+ * Default implementation of resize
1979
+ * Creates new textures with correct size for all attachments.
1980
+ * and destroys existing textures if owned
1981
+ */
1982
+ resizeAttachments(width, height) {
1983
+ for (let i = 0; i < this.colorAttachments.length; ++i) {
1984
+ if (this.colorAttachments[i]) {
1985
+ const resizedTexture = this.device._createTexture({
1986
+ ...this.colorAttachments[i].props,
1987
+ width,
1988
+ height
1989
+ });
1990
+ this.destroyAttachedResource(this.colorAttachments[i]);
1991
+ this.colorAttachments[i] = resizedTexture;
1992
+ this.attachResource(resizedTexture);
1993
+ }
1994
+ }
1995
+ if (this.depthStencilAttachment) {
1996
+ const resizedTexture = this.device._createTexture({
1997
+ ...this.depthStencilAttachment.props,
1998
+ width,
1999
+ height
2000
+ });
2001
+ this.destroyAttachedResource(this.depthStencilAttachment);
2002
+ this.depthStencilAttachment = resizedTexture;
2003
+ this.attachResource(resizedTexture);
2004
+ }
2005
+ }
2006
+ /** Create a color attachment for WebGL *
2007
+ protected override createColorTexture(colorAttachment: Required<ColorAttachment>): Required<ColorAttachment> {
2008
+ return this.device._createTexture({
2009
+ id: `${this.id}-color`,
2010
+ data: null, // reserves texture memory, but texels are undefined
2011
+ format,
2012
+ // type: GL.UNSIGNED_BYTE,
2013
+ width: this.width,
2014
+ height: this.height,
2015
+ // Note: Mipmapping can be disabled by texture resource when we resize the texture
2016
+ // to a non-power-of-two dimenstion (NPOT texture) under WebGL1. To have consistant
2017
+ // behavior we always disable mipmaps.
2018
+ mipmaps: false,
2019
+ // Set MIN and MAG filtering parameters so mipmaps are not used in sampling.
2020
+ // Use LINEAR so subpixel algos like fxaa work.
2021
+ // Set WRAP modes that support NPOT textures too.
2022
+ sampler: {
2023
+ minFilter: 'linear',
2024
+ magFilter: 'linear',
2025
+ addressModeU: 'clamp-to-edge',
2026
+ addressModeV: 'clamp-to-edge'
2027
+ }
2028
+ // parameters: {
2029
+ // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR,
2030
+ // [GL.TEXTURE_MAG_FILTER]: GL.LINEAR,
2031
+ // [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,
2032
+ // [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE
2033
+ // }
2034
+ });
2035
+ }
2036
+ */
1818
2037
  };
1819
2038
 
1820
2039
  // ../api/src/adapter/resources/render-pipeline.ts
@@ -1859,18 +2078,14 @@ var __exports__ = (() => {
1859
2078
  __publicField(RenderPipeline, "_DEFAULT_PROPS", DEFAULT_RENDER_PIPELINE_PROPS);
1860
2079
 
1861
2080
  // ../api/src/adapter/resources/render-pass.ts
1862
- var DEFAULT_RENDERPASS_PROPS = {
1863
- ...DEFAULT_RESOURCE_PROPS,
1864
- framebuffer: null,
1865
- parameters: null
1866
- };
1867
- var RenderPass = class extends Resource {
2081
+ var _RenderPass = class extends Resource {
1868
2082
  get [Symbol.toStringTag]() {
1869
2083
  return "RenderPass";
1870
2084
  }
1871
2085
  constructor(device, props) {
1872
- super(device, props, DEFAULT_RENDERPASS_PROPS);
2086
+ super(device, props, _RenderPass.defaultProps);
1873
2087
  }
2088
+ /** A small set of parameters can be changed between every draw call (viewport, scissorRect, blendColor, stencilReference) */
1874
2089
  // writeTimestamp(querySet: GPUQuerySet, queryIndex: number): void;
1875
2090
  // beginOcclusionQuery(queryIndex: number): void;
1876
2091
  // endOcclusionQuery(): void;
@@ -1901,6 +2116,63 @@ var __exports__ = (() => {
1901
2116
  drawIndexedIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): void;
1902
2117
  */
1903
2118
  };
2119
+ var RenderPass = _RenderPass;
2120
+ /** Default properties for RenderPass */
2121
+ __publicField(RenderPass, "defaultProps", {
2122
+ ...Resource.defaultProps,
2123
+ framebuffer: null,
2124
+ parameters: void 0,
2125
+ clearColor: [0, 0, 0, 0],
2126
+ clearDepth: 1,
2127
+ clearStencil: 0,
2128
+ depthReadOnly: false,
2129
+ stencilReadOnly: false,
2130
+ discard: false
2131
+ });
2132
+
2133
+ // ../api/src/adapter/resources/command-encoder.ts
2134
+ var DEFAULT_COMMAND_ENCODER_PROPS = {
2135
+ ...DEFAULT_RESOURCE_PROPS
2136
+ };
2137
+ var CommandEncoder = class extends Resource {
2138
+ get [Symbol.toStringTag]() {
2139
+ return "CommandEncoder";
2140
+ }
2141
+ constructor(props) {
2142
+ super(props, DEFAULT_COMMAND_ENCODER_PROPS);
2143
+ }
2144
+ // TODO - return the CommandBuffer?
2145
+ // beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
2146
+ // beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
2147
+ // finish(options?: {id?: string}): GPUCommandBuffer;
2148
+ pushDebugGroup(groupLabel) {
2149
+ }
2150
+ popDebugGroup() {
2151
+ }
2152
+ insertDebugMarker(markerLabel) {
2153
+ }
2154
+ // writeTimestamp(querySet: Query, queryIndex: number): void;
2155
+ // resolveQuerySet(options: {
2156
+ // querySet: GPUQuerySet,
2157
+ // firstQuery: number,
2158
+ // queryCount: number,
2159
+ // destination: Buffer,
2160
+ // destinationOffset?: number;
2161
+ // }): void;
2162
+ };
2163
+
2164
+ // ../api/src/adapter/resources/command-buffer.ts
2165
+ var DEFAULT_COMMAND_ENCODER_PROPS2 = {
2166
+ ...DEFAULT_RESOURCE_PROPS
2167
+ };
2168
+ var CommandBuffer = class extends Resource {
2169
+ get [Symbol.toStringTag]() {
2170
+ return "CommandBuffer";
2171
+ }
2172
+ constructor(props) {
2173
+ super(props, DEFAULT_COMMAND_ENCODER_PROPS2);
2174
+ }
2175
+ };
1904
2176
 
1905
2177
  // ../api/src/lib/utils/assert.ts
1906
2178
  function assert2(condition, message2) {
@@ -1989,7 +2261,130 @@ var __exports__ = (() => {
1989
2261
  };
1990
2262
  }
1991
2263
  }
1992
- throw new Error(`Unknown format ${format}`);
2264
+ return decodeNonStandardFormat(format);
2265
+ }
2266
+ var EXCEPTIONS = {
2267
+ // Packed 16 bit formats
2268
+ "rgba4unorm-webgl": {
2269
+ format: "rgba",
2270
+ bpp: 2
2271
+ },
2272
+ "rgb565unorm-webgl": {
2273
+ format: "rgb",
2274
+ bpp: 2
2275
+ },
2276
+ "rgb5a1unorm-webgl": {
2277
+ format: "rgba",
2278
+ bbp: 2
2279
+ },
2280
+ // Packed 32 bit formats
2281
+ "rgb9e5ufloat": {
2282
+ format: "rgb",
2283
+ bbp: 4
2284
+ },
2285
+ "rg11b10ufloat": {
2286
+ format: "rgb",
2287
+ bbp: 4
2288
+ },
2289
+ "rgb10a2unorm": {
2290
+ format: "rgba",
2291
+ bbp: 4
2292
+ },
2293
+ "rgb10a2unorm-webgl": {
2294
+ format: "rgba",
2295
+ bbp: 4
2296
+ },
2297
+ // Depth/stencil
2298
+ "stencil8": {
2299
+ components: 1,
2300
+ bpp: 1,
2301
+ a: "stencil"
2302
+ },
2303
+ "depth16unorm": {
2304
+ components: 1,
2305
+ bpp: 2,
2306
+ a: "depth"
2307
+ },
2308
+ "depth24plus": {
2309
+ components: 1,
2310
+ bpp: 3,
2311
+ a: "depth"
2312
+ },
2313
+ "depth32float": {
2314
+ components: 1,
2315
+ bpp: 4,
2316
+ a: "depth"
2317
+ },
2318
+ "depth24plus-stencil8": {
2319
+ components: 2,
2320
+ bpp: 4,
2321
+ a: "depth-stencil"
2322
+ },
2323
+ // "depth24unorm-stencil8" feature
2324
+ "depth24unorm-stencil8": {
2325
+ components: 2,
2326
+ bpp: 4,
2327
+ a: "depth-stencil"
2328
+ },
2329
+ // "depth32float-stencil8" feature
2330
+ "depth32float-stencil8": {
2331
+ components: 2,
2332
+ bpp: 4,
2333
+ a: "depth-stencil"
2334
+ }
2335
+ };
2336
+ function decodeNonStandardFormat(format) {
2337
+ const data = EXCEPTIONS[format];
2338
+ if (!data) {
2339
+ throw new Error(`Unknown format ${format}`);
2340
+ }
2341
+ return {
2342
+ format: data.format || "",
2343
+ components: data.components || 1,
2344
+ byteLength: data.bpp || 1,
2345
+ srgb: false,
2346
+ unsized: false
2347
+ };
2348
+ }
2349
+
2350
+ // ../api/src/lib/compiler-log/format-compiler-log.ts
2351
+ function formatCompilerLog(shaderLog, source, options) {
2352
+ const lines = source.split(/\r?\n/);
2353
+ let formattedLog = "";
2354
+ for (const message2 of shaderLog) {
2355
+ formattedLog += formatCompilerMessage(message2, lines, message2.lineNum, options);
2356
+ }
2357
+ return formattedLog;
2358
+ }
2359
+ function formatCompilerMessage(message2, lines, lineNum, options) {
2360
+ if (options?.showSourceCode) {
2361
+ const positionIndicator = message2.linePos > 0 ? `${" ".repeat(message2.linePos + 5)}^^^
2362
+ ` : "";
2363
+ const numberedLines = getNumberedLines(lines, lineNum);
2364
+ return `${numberedLines}${positionIndicator}${message2.type.toUpperCase()}: ${message2.message}
2365
+
2366
+ `;
2367
+ }
2368
+ return `${message2.type.toUpperCase()}: ${message2.message}
2369
+ `;
2370
+ }
2371
+ function getNumberedLines(lines, lineNum) {
2372
+ let numberedLines = "";
2373
+ for (let line = lineNum - 2; line <= lineNum; line++) {
2374
+ const sourceLine = lines[line];
2375
+ if (sourceLine !== void 0) {
2376
+ numberedLines += `${padLeft(String(line), 4)}: ${sourceLine}
2377
+ `;
2378
+ }
2379
+ }
2380
+ return numberedLines;
2381
+ }
2382
+ function padLeft(string, paddedLength) {
2383
+ let result = "";
2384
+ for (let i = string.length; i < paddedLength; ++i) {
2385
+ result += " ";
2386
+ }
2387
+ return result + string;
1993
2388
  }
1994
2389
 
1995
2390
  // ../api/src/lib/utils/cast.ts
@@ -2067,54 +2462,14 @@ var __exports__ = (() => {
2067
2462
  const script = document.createElement("script");
2068
2463
  script.setAttribute("type", "text/javascript");
2069
2464
  script.setAttribute("src", scriptUrl);
2070
- if (scriptId) {
2071
- script.id = scriptId;
2072
- }
2073
- return new Promise((resolve, reject) => {
2074
- script.onload = resolve;
2075
- script.onerror = (error2) => reject(new Error(`Unable to load script '${scriptUrl}': ${error2}`));
2076
- head.appendChild(script);
2077
- });
2078
- }
2079
-
2080
- // ../api/src/lib/compiler-log/format-compiler-log.ts
2081
- function formatCompilerLog(shaderLog, source, options) {
2082
- const lines = source.split(/\r?\n/);
2083
- let formattedLog = "";
2084
- for (const message2 of shaderLog) {
2085
- formattedLog += formatCompilerMessage(message2, lines, message2.lineNum, options);
2086
- }
2087
- return formattedLog;
2088
- }
2089
- function formatCompilerMessage(message2, lines, lineNum, options) {
2090
- if (options?.showSourceCode) {
2091
- const positionIndicator = message2.linePos > 0 ? `${" ".repeat(message2.linePos + 5)}^^^
2092
- ` : "";
2093
- const numberedLines = getNumberedLines(lines, lineNum);
2094
- return `${numberedLines}${positionIndicator}${message2.type.toUpperCase()}: ${message2.message}
2095
-
2096
- `;
2097
- }
2098
- return `${message2.type.toUpperCase()}: ${message2.message}
2099
- `;
2100
- }
2101
- function getNumberedLines(lines, lineNum) {
2102
- let numberedLines = "";
2103
- for (let line = lineNum - 2; line <= lineNum; line++) {
2104
- const sourceLine = lines[line];
2105
- if (sourceLine !== void 0) {
2106
- numberedLines += `${padLeft(String(line), 4)}: ${sourceLine}
2107
- `;
2108
- }
2109
- }
2110
- return numberedLines;
2111
- }
2112
- function padLeft(string, paddedLength) {
2113
- let result = "";
2114
- for (let i = string.length; i < paddedLength; ++i) {
2115
- result += " ";
2465
+ if (scriptId) {
2466
+ script.id = scriptId;
2116
2467
  }
2117
- return result + string;
2468
+ return new Promise((resolve, reject) => {
2469
+ script.onload = resolve;
2470
+ script.onerror = (error2) => reject(new Error(`Unable to load script '${scriptUrl}': ${error2}`));
2471
+ head.appendChild(script);
2472
+ });
2118
2473
  }
2119
2474
 
2120
2475
  // ../api/src/lib/request-animation-frame.ts
@@ -2313,7 +2668,7 @@ var __exports__ = (() => {
2313
2668
  }
2314
2669
  _setDisplay(display) {
2315
2670
  if (this.display) {
2316
- this.display.delete();
2671
+ this.display.destroy();
2317
2672
  this.display.animationLoop = null;
2318
2673
  }
2319
2674
  if (display) {
@@ -2366,6 +2721,7 @@ var __exports__ = (() => {
2366
2721
  animationLoop: this,
2367
2722
  device: this.device,
2368
2723
  canvas: this.device?.canvasContext?.canvas,
2724
+ renderPass: this.device.getDefaultRenderPass(),
2369
2725
  timeline: this.timeline,
2370
2726
  // Initial values
2371
2727
  useDevicePixels: this.props.useDevicePixels,
@@ -2396,6 +2752,7 @@ var __exports__ = (() => {
2396
2752
  if (!this.animationProps) {
2397
2753
  return;
2398
2754
  }
2755
+ this.animationProps.renderPass = this.device.getDefaultRenderPass();
2399
2756
  const {
2400
2757
  width,
2401
2758
  height,
@@ -2531,7 +2888,7 @@ var __exports__ = (() => {
2531
2888
  return animationLoop;
2532
2889
  }
2533
2890
 
2534
- // src/lib/model-utils.ts
2891
+ // src/model/model-utils.ts
2535
2892
  var GLTF_TO_LUMA_ATTRIBUTE_MAP = {
2536
2893
  POSITION: "positions",
2537
2894
  NORMAL: "normals",
@@ -2665,6 +3022,19 @@ var __exports__ = (() => {
2665
3022
  // ../shadertools/src/lib/shader-module/shader-module-instance.ts
2666
3023
  var ShaderModuleInstance = class {
2667
3024
  uniforms = {};
3025
+ uniformFormats = {};
3026
+ static instantiateModules(modules) {
3027
+ return modules.map((module) => {
3028
+ if (module instanceof ShaderModuleInstance) {
3029
+ return module;
3030
+ }
3031
+ assert3(typeof module !== "string", `Shader module use by name is deprecated. Import shader module '${module}' and use it directly.`);
3032
+ assert3(module.name, "shader module has no name");
3033
+ const moduleObject = new ShaderModuleInstance(module);
3034
+ moduleObject.dependencies = ShaderModuleInstance.instantiateModules(module.dependencies || []);
3035
+ return moduleObject;
3036
+ });
3037
+ }
2668
3038
  constructor(props) {
2669
3039
  const {
2670
3040
  name,
@@ -2682,7 +3052,7 @@ var __exports__ = (() => {
2682
3052
  this.vs = vs;
2683
3053
  this.fs = fs;
2684
3054
  this.getModuleUniforms = getUniforms;
2685
- this.dependencies = dependencies;
3055
+ this.dependencies = ShaderModuleInstance.instantiateModules(dependencies);
2686
3056
  this.deprecations = this._parseDeprecationDefinitions(deprecations);
2687
3057
  this.defines = defines;
2688
3058
  this.injections = normalizeInjections(inject);
@@ -2782,19 +3152,8 @@ ${moduleSource}// END MODULE_${this.name}
2782
3152
 
2783
3153
  // ../shadertools/src/lib/shader-assembler/resolve-modules.ts
2784
3154
  function resolveModules(modules) {
2785
- return getShaderDependencies(instantiateModules(modules));
2786
- }
2787
- function instantiateModules(modules) {
2788
- return modules.map((module) => {
2789
- if (module instanceof ShaderModuleInstance) {
2790
- return module;
2791
- }
2792
- assert3(typeof module !== "string", `Shader module use by name is deprecated. Import shader module '${module}' and use it directly.`);
2793
- assert3(module.name, "shader module has no name");
2794
- const moduleObject = new ShaderModuleInstance(module);
2795
- moduleObject.dependencies = instantiateModules(module.dependencies || []);
2796
- return moduleObject;
2797
- });
3155
+ const instances = ShaderModuleInstance.instantiateModules(modules);
3156
+ return getShaderDependencies(instances);
2798
3157
  }
2799
3158
  function getShaderDependencies(modules) {
2800
3159
  const moduleMap = {};
@@ -3344,6 +3703,88 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
3344
3703
  return result;
3345
3704
  }
3346
3705
 
3706
+ // ../shadertools/src/lib/glsl-utils/get-shader-info.ts
3707
+ function getShaderInfo(source, defaultName) {
3708
+ return {
3709
+ name: getShaderName(source, defaultName),
3710
+ language: "glsl",
3711
+ version: getShaderVersion(source)
3712
+ };
3713
+ }
3714
+ function getShaderName(shader, defaultName = "unnamed") {
3715
+ const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
3716
+ const match = SHADER_NAME_REGEXP.exec(shader);
3717
+ return match ? match[1] : defaultName;
3718
+ }
3719
+ function getShaderVersion(source) {
3720
+ let version = 100;
3721
+ const words = source.match(/[^\s]+/g);
3722
+ if (words && words.length >= 2 && words[0] === "#version") {
3723
+ const v = parseInt(words[1], 10);
3724
+ if (Number.isFinite(v)) {
3725
+ version = v;
3726
+ }
3727
+ }
3728
+ return version;
3729
+ }
3730
+
3731
+ // ../shadertools/src/lib/glsl-utils/shader-utils.ts
3732
+ var FS100 = glsl2`void main() {gl_FragColor = vec4(0);}`;
3733
+ var FS_GLES = glsl2`\
3734
+ out vec4 transform_output;
3735
+ void main() {
3736
+ transform_output = vec4(0);
3737
+ }`;
3738
+ var FS300 = `#version 300 es
3739
+ ${FS_GLES}`;
3740
+ function getPassthroughFS(options) {
3741
+ const {
3742
+ version = 100,
3743
+ input,
3744
+ inputType,
3745
+ output
3746
+ } = options || {};
3747
+ if (!input) {
3748
+ if (version === 300) {
3749
+ return FS300;
3750
+ } else if (version > 300) {
3751
+ return `#version ${version}
3752
+ ${FS_GLES}`;
3753
+ }
3754
+ return FS100;
3755
+ }
3756
+ if (!inputType) {
3757
+ throw new Error("inputType");
3758
+ }
3759
+ const outputValue = convertToVec4(input, inputType);
3760
+ if (version >= 300) {
3761
+ return `#version ${version} ${version === 300 ? "es" : ""}
3762
+ in ${inputType} ${input};
3763
+ out vec4 ${output};
3764
+ void main() {
3765
+ ${output} = ${outputValue};
3766
+ }`;
3767
+ }
3768
+ return `varying ${inputType} ${input};
3769
+ void main() {
3770
+ gl_FragColor = ${outputValue};
3771
+ }`;
3772
+ }
3773
+ function convertToVec4(variable, type) {
3774
+ switch (type) {
3775
+ case "float":
3776
+ return `vec4(${variable}, 0.0, 0.0, 1.0)`;
3777
+ case "vec2":
3778
+ return `vec4(${variable}, 0.0, 1.0)`;
3779
+ case "vec3":
3780
+ return `vec4(${variable}, 1.0)`;
3781
+ case "vec4":
3782
+ return variable;
3783
+ default:
3784
+ throw new Error(type);
3785
+ }
3786
+ }
3787
+
3347
3788
  // ../../node_modules/@math.gl/core/dist/lib/common.js
3348
3789
  var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
3349
3790
  var DEGREES_TO_RADIANS = 1 / 180 * Math.PI;
@@ -4214,7 +4655,7 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
4214
4655
  }
4215
4656
  };
4216
4657
 
4217
- // src/lib/model.ts
4658
+ // src/model/model.ts
4218
4659
  var DEFAULT_MODEL_PROPS = {
4219
4660
  ...RenderPipeline._DEFAULT_PROPS,
4220
4661
  vs: null,
@@ -4222,9 +4663,11 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
4222
4663
  id: "unnamed",
4223
4664
  handle: void 0,
4224
4665
  userData: {},
4666
+ defines: {},
4225
4667
  modules: [],
4226
4668
  moduleSettings: {},
4227
- geometry: null
4669
+ geometry: null,
4670
+ pipelineFactory: void 0
4228
4671
  };
4229
4672
  var Model = class {
4230
4673
  fs = null;
@@ -4249,15 +4692,16 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
4249
4692
  this.vertexCount = this.props.geometry.vertexCount;
4250
4693
  this.topology = this.props.geometry.topology || "triangle-list";
4251
4694
  }
4252
- const pipelineFactory = PipelineFactory.getDefaultPipelineFactory(this.device);
4695
+ this.pipelineFactory = this.props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
4253
4696
  const {
4254
4697
  pipeline,
4255
4698
  getUniforms
4256
- } = pipelineFactory.createRenderPipeline({
4699
+ } = this.pipelineFactory.createRenderPipeline({
4257
4700
  ...this.props,
4258
4701
  vs: this.vs,
4259
4702
  fs: this.fs,
4260
4703
  topology: this.topology,
4704
+ defines: props.defines,
4261
4705
  parameters: props.parameters,
4262
4706
  layout: props.layout
4263
4707
  });
@@ -4270,7 +4714,7 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
4270
4714
  this.setProps(this.props);
4271
4715
  }
4272
4716
  destroy() {
4273
- this.pipeline.destroy();
4717
+ this.pipelineFactory.release(this.pipeline);
4274
4718
  }
4275
4719
  draw(renderPass) {
4276
4720
  this.pipeline.draw({
@@ -4519,13 +4963,13 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
4519
4963
  GL2[GL2["SHADING_LANGUAGE_VERSION"] = 35724] = "SHADING_LANGUAGE_VERSION";
4520
4964
  GL2[GL2["CURRENT_PROGRAM"] = 35725] = "CURRENT_PROGRAM";
4521
4965
  GL2[GL2["NEVER"] = 512] = "NEVER";
4522
- GL2[GL2["ALWAYS"] = 519] = "ALWAYS";
4523
4966
  GL2[GL2["LESS"] = 513] = "LESS";
4524
4967
  GL2[GL2["EQUAL"] = 514] = "EQUAL";
4525
4968
  GL2[GL2["LEQUAL"] = 515] = "LEQUAL";
4526
4969
  GL2[GL2["GREATER"] = 516] = "GREATER";
4527
- GL2[GL2["GEQUAL"] = 518] = "GEQUAL";
4528
4970
  GL2[GL2["NOTEQUAL"] = 517] = "NOTEQUAL";
4971
+ GL2[GL2["GEQUAL"] = 518] = "GEQUAL";
4972
+ GL2[GL2["ALWAYS"] = 519] = "ALWAYS";
4529
4973
  GL2[GL2["KEEP"] = 7680] = "KEEP";
4530
4974
  GL2[GL2["REPLACE"] = 7681] = "REPLACE";
4531
4975
  GL2[GL2["INCR"] = 7682] = "INCR";
@@ -5017,135 +5461,6 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
5017
5461
  return GL2;
5018
5462
  }({});
5019
5463
 
5020
- // src/geometry/geometry.ts
5021
- var Geometry = class {
5022
- userData = {};
5023
- /** Determines how vertices are read from the 'vertex' attributes */
5024
- /** @deprecated */
5025
- drawMode = GL.TRIANGLES;
5026
- constructor(props = {}) {
5027
- const {
5028
- id = uid("geometry"),
5029
- drawMode = GL.TRIANGLES,
5030
- attributes = {},
5031
- indices = null,
5032
- vertexCount = null
5033
- } = props;
5034
- this.id = id;
5035
- this.drawMode = drawMode;
5036
- this.topology = props.topology || convertToTopology(drawMode);
5037
- if (indices) {
5038
- this.indices = ArrayBuffer.isView(indices) ? {
5039
- value: indices,
5040
- size: 1
5041
- } : indices;
5042
- }
5043
- this.attributes = {};
5044
- for (const [attributeName, attributeValue] of Object.entries(attributes)) {
5045
- const attribute = ArrayBuffer.isView(attributeValue) ? {
5046
- value: attributeValue
5047
- } : attributeValue;
5048
- assert2(ArrayBuffer.isView(attribute.value), `${this._print(attributeName)}: must be typed array or object with value as typed array`);
5049
- if ((attributeName === "POSITION" || attributeName === "positions") && !attribute.size) {
5050
- attribute.size = 3;
5051
- }
5052
- if (attributeName === "indices") {
5053
- assert2(!this.indices);
5054
- this.indices = attribute;
5055
- } else {
5056
- this.attributes[attributeName] = attribute;
5057
- }
5058
- }
5059
- if (this.indices && this.indices.isIndexed !== void 0) {
5060
- this.indices = Object.assign({}, this.indices);
5061
- delete this.indices.isIndexed;
5062
- }
5063
- this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
5064
- }
5065
- /** @deprecated Use string topology constants instead */
5066
- get mode() {
5067
- return this.drawMode;
5068
- }
5069
- getVertexCount() {
5070
- return this.vertexCount;
5071
- }
5072
- // Return an object with all attributes plus indices added as a field.
5073
- getAttributes() {
5074
- return this.indices ? {
5075
- indices: this.indices,
5076
- ...this.attributes
5077
- } : this.attributes;
5078
- }
5079
- // PRIVATE
5080
- _print(attributeName) {
5081
- return `Geometry ${this.id} attribute ${attributeName}`;
5082
- }
5083
- // GeometryAttribute
5084
- // value: typed array
5085
- // type: indices, vertices, uvs
5086
- // size: elements per vertex
5087
- // target: WebGL buffer type (string or constant)
5088
- _setAttributes(attributes, indices) {
5089
- return this;
5090
- }
5091
- _calculateVertexCount(attributes, indices) {
5092
- if (indices) {
5093
- return indices.value.length;
5094
- }
5095
- let vertexCount = Infinity;
5096
- for (const attributeName in attributes) {
5097
- const attribute = attributes[attributeName];
5098
- const {
5099
- value,
5100
- size,
5101
- constant
5102
- } = attribute;
5103
- if (!constant && value && size >= 1) {
5104
- vertexCount = Math.min(vertexCount, value.length / size);
5105
- }
5106
- }
5107
- assert2(Number.isFinite(vertexCount));
5108
- return vertexCount;
5109
- }
5110
- };
5111
- /** @deprecated */
5112
- __publicField(Geometry, "DRAW_MODE", {
5113
- POINTS: GL.POINTS,
5114
- // draw single points.
5115
- LINES: GL.LINES,
5116
- // draw lines. Each vertex connects to the one after it.
5117
- LINE_LOOP: GL.LINE_LOOP,
5118
- // draw lines. Each set of two vertices is treated as a separate line segment.
5119
- LINE_STRIP: GL.LINE_STRIP,
5120
- // draw a connected group of line segments from the first vertex to the last
5121
- TRIANGLES: GL.TRIANGLES,
5122
- // draw triangles. Each set of three vertices creates a separate triangle.
5123
- TRIANGLE_STRIP: GL.TRIANGLE_STRIP,
5124
- // draw a connected group of triangles.
5125
- TRIANGLE_FAN: GL.TRIANGLE_FAN
5126
- // draw a connected group of triangles.
5127
- });
5128
- function convertToTopology(drawMode) {
5129
- switch (drawMode) {
5130
- case GL.POINTS:
5131
- return "point-list";
5132
- case GL.LINES:
5133
- return "line-list";
5134
- case GL.LINE_STRIP:
5135
- return "line-strip";
5136
- case GL.TRIANGLES:
5137
- return "triangle-list";
5138
- case GL.TRIANGLE_STRIP:
5139
- return "triangle-strip";
5140
- case GL.TRIANGLE_FAN:
5141
- return "triangle-fan";
5142
- case GL.LINE_LOOP:
5143
- return "line-loop";
5144
- default:
5145
- throw new Error(String(drawMode));
5146
- }
5147
- }
5148
-
5149
5464
  // ../webgl/src/context/context/create-headless-context.ts
5150
5465
  var ERR_HEADLESSGL_FAILED = "Failed to create WebGL context in Node.js, headless gl returned null";
5151
5466
  var ERR_HEADLESSGL_LOAD = " luma.gl: loaded under Node.js without headless gl installed, meaning that WebGL contexts can not be created. This may not be an error. For example, this is a typical configuration for isorender applications running on the server.";
@@ -6707,7 +7022,8 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
6707
7022
  "r8unorm": {
6708
7023
  gl: GL.R8,
6709
7024
  b: 1,
6710
- c: 1
7025
+ c: 1,
7026
+ renderbuffer: true
6711
7027
  },
6712
7028
  "r8snorm": {
6713
7029
  gl: GL.R8_SNORM,
@@ -6717,18 +7033,21 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
6717
7033
  "r8uint": {
6718
7034
  gl: GL.R8UI,
6719
7035
  b: 1,
6720
- c: 1
7036
+ c: 1,
7037
+ renderbuffer: true
6721
7038
  },
6722
7039
  "r8sint": {
6723
7040
  gl: GL.R8I,
6724
7041
  b: 1,
6725
- c: 1
7042
+ c: 1,
7043
+ renderbuffer: true
6726
7044
  },
6727
7045
  // 16-bit formats
6728
7046
  "rg8unorm": {
6729
7047
  gl: GL.RG8,
6730
7048
  b: 2,
6731
- c: 2
7049
+ c: 2,
7050
+ renderbuffer: true
6732
7051
  },
6733
7052
  "rg8snorm": {
6734
7053
  gl: GL.RG8_SNORM,
@@ -6738,69 +7057,80 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
6738
7057
  "rg8uint": {
6739
7058
  gl: GL.RG8UI,
6740
7059
  b: 2,
6741
- c: 2
7060
+ c: 2,
7061
+ renderbuffer: true
6742
7062
  },
6743
7063
  "rg8sint": {
6744
7064
  gl: GL.RG8I,
6745
7065
  b: 2,
6746
- c: 2
7066
+ c: 2,
7067
+ renderbuffer: true
6747
7068
  },
6748
7069
  "r16uint": {
6749
7070
  gl: GL.R16UI,
6750
7071
  b: 2,
6751
- c: 1
7072
+ c: 1,
7073
+ renderbuffer: true
6752
7074
  },
6753
7075
  "r16sint": {
6754
7076
  gl: GL.R16I,
6755
7077
  b: 2,
6756
- c: 1
7078
+ c: 1,
7079
+ renderbuffer: true
6757
7080
  },
6758
7081
  "r16float": {
6759
7082
  gl: GL.R16F,
6760
7083
  b: 2,
6761
7084
  c: 1,
6762
7085
  render: "texture-renderable-float16-webgl",
6763
- filter: "texture-filter-linear-float16-webgl"
7086
+ filter: "texture-filter-linear-float16-webgl",
7087
+ renderbuffer: true
6764
7088
  },
6765
7089
  "r16unorm-webgl": {
6766
7090
  gl: GL.R16_EXT,
6767
7091
  b: 2,
6768
7092
  c: 1,
6769
- f: "texture-formats-norm16-webgl"
7093
+ f: "texture-formats-norm16-webgl",
7094
+ renderbuffer: true,
7095
+ x: EXT_TEXTURE_NORM16
6770
7096
  },
6771
7097
  "r16snorm-webgl": {
6772
7098
  gl: GL.R16_SNORM_EXT,
6773
7099
  b: 2,
6774
7100
  c: 1,
6775
- f: "texture-formats-norm16-webgl"
7101
+ f: "texture-formats-norm16-webgl",
7102
+ x: EXT_TEXTURE_NORM16
6776
7103
  },
6777
7104
  // Packed 16-bit formats
6778
7105
  "rgba4unorm-webgl": {
6779
7106
  gl: GL.RGBA4,
6780
7107
  b: 2,
6781
7108
  c: 4,
6782
- wgpu: false
7109
+ wgpu: false,
7110
+ renderbuffer: true
6783
7111
  },
6784
7112
  "rgb565unorm-webgl": {
6785
7113
  gl: GL.RGB565,
6786
7114
  b: 2,
6787
7115
  c: 4,
6788
- wgpu: false
7116
+ wgpu: false,
7117
+ renderbuffer: true
6789
7118
  },
6790
7119
  "rgb5a1unorm-webgl": {
6791
7120
  gl: GL.RGB5_A1,
6792
7121
  b: 2,
6793
7122
  c: 4,
6794
- wgpu: false
7123
+ wgpu: false,
7124
+ renderbuffer: true
6795
7125
  },
6796
7126
  // 24-bit formats
6797
- "rbg8unorm-webgl": {
7127
+ "rgb8unorm-webgl": {
6798
7128
  gl: GL.RGB8,
6799
7129
  b: 3,
6800
7130
  c: 3,
6801
7131
  wgpu: false
6802
7132
  },
6803
- "rbg8snorm-webgl": {
7133
+ "rgb8snorm-webgl": {
6804
7134
  gl: GL.RGB8_SNORM,
6805
7135
  b: 3,
6806
7136
  c: 3,
@@ -6867,31 +7197,36 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
6867
7197
  b: 4,
6868
7198
  c: 2,
6869
7199
  render: "texture-renderable-float16-webgl",
6870
- filter: "texture-filter-linear-float16-webgl"
7200
+ filter: "texture-filter-linear-float16-webgl",
7201
+ renderbuffer: true
6871
7202
  },
6872
7203
  "rg16unorm-webgl": {
6873
7204
  gl: GL.RG16_EXT,
6874
7205
  b: 2,
6875
7206
  c: 2,
6876
- f: "texture-formats-norm16-webgl"
7207
+ f: "texture-formats-norm16-webgl",
7208
+ x: EXT_TEXTURE_NORM16
6877
7209
  },
6878
7210
  "rg16snorm-webgl": {
6879
7211
  gl: GL.RG16_SNORM_EXT,
6880
7212
  b: 2,
6881
7213
  c: 2,
6882
- f: "texture-formats-norm16-webgl"
7214
+ f: "texture-formats-norm16-webgl",
7215
+ x: EXT_TEXTURE_NORM16
6883
7216
  },
6884
7217
  "r32uint": {
6885
7218
  gl: GL.R32UI,
6886
7219
  b: 4,
6887
7220
  c: 1,
6888
- bpp: 4
7221
+ bpp: 4,
7222
+ renderbuffer: true
6889
7223
  },
6890
7224
  "r32sint": {
6891
7225
  gl: GL.R32I,
6892
7226
  b: 4,
6893
7227
  c: 1,
6894
- bpp: 4
7228
+ bpp: 4,
7229
+ renderbuffer: true
6895
7230
  },
6896
7231
  "r32float": {
6897
7232
  gl: GL.R32F,
@@ -6915,13 +7250,15 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
6915
7250
  b: 4,
6916
7251
  c: 3,
6917
7252
  p: 1,
6918
- render: "texture-renderable-float32-webgl"
7253
+ render: "texture-renderable-float32-webgl",
7254
+ renderbuffer: true
6919
7255
  },
6920
7256
  "rgb10a2unorm": {
6921
7257
  gl: GL.RGB10_A2,
6922
7258
  b: 4,
6923
7259
  c: 4,
6924
- p: 1
7260
+ p: 1,
7261
+ renderbuffer: true
6925
7262
  },
6926
7263
  // webgl2 only
6927
7264
  "rgb10a2unorm-webgl": {
@@ -6930,48 +7267,56 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
6930
7267
  gl: GL.RGB10_A2UI,
6931
7268
  p: 1,
6932
7269
  wgpu: false,
6933
- bpp: 4
7270
+ bpp: 4,
7271
+ renderbuffer: true
6934
7272
  },
6935
7273
  // 48-bit formats
6936
7274
  "rgb16unorm-webgl": {
6937
7275
  gl: GL.RGB16_EXT,
6938
7276
  b: 2,
6939
7277
  c: 3,
6940
- f: "texture-formats-norm16-webgl"
7278
+ f: "texture-formats-norm16-webgl",
7279
+ x: EXT_TEXTURE_NORM16
6941
7280
  },
6942
7281
  "rgb16snorm-webgl": {
6943
7282
  gl: GL.RGB16_SNORM_EXT,
6944
7283
  b: 2,
6945
7284
  c: 3,
6946
- f: "texture-formats-norm16-webgl"
7285
+ f: "texture-formats-norm16-webgl",
7286
+ x: EXT_TEXTURE_NORM16
6947
7287
  },
6948
7288
  // 64-bit formats
6949
7289
  "rg32uint": {
6950
7290
  gl: GL.RG32UI,
6951
7291
  b: 8,
6952
- c: 2
7292
+ c: 2,
7293
+ renderbuffer: true
6953
7294
  },
6954
7295
  "rg32sint": {
6955
7296
  gl: GL.RG32I,
6956
7297
  b: 8,
6957
- c: 2
7298
+ c: 2,
7299
+ renderbuffer: true
6958
7300
  },
6959
7301
  "rg32float": {
6960
7302
  gl: GL.RG32F,
6961
7303
  b: 8,
6962
7304
  c: 2,
6963
7305
  render: "texture-renderable-float32-webgl",
6964
- filter: "texture-filter-linear-float32-webgl"
7306
+ filter: "texture-filter-linear-float32-webgl",
7307
+ renderbuffer: true
6965
7308
  },
6966
7309
  "rgba16uint": {
6967
7310
  gl: GL.RGBA16UI,
6968
7311
  b: 8,
6969
- c: 4
7312
+ c: 4,
7313
+ renderbuffer: true
6970
7314
  },
6971
7315
  "rgba16sint": {
6972
7316
  gl: GL.RGBA16I,
6973
7317
  b: 8,
6974
- c: 4
7318
+ c: 4,
7319
+ renderbuffer: true
6975
7320
  },
6976
7321
  "rgba16float": {
6977
7322
  gl: GL.RGBA16F,
@@ -6985,13 +7330,16 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
6985
7330
  gl: GL.RGBA16_EXT,
6986
7331
  b: 2,
6987
7332
  c: 4,
6988
- f: "texture-formats-norm16-webgl"
7333
+ f: "texture-formats-norm16-webgl",
7334
+ renderbuffer: true,
7335
+ x: EXT_TEXTURE_NORM16
6989
7336
  },
6990
7337
  "rgba16snorm-webgl": {
6991
7338
  gl: GL.RGBA16_SNORM_EXT,
6992
7339
  b: 2,
6993
7340
  c: 4,
6994
- f: "texture-formats-norm16-webgl"
7341
+ f: "texture-formats-norm16-webgl",
7342
+ x: EXT_TEXTURE_NORM16
6995
7343
  },
6996
7344
  // 96-bit formats (deprecated!)
6997
7345
  "rgb32float-webgl": {
@@ -7009,27 +7357,31 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7009
7357
  "rgba32uint": {
7010
7358
  gl: GL.RGBA32UI,
7011
7359
  b: 16,
7012
- c: 4
7360
+ c: 4,
7361
+ renderbuffer: true
7013
7362
  },
7014
7363
  "rgba32sint": {
7015
7364
  gl: GL.RGBA32I,
7016
7365
  b: 16,
7017
- c: 4
7366
+ c: 4,
7367
+ renderbuffer: true
7018
7368
  },
7019
7369
  "rgba32float": {
7020
7370
  gl: GL.RGBA32F,
7021
- gl1: GL.RGBA,
7022
7371
  b: 16,
7023
7372
  c: 4,
7024
7373
  render: "texture-renderable-float32-webgl",
7025
- filter: "texture-filter-linear-float32-webgl"
7374
+ filter: "texture-filter-linear-float32-webgl",
7375
+ renderbuffer: true
7026
7376
  },
7027
7377
  // Depth and stencil formats
7028
7378
  "stencil8": {
7029
7379
  gl: GL.STENCIL_INDEX8,
7380
+ gl1: GL.STENCIL_INDEX8,
7030
7381
  b: 1,
7031
7382
  c: 1,
7032
- attachment: GL.STENCIL_ATTACHMENT
7383
+ attachment: GL.STENCIL_ATTACHMENT,
7384
+ renderbuffer: true
7033
7385
  },
7034
7386
  // 8 stencil bits
7035
7387
  "depth16unorm": {
@@ -7037,7 +7389,8 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7037
7389
  gl1: GL.DEPTH_COMPONENT16,
7038
7390
  b: 2,
7039
7391
  c: 1,
7040
- attachment: GL.DEPTH_ATTACHMENT
7392
+ attachment: GL.DEPTH_ATTACHMENT,
7393
+ renderbuffer: true
7041
7394
  },
7042
7395
  // 16 depth bits
7043
7396
  "depth24plus": {
@@ -7050,15 +7403,19 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7050
7403
  gl: GL.DEPTH_COMPONENT32F,
7051
7404
  b: 4,
7052
7405
  c: 1,
7053
- attachment: GL.DEPTH_ATTACHMENT
7406
+ attachment: GL.DEPTH_ATTACHMENT,
7407
+ renderbuffer: true
7054
7408
  },
7409
+ // The depth component of the "depth24plus" and "depth24plus-stencil8" formats may be implemented as either a 24-bit depth value or a "depth32float" value.
7055
7410
  "depth24plus-stencil8": {
7056
- b: 4,
7057
- gl: GL.UNSIGNED_INT_24_8,
7411
+ gl: GL.DEPTH_STENCIL,
7058
7412
  gl1: GL.DEPTH_STENCIL,
7413
+ b: 4,
7059
7414
  c: 2,
7060
7415
  p: 1,
7061
- attachment: GL.DEPTH_STENCIL_ATTACHMENT
7416
+ attachment: GL.DEPTH_STENCIL_ATTACHMENT,
7417
+ renderbuffer: true,
7418
+ depthTexture: true
7062
7419
  },
7063
7420
  // "depth24unorm-stencil8" feature
7064
7421
  "depth24unorm-stencil8": {
@@ -7066,7 +7423,8 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7066
7423
  b: 4,
7067
7424
  c: 2,
7068
7425
  p: 1,
7069
- attachment: GL.DEPTH_STENCIL_ATTACHMENT
7426
+ attachment: GL.DEPTH_STENCIL_ATTACHMENT,
7427
+ renderbuffer: true
7070
7428
  },
7071
7429
  // "depth32float-stencil8" feature
7072
7430
  "depth32float-stencil8": {
@@ -7074,7 +7432,8 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7074
7432
  b: 5,
7075
7433
  c: 2,
7076
7434
  p: 1,
7077
- attachment: GL.DEPTH_STENCIL_ATTACHMENT
7435
+ attachment: GL.DEPTH_STENCIL_ATTACHMENT,
7436
+ renderbuffer: true
7078
7437
  },
7079
7438
  // BC compressed formats: check device.features.has("texture-compression-bc");
7080
7439
  "bc1-rgb-unorm-webgl": {
@@ -7348,18 +7707,33 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7348
7707
  f: texture_compression_atc_webgl
7349
7708
  }
7350
7709
  };
7351
- function getTextureFormat(format) {
7352
- if (typeof format === "string") {
7353
- return format;
7354
- }
7355
- const entry = Object.entries(TEXTURE_FORMATS).find(([, entry2]) => entry2.gl === format || entry2.gl1 === format);
7356
- if (!entry) {
7357
- throw new Error(`Unknown texture format ${format}`);
7358
- }
7359
- return entry[0];
7360
- }
7710
+ var DATA_FORMAT_CHANNELS = {
7711
+ [GL.RED]: 1,
7712
+ [GL.RED_INTEGER]: 1,
7713
+ [GL.RG]: 2,
7714
+ [GL.RG_INTEGER]: 2,
7715
+ [GL.RGB]: 3,
7716
+ [GL.RGB_INTEGER]: 3,
7717
+ [GL.RGBA]: 4,
7718
+ [GL.RGBA_INTEGER]: 4,
7719
+ [GL.DEPTH_COMPONENT]: 1,
7720
+ [GL.DEPTH_STENCIL]: 1,
7721
+ [GL.ALPHA]: 1,
7722
+ [GL.LUMINANCE]: 1,
7723
+ [GL.LUMINANCE_ALPHA]: 2
7724
+ };
7725
+ var TYPE_SIZES2 = {
7726
+ [GL.FLOAT]: 4,
7727
+ [GL.UNSIGNED_INT]: 4,
7728
+ [GL.INT]: 4,
7729
+ [GL.UNSIGNED_SHORT]: 2,
7730
+ [GL.SHORT]: 2,
7731
+ [GL.HALF_FLOAT]: 2,
7732
+ [GL.BYTE]: 1,
7733
+ [GL.UNSIGNED_BYTE]: 1
7734
+ };
7361
7735
  function isTextureFormatSupported(gl, formatOrGL) {
7362
- const format = getTextureFormat(formatOrGL);
7736
+ const format = convertGLToTextureFormat(formatOrGL);
7363
7737
  const info = TEXTURE_FORMATS[format];
7364
7738
  if (!info) {
7365
7739
  return false;
@@ -7373,8 +7747,29 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7373
7747
  }
7374
7748
  return true;
7375
7749
  }
7750
+ function isRenderbufferFormatSupported(gl, format) {
7751
+ return isTextureFormatSupported(gl, format) && TEXTURE_FORMATS[format]?.renderbuffer;
7752
+ }
7753
+ function convertGLToTextureFormat(format) {
7754
+ if (typeof format === "string") {
7755
+ return format;
7756
+ }
7757
+ const entry = Object.entries(TEXTURE_FORMATS).find(([, entry2]) => entry2.gl === format || entry2.gl1 === format);
7758
+ if (!entry) {
7759
+ throw new Error(`Unknown texture format ${format}`);
7760
+ }
7761
+ return entry[0];
7762
+ }
7763
+ function convertTextureFormatToGL(format, isWebGL23) {
7764
+ const formatInfo = TEXTURE_FORMATS[format];
7765
+ const webglFormat = isWebGL23 ? formatInfo?.gl : formatInfo?.gl1;
7766
+ if (webglFormat === void 0) {
7767
+ throw new Error(`Unsupported texture format ${format}`);
7768
+ }
7769
+ return webglFormat;
7770
+ }
7376
7771
  function isTextureFormatFilterable(gl, formatOrGL) {
7377
- const format = getTextureFormat(formatOrGL);
7772
+ const format = convertGLToTextureFormat(formatOrGL);
7378
7773
  if (!isTextureFormatSupported(gl, format)) {
7379
7774
  return false;
7380
7775
  }
@@ -7395,7 +7790,7 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7395
7790
  return true;
7396
7791
  }
7397
7792
  function isTextureFormatRenderable(gl, formatOrGL) {
7398
- const format = getTextureFormat(formatOrGL);
7793
+ const format = convertGLToTextureFormat(formatOrGL);
7399
7794
  if (!isTextureFormatSupported(gl, format)) {
7400
7795
  return false;
7401
7796
  }
@@ -7404,21 +7799,9 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7404
7799
  }
7405
7800
  return true;
7406
7801
  }
7407
- function getWebGLTextureFormat(gl, formatOrGL) {
7408
- const format = getTextureFormat(formatOrGL);
7409
- const formatInfo = TEXTURE_FORMATS[format];
7410
- const webglFormat = isWebGL2(gl) ? formatInfo?.gl : formatInfo?.gl1;
7411
- if (typeof format === "number") {
7412
- return webglFormat || format;
7413
- }
7414
- if (webglFormat === void 0) {
7415
- throw new Error(`Unsupported texture format ${format}`);
7416
- }
7417
- return webglFormat;
7418
- }
7419
- function getWebGLTextureParameters(gl, formatOrGL) {
7420
- const format = getTextureFormat(formatOrGL);
7421
- const webglFormat = getWebGLTextureFormat(gl, format);
7802
+ function getWebGLTextureParameters(formatOrGL, isWebGL23) {
7803
+ const format = convertGLToTextureFormat(formatOrGL);
7804
+ const webglFormat = convertTextureFormatToGL(format, isWebGL23);
7422
7805
  const decoded = decodeTextureFormat(format);
7423
7806
  return {
7424
7807
  format: webglFormat,
@@ -7428,17 +7811,12 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7428
7811
  compressed: decoded.compressed
7429
7812
  };
7430
7813
  }
7431
- function getWebGLDepthStencilAttachment(formatOrGL) {
7432
- const format = getTextureFormat(formatOrGL);
7433
- if (typeof format === "number") {
7434
- throw new Error("unsupported depth stencil format");
7435
- }
7814
+ function getDepthStencilAttachmentWebGL(format) {
7436
7815
  const info = TEXTURE_FORMATS[format];
7437
- const attachment = info.attachment;
7438
- if (!attachment) {
7439
- throw new Error("not a depth stencil format");
7816
+ if (!info?.attachment) {
7817
+ throw new Error(`${format} is not a depth stencil format`);
7440
7818
  }
7441
- return attachment;
7819
+ return info.attachment;
7442
7820
  }
7443
7821
  function _checkFloat32ColorAttachment(gl, internalFormat = gl.RGBA, srcFormat = GL.RGBA, srcType = GL.UNSIGNED_BYTE) {
7444
7822
  let texture = null;
@@ -7463,34 +7841,9 @@ ${isVertex ? "" : FRAGMENT_SHADER_PROLOGUE}
7463
7841
  gl.deleteFramebuffer(framebuffer);
7464
7842
  }
7465
7843
  }
7466
- var DATA_FORMAT_CHANNELS = {
7467
- [GL.RED]: 1,
7468
- [GL.RED_INTEGER]: 1,
7469
- [GL.RG]: 2,
7470
- [GL.RG_INTEGER]: 2,
7471
- [GL.RGB]: 3,
7472
- [GL.RGB_INTEGER]: 3,
7473
- [GL.RGBA]: 4,
7474
- [GL.RGBA_INTEGER]: 4,
7475
- [GL.DEPTH_COMPONENT]: 1,
7476
- [GL.DEPTH_STENCIL]: 1,
7477
- [GL.ALPHA]: 1,
7478
- [GL.LUMINANCE]: 1,
7479
- [GL.LUMINANCE_ALPHA]: 2
7480
- };
7481
- var TYPE_SIZES2 = {
7482
- [GL.FLOAT]: 4,
7483
- [GL.UNSIGNED_INT]: 4,
7484
- [GL.INT]: 4,
7485
- [GL.UNSIGNED_SHORT]: 2,
7486
- [GL.SHORT]: 2,
7487
- [GL.HALF_FLOAT]: 2,
7488
- [GL.BYTE]: 1,
7489
- [GL.UNSIGNED_BYTE]: 1
7490
- };
7491
- function getTextureFormatBytesPerPixel(gl, formatOrGL) {
7492
- const format = getTextureFormat(formatOrGL);
7493
- const params = getWebGLTextureParameters(gl, format);
7844
+ function getTextureFormatBytesPerPixel(formatOrGL, isWebGL23) {
7845
+ const format = convertGLToTextureFormat(formatOrGL);
7846
+ const params = getWebGLTextureParameters(format, isWebGL23);
7494
7847
  const channels = DATA_FORMAT_CHANNELS[params.dataFormat] || 4;
7495
7848
  const channelSize = TYPE_SIZES2[params.type] || 1;
7496
7849
  return channels * channelSize;
@@ -7895,22 +8248,22 @@ void main(void) {}`;
7895
8248
  }
7896
8249
  function convertCompareFunction(parameter, value) {
7897
8250
  return map(parameter, value, {
7898
- "never": GL.NEVER,
7899
- "less": GL.LESS,
7900
- "equal": GL.EQUAL,
8251
+ never: GL.NEVER,
8252
+ less: GL.LESS,
8253
+ equal: GL.EQUAL,
7901
8254
  "less-equal": GL.LEQUAL,
7902
- "greater": GL.GREATER,
8255
+ greater: GL.GREATER,
7903
8256
  "not-equal": GL.NOTEQUAL,
7904
8257
  "greater-equal": GL.GEQUAL,
7905
- "always": GL.ALWAYS
8258
+ always: GL.ALWAYS
7906
8259
  });
7907
8260
  }
7908
8261
  function convertStencilOperation(parameter, value) {
7909
8262
  return map(parameter, value, {
7910
- "keep": GL.KEEP,
7911
- "zero": GL.ZERO,
7912
- "replace": GL.REPLACE,
7913
- "invert": GL.INVERT,
8263
+ keep: GL.KEEP,
8264
+ zero: GL.ZERO,
8265
+ replace: GL.REPLACE,
8266
+ invert: GL.INVERT,
7914
8267
  "increment-clamp": GL.INCR,
7915
8268
  "decrement-clamp": GL.DECR,
7916
8269
  "increment-wrap": GL.INCR_WRAP,
@@ -8068,16 +8421,17 @@ void main(void) {}`;
8068
8421
  this.trackDeallocatedMemory();
8069
8422
  this.gl.deleteBuffer(this.handle);
8070
8423
  this.destroyed = true;
8424
+ this.handle = null;
8071
8425
  }
8072
8426
  }
8073
8427
  write(data, byteOffset = 0) {
8074
8428
  const srcOffset = 0;
8075
- const byteLength = data.byteLength;
8429
+ const byteLength = void 0;
8076
8430
  const target = this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.target;
8077
8431
  this.gl.bindBuffer(target, this.handle);
8078
8432
  if (srcOffset !== 0 || byteLength !== void 0) {
8079
8433
  this.device.assertWebGL2();
8080
- this.gl.bufferSubData(this.target, byteOffset, data, srcOffset, byteLength);
8434
+ this.gl2.bufferSubData(target, byteOffset, data, srcOffset, byteLength);
8081
8435
  } else {
8082
8436
  this.gl.bufferSubData(target, byteOffset, data);
8083
8437
  }
@@ -8167,11 +8521,21 @@ void main(void) {}`;
8167
8521
  };
8168
8522
 
8169
8523
  // ../webgl/src/adapter/resources/webgl-texture.ts
8524
+ var DEFAULT_WEBGL_TEXTURE_PROPS = {
8525
+ // deprecated
8526
+ parameters: {},
8527
+ pixelStore: {},
8528
+ pixels: null,
8529
+ border: 0,
8530
+ dataFormat: void 0,
8531
+ textureUnit: void 0,
8532
+ target: void 0
8533
+ };
8170
8534
  var _WEBGLTexture = class extends Texture {
8171
- width = void 0;
8172
- height = void 0;
8173
- depth = void 0;
8174
- format = void 0;
8535
+ /** Sampler object (currently unused) */
8536
+ sampler = void 0;
8537
+ // data;
8538
+ glFormat = void 0;
8175
8539
  type = void 0;
8176
8540
  dataFormat = void 0;
8177
8541
  mipmaps = void 0;
@@ -8185,8 +8549,6 @@ void main(void) {}`;
8185
8549
  * attempting to bind it as GL_TEXTURE_3D will give rise to a run-time error
8186
8550
  * */
8187
8551
  textureUnit = void 0;
8188
- /** Sampler object (currently unused) */
8189
- sampler = void 0;
8190
8552
  /**
8191
8553
  * Program.draw() checks the loaded flag of all textures to avoid
8192
8554
  * Textures that are still loading from promises
@@ -8195,7 +8557,8 @@ void main(void) {}`;
8195
8557
  loaded = false;
8196
8558
  constructor(device, props) {
8197
8559
  super(device, {
8198
- format: GL.RGBA,
8560
+ ...DEFAULT_WEBGL_TEXTURE_PROPS,
8561
+ format: "rgba8unorm",
8199
8562
  ...props
8200
8563
  });
8201
8564
  this.device = cast(device);
@@ -8206,6 +8569,7 @@ void main(void) {}`;
8206
8569
  ...this.props,
8207
8570
  data: typeof this.props.data
8208
8571
  });
8572
+ this.glFormat = GL.RGBA;
8209
8573
  this.target = getWebGLTextureTarget(this.props);
8210
8574
  this.loaded = false;
8211
8575
  if (typeof this.props?.data === "string") {
@@ -8251,7 +8615,6 @@ void main(void) {}`;
8251
8615
  } = props;
8252
8616
  const {
8253
8617
  pixels = null,
8254
- recreate = false,
8255
8618
  pixelStore = {},
8256
8619
  textureUnit = void 0
8257
8620
  } = props;
@@ -8269,6 +8632,7 @@ void main(void) {}`;
8269
8632
  const {
8270
8633
  depth = 0
8271
8634
  } = props;
8635
+ const glFormat = convertTextureFormatToGL(props.format, this.device.isWebGL2);
8272
8636
  ({
8273
8637
  width,
8274
8638
  height,
@@ -8284,11 +8648,9 @@ void main(void) {}`;
8284
8648
  width,
8285
8649
  height
8286
8650
  }));
8287
- const format = getWebGLTextureFormat(this.gl, props.format);
8288
8651
  this.width = width;
8289
8652
  this.height = height;
8290
- this.depth = depth;
8291
- this.format = format;
8653
+ this.glFormat = glFormat;
8292
8654
  this.type = type;
8293
8655
  this.dataFormat = dataFormat;
8294
8656
  this.textureUnit = textureUnit;
@@ -8306,7 +8668,7 @@ void main(void) {}`;
8306
8668
  width,
8307
8669
  height,
8308
8670
  depth,
8309
- format,
8671
+ format: glFormat,
8310
8672
  type,
8311
8673
  dataFormat,
8312
8674
  // @ts-expect-error
@@ -8318,9 +8680,6 @@ void main(void) {}`;
8318
8680
  if (mipmaps) {
8319
8681
  this.generateMipmap();
8320
8682
  }
8321
- if (recreate) {
8322
- this.data = data;
8323
- }
8324
8683
  if (isVideo) {
8325
8684
  this._video = {
8326
8685
  video: data,
@@ -8438,7 +8797,7 @@ void main(void) {}`;
8438
8797
  */
8439
8798
  // eslint-disable-next-line max-statements, complexity
8440
8799
  setImageData(options) {
8441
- if (this.props.dimension === "3d") {
8800
+ if (this.props.dimension === "3d" || this.props.dimension === "2d-array") {
8442
8801
  return this.setImageData3D(options);
8443
8802
  }
8444
8803
  this.trackDeallocatedMemory("Texture");
@@ -8446,7 +8805,7 @@ void main(void) {}`;
8446
8805
  target = this.target,
8447
8806
  pixels = null,
8448
8807
  level = 0,
8449
- format = this.format,
8808
+ glFormat = this.glFormat,
8450
8809
  offset = 0,
8451
8810
  parameters = {}
8452
8811
  } = options;
@@ -8492,13 +8851,13 @@ void main(void) {}`;
8492
8851
  withParameters(this.gl, parameters, () => {
8493
8852
  switch (dataType) {
8494
8853
  case "null":
8495
- gl.texImage2D(target, level, format, width, height, 0, dataFormat, type, data);
8854
+ gl.texImage2D(target, level, glFormat, width, height, 0, dataFormat, type, data);
8496
8855
  break;
8497
8856
  case "typed-array":
8498
8857
  gl.texImage2D(
8499
8858
  target,
8500
8859
  level,
8501
- format,
8860
+ glFormat,
8502
8861
  width,
8503
8862
  height,
8504
8863
  0,
@@ -8513,14 +8872,14 @@ void main(void) {}`;
8513
8872
  case "buffer":
8514
8873
  gl2 = this.device.assertWebGL2();
8515
8874
  gl2.bindBuffer(GL.PIXEL_UNPACK_BUFFER, data.handle || data);
8516
- gl2.texImage2D(target, level, format, width, height, 0, dataFormat, type, offset);
8875
+ gl2.texImage2D(target, level, glFormat, width, height, 0, dataFormat, type, offset);
8517
8876
  gl2.bindBuffer(GL.PIXEL_UNPACK_BUFFER, null);
8518
8877
  break;
8519
8878
  case "browser-object":
8520
8879
  if (this.device.isWebGL2) {
8521
- gl.texImage2D(target, level, format, width, height, 0, dataFormat, type, data);
8880
+ gl.texImage2D(target, level, glFormat, width, height, 0, dataFormat, type, data);
8522
8881
  } else {
8523
- gl.texImage2D(target, level, format, dataFormat, type, data);
8882
+ gl.texImage2D(target, level, glFormat, dataFormat, type, data);
8524
8883
  }
8525
8884
  break;
8526
8885
  case "compressed":
@@ -8535,7 +8894,7 @@ void main(void) {}`;
8535
8894
  if (data && data.byteLength) {
8536
8895
  this.trackAllocatedMemory(data.byteLength, "Texture");
8537
8896
  } else {
8538
- const bytesPerPixel = getTextureFormatBytesPerPixel(this.gl, this.props.format);
8897
+ const bytesPerPixel = getTextureFormatBytesPerPixel(this.props.format, this.device.isWebGL2);
8539
8898
  this.trackAllocatedMemory(this.width * this.height * bytesPerPixel, "Texture");
8540
8899
  }
8541
8900
  this.loaded = true;
@@ -8555,7 +8914,7 @@ void main(void) {}`;
8555
8914
  width = this.width,
8556
8915
  height = this.height,
8557
8916
  level = 0,
8558
- format = this.format,
8917
+ glFormat = this.glFormat,
8559
8918
  type = this.type,
8560
8919
  dataFormat = this.dataFormat,
8561
8920
  compressed = false,
@@ -8593,7 +8952,7 @@ void main(void) {}`;
8593
8952
  this.gl.bindTexture(this.target, this.handle);
8594
8953
  withParameters(this.gl, parameters, () => {
8595
8954
  if (compressed) {
8596
- this.gl.compressedTexSubImage2D(target, level, x, y, width, height, format, data);
8955
+ this.gl.compressedTexSubImage2D(target, level, x, y, width, height, glFormat, data);
8597
8956
  } else if (data === null) {
8598
8957
  this.gl.texSubImage2D(target, level, x, y, width, height, dataFormat, type, null);
8599
8958
  } else if (ArrayBuffer.isView(data)) {
@@ -8702,7 +9061,7 @@ void main(void) {}`;
8702
9061
  type,
8703
9062
  compressed
8704
9063
  } = opts;
8705
- const parameters = getWebGLTextureParameters(this.gl, format);
9064
+ const parameters = getWebGLTextureParameters(format, this.device.isWebGL2);
8706
9065
  dataFormat = dataFormat || parameters.dataFormat;
8707
9066
  type = type || parameters.type;
8708
9067
  compressed = compressed || parameters.compressed;
@@ -8845,7 +9204,7 @@ void main(void) {}`;
8845
9204
  } = options;
8846
9205
  this.trackDeallocatedMemory("Texture");
8847
9206
  this.gl.bindTexture(this.target, this.handle);
8848
- const webglTextureFormat = getWebGLTextureParameters(this.gl, format);
9207
+ const webglTextureFormat = getWebGLTextureParameters(format, this.device.isWebGL2);
8849
9208
  withParameters(this.gl, parameters, () => {
8850
9209
  if (ArrayBuffer.isView(data)) {
8851
9210
  this.gl.texImage3D(
@@ -8870,7 +9229,7 @@ void main(void) {}`;
8870
9229
  if (data && data.byteLength) {
8871
9230
  this.trackAllocatedMemory(data.byteLength, "Texture");
8872
9231
  } else {
8873
- const bytesPerPixel = getTextureFormatBytesPerPixel(this.gl, this.props.format);
9232
+ const bytesPerPixel = getTextureFormatBytesPerPixel(this.props.format, this.device.isWebGL2);
8874
9233
  this.trackAllocatedMemory(this.width * this.height * this.depth * bytesPerPixel, "Texture");
8875
9234
  }
8876
9235
  this.loaded = true;
@@ -8969,16 +9328,6 @@ void main(void) {}`;
8969
9328
  assert2(value !== void 0, `Accessing undefined constant GL.${name}`);
8970
9329
  return value;
8971
9330
  }
8972
- function getKey(gl, value) {
8973
- gl = gl.gl || gl;
8974
- value = Number(value);
8975
- for (const key in gl) {
8976
- if (gl[key] === value) {
8977
- return `GL.${key}`;
8978
- }
8979
- }
8980
- return String(value);
8981
- }
8982
9331
 
8983
9332
  // ../webgl/src/adapter/objects/webgl-resource.ts
8984
9333
  var ERR_RESOURCE_METHOD_UNDEFINED = "Resource subclass must define virtual methods";
@@ -9009,9 +9358,6 @@ void main(void) {}`;
9009
9358
  get handle() {
9010
9359
  return this._handle;
9011
9360
  }
9012
- destroy() {
9013
- this.delete();
9014
- }
9015
9361
  delete({
9016
9362
  deleteChildren = false
9017
9363
  } = {}) {
@@ -9021,7 +9367,7 @@ void main(void) {}`;
9021
9367
  }
9022
9368
  this._handle = null;
9023
9369
  if (children && deleteChildren) {
9024
- children.filter(Boolean).forEach((child) => child.delete());
9370
+ children.filter(Boolean).forEach((child) => child.destroy());
9025
9371
  }
9026
9372
  return this;
9027
9373
  }
@@ -9084,10 +9430,10 @@ void main(void) {}`;
9084
9430
  const parameter = PARAMETERS[pname];
9085
9431
  const parameterAvailable = parameter && (!("webgl2" in parameter) || isWebgl2) && (!("extension" in parameter) || this.gl.getExtension(parameter.extension));
9086
9432
  if (parameterAvailable) {
9087
- const key = keys ? getKey(this.gl, pname) : pname;
9433
+ const key = keys ? this.device.getGLKey(pname) : pname;
9088
9434
  values[key] = this.getParameter(pname, options);
9089
9435
  if (keys && parameter.type === "GLenum") {
9090
- values[key] = getKey(this.gl, values[key]);
9436
+ values[key] = this.device.getGLKey(values[key]);
9091
9437
  }
9092
9438
  }
9093
9439
  }
@@ -9185,204 +9531,8 @@ void main(void) {}`;
9185
9531
  */
9186
9532
  };
9187
9533
 
9188
- // ../webgl/src/adapter/converters/renderbuffer-formats.ts
9189
- function isRenderbufferFormatSupported(gl, format) {
9190
- const info = RENDERBUFFER_FORMATS[format];
9191
- if (!info) {
9192
- return false;
9193
- }
9194
- if (info.ext) {
9195
- return Boolean(gl.getExtension(info.ext));
9196
- }
9197
- if (info.gl2) {
9198
- return isWebGL2(gl);
9199
- }
9200
- return true;
9201
- }
9202
- function getRenderbufferFormatBytesPerPixel(format) {
9203
- return RENDERBUFFER_FORMATS[format].bpp;
9204
- }
9205
- var EXT_FLOAT_WEBGL2 = "EXT_color_buffer_float";
9206
- var RENDERBUFFER_FORMATS = {
9207
- [GL.DEPTH_COMPONENT16]: {
9208
- bpp: 2
9209
- },
9210
- // 16 depth bits.
9211
- [GL.DEPTH_COMPONENT24]: {
9212
- gl2: true,
9213
- bpp: 3
9214
- },
9215
- [GL.DEPTH_COMPONENT32F]: {
9216
- gl2: true,
9217
- bpp: 4
9218
- },
9219
- [GL.STENCIL_INDEX8]: {
9220
- bpp: 1
9221
- },
9222
- // 8 stencil bits.
9223
- [GL.DEPTH_STENCIL]: {
9224
- bpp: 4
9225
- },
9226
- [GL.DEPTH24_STENCIL8]: {
9227
- gl2: true,
9228
- bpp: 4
9229
- },
9230
- [GL.DEPTH32F_STENCIL8]: {
9231
- gl2: true,
9232
- bpp: 5
9233
- },
9234
- // When using a WebGL 1 context, color renderbuffer formats are limited
9235
- [GL.RGBA4]: {
9236
- bpp: 2
9237
- },
9238
- [GL.RGB565]: {
9239
- bpp: 2
9240
- },
9241
- [GL.RGB5_A1]: {
9242
- bpp: 2
9243
- },
9244
- // When using a WebGL 2 context, the following values are available additionally:
9245
- [GL.R8]: {
9246
- gl2: true,
9247
- bpp: 1
9248
- },
9249
- [GL.R8UI]: {
9250
- gl2: true,
9251
- bpp: 1
9252
- },
9253
- [GL.R8I]: {
9254
- gl2: true,
9255
- bpp: 1
9256
- },
9257
- [GL.R16UI]: {
9258
- gl2: true,
9259
- bpp: 2
9260
- },
9261
- [GL.R16I]: {
9262
- gl2: true,
9263
- bpp: 2
9264
- },
9265
- [GL.R32UI]: {
9266
- gl2: true,
9267
- bpp: 4
9268
- },
9269
- [GL.R32I]: {
9270
- gl2: true,
9271
- bpp: 4
9272
- },
9273
- [GL.RG8]: {
9274
- gl2: true,
9275
- bpp: 2
9276
- },
9277
- [GL.RG8UI]: {
9278
- gl2: true,
9279
- bpp: 2
9280
- },
9281
- [GL.RG8I]: {
9282
- gl2: true,
9283
- bpp: 2
9284
- },
9285
- [GL.RG16UI]: {
9286
- gl2: true,
9287
- bpp: 4
9288
- },
9289
- [GL.RG16I]: {
9290
- gl2: true,
9291
- bpp: 4
9292
- },
9293
- [GL.RG32UI]: {
9294
- gl2: true,
9295
- bpp: 8
9296
- },
9297
- [GL.RG32I]: {
9298
- gl2: true,
9299
- bpp: 8
9300
- },
9301
- [GL.RGB8]: {
9302
- gl2: true,
9303
- bpp: 3
9304
- },
9305
- [GL.RGBA8]: {
9306
- gl2: true,
9307
- bpp: 4
9308
- },
9309
- // [GL.SRGB8_ALPHA8]: {gl2: true, gl1: SRGB}, // When using the EXT_sRGB WebGL1 extension
9310
- [GL.RGB10_A2]: {
9311
- gl2: true,
9312
- bpp: 4
9313
- },
9314
- [GL.RGBA8UI]: {
9315
- gl2: true,
9316
- bpp: 4
9317
- },
9318
- [GL.RGBA8I]: {
9319
- gl2: true,
9320
- bpp: 4
9321
- },
9322
- [GL.RGB10_A2UI]: {
9323
- gl2: true,
9324
- bpp: 4
9325
- },
9326
- [GL.RGBA16UI]: {
9327
- gl2: true,
9328
- bpp: 8
9329
- },
9330
- [GL.RGBA16I]: {
9331
- gl2: true,
9332
- bpp: 8
9333
- },
9334
- [GL.RGBA32I]: {
9335
- gl2: true,
9336
- bpp: 16
9337
- },
9338
- [GL.RGBA32UI]: {
9339
- gl2: true,
9340
- bpp: 16
9341
- },
9342
- // When using a WebGL 2 context and the EXT_color_buffer_float WebGL2 extension
9343
- [GL.R16F]: {
9344
- ext: EXT_FLOAT_WEBGL2,
9345
- bpp: 2
9346
- },
9347
- [GL.RG16F]: {
9348
- ext: EXT_FLOAT_WEBGL2,
9349
- bpp: 4
9350
- },
9351
- [GL.RGBA16F]: {
9352
- ext: EXT_FLOAT_WEBGL2,
9353
- bpp: 8
9354
- },
9355
- [GL.R32F]: {
9356
- ext: EXT_FLOAT_WEBGL2,
9357
- bpp: 4
9358
- },
9359
- [GL.RG32F]: {
9360
- ext: EXT_FLOAT_WEBGL2,
9361
- bpp: 8
9362
- },
9363
- // TODO - can't get WEBGL_color_buffer_float to work on renderbuffers
9364
- [GL.RGBA32F]: {
9365
- ext: EXT_FLOAT_WEBGL2,
9366
- bpp: 16
9367
- },
9368
- // [GL.RGBA32F]: {ext: EXT_FLOAT_WEBGL2, gl1: EXT_FLOAT_WEBGL1},
9369
- [GL.R11F_G11F_B10F]: {
9370
- ext: EXT_FLOAT_WEBGL2,
9371
- bpp: 4
9372
- }
9373
- };
9374
-
9375
9534
  // ../webgl/src/adapter/objects/webgl-renderbuffer.ts
9376
- var DEFAULT_RENDERBUFFER_PROPS = {
9377
- id: void 0,
9378
- handle: void 0,
9379
- userData: void 0,
9380
- format: 0,
9381
- width: 1,
9382
- height: 1,
9383
- samples: 0
9384
- };
9385
- var WEBGLRenderbuffer = class extends WebGLResource {
9535
+ var _WEBGLRenderbuffer = class extends WebGLResource {
9386
9536
  get [Symbol.toStringTag]() {
9387
9537
  return "Renderbuffer";
9388
9538
  }
@@ -9398,11 +9548,19 @@ void main(void) {}`;
9398
9548
  get samples() {
9399
9549
  return this.props.samples;
9400
9550
  }
9401
- static isSupported(gl, options) {
9402
- return !options?.format || isRenderbufferFormatSupported(gl, options.format);
9551
+ get attachment() {
9552
+ return;
9553
+ }
9554
+ /** WebGL format constant */
9555
+ static isTextureFormatSupported(device, format) {
9556
+ return isRenderbufferFormatSupported(device.gl, format);
9403
9557
  }
9404
9558
  constructor(device, props) {
9405
- super(device, props, DEFAULT_RENDERBUFFER_PROPS);
9559
+ if (typeof props.format === "number") {
9560
+ throw new Error("Renderbuffer");
9561
+ }
9562
+ super(device, props, _WEBGLRenderbuffer.defaultProps);
9563
+ this.glFormat = convertTextureFormatToGL(this.props.format, device.isWebGL2);
9406
9564
  this._initialize(this.props);
9407
9565
  }
9408
9566
  resize(size) {
@@ -9414,7 +9572,6 @@ void main(void) {}`;
9414
9572
  });
9415
9573
  this._initialize(this.props);
9416
9574
  }
9417
- return this;
9418
9575
  }
9419
9576
  // PRIVATE METHODS
9420
9577
  /** Creates and initializes a renderbuffer object's data store */
@@ -9429,13 +9586,12 @@ void main(void) {}`;
9429
9586
  this.trackDeallocatedMemory();
9430
9587
  this.gl.bindRenderbuffer(GL.RENDERBUFFER, this.handle);
9431
9588
  if (samples !== 0 && this.device.isWebGL2) {
9432
- this.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, format, width, height);
9589
+ this.gl2.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, this.glFormat, width, height);
9433
9590
  } else {
9434
- this.gl.renderbufferStorage(GL.RENDERBUFFER, format, width, height);
9591
+ this.gl.renderbufferStorage(GL.RENDERBUFFER, this.glFormat, width, height);
9435
9592
  }
9436
9593
  this.gl.bindRenderbuffer(GL.RENDERBUFFER, null);
9437
- this.trackAllocatedMemory(width * height * (samples || 1) * getRenderbufferFormatBytesPerPixel(format));
9438
- return this;
9594
+ this.trackAllocatedMemory(width * height * (samples || 1) * getTextureFormatBytesPerPixel(this.glFormat, this.device.isWebGL2));
9439
9595
  }
9440
9596
  // RESOURCE IMPLEMENTATION
9441
9597
  _createHandle() {
@@ -9449,51 +9605,57 @@ void main(void) {}`;
9449
9605
  this.gl.bindRenderbuffer(GL.RENDERBUFFER, handle);
9450
9606
  }
9451
9607
  };
9608
+ var WEBGLRenderbuffer = _WEBGLRenderbuffer;
9609
+ __publicField(WEBGLRenderbuffer, "defaultProps", {
9610
+ id: void 0,
9611
+ handle: void 0,
9612
+ userData: void 0,
9613
+ format: void 0,
9614
+ // 'depth16unorm'
9615
+ width: 1,
9616
+ height: 1,
9617
+ samples: 0
9618
+ });
9452
9619
 
9453
9620
  // ../webgl/src/adapter/resources/webgl-framebuffer.ts
9454
9621
  var WEBGLFramebuffer = class extends Framebuffer {
9455
9622
  get texture() {
9456
9623
  return this.colorAttachments[0];
9457
9624
  }
9458
- colorAttachments = [];
9459
- depthStencilAttachment = null;
9460
- _ownResources = [];
9461
9625
  constructor(device, props) {
9462
9626
  super(device, props);
9627
+ const isDefaultFramebuffer = props.handle === null;
9463
9628
  this.device = device;
9464
9629
  this.gl = device.gl;
9465
- this.handle = this.props.handle !== void 0 ? this.props.handle : this.gl.createFramebuffer();
9466
- if (this.handle) {
9630
+ this.handle = this.props.handle || isDefaultFramebuffer ? this.props.handle : this.gl.createFramebuffer();
9631
+ if (!isDefaultFramebuffer) {
9467
9632
  device.setSpectorMetadata(this.handle, {
9468
9633
  id: this.props.id,
9469
9634
  props: this.props
9470
9635
  });
9471
- }
9472
- this.colorAttachments = this._createColorAttachments();
9473
- this.depthStencilAttachment = this._createDepthStencilAttachment();
9474
- const prevHandle = this.gl.bindFramebuffer(GL.FRAMEBUFFER, this.handle);
9475
- for (let i = 0; i < this.colorAttachments.length; ++i) {
9476
- const attachment = this.colorAttachments[i];
9477
- const attachmentPoint = GL.COLOR_ATTACHMENT0 + i;
9478
- if (attachment) {
9479
- this._attachOne(attachmentPoint, attachment);
9636
+ this.autoCreateAttachmentTextures();
9637
+ this.gl.bindFramebuffer(GL.FRAMEBUFFER, this.handle);
9638
+ for (let i = 0; i < this.colorAttachments.length; ++i) {
9639
+ const attachment = this.colorAttachments[i];
9640
+ const attachmentPoint = GL.COLOR_ATTACHMENT0 + i;
9641
+ if (attachment) {
9642
+ this._attachOne(attachmentPoint, attachment);
9643
+ }
9480
9644
  }
9645
+ if (this.depthStencilAttachment) {
9646
+ this._attachOne(getDepthStencilAttachmentWebGL(this.depthStencilAttachment.format), this.depthStencilAttachment);
9647
+ }
9648
+ this.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
9481
9649
  }
9482
- if (this.props.depthStencilAttachment) {
9483
- this._attachOne(getWebGLDepthStencilAttachment(this.depthStencilAttachment.format), this.depthStencilAttachment);
9484
- }
9485
- this.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
9486
9650
  if (props.check !== false) {
9487
9651
  this._checkStatus();
9488
9652
  }
9489
9653
  }
9654
+ /** destroys any auto created resources etc. */
9490
9655
  destroy() {
9491
- if (this.handle !== null) {
9492
- for (const resource of this._ownResources) {
9493
- resource.destroy();
9494
- }
9656
+ super.destroy();
9657
+ if (!this.destroyed && this.handle !== null) {
9495
9658
  this.gl.deleteFramebuffer(this.handle);
9496
- this.destroyed = true;
9497
9659
  }
9498
9660
  }
9499
9661
  // PRIVATE
@@ -9502,84 +9664,29 @@ void main(void) {}`;
9502
9664
  const {
9503
9665
  gl
9504
9666
  } = this;
9505
- const prevHandle = gl.bindFramebuffer(GL.FRAMEBUFFER, this.handle);
9667
+ const prevHandle2 = gl.bindFramebuffer(GL.FRAMEBUFFER, this.handle);
9506
9668
  const status = gl.checkFramebufferStatus(GL.FRAMEBUFFER);
9507
- gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
9669
+ gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle2 || null);
9508
9670
  if (status !== gl.FRAMEBUFFER_COMPLETE) {
9509
9671
  throw new Error(`Framebuffer ${_getFrameBufferStatus(status)}`);
9510
9672
  }
9511
9673
  }
9512
- _createColorAttachments() {
9513
- return this.props.colorAttachments.map((colorAttachment) => {
9514
- if (!colorAttachment) {
9515
- return void 0;
9516
- }
9517
- if (colorAttachment instanceof WEBGLTexture) {
9518
- return colorAttachment;
9519
- }
9520
- return this._createColorAttachment(colorAttachment, this.width, this.height);
9521
- });
9522
- }
9523
- /** Create a color attachment */
9524
- _createColorAttachment(format, width, height) {
9525
- const texture = this.device._createTexture({
9526
- id: `${this.id}-color`,
9527
- data: null,
9528
- // reserves texture memory, but texels are undefined
9529
- format,
9530
- // type: GL.UNSIGNED_BYTE,
9531
- width,
9532
- height,
9533
- // Note: Mipmapping can be disabled by texture resource when we resize the texture
9534
- // to a non-power-of-two dimenstion (NPOT texture) under WebGL1. To have consistant
9535
- // behavior we always disable mipmaps.
9536
- mipmaps: false,
9537
- // Set MIN and MAG filtering parameters so mipmaps are not used in sampling.
9538
- // Use LINEAR so subpixel algos like fxaa work.
9539
- // Set WRAP modes that support NPOT textures too.
9540
- sampler: {
9541
- minFilter: "linear",
9542
- magFilter: "linear",
9543
- addressModeU: "clamp-to-edge",
9544
- addressModeV: "clamp-to-edge"
9545
- }
9546
- // parameters: {
9547
- // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR,
9548
- // [GL.TEXTURE_MAG_FILTER]: GL.LINEAR,
9549
- // [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,
9550
- // [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE
9551
- // }
9552
- });
9553
- this._ownResources.push(texture);
9554
- return texture;
9555
- }
9556
- /** Create a depth stencil attachment GL.DEPTH24_STENCIL8 */
9557
- _createDepthStencilAttachment() {
9558
- if (!this.props.depthStencilAttachment) {
9559
- return void 0;
9560
- }
9561
- if (this.props.depthStencilAttachment instanceof WEBGLRenderbuffer) {
9562
- return this.props.depthStencilAttachment;
9563
- }
9564
- if (this.props.depthStencilAttachment instanceof Texture) {
9565
- return this.props.depthStencilAttachment;
9566
- }
9567
- const format = this.props.depthStencilAttachment;
9568
- const webglFormat = getWebGLTextureFormat(this.gl, format);
9569
- const texture = new WEBGLRenderbuffer(this.device, {
9674
+ /** In WebGL we must use renderbuffers for depth/stencil attachments (unless we have extensions) */
9675
+ createDepthStencilTexture(format) {
9676
+ return new WEBGLRenderbuffer(this.device, {
9570
9677
  id: `${this.id}-depth-stencil`,
9571
9678
  // TODO misleading if not depth and stencil?
9572
- format: webglFormat,
9679
+ format,
9573
9680
  // dataFormat: GL.DEPTH_STENCIL,
9574
9681
  // type: GL.UNSIGNED_INT_24_8,
9575
9682
  width: this.width,
9576
9683
  height: this.height
9577
9684
  });
9578
- this._ownResources.push(texture);
9579
- return texture;
9580
9685
  }
9581
- /** Attachment resize is expected to be a noop if size is same */
9582
- _resizeAttachments(width, height) {
9686
+ /**
9687
+ * Attachment resize is expected to be a noop if size is same
9688
+ */
9689
+ resizeAttachments(width, height) {
9583
9690
  if (this.handle === null) {
9584
9691
  this.width = this.gl.drawingBufferWidth;
9585
9692
  this.height = this.gl.drawingBufferHeight;
@@ -9591,25 +9698,24 @@ void main(void) {}`;
9591
9698
  if (height === void 0) {
9592
9699
  height = this.gl.drawingBufferHeight;
9593
9700
  }
9594
- if (width !== this.width && height !== this.height) {
9595
- log.log(2, `Resizing framebuffer ${this.id} to ${width}x${height}`)();
9596
- }
9597
9701
  for (const colorAttachment of this.colorAttachments) {
9598
9702
  colorAttachment.resize({
9599
9703
  width,
9600
9704
  height
9601
9705
  });
9602
9706
  }
9603
- this.depthStencilAttachment?.resize({
9604
- width,
9605
- height
9606
- });
9707
+ if (this.depthStencilAttachment) {
9708
+ this.depthStencilAttachment.resize({
9709
+ width,
9710
+ height
9711
+ });
9712
+ }
9607
9713
  return this;
9608
9714
  }
9609
9715
  /** Attach one attachment */
9610
9716
  _attachOne(attachmentPoint, attachment) {
9611
9717
  if (attachment instanceof WEBGLRenderbuffer) {
9612
- this._attachRenderbuffer(attachmentPoint, attachment);
9718
+ this._attachWEBGLRenderbuffer(attachmentPoint, attachment);
9613
9719
  return attachment;
9614
9720
  } else if (Array.isArray(attachment)) {
9615
9721
  const [texture, layer = 0, level = 0] = attachment;
@@ -9621,13 +9727,13 @@ void main(void) {}`;
9621
9727
  }
9622
9728
  throw new Error("attach");
9623
9729
  }
9624
- _attachRenderbuffer(attachment, renderbuffer) {
9730
+ _attachWEBGLRenderbuffer(attachment, renderbuffer) {
9625
9731
  this.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, attachment, GL.RENDERBUFFER, renderbuffer.handle);
9626
9732
  }
9627
9733
  /**
9628
9734
  * @param attachment
9629
9735
  * @param texture
9630
- * @param layer = 0 - index into WebGLTextureArray and Texture3D or face for `TextureCubeMap`
9736
+ * @param layer = 0 - index into WEBGLTextureArray and Texture3D or face for `TextureCubeMap`
9631
9737
  * @param level = 0 - mipmapLevel (must be 0 in WebGL1)
9632
9738
  */
9633
9739
  _attachTexture(attachment, texture, layer, level) {
@@ -10109,12 +10215,9 @@ void main(void) {}`;
10109
10215
  }
10110
10216
  Object.seal(this);
10111
10217
  }
10112
- write(data, byteOffset) {
10113
- this.subData({
10114
- data,
10115
- offset: byteOffset
10116
- });
10117
- }
10218
+ // override write(data: TypedArray, byteOffset: number = 0): void {
10219
+ // this.subData({data, offset: byteOffset});
10220
+ // }
10118
10221
  // returns number of elements in the buffer (assuming that the full buffer is used)
10119
10222
  getElementCount(accessor = this.accessor) {
10120
10223
  return Math.round(this.byteLength / Accessor.getBytesPerElement(accessor));
@@ -10410,19 +10513,19 @@ void main(void) {}`;
10410
10513
  };
10411
10514
 
10412
10515
  // ../webgl/src/adapter/helpers/get-shader-info.ts
10413
- function getShaderInfo(source, defaultName) {
10516
+ function getShaderInfo2(source, defaultName) {
10414
10517
  return {
10415
- name: getShaderName(source, defaultName),
10518
+ name: getShaderName2(source, defaultName),
10416
10519
  language: "glsl",
10417
- version: getShaderVersion(source)
10520
+ version: getShaderVersion2(source)
10418
10521
  };
10419
10522
  }
10420
- function getShaderName(shader, defaultName = "unnamed") {
10523
+ function getShaderName2(shader, defaultName = "unnamed") {
10421
10524
  const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
10422
10525
  const match = SHADER_NAME_REGEXP.exec(shader);
10423
10526
  return match ? match[1] : defaultName;
10424
10527
  }
10425
- function getShaderVersion(source) {
10528
+ function getShaderVersion2(source) {
10426
10529
  let version = 100;
10427
10530
  const words = source.match(/[^\s]+/g);
10428
10531
  if (words && words.length >= 2 && words[0] === "#version") {
@@ -10513,7 +10616,7 @@ ${source2}`;
10513
10616
  const parsedLog = shaderLog ? parseShaderCompilerLog(shaderLog) : [];
10514
10617
  const messages = parsedLog.filter((message2) => message2.type === "error");
10515
10618
  const formattedLog = formatCompilerLog(messages, source);
10516
- const shaderName = getShaderInfo(source).name;
10619
+ const shaderName = getShaderInfo2(source).name;
10517
10620
  const shaderDescription = `${this.stage} shader ${shaderName}`;
10518
10621
  log.error(`GLSL compilation errors in ${shaderDescription}
10519
10622
  ${formattedLog}`)();
@@ -10522,14 +10625,21 @@ ${formattedLog}`)();
10522
10625
  }
10523
10626
  };
10524
10627
  function getShaderIdFromProps(props) {
10525
- return getShaderInfo(props.source).name || props.id || uid(`unnamed ${props.stage}-shader`);
10628
+ return getShaderInfo2(props.source).name || props.id || uid(`unnamed ${props.stage}-shader`);
10526
10629
  }
10527
10630
 
10528
10631
  // ../webgl/src/adapter/resources/webgl-render-pass.ts
10632
+ var GL_DEPTH_BUFFER_BIT = 256;
10633
+ var GL_STENCIL_BUFFER_BIT = 1024;
10634
+ var GL_COLOR_BUFFER_BIT = 16384;
10635
+ var GL_COLOR = 6144;
10529
10636
  var WEBGLRenderPass = class extends RenderPass {
10637
+ /** Parameters that should be applied before each draw call */
10530
10638
  constructor(device, props) {
10531
10639
  super(device, props);
10532
10640
  this.device = device;
10641
+ this.setParameters(this.props.parameters);
10642
+ this.clear();
10533
10643
  }
10534
10644
  end() {
10535
10645
  }
@@ -10543,6 +10653,102 @@ ${formattedLog}`)();
10543
10653
  // beginOcclusionQuery(queryIndex: number): void;
10544
10654
  // endOcclusionQuery(): void;
10545
10655
  // executeBundles(bundles: Iterable<GPURenderBundle>): void;
10656
+ /**
10657
+ * Maps RenderPass parameters to GL parameters
10658
+ */
10659
+ setParameters(parameters = {}) {
10660
+ const glParameters = {};
10661
+ if (this.props.framebuffer) {
10662
+ glParameters.framebuffer = this.props.framebuffer;
10663
+ }
10664
+ if (this.props.depthReadOnly) {
10665
+ glParameters.depthMask = !this.props.depthReadOnly;
10666
+ }
10667
+ glParameters.stencilMask = this.props.stencilReadOnly ? 0 : 1;
10668
+ glParameters[GL.RASTERIZER_DISCARD] = this.props.discard;
10669
+ if (parameters.viewport) {
10670
+ glParameters.viewport = parameters.viewport;
10671
+ glParameters.depthRange = [parameters.viewport[4], parameters.viewport[5]];
10672
+ }
10673
+ glParameters.scissorTest = Boolean(parameters.scissorRect);
10674
+ if (parameters.scissorRect) {
10675
+ glParameters.scissor = parameters.scissorRect;
10676
+ }
10677
+ if (parameters.blendConstant) {
10678
+ glParameters.blendColor = parameters.blendConstant;
10679
+ }
10680
+ if (parameters.stencilReference) {
10681
+ console.warn("RenderPassParameters.stencilReference not yet implemented in WebGL");
10682
+ parameters[GL.STENCIL_REF] = parameters.stencilReference;
10683
+ }
10684
+ this.glParameters = glParameters;
10685
+ }
10686
+ // Internal
10687
+ /**
10688
+ * Optionally clears depth, color and stencil buffers based on parameters
10689
+ */
10690
+ clear() {
10691
+ const glParameters = {
10692
+ ...this.glParameters
10693
+ };
10694
+ let clearMask = 0;
10695
+ if (this.props.clearColor !== false) {
10696
+ clearMask |= GL_COLOR_BUFFER_BIT;
10697
+ glParameters.clearColor = this.props.clearColor;
10698
+ }
10699
+ if (this.props.clearDepth !== false) {
10700
+ clearMask |= GL_DEPTH_BUFFER_BIT;
10701
+ glParameters.clearDepth = this.props.clearDepth;
10702
+ }
10703
+ if (this.props.clearStencil !== false) {
10704
+ clearMask |= GL_STENCIL_BUFFER_BIT;
10705
+ glParameters.clearStencil = this.props.clearStencil;
10706
+ }
10707
+ if (clearMask !== 0) {
10708
+ withParameters(this.device, glParameters, () => {
10709
+ this.device.gl.clear(clearMask);
10710
+ });
10711
+ }
10712
+ }
10713
+ /**
10714
+ * WebGL2 - clear a specific color buffer
10715
+ */
10716
+ clearColorBuffer(drawBuffer = 0, value = [0, 0, 0, 0]) {
10717
+ withParameters(this.device.gl2, {
10718
+ framebuffer: this.props.framebuffer
10719
+ }, () => {
10720
+ switch (value.constructor) {
10721
+ case Int32Array:
10722
+ this.device.gl2.clearBufferiv(GL_COLOR, drawBuffer, value);
10723
+ break;
10724
+ case Uint32Array:
10725
+ this.device.gl2.clearBufferuiv(GL_COLOR, drawBuffer, value);
10726
+ break;
10727
+ case Float32Array:
10728
+ default:
10729
+ this.device.gl2.clearBufferfv(GL_COLOR, drawBuffer, value);
10730
+ break;
10731
+ }
10732
+ });
10733
+ }
10734
+ // clearDepthStencil() {
10735
+ // const GL_DEPTH = 0x1801;
10736
+ // const GL_STENCIL = 0x1802;
10737
+ // const GL_DEPTH_STENCIL = 0x84f9;
10738
+ // case GL_DEPTH:
10739
+ // this.device.gl2.clearBufferfv(GL_DEPTH, 0, [value]);
10740
+ // break;
10741
+ // case GL_STENCIL:
10742
+ // this.device.gl2.clearBufferiv(GL_STENCIL, 0, [value]);
10743
+ // break;
10744
+ // case GL_DEPTH_STENCIL:
10745
+ // const [depth, stencil] = value;
10746
+ // this.device.gl2.clearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil);
10747
+ // break;
10748
+ // default:
10749
+ // assert(false, ERR_ARGUMENTS);
10750
+ // }
10751
+ // });
10546
10752
  };
10547
10753
 
10548
10754
  // ../webgl/src/adapter/helpers/uniforms.ts
@@ -11198,7 +11404,7 @@ ${formattedLog}`)();
11198
11404
  */
11199
11405
  draw(options) {
11200
11406
  const {
11201
- renderPass = this.device.getDefaultRenderPass(),
11407
+ renderPass,
11202
11408
  vertexCount,
11203
11409
  // indexCount,
11204
11410
  instanceCount,
@@ -11223,10 +11429,9 @@ ${formattedLog}`)();
11223
11429
  }
11224
11430
  this._applyBindings();
11225
11431
  this._applyUniforms();
11432
+ const webglRenderPass = renderPass;
11226
11433
  withDeviceParameters(this.device, this.props.parameters, () => {
11227
- withGLParameters(this.device, {
11228
- framebuffer: renderPass.props.framebuffer
11229
- }, () => {
11434
+ withGLParameters(this.device, webglRenderPass.glParameters, () => {
11230
11435
  if (isIndexed && isInstanced) {
11231
11436
  this.device.gl2?.drawElementsInstanced(
11232
11437
  drawMode,
@@ -11402,6 +11607,257 @@ ${formattedLog}`)();
11402
11607
  return layout.attributes.find((binding) => binding.name === name) || null;
11403
11608
  }
11404
11609
 
11610
+ // ../webgl/src/adapter/resources/webgl-command-buffer.ts
11611
+ function cast2(value) {
11612
+ return value;
11613
+ }
11614
+ var WEBGLCommandBuffer = class extends CommandBuffer {
11615
+ commands = [];
11616
+ constructor(device) {
11617
+ super({});
11618
+ this.device = device;
11619
+ }
11620
+ submitCommands(commands = this.commands) {
11621
+ for (const command of commands) {
11622
+ switch (command.name) {
11623
+ case "copy-buffer-to-buffer":
11624
+ _copyBufferToBuffer(this.device, command.options);
11625
+ break;
11626
+ case "copy-buffer-to-texture":
11627
+ _copyBufferToTexture(this.device, command.options);
11628
+ break;
11629
+ case "copy-texture-to-buffer":
11630
+ _copyTextureToBuffer(this.device, command.options);
11631
+ break;
11632
+ case "copy-texture-to-texture":
11633
+ _copyTextureToTexture(this.device, command.options);
11634
+ break;
11635
+ }
11636
+ }
11637
+ }
11638
+ };
11639
+ function _copyBufferToBuffer(device, options) {
11640
+ const source = cast2(options.source);
11641
+ const destination = cast2(options.destination);
11642
+ const gl2 = device.assertWebGL2();
11643
+ if (gl2) {
11644
+ gl2.bindBuffer(GL.COPY_READ_BUFFER, source.handle);
11645
+ gl2.bindBuffer(GL.COPY_WRITE_BUFFER, destination.handle);
11646
+ gl2.copyBufferSubData(GL.COPY_READ_BUFFER, GL.COPY_WRITE_BUFFER, options.sourceOffset ?? 0, options.destinationOffset ?? 0, options.size);
11647
+ gl2.bindBuffer(GL.COPY_READ_BUFFER, null);
11648
+ gl2.bindBuffer(GL.COPY_WRITE_BUFFER, null);
11649
+ } else {
11650
+ throw new Error("copyBufferToBuffer not implemented in WebGL1");
11651
+ }
11652
+ }
11653
+ function _copyBufferToTexture(device, options) {
11654
+ throw new Error("Not implemented");
11655
+ }
11656
+ function _copyTextureToBuffer(device, options) {
11657
+ const {
11658
+ /** Texture to copy to/from. */
11659
+ source,
11660
+ /** Mip-map level of the texture to copy to/from. (Default 0) */
11661
+ mipLevel = 0,
11662
+ /** Defines which aspects of the texture to copy to/from. */
11663
+ aspect = "all",
11664
+ /** Width to copy */
11665
+ width = options.source.width,
11666
+ /** Height to copy */
11667
+ height = options.source.height,
11668
+ depthOrArrayLayers = 0,
11669
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
11670
+ origin = [0, 0],
11671
+ /** Destination buffer */
11672
+ destination,
11673
+ /** Offset, in bytes, from the beginning of the buffer to the start of the image data (default 0) */
11674
+ byteOffset = 0,
11675
+ /**
11676
+ * The stride, in bytes, between the beginning of each block row and the subsequent block row.
11677
+ * Required if there are multiple block rows (i.e. the copy height or depth is more than one block).
11678
+ */
11679
+ bytesPerRow,
11680
+ /**
11681
+ * Number of block rows per single image of the texture.
11682
+ * rowsPerImage &times; bytesPerRow is the stride, in bytes, between the beginning of each image of data and the subsequent image.
11683
+ * Required if there are multiple images (i.e. the copy depth is more than one).
11684
+ */
11685
+ rowsPerImage
11686
+ } = options;
11687
+ if (aspect !== "all") {
11688
+ throw new Error("not supported");
11689
+ }
11690
+ if (mipLevel !== 0 || depthOrArrayLayers !== void 0 || bytesPerRow || rowsPerImage) {
11691
+ throw new Error("not implemented");
11692
+ }
11693
+ const gl2 = device.assertWebGL2();
11694
+ const {
11695
+ framebuffer,
11696
+ destroyFramebuffer
11697
+ } = getFramebuffer(source);
11698
+ try {
11699
+ const webglBuffer = destination;
11700
+ const sourceWidth = width || framebuffer.width;
11701
+ const sourceHeight = height || framebuffer.height;
11702
+ const sourceFormat = GL.RGBA;
11703
+ const sourceType = GL.UNSIGNED_BYTE;
11704
+ gl2.bindBuffer(GL.PIXEL_PACK_BUFFER, webglBuffer.handle);
11705
+ gl2.bindFramebuffer(GL.FRAMEBUFFER, framebuffer.handle);
11706
+ gl2.readPixels(origin[0], origin[1], sourceWidth, sourceHeight, sourceFormat, sourceType, byteOffset);
11707
+ } finally {
11708
+ gl2.bindBuffer(GL.PIXEL_PACK_BUFFER, null);
11709
+ gl2.bindFramebuffer(GL.FRAMEBUFFER, null);
11710
+ if (destroyFramebuffer) {
11711
+ framebuffer.destroy();
11712
+ }
11713
+ }
11714
+ }
11715
+ function _copyTextureToTexture(device, options) {
11716
+ const {
11717
+ /** Texture to copy to/from. */
11718
+ source,
11719
+ /** Mip-map level of the texture to copy to/from. (Default 0) */
11720
+ // mipLevel = 0,
11721
+ /** Defines which aspects of the texture to copy to/from. */
11722
+ // aspect = 'all',
11723
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
11724
+ origin = [0, 0],
11725
+ /** Texture to copy to/from. */
11726
+ destination
11727
+ /** Mip-map level of the texture to copy to/from. (Default 0) */
11728
+ // destinationMipLevel = options.mipLevel,
11729
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
11730
+ // destinationOrigin = [0, 0],
11731
+ /** Defines which aspects of the texture to copy to/from. */
11732
+ // destinationAspect = options.aspect,
11733
+ } = options;
11734
+ let {
11735
+ width = options.destination.width,
11736
+ height = options.destination.width
11737
+ // depthOrArrayLayers = 0
11738
+ } = options;
11739
+ const destinationMipmaplevel = 0;
11740
+ const destinationInternalFormat = GL.RGBA;
11741
+ const {
11742
+ framebuffer,
11743
+ destroyFramebuffer
11744
+ } = getFramebuffer(source);
11745
+ const [sourceX, sourceY] = origin;
11746
+ const isSubCopy = false;
11747
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, framebuffer.handle);
11748
+ let texture = null;
11749
+ let textureTarget;
11750
+ if (destination instanceof WEBGLTexture) {
11751
+ texture = destination;
11752
+ width = Number.isFinite(width) ? width : texture.width;
11753
+ height = Number.isFinite(height) ? height : texture.height;
11754
+ texture.bind(0);
11755
+ textureTarget = texture.destination;
11756
+ } else {
11757
+ throw new Error("whoops");
11758
+ }
11759
+ if (!isSubCopy) {
11760
+ device.gl.copyTexImage2D(
11761
+ textureTarget,
11762
+ destinationMipmaplevel,
11763
+ destinationInternalFormat,
11764
+ sourceX,
11765
+ sourceY,
11766
+ width,
11767
+ height,
11768
+ 0
11769
+ /* border must be 0 */
11770
+ );
11771
+ } else {
11772
+ }
11773
+ if (texture) {
11774
+ texture.unbind();
11775
+ }
11776
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
11777
+ if (destroyFramebuffer) {
11778
+ framebuffer.destroy();
11779
+ }
11780
+ return texture;
11781
+ }
11782
+ function getFramebuffer(source) {
11783
+ if (source instanceof Texture) {
11784
+ const {
11785
+ width,
11786
+ height,
11787
+ id
11788
+ } = source;
11789
+ const framebuffer = source.device.createFramebuffer({
11790
+ id: `framebuffer-for-${id}`,
11791
+ width,
11792
+ height,
11793
+ colorAttachments: [source]
11794
+ });
11795
+ return {
11796
+ framebuffer,
11797
+ destroyFramebuffer: true
11798
+ };
11799
+ }
11800
+ return {
11801
+ framebuffer: source,
11802
+ destroyFramebuffer: false
11803
+ };
11804
+ }
11805
+
11806
+ // ../webgl/src/adapter/resources/webgl-command-encoder.ts
11807
+ var WEBGLCommandEncoder = class extends CommandEncoder {
11808
+ constructor(device, props) {
11809
+ super(props);
11810
+ this.device = device;
11811
+ this.commandBuffer = new WEBGLCommandBuffer(device);
11812
+ }
11813
+ destroy() {
11814
+ }
11815
+ finish() {
11816
+ this.commandBuffer.submitCommands();
11817
+ }
11818
+ // beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
11819
+ // beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
11820
+ // finish(options?: {id?: string}): GPUCommandBuffer;
11821
+ copyBufferToBuffer(options) {
11822
+ this.commandBuffer.commands.push({
11823
+ name: "copy-buffer-to-buffer",
11824
+ options
11825
+ });
11826
+ }
11827
+ copyBufferToTexture(options) {
11828
+ this.commandBuffer.commands.push({
11829
+ name: "copy-buffer-to-texture",
11830
+ options
11831
+ });
11832
+ }
11833
+ copyTextureToBuffer(options) {
11834
+ this.commandBuffer.commands.push({
11835
+ name: "copy-texture-to-buffer",
11836
+ options
11837
+ });
11838
+ }
11839
+ copyTextureToTexture(options) {
11840
+ this.commandBuffer.commands.push({
11841
+ name: "copy-texture-to-texture",
11842
+ options
11843
+ });
11844
+ }
11845
+ pushDebugGroup(groupLabel) {
11846
+ }
11847
+ popDebugGroup() {
11848
+ }
11849
+ insertDebugMarker(markerLabel) {
11850
+ }
11851
+ // writeTimestamp(querySet: Query, queryIndex: number): void {}
11852
+ // resolveQuerySet(options: {
11853
+ // querySet: GPUQuerySet,
11854
+ // firstQuery: number,
11855
+ // queryCount: number,
11856
+ // destination: Buffer,
11857
+ // destinationOffset?: number;
11858
+ // }): void;
11859
+ };
11860
+
11405
11861
  // ../webgl/src/adapter/webgl-device.ts
11406
11862
  var LOG_LEVEL2 = 1;
11407
11863
  var _WebGLDevice = class extends Device {
@@ -11565,8 +12021,9 @@ ${formattedLog}`)();
11565
12021
  createCanvasContext(props) {
11566
12022
  throw new Error("WebGL only supports a single canvas");
11567
12023
  }
11568
- _createBuffer(props) {
11569
- return new ClassicBuffer(this, props);
12024
+ createBuffer(props) {
12025
+ const newProps = this._getBufferProps(props);
12026
+ return new ClassicBuffer(this, newProps);
11570
12027
  }
11571
12028
  _createTexture(props) {
11572
12029
  return new WEBGLTexture(this, props);
@@ -11602,6 +12059,9 @@ ${formattedLog}`)();
11602
12059
  });
11603
12060
  return this.renderPass;
11604
12061
  }
12062
+ createCommandEncoder(props) {
12063
+ return new WEBGLCommandEncoder(this, props);
12064
+ }
11605
12065
  /**
11606
12066
  * Offscreen Canvas Support: Commit the frame
11607
12067
  * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/commit
@@ -11636,19 +12096,21 @@ ${formattedLog}`)();
11636
12096
  return this._webglLimits;
11637
12097
  }
11638
12098
  /**
11639
- * Loses the context
11640
- * @note Triggers context loss, mainly for testing
11641
- * @todo Promote to `Device` API?
12099
+ * Triggers device (or WebGL context) loss.
12100
+ * @note primarily intended for testing how application reacts to device loss
11642
12101
  */
11643
12102
  loseDevice() {
12103
+ let deviceLossTriggered = false;
11644
12104
  const ext = this.gl.getExtension("WEBGL_lose_context");
11645
12105
  if (ext) {
12106
+ deviceLossTriggered = true;
11646
12107
  ext.loseContext();
11647
12108
  }
11648
12109
  this._resolveContextLost?.({
11649
12110
  reason: "destroyed",
11650
12111
  message: "Application triggered context loss"
11651
12112
  });
12113
+ return deviceLossTriggered;
11652
12114
  }
11653
12115
  /** Save current WebGL context state onto an internal stack */
11654
12116
  pushState() {
@@ -11665,6 +12127,21 @@ ${formattedLog}`)();
11665
12127
  setSpectorMetadata(handle, props) {
11666
12128
  handle.__SPECTOR_Metadata = props;
11667
12129
  }
12130
+ /**
12131
+ * Returns the GL.<KEY> constant that corresponds to a numeric value of a GL constant
12132
+ * Be aware that there are some duplicates especially for constants that are 0,
12133
+ * so this isn't guaranteed to return the right key in all cases.
12134
+ */
12135
+ getGLKey(value, gl) {
12136
+ gl = gl || this.gl2 || this.gl;
12137
+ const number = Number(value);
12138
+ for (const key in gl) {
12139
+ if (gl[key] === number) {
12140
+ return `GL.${key}`;
12141
+ }
12142
+ }
12143
+ return String(value);
12144
+ }
11668
12145
  };
11669
12146
  var WebGLDevice = _WebGLDevice;
11670
12147
  //
@@ -11687,6 +12164,216 @@ ${formattedLog}`)();
11687
12164
  return Boolean(gl && gl._version === 2);
11688
12165
  }
11689
12166
 
12167
+ // src/transform/transform.ts
12168
+ var Transform = class {
12169
+ /**
12170
+ * Check if Transforms are supported (they are not under WebGL1)
12171
+ * @todo differentiate writing to buffer vs not
12172
+ */
12173
+ static isSupported(device) {
12174
+ return false;
12175
+ }
12176
+ // model: Model;
12177
+ elementCount = 0;
12178
+ // bufferTransform: BufferTransform | null = null;
12179
+ // textureTransform: TextureTransform | null = null;
12180
+ elementIDBuffer = null;
12181
+ constructor(device, props = {}) {
12182
+ this.device = WebGLDevice.attach(device);
12183
+ this.gl = this.device.gl2;
12184
+ this._buildResourceTransforms(props);
12185
+ props = this._updateModelProps(props);
12186
+ this.model = new Model(this.device, {
12187
+ ...props,
12188
+ fs: props.fs || getPassthroughFS({
12189
+ version: getShaderInfo(props.vs).version
12190
+ }),
12191
+ id: props.id || "transform-model",
12192
+ // @ts-expect-error
12193
+ drawMode: props.drawMode || GL.POINTS,
12194
+ vertexCount: props.elementCount
12195
+ });
12196
+ Object.seal(this);
12197
+ }
12198
+ /** Delete owned resources. */
12199
+ destroy() {
12200
+ }
12201
+ /** @deprecated Use destroy*() */
12202
+ delete() {
12203
+ this.destroy();
12204
+ }
12205
+ /** Run one transform loop. */
12206
+ run(options) {
12207
+ const {
12208
+ clearRenderTarget = true
12209
+ } = options || {};
12210
+ const updatedOpts = this._updateDrawOptions(options);
12211
+ if (clearRenderTarget && updatedOpts.framebuffer) {
12212
+ }
12213
+ }
12214
+ /** swap resources if a map is provided */
12215
+ swap() {
12216
+ }
12217
+ /** Return Buffer object for given varying name. */
12218
+ getBuffer(varyingName) {
12219
+ return null;
12220
+ }
12221
+ /** Return data either from Buffer or from Texture */
12222
+ getData(options = {}) {
12223
+ }
12224
+ /** Return framebuffer object if rendering to textures */
12225
+ getFramebuffer() {
12226
+ return null;
12227
+ }
12228
+ /** Update some or all buffer/texture bindings. */
12229
+ update(props) {
12230
+ }
12231
+ // Private
12232
+ _updateModelProps(props) {
12233
+ const updatedProps = {
12234
+ ...props
12235
+ };
12236
+ return updatedProps;
12237
+ }
12238
+ _buildResourceTransforms(props) {
12239
+ }
12240
+ _updateDrawOptions(options) {
12241
+ const updatedOpts = {
12242
+ ...options
12243
+ };
12244
+ return updatedOpts;
12245
+ }
12246
+ };
12247
+
12248
+ // src/geometry/geometry.ts
12249
+ var Geometry = class {
12250
+ userData = {};
12251
+ /** Determines how vertices are read from the 'vertex' attributes */
12252
+ /** @deprecated */
12253
+ drawMode = GL.TRIANGLES;
12254
+ constructor(props = {}) {
12255
+ const {
12256
+ id = uid("geometry"),
12257
+ drawMode = GL.TRIANGLES,
12258
+ attributes = {},
12259
+ indices = null,
12260
+ vertexCount = null
12261
+ } = props;
12262
+ this.id = id;
12263
+ this.drawMode = drawMode;
12264
+ this.topology = props.topology || convertToTopology(drawMode);
12265
+ if (indices) {
12266
+ this.indices = ArrayBuffer.isView(indices) ? {
12267
+ value: indices,
12268
+ size: 1
12269
+ } : indices;
12270
+ }
12271
+ this.attributes = {};
12272
+ for (const [attributeName, attributeValue] of Object.entries(attributes)) {
12273
+ const attribute = ArrayBuffer.isView(attributeValue) ? {
12274
+ value: attributeValue
12275
+ } : attributeValue;
12276
+ assert2(ArrayBuffer.isView(attribute.value), `${this._print(attributeName)}: must be typed array or object with value as typed array`);
12277
+ if ((attributeName === "POSITION" || attributeName === "positions") && !attribute.size) {
12278
+ attribute.size = 3;
12279
+ }
12280
+ if (attributeName === "indices") {
12281
+ assert2(!this.indices);
12282
+ this.indices = attribute;
12283
+ } else {
12284
+ this.attributes[attributeName] = attribute;
12285
+ }
12286
+ }
12287
+ if (this.indices && this.indices.isIndexed !== void 0) {
12288
+ this.indices = Object.assign({}, this.indices);
12289
+ delete this.indices.isIndexed;
12290
+ }
12291
+ this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
12292
+ }
12293
+ /** @deprecated Use string topology constants instead */
12294
+ get mode() {
12295
+ return this.drawMode;
12296
+ }
12297
+ getVertexCount() {
12298
+ return this.vertexCount;
12299
+ }
12300
+ // Return an object with all attributes plus indices added as a field.
12301
+ getAttributes() {
12302
+ return this.indices ? {
12303
+ indices: this.indices,
12304
+ ...this.attributes
12305
+ } : this.attributes;
12306
+ }
12307
+ // PRIVATE
12308
+ _print(attributeName) {
12309
+ return `Geometry ${this.id} attribute ${attributeName}`;
12310
+ }
12311
+ // GeometryAttribute
12312
+ // value: typed array
12313
+ // type: indices, vertices, uvs
12314
+ // size: elements per vertex
12315
+ // target: WebGL buffer type (string or constant)
12316
+ _setAttributes(attributes, indices) {
12317
+ return this;
12318
+ }
12319
+ _calculateVertexCount(attributes, indices) {
12320
+ if (indices) {
12321
+ return indices.value.length;
12322
+ }
12323
+ let vertexCount = Infinity;
12324
+ for (const attributeName in attributes) {
12325
+ const attribute = attributes[attributeName];
12326
+ const {
12327
+ value,
12328
+ size,
12329
+ constant
12330
+ } = attribute;
12331
+ if (!constant && value && size >= 1) {
12332
+ vertexCount = Math.min(vertexCount, value.length / size);
12333
+ }
12334
+ }
12335
+ assert2(Number.isFinite(vertexCount));
12336
+ return vertexCount;
12337
+ }
12338
+ };
12339
+ /** @deprecated */
12340
+ __publicField(Geometry, "DRAW_MODE", {
12341
+ POINTS: GL.POINTS,
12342
+ // draw single points.
12343
+ LINES: GL.LINES,
12344
+ // draw lines. Each vertex connects to the one after it.
12345
+ LINE_LOOP: GL.LINE_LOOP,
12346
+ // draw lines. Each set of two vertices is treated as a separate line segment.
12347
+ LINE_STRIP: GL.LINE_STRIP,
12348
+ // draw a connected group of line segments from the first vertex to the last
12349
+ TRIANGLES: GL.TRIANGLES,
12350
+ // draw triangles. Each set of three vertices creates a separate triangle.
12351
+ TRIANGLE_STRIP: GL.TRIANGLE_STRIP,
12352
+ // draw a connected group of triangles.
12353
+ TRIANGLE_FAN: GL.TRIANGLE_FAN
12354
+ // draw a connected group of triangles.
12355
+ });
12356
+ function convertToTopology(drawMode) {
12357
+ switch (drawMode) {
12358
+ case GL.POINTS:
12359
+ return "point-list";
12360
+ case GL.LINES:
12361
+ return "line-list";
12362
+ case GL.LINE_STRIP:
12363
+ return "line-strip";
12364
+ case GL.TRIANGLES:
12365
+ return "triangle-list";
12366
+ case GL.TRIANGLE_STRIP:
12367
+ return "triangle-strip";
12368
+ case GL.TRIANGLE_FAN:
12369
+ return "triangle-fan";
12370
+ case GL.LINE_LOOP:
12371
+ return "line-loop";
12372
+ default:
12373
+ throw new Error(String(drawMode));
12374
+ }
12375
+ }
12376
+
11690
12377
  // src/lib/clip-space.ts
11691
12378
  var CLIPSPACE_VERTEX_SHADER = glsl`\
11692
12379
  attribute vec2 aClipSpacePosition;