@luma.gl/webgl 9.0.3 → 9.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma.gl/webgl",
3
- "version": "9.0.3",
3
+ "version": "9.0.4",
4
4
  "description": "WebGL2 adapter for the luma.gl core API",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,8 +43,8 @@
43
43
  "@luma.gl/core": "^9.0.0"
44
44
  },
45
45
  "dependencies": {
46
- "@luma.gl/constants": "9.0.3",
46
+ "@luma.gl/constants": "9.0.4",
47
47
  "@probe.gl/env": "^4.0.2"
48
48
  },
49
- "gitHead": "543e03b2d4bd865ac86cc8927611b91cc3e0393c"
49
+ "gitHead": "d8d47a36bd014fc4848043082bdff31604f6b5c1"
50
50
  }
@@ -2,18 +2,18 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {
6
- Device,
7
- Parameters,
8
- CompareFunction,
9
- StencilOperation,
10
- log,
11
- isObjectEmpty,
12
- BlendOperation,
13
- BlendFactor
14
- } from '@luma.gl/core';
5
+ import type {CompareFunction, StencilOperation, BlendOperation, BlendFactor} from '@luma.gl/core';
6
+ import {Device, log, isObjectEmpty, Parameters, PolygonMode, ProvokingVertex} from '@luma.gl/core';
15
7
  import {GL} from '@luma.gl/constants';
16
- import type {GLBlendEquation, GLBlendFunction, GLParameters} from '@luma.gl/constants';
8
+ import type {
9
+ GLBlendEquation,
10
+ GLBlendFunction,
11
+ GLFunction,
12
+ GLParameters,
13
+ GLPolygonMode,
14
+ GLProvokingVertex,
15
+ GLStencilOp
16
+ } from '@luma.gl/constants';
17
17
  import {pushContextState, popContextState} from '../../context/state-tracker/track-context-state';
18
18
  import {setGLParameters} from '../../context/parameters/unified-parameter-api';
19
19
  import {WebGLDevice} from '../webgl-device';
@@ -164,10 +164,14 @@ export function setDeviceParameters(device: Device, parameters: Parameters) {
164
164
  const ext = extensions.WEBGL_provoking_vertex;
165
165
 
166
166
  if (parameters.provokingVertex) {
167
- const vertex = map('provokingVertex', parameters.provokingVertex, {
168
- first: GL.FIRST_VERTEX_CONVENTION_WEBGL,
169
- last: GL.LAST_VERTEX_CONVENTION_WEBGL
170
- });
167
+ const vertex = map<ProvokingVertex, GLProvokingVertex>(
168
+ 'provokingVertex',
169
+ parameters.provokingVertex,
170
+ {
171
+ first: GL.FIRST_VERTEX_CONVENTION_WEBGL,
172
+ last: GL.LAST_VERTEX_CONVENTION_WEBGL
173
+ }
174
+ );
171
175
  ext?.provokingVertexWEBGL(vertex);
172
176
  }
173
177
  }
