@luma.gl/webgl 9.1.0-alpha.10 → 9.1.0-alpha.13

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 (63) hide show
  1. package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
  2. package/dist/adapter/device-helpers/webgl-device-features.js +1 -2
  3. package/dist/adapter/helpers/format-utils.d.ts.map +1 -0
  4. package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
  5. package/dist/adapter/helpers/get-shader-layout.js +1 -3
  6. package/dist/adapter/helpers/typed-array-utils.d.ts.map +1 -0
  7. package/dist/adapter/helpers/webgl-texture-utils.d.ts +85 -18
  8. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  9. package/dist/adapter/helpers/webgl-texture-utils.js +210 -18
  10. package/dist/adapter/resources/webgl-framebuffer.d.ts +1 -2
  11. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  12. package/dist/adapter/resources/webgl-framebuffer.js +27 -31
  13. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  14. package/dist/adapter/resources/webgl-render-pipeline.d.ts +1 -3
  15. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  16. package/dist/adapter/resources/webgl-texture.d.ts +1 -1
  17. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  18. package/dist/adapter/resources/webgl-texture.js +33 -8
  19. package/dist/adapter/webgl-device.d.ts +1 -2
  20. package/dist/adapter/webgl-device.d.ts.map +1 -1
  21. package/dist/adapter/webgl-device.js +2 -2
  22. package/dist/deprecated/accessor.d.ts.map +1 -0
  23. package/dist/{classic → deprecated}/accessor.js +36 -1
  24. package/dist/deprecated/clear.d.ts.map +1 -0
  25. package/dist/{classic → deprecated}/clear.js +2 -0
  26. package/dist/dist.dev.js +514 -457
  27. package/dist/dist.min.js +2 -2
  28. package/dist/index.cjs +509 -459
  29. package/dist/index.cjs.map +4 -4
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/utils/fill-array.d.ts +4 -4
  34. package/dist/utils/fill-array.d.ts.map +1 -1
  35. package/package.json +5 -5
  36. package/src/adapter/device-helpers/webgl-device-features.ts +5 -2
  37. package/src/adapter/helpers/get-shader-layout.ts +1 -3
  38. package/src/adapter/helpers/webgl-texture-utils.ts +356 -37
  39. package/src/adapter/resources/webgl-framebuffer.ts +37 -42
  40. package/src/adapter/resources/webgl-render-pass.ts +3 -3
  41. package/src/adapter/resources/webgl-render-pipeline.ts +10 -3
  42. package/src/adapter/resources/webgl-texture.ts +41 -8
  43. package/src/adapter/webgl-device.ts +13 -4
  44. package/src/{classic → deprecated}/accessor.ts +44 -3
  45. package/src/{classic → deprecated}/clear.ts +3 -1
  46. package/src/index.ts +1 -1
  47. package/src/utils/fill-array.ts +4 -4
  48. package/dist/classic/accessor.d.ts.map +0 -1
  49. package/dist/classic/clear.d.ts.map +0 -1
  50. package/dist/classic/copy-and-blit.d.ts +0 -64
  51. package/dist/classic/copy-and-blit.d.ts.map +0 -1
  52. package/dist/classic/copy-and-blit.js +0 -194
  53. package/dist/classic/format-utils.d.ts.map +0 -1
  54. package/dist/classic/typed-array-utils.d.ts.map +0 -1
  55. package/src/classic/copy-and-blit.ts +0 -323
  56. /package/dist/{classic → adapter/helpers}/format-utils.d.ts +0 -0
  57. /package/dist/{classic → adapter/helpers}/format-utils.js +0 -0
  58. /package/dist/{classic → adapter/helpers}/typed-array-utils.d.ts +0 -0
  59. /package/dist/{classic → adapter/helpers}/typed-array-utils.js +0 -0
  60. /package/dist/{classic → deprecated}/accessor.d.ts +0 -0
  61. /package/dist/{classic → deprecated}/clear.d.ts +0 -0
  62. /package/src/{classic → adapter/helpers}/format-utils.ts +0 -0
  63. /package/src/{classic → adapter/helpers}/typed-array-utils.ts +0 -0
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export { WEBGLCommandEncoder } from "./adapter/resources/webgl-command-encoder.j
13
13
  export { WEBGLRenderPass } from "./adapter/resources/webgl-render-pass.js";
14
14
  export { WEBGLVertexArray } from "./adapter/resources/webgl-vertex-array.js";