@@ -177,9 +181,9 @@ export function setDeviceParameters(device: Device, parameters: Parameters) {
177
181
  const ext = extensions.WEBGL_polygon_mode;
178
182
 
179
183
  if (parameters.polygonMode) {
180
- const mode = map('polygonMode', parameters.provokingVertex, {
184
+ const mode = map<PolygonMode, GLPolygonMode>('polygonMode', parameters.polygonMode, {
181
185
  fill: GL.FILL_WEBGL,
182
- lint: GL.LINE_WEBGL
186
+ line: GL.LINE_WEBGL
183
187
  });
184
188
  ext?.polygonModeWEBGL(GL.FRONT, mode);
185
189
  ext?.polygonModeWEBGL(GL.BACK, mode);
@@ -331,8 +335,8 @@ export function setDeviceParameters(device: Device, parameters: Parameters) {
331
335
  });
332
336
  */
333
337
 
334
- export function convertCompareFunction(parameter: string, value: CompareFunction): GL {
335
- return map(parameter, value, {
338
+ export function convertCompareFunction(parameter: string, value: CompareFunction): GLFunction {
339
+ return map<CompareFunction, GLFunction>(parameter, value, {
336
340
  never: GL.NEVER,
337
341
  less: GL.LESS,
338
342
  equal: GL.EQUAL,
@@ -344,8 +348,8 @@ export function convertCompareFunction(parameter: string, value: CompareFunction
344
348
  });
345
349
  }
346
350
 
347
- export function convertToCompareFunction(parameter: string, value: GL): CompareFunction {
348
- return map(parameter, value, {
351
+ export function convertToCompareFunction(parameter: string, value: GLFunction): CompareFunction {
352
+ return map<GLFunction, CompareFunction>(parameter, value, {
349
353
  [GL.NEVER]: 'never',
350
354
  [GL.LESS]: 'less',
351
355
  [GL.EQUAL]: 'equal',
@@ -358,7 +362,7 @@ export function convertToCompareFunction(parameter: string, value: GL): CompareF
358
362
  }
359
363
 
360
364
  function convertStencilOperation(parameter: string, value: StencilOperation): GL {
361
- return map(parameter, value, {
365
+ return map<StencilOperation, GLStencilOp>(parameter, value, {
362
366
  keep: GL.KEEP,
363
367
  zero: GL.ZERO,
364
368
  replace: GL.REPLACE,
@@ -374,17 +378,17 @@ function convertBlendOperationToEquation(
374
378
  parameter: string,
375
379
  value: BlendOperation
376
380
  ): GLBlendEquation {
377
- return map(parameter, value, {
381
+ return map<BlendOperation, GLBlendEquation>(parameter, value, {
378
382
  add: GL.FUNC_ADD,
379
383
  subtract: GL.FUNC_SUBTRACT,
380
384
  'reverse-subtract': GL.FUNC_REVERSE_SUBTRACT,
381
385
  min: GL.MIN,
382
386
  max: GL.MAX
383
- } as Record<BlendOperation, GLBlendEquation>);
387
+ });
384
388
  }
385
389
 
386
390
  function convertBlendFactorToFunction(parameter: string, value: BlendFactor): GLBlendFunction {
387
- return map(parameter, value, {
391
+ return map<BlendFactor, GLBlendFunction>(parameter, value, {
388
392
  one: GL.ONE,
389
393
  zero: GL.ZERO,
390
394
  'src-color': GL.SRC_COLOR,
@@ -394,15 +398,20 @@ function convertBlendFactorToFunction(parameter: string, value: BlendFactor): GL
394
398
  'src-alpha': GL.SRC_ALPHA,
395
399
  'one-minus-src-alpha': GL.ONE_MINUS_SRC_ALPHA,
396
400
  'dst-alpha': GL.DST_ALPHA,
397
- 'one-minus-dst-alpha': GL.ONE_MINUS_DST_ALPHA
398
- } as Record<BlendFactor, GLBlendFunction>);
401
+ 'one-minus-dst-alpha': GL.ONE_MINUS_DST_ALPHA,
402
+ 'src-alpha-saturated': GL.SRC_ALPHA_SATURATE,
403
+ 'constant-color': GL.CONSTANT_COLOR,
404
+ 'one-minus-constant-color': GL.ONE_MINUS_CONSTANT_COLOR,
405
+ 'constant-alpha': GL.CONSTANT_ALPHA,
406
+ 'one-minus-constant-alpha': GL.ONE_MINUS_CONSTANT_ALPHA
407
+ });
399
408
  }
400
409
 
401
410
  function message(parameter: string, value: any): string {
402
411
  return `Illegal parameter ${value} for ${parameter}`;
403
412
  }
404
413
 
405
- function map(parameter: string, value: any, valueMap: Record<string, any>): any {
414
+ function map<K extends string | number, V>(parameter: string, value: K, valueMap: Record<K, V>): V {
406
415
  if (!(value in valueMap)) {
407
416
  throw new Error(message(parameter, value));
408
417
  }
@@ -153,6 +153,7 @@ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferO
153
153
 
154
154
  // Asynchronous read (PIXEL_PACK_BUFFER) is WebGL2 only feature
155
155
  const {framebuffer, destroyFramebuffer} = getFramebuffer(source);
156
+ let prevHandle: WebGLFramebuffer | null | undefined;
156
157
  try {
157
158
  const webglBuffer = destination as WEBGLBuffer;
158
159
  const sourceWidth = width || framebuffer.width;
@@ -170,7 +171,8 @@ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferO
170
171
  // }
171
172
 
172
173
  device.gl.bindBuffer(GL.PIXEL_PACK_BUFFER, webglBuffer.handle);
173
- device.gl.bindFramebuffer(GL.FRAMEBUFFER, framebuffer.handle);
174
+ // @ts-expect-error native bindFramebuffer is overridden by our state tracker
175
+ prevHandle = device.gl.bindFramebuffer(GL.FRAMEBUFFER, framebuffer.handle);
174
176
 
175
177
  device.gl.readPixels(
176
178
  origin[0],
@@ -183,7 +185,10 @@ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferO
183
185
  );
184
186
  } finally {
185
187
  device.gl.bindBuffer(GL.PIXEL_PACK_BUFFER, null);
186
- device.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
188
+ // prevHandle may be unassigned if the try block failed before binding
189
+ if (prevHandle !== undefined) {
190
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle);
191
+ }
187
192
 
188
193
  if (destroyFramebuffer) {
189
194
  framebuffer.destroy();
@@ -218,13 +223,16 @@ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextur
218
223
  const {
219
224
  /** Texture to copy to/from. */
220
225
  source,
221
- /** Mip-map level of the texture to copy to/from. (Default 0) */
222
- // mipLevel = 0,
226
+ /** Mip-map level of the texture to copy to (Default 0) */
227
+ destinationMipLevel = 0,
223
228
  /** Defines which aspects of the texture to copy to/from. */
224
229
  // aspect = 'all',
225
- /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
230
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy from. */
226
231
  origin = [0, 0],
227
232
 
233
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to. */
234
+ destinationOrigin = [0, 0],
235
+
228
236
  /** Texture to copy to/from. */
229
237
  destination
230
238
  /** Mip-map level of the texture to copy to/from. (Default 0) */
@@ -237,93 +245,72 @@ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextur
237
245
 
238
246
  let {
239
247
  width = options.destination.width,
240
- height = options.destination.width
248
+ height = options.destination.height
241
249
  // depthOrArrayLayers = 0
242
250
  } = options;
243
251
 
244
- const destinationMipmaplevel = 0;
245
- const destinationInternalFormat = GL.RGBA;
246
-
247
252
  const {framebuffer, destroyFramebuffer} = getFramebuffer(source);
248
253
  const [sourceX, sourceY] = origin;
254
+ const [destinationX, destinationY, destinationZ] = destinationOrigin;
249
255
 
250
- const isSubCopy = false;
251
- // typeof destinationX !== 'undefined' ||
252
- // typeof destinationY !== 'undefined' ||
253
- // typeof destinationZ !== 'undefined';
254
-
255
- // destinationX = destinationX || 0;
256
- // destinationY = destinationY || 0;
257
- // destinationZ = destinationZ || 0;
258
- device.gl.bindFramebuffer(GL.FRAMEBUFFER, framebuffer.handle);
256
+ // @ts-expect-error native bindFramebuffer is overridden by our state tracker
257
+ const prevHandle: WebGLFramebuffer | null = device.gl.bindFramebuffer(
258
+ GL.FRAMEBUFFER,
259
+ framebuffer.handle
260
+ );
259
261
  // TODO - support gl.readBuffer (WebGL2 only)
260
262
  // const prevBuffer = gl.readBuffer(attachment);
261
263
 
262
- let texture = null;
264
+ let texture: WEBGLTexture = null;
263
265
  let textureTarget: GL;
264
266
  if (destination instanceof WEBGLTexture) {
265
267
  texture = destination;
266
268
  width = Number.isFinite(width) ? width : texture.width;
267
269
  height = Number.isFinite(height) ? height : texture.height;
268
270
  texture.bind(0);
269
- textureTarget = texture.destination;
271
+ textureTarget = texture.target;
270
272
  } else {
271
- throw new Error('whoops');
272
- // textureTarget = destination;
273
+ throw new Error('invalid destination');
273
274
  }
274
275
 
275
- if (!isSubCopy) {
276
- device.gl.copyTexImage2D(
277
- textureTarget,
278
- destinationMipmaplevel,
279
- destinationInternalFormat,
280
- sourceX,
281
- sourceY,
282
- width,
283
- height,
284
- 0 /* border must be 0 */
285
- );
286
- } else {
287
- // switch (textureTarget) {
288
- // case GL.TEXTURE_2D:
289
- // case GL.TEXTURE_CUBE_MAP:
290
- // device.gl.copyTexSubImage2D(
291
- // textureTarget,
292
- // destinationMipmaplevel,
293
- // destinationX,
294
- // destinationY,
295
- // sourceX,
296
- // sourceY,
297
- // width,
298
- // height
299
- // );
300
- // break;
301
- // case GL.TEXTURE_2D_ARRAY:
302
- // case GL.TEXTURE_3D:
303
- // device.gl.copyTexSubImage3D(
304
- // textureTarget,
305
- // destinationMipmaplevel,
306
- // destinationX,
307
- // destinationY,
308
- // destinationZ,
309
- // sourceX,
310
- // sourceY,
311
- // width,
312
- // height
313
- // );
314
- // break;
315
- // default:
316
- // }
276
+ switch (textureTarget) {
277
+ case GL.TEXTURE_2D:
278
+ case GL.TEXTURE_CUBE_MAP:
279
+ device.gl.copyTexSubImage2D(
280
+ textureTarget,
281
+ destinationMipLevel,
282
+ destinationX,
283
+ destinationY,
284
+ sourceX,
285
+ sourceY,
286
+ width,
287
+ height
288
+ );
289
+ break;
290
+ case GL.TEXTURE_2D_ARRAY:
291
+ case GL.TEXTURE_3D:
292
+ device.gl.copyTexSubImage3D(
293
+ textureTarget,
294
+ destinationMipLevel,
295
+ destinationX,
296
+ destinationY,
297
+ destinationZ,
298
+ sourceX,
299
+ sourceY,
300
+ width,
301
+ height
302
+ );
303
+ break;
304
+ default:
317
305
  }
306
+
318
307
  if (texture) {
319
308
  texture.unbind();
320
309
  }
321
- // ts-expect-error
322
- // device.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
310
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle);
323
311
  if (destroyFramebuffer) {
324
312
  framebuffer.destroy();
325
313
  }
326
- return texture;
327
314
  }
328
315
 
329
316
  // Returns number of components in a specific readPixels WebGL format
@@ -44,7 +44,11 @@ export class WEBGLFramebuffer extends Framebuffer {
44
44
  this.autoCreateAttachmentTextures();
45
45
 
46
46
  /** Attach from a map of attachments */
47
- this.gl.bindFramebuffer(GL.FRAMEBUFFER, this.handle);
47
+ // @ts-expect-error native bindFramebuffer is overridden by our state tracker
48
+ const prevHandle: WebGLFramebuffer | null = this.gl.bindFramebuffer(
49
+ GL.FRAMEBUFFER,
50
+ this.handle
51
+ );
48
52
 
49
53
  // Walk the attachments
50
54
  for (let i = 0; i < this.colorAttachments.length; ++i) {
@@ -71,7 +75,7 @@ export class WEBGLFramebuffer extends Framebuffer {
71
75
  }
72
76
  }
73
77
 
74
- this.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
78
+ this.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle);
75
79
  }
76
80
  }
77
81