15
15
  export { WEBGLTransformFeedback } from "./adapter/resources/webgl-transform-feedback.js";
16
- export { Accessor } from "./classic/accessor.js";
16
+ export { Accessor } from "./deprecated/accessor.js";
17
17
  export type { AccessorObject } from "./types.js";
18
18
  export { setDeviceParameters, withDeviceParameters } from "./adapter/converters/device-parameters.js";
19
19
  export { getShaderLayout } from "./adapter/helpers/get-shader-layout.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,YAAY,EAAC,iBAAiB,EAAC,wDAAqD;AAGpF,OAAO,EAAC,aAAa,EAAC,mCAAgC;AACtD,YAAY,EAAC,YAAY,EAAC,mCAAgC;AAG1D,OAAO,EAAC,WAAW,EAAC,kCAA+B;AACnD,OAAO,EAAC,kBAAkB,EAAC,0CAAuC;AAGlE,OAAO,EAAC,WAAW,EAAC,4CAAyC;AAC7D,OAAO,EAAC,YAAY,EAAC,6CAA0C;AAE/D,OAAO,EAAC,WAAW,EAAC,4CAAyC;AAC7D,OAAO,EAAC,YAAY,EAAC,6CAA0C;AAC/D,OAAO,EAAC,gBAAgB,EAAC,iDAA8C;AAEvE,OAAO,EAAC,mBAAmB,EAAC,qDAAkD;AAE9E,OAAO,EAAC,mBAAmB,EAAC,qDAAkD;AAC9E,OAAO,EAAC,eAAe,EAAC,iDAA8C;AAEtE,OAAO,EAAC,gBAAgB,EAAC,kDAA+C;AAGxE,OAAO,EAAC,sBAAsB,EAAC,wDAAqD;AAGpF,OAAO,EAAC,QAAQ,EAAC,8BAA2B;AAC5C,YAAY,EAAC,cAAc,EAAC,mBAAgB;AAI5C,OAAO,EAAC,mBAAmB,EAAE,oBAAoB,EAAC,kDAA+C;AAGjG,OAAO,EAAC,eAAe,EAAC,+CAA4C;AACpE,OAAO,EAAC,iBAAiB,EAAC,uDAAoD;AAG9E,OAAO,EAAC,eAAe,IAAI,gBAAgB,EAAC,gDAA6C;AAGzF,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,eAAe,EAChB,sDAAmD;AAEpD,OAAO,EAAC,gBAAgB,EAAC,mDAAgD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,YAAY,EAAC,iBAAiB,EAAC,wDAAqD;AAGpF,OAAO,EAAC,aAAa,EAAC,mCAAgC;AACtD,YAAY,EAAC,YAAY,EAAC,mCAAgC;AAG1D,OAAO,EAAC,WAAW,EAAC,kCAA+B;AACnD,OAAO,EAAC,kBAAkB,EAAC,0CAAuC;AAGlE,OAAO,EAAC,WAAW,EAAC,4CAAyC;AAC7D,OAAO,EAAC,YAAY,EAAC,6CAA0C;AAE/D,OAAO,EAAC,WAAW,EAAC,4CAAyC;AAC7D,OAAO,EAAC,YAAY,EAAC,6CAA0C;AAC/D,OAAO,EAAC,gBAAgB,EAAC,iDAA8C;AAEvE,OAAO,EAAC,mBAAmB,EAAC,qDAAkD;AAE9E,OAAO,EAAC,mBAAmB,EAAC,qDAAkD;AAC9E,OAAO,EAAC,eAAe,EAAC,iDAA8C;AAEtE,OAAO,EAAC,gBAAgB,EAAC,kDAA+C;AAGxE,OAAO,EAAC,sBAAsB,EAAC,wDAAqD;AAGpF,OAAO,EAAC,QAAQ,EAAC,iCAA8B;AAC/C,YAAY,EAAC,cAAc,EAAC,mBAAgB;AAI5C,OAAO,EAAC,mBAAmB,EAAE,oBAAoB,EAAC,kDAA+C;AAGjG,OAAO,EAAC,eAAe,EAAC,+CAA4C;AACpE,OAAO,EAAC,iBAAiB,EAAC,uDAAoD;AAG9E,OAAO,EAAC,eAAe,IAAI,gBAAgB,EAAC,gDAA6C;AAGzF,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,eAAe,EAChB,sDAAmD;AAEpD,OAAO,EAAC,gBAAgB,EAAC,mDAAgD"}
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ export { WEBGLVertexArray } from "./adapter/resources/webgl-vertex-array.js";
22
22
  // WebGL adapter classes
23
23
  export { WEBGLTransformFeedback } from "./adapter/resources/webgl-transform-feedback.js";
24
24
  // WebGL adapter classes
25
- export { Accessor } from "./classic/accessor.js";
25
+ export { Accessor } from "./deprecated/accessor.js";
26
26
  // Unified parameter API
27
27
  export { setDeviceParameters, withDeviceParameters } from "./adapter/converters/device-parameters.js";
28
28
  // HELPERS - EXPERIMENTAL
@@ -1,8 +1,8 @@
1
- import type { NumberArray } from '@math.gl/types';
1
+ import type { NumericArray } from '@math.gl/types';
2
2
  export declare function fillArray(options: {
3
- target: NumberArray;
4
- source: NumberArray;
3
+ target: NumericArray;
4
+ source: NumericArray;
5
5
  start?: number;
6
6
  count?: number;
7
- }): NumberArray;
7
+ }): NumericArray;
8
8
  //# sourceMappingURL=fill-array.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fill-array.d.ts","sourceRoot":"","sources":["../../src/utils/fill-array.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAGhD,wBAAgB,SAAS,CAAC,OAAO,EAAE;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,WAAW,CAsBd"}
1
+ {"version":3,"file":"fill-array.d.ts","sourceRoot":"","sources":["../../src/utils/fill-array.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAGjD,wBAAgB,SAAS,CAAC,OAAO,EAAE;IACjC,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,YAAY,CAsBf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma.gl/webgl",
3
- "version": "9.1.0-alpha.10",
3
+ "version": "9.1.0-alpha.13",
4
4
  "description": "WebGL2 adapter for the luma.gl core API",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,12 +40,12 @@
40
40
  "prepublishOnly": "npm run build-minified-bundle && npm run build-dev-bundle"
41
41
  },
42
42
  "peerDependencies": {
43
- "@luma.gl/core": "^9.0.0-beta"
43
+ "@luma.gl/core": "9.1.0-alpha.10"
44
44
  },
45
45
  "dependencies": {
46
- "@luma.gl/constants": "9.1.0-alpha.10",
47
- "@math.gl/types": "^4.0.0",
46
+ "@luma.gl/constants": "9.1.0-alpha.13",
47
+ "@math.gl/types": "4.1.0-alpha.3",
48
48
  "@probe.gl/env": "^4.0.8"
49
49
  },
50
- "gitHead": "f419cdc284e87b553df60af49d2888ac7dbbf288"
50
+ "gitHead": "c2c641d67a5aec97467de13b0e3d8f9307ba03c2"
51
51
  }
@@ -8,8 +8,11 @@
8
8
  import {DeviceFeature, DeviceFeatures} from '@luma.gl/core';
9
9
  import {GLExtensions} from '@luma.gl/constants';
10
10
  import {getWebGLExtension} from '../../context/helpers/webgl-extensions';
11
- import {isTextureFeature, checkTextureFeature} from '../converters/texture-formats';
12
- import {TEXTURE_FEATURES} from '../converters/texture-formats';
11
+ import {
12
+ isTextureFeature,
13
+ checkTextureFeature,
14
+ TEXTURE_FEATURES
15
+ } from '../converters/texture-formats';
13
16
 
14
17
  /**
15
18
  * Defines luma.gl "feature" names and semantics
@@ -11,7 +11,6 @@ import type {
11
11
  } from '@luma.gl/core';
12
12
 
13
13
  import {GL} from '@luma.gl/constants';
14
- import {Accessor} from '../../classic/accessor'; // TODO - should NOT depend on classic API
15
14
  import {decodeGLUniformType, decodeGLAttributeType, isSamplerUniform} from './decode-webgl-types';
16
15
 
17
16
  /**
@@ -143,8 +142,7 @@ function readVaryings(gl: WebGL2RenderingContext, program: WebGLProgram): Varyin
143
142
  }
144
143
  const {name, type: compositeType, size} = activeInfo;
145
144
  const {glType, components} = decodeGLUniformType(compositeType);
146
- const accessor = new Accessor({type: glType, size: size * components});
147
- const varying = {location, name, accessor}; // Base values
145
+ const varying = {location, name, type: glType, size: size * components}; // Base values
148
146
  varyings.push(varying);
149
147
  }
150
148
 
@@ -7,7 +7,8 @@
7
7
  //
8
8
 
9
9
  import type {ExternalImage} from '@luma.gl/core';
10
- // import {Buffer} from '@luma.gl/core';
10
+ import {Buffer, Texture, Framebuffer, FramebufferProps} from '@luma.gl/core';
11
+
11
12
  import {
12
13
  GL,
13
14
  GLTextureTarget,
@@ -18,39 +19,36 @@ import {
18
19
 
19
20
  import {TypedArray} from '@math.gl/types';
20
21
 
22
+ import {WEBGLFramebuffer} from '../resources/webgl-framebuffer';
23
+ import {getGLTypeFromTypedArray, getTypedArrayFromGLType} from './typed-array-utils';
24
+ import {glFormatToComponents, glTypeToBytes} from './format-utils';
25
+ import {WEBGLBuffer} from '../resources/webgl-buffer';
26
+ import {WEBGLTexture} from '../resources/webgl-texture';
27
+
21
28
  /** A "border" parameter is required in many WebGL texture APIs, but must always be 0... */
22
29
  const BORDER = 0;
23
30
 
31
+ /**
32
+ * Options for setting data into a texture
33
+ */
24
34
  export type WebGLSetTextureOptions = {
25
35
  dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d';
26
36
  height: number;
27
37
  width: number;
28
- depth?: number;
29
- level?: number;
38
+ depth: number;
39
+ mipLevel?: number;
30
40
  glTarget: GLTextureTarget;
31
41
  glInternalFormat: GL;
32
42
  glFormat: GLTexelDataFormat;
33
43
  glType: GLPixelType;
34
44
  compressed?: boolean;
35
-
36
45
  byteOffset?: number;
37
46
  byteLength?: number;
38
47
  };
39
48
 
40
49
  /**
41
- * @param {*} pixels, data -
42
- * null - create empty texture of specified format
43
- * Typed array - init from image data in typed array
44
- * Buffer|WebGLBuffer - (WEBGL2) init from image data in WebGLBuffer
45
- * HTMLImageElement|Image - Inits with content of image. Auto width/height
46
- * HTMLCanvasElement - Inits with contents of canvas. Auto width/height
47
- * HTMLVideoElement - Creates video texture. Auto width/height
50
+ * Options for copying an image or data into a texture
48
51
  *
49
- * @param x - xOffset from where texture to be updated
50
- * @param y - yOffset from where texture to be updated
51
- * @param width - width of the sub image to be updated
52
- * @param height - height of the sub image to be updated
53
- * @param level - mip level to be updated
54
52
  * @param {GLenum} format - internal format of image data.
55
53
  * @param {GLenum} type
56
54
  * - format of array (autodetect from type) or
@@ -61,12 +59,19 @@ export type WebGLSetTextureOptions = {
61
59
  */
62
60
  export type WebGLCopyTextureOptions = {
63
61
  dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d';
64
- level?: number;
65
- height: number;
62
+ /** mip level to be updated */
63
+ mipLevel?: number;
64
+ /** width of the sub image to be updated */
66
65
  width: number;
66
+ /** height of the sub image to be updated */
67
+ height: number;
68
+ /** depth of texture to be updated */
67
69
  depth?: number;
70
+ /** xOffset from where texture to be updated */
68
71
  x?: number;
72
+ /** yOffset from where texture to be updated */
69
73
  y?: number;
74
+ /** yOffset from where texture to be updated */
70
75
  z?: number;
71
76
 
72
77
  glTarget: GLTextureTarget;
@@ -74,7 +79,6 @@ export type WebGLCopyTextureOptions = {
74
79
  glFormat: GL;
75
80
  glType: GL;
76
81
  compressed?: boolean;
77
-
78
82
  byteOffset?: number;
79
83
  byteLength?: number;
80
84
  };
@@ -112,30 +116,34 @@ export function initializeTextureStorage(
112
116
  /**
113
117
  * Copy a region of compressed data from a GPU memory buffer into this texture.
114
118
  */
115
- export function copyCPUImageToMipLevel(
119
+ export function copyExternalImageToMipLevel(
116
120
  gl: WebGL2RenderingContext,
121
+ handle: WebGLTexture,
117
122
  image: ExternalImage,
118
123
  options: WebGLCopyTextureOptions
119
124
  ): void {
120
- const {dimension, width, height, depth = 0, level = 0} = options;
125
+ const {width, height} = options;
126
+ const {dimension, depth = 0, mipLevel = 0} = options;
121
127
  const {x = 0, y = 0, z = 0} = options;
122
128
  const {glFormat, glType} = options;
123
- const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
124
129
 
125
- // width = size.width,
126
- // height = size.height
130
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
127
131
 
128
132
  switch (dimension) {
129
133
  case '2d-array':
130
134
  case '3d':
135
+ gl.bindTexture(glTarget, handle);
131
136
  // prettier-ignore
132
- gl.texSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, glType, image);
137
+ gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, image);
138
+ gl.bindTexture(glTarget, null);
133
139
  break;
134
140
 
135
141
  case '2d':
136
142
  case 'cube':
143
+ gl.bindTexture(glTarget, handle);
137
144
  // prettier-ignore
138
- gl.texSubImage2D(glTarget, level, x, y, width, height, glFormat, glType, image);
145
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, image);
146
+ gl.bindTexture(glTarget, null);
139
147
  break;
140
148
 
141
149
  default:
@@ -151,7 +159,7 @@ export function copyCPUDataToMipLevel(
151
159
  typedArray: TypedArray,
152
160
  options: WebGLCopyTextureOptions
153
161
  ): void {
154
- const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
162
+ const {dimension, width, height, depth = 0, mipLevel = 0, byteOffset = 0} = options;
155
163
  const {x = 0, y = 0, z = 0} = options;
156
164
  const {glFormat, glType, compressed} = options;
157
165
  const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
@@ -163,10 +171,10 @@ export function copyCPUDataToMipLevel(
163
171
  case '3d':
164
172
  if (compressed) {
165
173
  // prettier-ignore
166
- gl.compressedTexSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, typedArray, byteOffset); // , byteLength
174
+ gl.compressedTexSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, typedArray, byteOffset); // , byteLength
167
175
  } else {
168
176
  // prettier-ignore
169
- gl.texSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, glType, typedArray, byteOffset); // , byteLength
177
+ gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, typedArray, byteOffset); // , byteLength
170
178
  }
171
179
  break;
172
180
 
@@ -174,10 +182,10 @@ export function copyCPUDataToMipLevel(
174
182
  case 'cube':
175
183
  if (compressed) {
176
184
  // prettier-ignore
177
- gl.compressedTexSubImage2D(glTarget, level, x, y, width, height, glFormat, typedArray, byteOffset); // , byteLength
185
+ gl.compressedTexSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, typedArray, byteOffset); // , byteLength
178
186
  } else {
179
187
  // prettier-ignore
180
- gl.texSubImage2D(glTarget, level, x, y, width, height, glFormat, glType, typedArray, byteOffset); // , byteLength
188
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, typedArray, byteOffset); // , byteLength
181
189
  }
182
190
  break;
183
191
 
@@ -195,7 +203,7 @@ export function copyGPUBufferToMipLevel(
195
203
  byteLength: number,
196
204
  options: WebGLCopyTextureOptions
197
205
  ): void {
198
- const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
206
+ const {dimension, width, height, depth = 0, mipLevel = 0, byteOffset = 0} = options;
199
207
  const {x = 0, y = 0, z = 0} = options;
200
208
  const {glFormat, glType, compressed} = options;
201
209
  const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
@@ -209,10 +217,10 @@ export function copyGPUBufferToMipLevel(
209
217
  if (compressed) {
210
218
  // TODO enable extension?
211
219
  // prettier-ignore
212
- gl.compressedTexSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, byteLength, byteOffset);
220
+ gl.compressedTexSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, byteLength, byteOffset);
213
221
  } else {
214
222
  // prettier-ignore
215
- gl.texSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, glType, byteOffset);
223
+ gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, byteOffset);
216
224
  }
217
225
  break;
218
226
 
@@ -220,10 +228,10 @@ export function copyGPUBufferToMipLevel(
220
228
  case 'cube':
221
229
  if (compressed) {
222
230
  // prettier-ignore
223
- gl.compressedTexSubImage2D(glTarget, level, x, y, width, height, glFormat, byteLength, byteOffset);
231
+ gl.compressedTexSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, byteLength, byteOffset);
224
232
  } else {
225
233
  // prettier-ignore
226
- gl.texSubImage2D(glTarget, level, x, y, width, height, BORDER, glFormat, byteOffset);
234
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, BORDER, glFormat, byteOffset);
227
235
  }
228
236
  break;
229
237
 
@@ -255,7 +263,7 @@ export function getWebGLTextureTarget(
255
263
  * @note We still bind the texture using GL.TEXTURE_CUBE_MAP, but we need to use the face-specific target when setting mip levels.
256
264
  * @returns glTarget unchanged, if dimension !== 'cube'.
257
265
  */
258
- function getWebGLCubeFaceTarget(
266
+ export function getWebGLCubeFaceTarget(
259
267
  glTarget: GLTextureTarget,
260
268
  dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d',
261
269
  level: number
@@ -482,3 +490,314 @@ export function setMipLevelFromGPUBuffer(
482
490
  gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, null);
483
491
  }
484
492
  */
493
+
494
+ /**
495
+ * Copies data from a type or a Texture object into ArrayBuffer object.
496
+ * App can provide targetPixelArray or have it auto allocated by this method
497
+ * newly allocated by this method unless provided by app.
498
+ * @deprecated Use CommandEncoder.copyTextureToBuffer and Buffer.read
499
+ * @note Slow requires roundtrip to GPU
500
+ *
501
+ * @param source
502
+ * @param options
503
+ * @returns pixel array,
504
+ */
505
+ export function readPixelsToArray(
506
+ source: Framebuffer | Texture,
507
+ options?: {
508
+ sourceX?: number;
509
+ sourceY?: number;
510
+ sourceFormat?: number;
511
+ sourceAttachment?: number;
512
+ target?: Uint8Array | Uint16Array | Float32Array;
513
+ // following parameters are auto deduced if not provided
514
+ sourceWidth?: number;
515
+ sourceHeight?: number;
516
+ sourceDepth?: number;
517
+ sourceType?: number;
518
+ }
519
+ ): Uint8Array | Uint16Array | Float32Array {
520
+ const {
521
+ sourceX = 0,
522
+ sourceY = 0,
523
+ sourceAttachment = GL.COLOR_ATTACHMENT0 // TODO - support gl.readBuffer
524
+ } = options || {};
525
+ let {
526
+ target = null,
527
+ // following parameters are auto deduced if not provided
528
+ sourceWidth,
529
+ sourceHeight,
530
+ sourceDepth,
531
+ sourceFormat,
532
+ sourceType
533
+ } = options || {};
534
+
535
+ const {framebuffer, deleteFramebuffer} = getFramebuffer(source);
536
+ // assert(framebuffer);
537
+ const {gl, handle} = framebuffer;
538
+ const attachment = sourceAttachment - GL.COLOR_ATTACHMENT0;
539
+
540
+ sourceWidth ||= framebuffer.width;
541
+ sourceHeight ||= framebuffer.height;
542
+
543
+ // TODO - Set and unset gl.readBuffer
544
+ // if (sourceAttachment === GL.COLOR_ATTACHMENT0 && handle === null) {
545
+ // sourceAttachment = GL.FRONT;
546
+ // }
547
+
548
+ sourceDepth = framebuffer.colorAttachments[attachment]?.texture?.depth || 1;
549
+
550
+ sourceFormat ||= framebuffer.colorAttachments[attachment]?.texture?.glFormat || GL.RGBA;
551
+ // Deduce the type from color attachment if not provided.
552
+ sourceType ||= framebuffer.colorAttachments[attachment]?.texture?.glType || GL.UNSIGNED_BYTE;
553
+
554
+ // Deduce type and allocated pixelArray if needed
555
+ target = getPixelArray(target, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
556
+
557
+ // Pixel array available, if necessary, deduce type from it.
558
+ sourceType = sourceType || getGLTypeFromTypedArray(target);
559
+
560
+ const prevHandle = gl.bindFramebuffer(GL.FRAMEBUFFER, handle);
561
+ gl.readPixels(sourceX, sourceY, sourceWidth, sourceHeight, sourceFormat, sourceType, target);
562
+ // @ts-expect-error
563
+ gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
564
+ if (deleteFramebuffer) {
565
+ framebuffer.destroy();
566
+ }
567
+ return target;
568
+ }
569
+
570
+ /**
571
+ * Copies data from a Framebuffer or a Texture object into a Buffer object.
572
+ * NOTE: doesn't wait for copy to be complete, it programs GPU to perform a DMA transffer.
573
+ * @deprecated Use CommandEncoder
574
+ * @param source
575
+ * @param options
576
+ */
577
+ export function readPixelsToBuffer(
578
+ source: Framebuffer | Texture,
579
+ options?: {
580
+ sourceX?: number;
581
+ sourceY?: number;
582
+ sourceFormat?: number;
583
+ target?: Buffer; // A new Buffer object is created when not provided.
584
+ targetByteOffset?: number; // byte offset in buffer object
585
+ // following parameters are auto deduced if not provided
586
+ sourceWidth?: number;
587
+ sourceHeight?: number;
588
+ sourceType?: number;
589
+ }
590
+ ): WEBGLBuffer {
591
+ const {
592
+ target,
593
+ sourceX = 0,
594
+ sourceY = 0,
595
+ sourceFormat = GL.RGBA,
596
+ targetByteOffset = 0
597
+ } = options || {};
598
+ // following parameters are auto deduced if not provided
599
+ let {sourceWidth, sourceHeight, sourceType} = options || {};
600
+ const {framebuffer, deleteFramebuffer} = getFramebuffer(source);
601
+ // assert(framebuffer);
602
+ sourceWidth = sourceWidth || framebuffer.width;
603
+ sourceHeight = sourceHeight || framebuffer.height;
604
+
605
+ // Asynchronous read (PIXEL_PACK_BUFFER) is WebGL2 only feature
606
+ const webglFramebuffer = framebuffer;
607
+
608
+ // deduce type if not available.
609
+ sourceType = sourceType || GL.UNSIGNED_BYTE;
610
+
611
+ let webglBufferTarget = target as unknown as WEBGLBuffer | undefined;
612
+ if (!webglBufferTarget) {
613
+ // Create new buffer with enough size
614
+ const components = glFormatToComponents(sourceFormat);
615
+ const byteCount = glTypeToBytes(sourceType);
616
+ const byteLength = targetByteOffset + sourceWidth * sourceHeight * components * byteCount;
617
+ webglBufferTarget = webglFramebuffer.device.createBuffer({byteLength});
618
+ }
619
+
620
+ // TODO(donmccurdy): Do we have tests to confirm this is working?
621
+ const commandEncoder = source.device.createCommandEncoder();
622
+ commandEncoder.copyTextureToBuffer({
623
+ source: source as Texture,
624
+ width: sourceWidth,
625
+ height: sourceHeight,
626
+ origin: [sourceX, sourceY],
627
+ destination: webglBufferTarget,
628
+ byteOffset: targetByteOffset
629
+ });
630
+ commandEncoder.destroy();
631
+
632
+ if (deleteFramebuffer) {
633
+ framebuffer.destroy();
634
+ }
635
+
636
+ return webglBufferTarget;
637
+ }
638
+
639
+ /**
640
+ * Copy a rectangle from a Framebuffer or Texture object into a texture (at an offset)
641
+ * @deprecated Use CommandEncoder
642
+ */
643
+ // eslint-disable-next-line complexity, max-statements
644
+ export function copyToTexture(
645
+ source: Framebuffer | Texture,
646
+ target: Texture | GL,
647
+ options?: {
648
+ sourceX?: number;
649
+ sourceY?: number;
650
+
651
+ targetX?: number;
652
+ targetY?: number;
653
+ targetZ?: number;
654
+ targetMipmaplevel?: number;
655
+ targetInternalFormat?: number;
656
+
657
+ width?: number; // defaults to target width
658
+ height?: number; // defaults to target height
659
+ }
660
+ ): Texture {
661
+ const {
662
+ sourceX = 0,
663
+ sourceY = 0,
664
+ // attachment = GL.COLOR_ATTACHMENT0, // TODO - support gl.readBuffer
665
+ targetMipmaplevel = 0,
666
+ targetInternalFormat = GL.RGBA
667
+ } = options || {};
668
+ let {
669
+ targetX,
670
+ targetY,
671
+ targetZ,
672
+ width, // defaults to target width
673
+ height // defaults to target height
674
+ } = options || {};
675
+
676
+ const {framebuffer, deleteFramebuffer} = getFramebuffer(source);
677
+ // assert(framebuffer);
678
+ const webglFramebuffer = framebuffer;
679
+ const {device, handle} = webglFramebuffer;
680
+ const isSubCopy =
681
+ typeof targetX !== 'undefined' ||
682
+ typeof targetY !== 'undefined' ||
683
+ typeof targetZ !== 'undefined';
684
+ targetX = targetX || 0;
685
+ targetY = targetY || 0;
686
+ targetZ = targetZ || 0;
687
+ const prevHandle = device.gl.bindFramebuffer(GL.FRAMEBUFFER, handle);
688
+ // TODO - support gl.readBuffer (WebGL2 only)
689
+ // const prevBuffer = gl.readBuffer(attachment);
690
+ // assert(target);
691
+ let texture: WEBGLTexture | null = null;
692
+ let textureTarget: GL;
693
+ if (target instanceof WEBGLTexture) {
694
+ texture = target;
695
+ width = Number.isFinite(width) ? width : texture.width;
696
+ height = Number.isFinite(height) ? height : texture.height;
697
+ texture?.bind(0);
698
+ // @ts-ignore
699
+ textureTarget = texture.target;
700
+ } else {
701
+ // @ts-ignore
702
+ textureTarget = target;
703
+ }
704
+
705
+ if (!isSubCopy) {
706
+ device.gl.copyTexImage2D(
707
+ textureTarget,
708
+ targetMipmaplevel,
709
+ targetInternalFormat,
710
+ sourceX,
711
+ sourceY,
712
+ width,
713
+ height,
714
+ 0 /* border must be 0 */
715
+ );
716
+ } else {
717
+ switch (textureTarget) {
718
+ case GL.TEXTURE_2D:
719
+ case GL.TEXTURE_CUBE_MAP:
720
+ device.gl.copyTexSubImage2D(
721
+ textureTarget,
722
+ targetMipmaplevel,
723
+ targetX,
724
+ targetY,
725
+ sourceX,
726
+ sourceY,
727
+ width,
728
+ height
729
+ );
730
+ break;
731
+ case GL.TEXTURE_2D_ARRAY:
732
+ case GL.TEXTURE_3D:
733
+ device.gl.copyTexSubImage3D(
734
+ textureTarget,
735
+ targetMipmaplevel,
736
+ targetX,
737
+ targetY,
738
+ targetZ,
739
+ sourceX,
740
+ sourceY,
741
+ width,
742
+ height
743
+ );
744
+ break;
745
+ default:
746
+ }
747
+ }
748
+ if (texture) {
749
+ texture.unbind();
750
+ }
751
+ // @ts-expect-error
752
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
753
+ if (deleteFramebuffer) {
754
+ framebuffer.destroy();
755
+ }
756
+ return texture;
757
+ }
758
+
759
+ function getFramebuffer(source: Texture | Framebuffer): {
760
+ framebuffer: WEBGLFramebuffer;
761
+ deleteFramebuffer: boolean;
762
+ } {
763
+ if (!(source instanceof Framebuffer)) {
764
+ return {framebuffer: toFramebuffer(source), deleteFramebuffer: true};
765
+ }
766
+ return {framebuffer: source as WEBGLFramebuffer, deleteFramebuffer: false};
767
+ }
768
+
769
+ /**
770
+ * Wraps a given texture into a framebuffer object, that can be further used
771
+ * to read data from the texture object.
772
+ */
773
+ export function toFramebuffer(texture: Texture, props?: FramebufferProps): WEBGLFramebuffer {
774
+ const {device, width, height, id} = texture;
775
+ const framebuffer = device.createFramebuffer({
776
+ ...props,
777
+ id: `framebuffer-for-${id}`,
778
+ width,
779
+ height,
780
+ colorAttachments: [texture]
781
+ });
782
+ return framebuffer as WEBGLFramebuffer;
783
+ }
784
+
785
+ // eslint-disable-next-line max-params
786
+ function getPixelArray(
787
+ pixelArray,
788
+ type,
789
+ format,
790
+ width: number,
791
+ height: number,
792
+ depth?: number
793
+ ): Uint8Array | Uint16Array | Float32Array {
794
+ if (pixelArray) {
795
+ return pixelArray;
796
+ }
797
+ // Allocate pixel array if not already available, using supplied type
798
+ type = type || GL.UNSIGNED_BYTE;
799
+ const ArrayType = getTypedArrayFromGLType(type, {clamped: false});
800
+ const components = glFormatToComponents(format);
801
+ // TODO - check for composite type (components = 1).
802
+ return new ArrayType(width * height * components) as Uint8Array | Uint16Array | Float32Array;
803
+ }