@luma.gl/webgl 9.1.0-alpha.15 → 9.1.0-alpha.17
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/dist/adapter/converters/device-parameters.d.ts +3 -3
- package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
- package/dist/adapter/converters/sampler-parameters.js +6 -4
- package/dist/adapter/converters/texture-formats.d.ts +49 -11
- package/dist/adapter/converters/texture-formats.d.ts.map +1 -1
- package/dist/adapter/converters/texture-formats.js +150 -160
- package/dist/adapter/helpers/format-utils.d.ts.map +1 -1
- package/dist/adapter/helpers/format-utils.js +6 -0
- package/dist/adapter/helpers/webgl-texture-utils.d.ts +34 -30
- package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.js +52 -256
- package/dist/adapter/resources/webgl-command-buffer.d.ts +59 -2
- package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.js +87 -31
- package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-encoder.js +3 -0
- package/dist/adapter/resources/webgl-external-texture.js +14 -0
- package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-framebuffer.js +1 -2
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +38 -20
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +30 -16
- package/dist/adapter/resources/webgl-shader.d.ts +1 -0
- package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-shader.js +7 -5
- package/dist/adapter/resources/webgl-texture.d.ts +8 -14
- package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-texture.js +119 -208
- package/dist/adapter/webgl-adapter.d.ts.map +1 -1
- package/dist/adapter/webgl-adapter.js +4 -10
- package/dist/adapter/webgl-device.d.ts +8 -3
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +53 -22
- package/dist/context/debug/spector-types.js +1 -1
- package/dist/context/debug/spector.d.ts +5 -5
- package/dist/context/debug/spector.d.ts.map +1 -1
- package/dist/context/debug/spector.js +6 -6
- package/dist/context/debug/webgl-developer-tools.d.ts +2 -3
- package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +6 -19
- package/dist/context/helpers/create-browser-context.d.ts +6 -22
- package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
- package/dist/context/helpers/create-browser-context.js +40 -32
- package/dist/dist.dev.js +366 -400
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +341 -384
- package/dist/index.cjs.map +3 -3
- package/package.json +4 -4
- package/src/adapter/converters/device-parameters.ts +3 -3
- package/src/adapter/converters/sampler-parameters.ts +6 -4
- package/src/adapter/converters/texture-formats.ts +171 -177
- package/src/adapter/helpers/format-utils.ts +6 -0
- package/src/adapter/helpers/webgl-texture-utils.ts +99 -75
- package/src/adapter/resources/webgl-command-buffer.ts +124 -40
- package/src/adapter/resources/webgl-command-encoder.ts +6 -0
- package/src/adapter/resources/webgl-external-texture.ts +14 -0
- package/src/adapter/resources/webgl-framebuffer.ts +1 -2
- package/src/adapter/resources/webgl-render-pass.ts +44 -23
- package/src/adapter/resources/webgl-render-pipeline.ts +32 -16
- package/src/adapter/resources/webgl-shader.ts +8 -6
- package/src/adapter/resources/webgl-texture.ts +126 -235
- package/src/adapter/webgl-adapter.ts +4 -12
- package/src/adapter/webgl-device.ts +88 -48
- package/src/context/debug/spector-types.ts +1 -1
- package/src/context/debug/spector.ts +11 -11
- package/src/context/debug/webgl-developer-tools.ts +8 -31
- package/src/context/helpers/create-browser-context.ts +53 -63
|
@@ -17,10 +17,8 @@ import type {
|
|
|
17
17
|
Sampler,
|
|
18
18
|
SamplerProps,
|
|
19
19
|
SamplerParameters,
|
|
20
|
-
// TextureFormat,
|
|
21
20
|
TextureCubeFace,
|
|
22
21
|
ExternalImage,
|
|
23
|
-
TextureLevelData,
|
|
24
22
|
Texture1DData,
|
|
25
23
|
Texture2DData,
|
|
26
24
|
Texture3DData,
|
|
@@ -58,42 +56,11 @@ import {
|
|
|
58
56
|
getWebGLTextureTarget
|
|
59
57
|
} from '../helpers/webgl-texture-utils';
|
|
60
58
|
|
|
61
|
-
// PORTABLE HELPERS (Move to methods on Texture?)
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Normalize TextureData to an array of TextureLevelData / ExternalImages
|
|
65
|
-
* @param data
|
|
66
|
-
* @param options
|
|
67
|
-
* @returns array of TextureLevelData / ExternalImages
|
|
68
|
-
*/
|
|
69
|
-
function normalizeTextureData(
|
|
70
|
-
data: Texture2DData,
|
|
71
|
-
options: {width: number; height: number; depth: number}
|
|
72
|
-
): (TextureLevelData | ExternalImage)[] {
|
|
73
|
-
let lodArray: (TextureLevelData | ExternalImage)[];
|
|
74
|
-
if (ArrayBuffer.isView(data)) {
|
|
75
|
-
lodArray = [
|
|
76
|
-
{
|
|
77
|
-
// ts-expect-error does data really need to be Uint8ClampedArray?
|
|
78
|
-
data,
|
|
79
|
-
width: options.width,
|
|
80
|
-
height: options.height
|
|
81
|
-
// depth: options.depth
|
|
82
|
-
}
|
|
83
|
-
];
|
|
84
|
-
} else if (!Array.isArray(data)) {
|
|
85
|
-
lodArray = [data];
|
|
86
|
-
} else {
|
|
87
|
-
lodArray = data;
|
|
88
|
-
}
|
|
89
|
-
return lodArray;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
59
|
/**
|
|
93
60
|
* WebGL... the texture API from hell... hopefully made simpler
|
|
94
61
|
*/
|
|
95
62
|
export class WEBGLTexture extends Texture {
|
|
96
|
-
readonly MAX_ATTRIBUTES: number;
|
|
63
|
+
// readonly MAX_ATTRIBUTES: number;
|
|
97
64
|
readonly device: WebGLDevice;
|
|
98
65
|
readonly gl: WebGL2RenderingContext;
|
|
99
66
|
handle: WebGLTexture;
|
|
@@ -101,9 +68,14 @@ export class WEBGLTexture extends Texture {
|
|
|
101
68
|
sampler: WEBGLSampler = undefined; // TODO - currently unused in WebGL. Create dummy sampler?
|
|
102
69
|
view: WEBGLTextureView = undefined; // TODO - currently unused in WebGL. Create dummy view?
|
|
103
70
|
|
|
104
|
-
mipmaps: boolean
|
|
71
|
+
mipmaps: boolean;
|
|
72
|
+
|
|
73
|
+
// Texture type
|
|
74
|
+
/** Whether the internal format is compressed */
|
|
75
|
+
compressed: boolean;
|
|
105
76
|
|
|
106
77
|
/**
|
|
78
|
+
* The WebGL target corresponding to the texture type
|
|
107
79
|
* @note `target` cannot be modified by bind:
|
|
108
80
|
* textures are special because when you first bind them to a target,
|
|
109
81
|
* When you first bind a texture as a GL_TEXTURE_2D, you are saying that this texture is a 2D texture.
|
|
@@ -112,41 +84,23 @@ export class WEBGLTexture extends Texture {
|
|
|
112
84
|
* attempting to bind it as GL_TEXTURE_3D will give rise to a run-time error
|
|
113
85
|
*/
|
|
114
86
|
glTarget: GLTextureTarget;
|
|
115
|
-
|
|
116
|
-
// Texture type
|
|
117
|
-
|
|
118
87
|
/** The WebGL format - essentially channel structure */
|
|
119
88
|
glFormat: GLTexelDataFormat;
|
|
120
89
|
/** The WebGL data format - the type of each channel */
|
|
121
90
|
glType: GLPixelType;
|
|
122
91
|
/** The WebGL constant corresponding to the WebGPU style constant in format */
|
|
123
92
|
glInternalFormat: GL;
|
|
124
|
-
/** Whether the internal format is compressed */
|
|
125
|
-
compressed: boolean;
|
|
126
|
-
|
|
127
|
-
// data;
|
|
128
|
-
// inherited props
|
|
129
|
-
// dimension: ...
|
|
130
|
-
// format: GLTextureTarget;
|
|
131
|
-
// width: number = undefined;
|
|
132
|
-
// height: number = undefined;
|
|
133
|
-
// depth: number = undefined;
|
|
134
93
|
|
|
135
94
|
// state
|
|
136
|
-
/** Texture binding slot */
|
|
95
|
+
/** Texture binding slot - TODO - move to texture view? */
|
|
137
96
|
textureUnit: number = 0;
|
|
138
|
-
/** For automatically updating video */
|
|
139
|
-
_video: {
|
|
140
|
-
video: HTMLVideoElement;
|
|
141
|
-
parameters: any;
|
|
142
|
-
lastTime: number;
|
|
143
|
-
} | null = null;
|
|
144
97
|
|
|
145
98
|
constructor(device: Device, props: TextureProps) {
|
|
146
|
-
|
|
99
|
+
super(device, props);
|
|
147
100
|
|
|
148
|
-
//
|
|
149
|
-
|
|
101
|
+
// Texture base class strips out the data prop, so we need to add it back in
|
|
102
|
+
const propsWithData = {...this.props};
|
|
103
|
+
propsWithData.data = props.data;
|
|
150
104
|
|
|
151
105
|
this.device = device as WebGLDevice;
|
|
152
106
|
this.gl = this.device.gl;
|
|
@@ -155,26 +109,14 @@ export class WEBGLTexture extends Texture {
|
|
|
155
109
|
this.glTarget = getWebGLTextureTarget(this.props.dimension);
|
|
156
110
|
|
|
157
111
|
// The target format of this texture
|
|
158
|
-
const
|
|
159
|
-
this.glInternalFormat =
|
|
160
|
-
this.glFormat =
|
|
161
|
-
this.glType =
|
|
162
|
-
this.compressed =
|
|
112
|
+
const formatInfo = getTextureFormatWebGL(this.props.format);
|
|
113
|
+
this.glInternalFormat = formatInfo.internalFormat;
|
|
114
|
+
this.glFormat = formatInfo.format;
|
|
115
|
+
this.glType = formatInfo.type;
|
|
116
|
+
this.compressed = formatInfo.compressed;
|
|
117
|
+
this.mipmaps = Boolean(this.props.mipmaps);
|
|
163
118
|
|
|
164
|
-
|
|
165
|
-
typeof HTMLVideoElement !== 'undefined' &&
|
|
166
|
-
props.data instanceof HTMLVideoElement &&
|
|
167
|
-
// @ts-expect-error
|
|
168
|
-
props.data.readyState < HTMLVideoElement.HAVE_METADATA
|
|
169
|
-
) {
|
|
170
|
-
const video = props.data;
|
|
171
|
-
this._video = null; // Declare member before the object is sealed
|
|
172
|
-
video.addEventListener('loadeddata', () => this.initialize(props));
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// We removed data, we need to add it again.
|
|
176
|
-
// @ts-expect-error
|
|
177
|
-
this.initialize({...this.props, data: props.data});
|
|
119
|
+
this._initialize(propsWithData);
|
|
178
120
|
|
|
179
121
|
Object.seal(this);
|
|
180
122
|
}
|
|
@@ -183,18 +125,14 @@ export class WEBGLTexture extends Texture {
|
|
|
183
125
|
* Initialize texture with supplied props
|
|
184
126
|
*/
|
|
185
127
|
// eslint-disable-next-line max-statements
|
|
186
|
-
|
|
128
|
+
_initialize(propsWithData: TextureProps): void {
|
|
187
129
|
this.handle = this.props.handle || this.gl.createTexture();
|
|
188
|
-
this.device.setSpectorMetadata(this.handle, {...this.props, data:
|
|
189
|
-
|
|
190
|
-
const data = props.data;
|
|
130
|
+
this.device.setSpectorMetadata(this.handle, {...this.props, data: propsWithData.data});
|
|
191
131
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
let {width, height} = props;
|
|
132
|
+
let {width, height} = propsWithData;
|
|
195
133
|
|
|
196
134
|
if (!width || !height) {
|
|
197
|
-
const textureSize = Texture.getTextureDataSize(data);
|
|
135
|
+
const textureSize = Texture.getTextureDataSize(propsWithData.data);
|
|
198
136
|
width = textureSize?.width || 1;
|
|
199
137
|
height = textureSize?.height || 1;
|
|
200
138
|
}
|
|
@@ -202,73 +140,35 @@ export class WEBGLTexture extends Texture {
|
|
|
202
140
|
// Store opts for accessors
|
|
203
141
|
this.width = width;
|
|
204
142
|
this.height = height;
|
|
205
|
-
this.depth =
|
|
143
|
+
this.depth = propsWithData.depth;
|
|
206
144
|
|
|
207
145
|
// Set texture sampler parameters
|
|
208
|
-
this.setSampler(
|
|
209
|
-
// @ts-ignore
|
|
146
|
+
this.setSampler(propsWithData.sampler);
|
|
147
|
+
// @ts-ignore TODO - fix types
|
|
210
148
|
this.view = new WEBGLTextureView(this.device, {...this.props, texture: this});
|
|
211
149
|
|
|
212
150
|
this.bind();
|
|
213
|
-
|
|
214
|
-
initializeTextureStorage(this.gl, this.mipLevels, this);
|
|
215
|
-
}
|
|
151
|
+
initializeTextureStorage(this.gl, this.mipLevels, this);
|
|
216
152
|
|
|
217
|
-
if (
|
|
153
|
+
if (propsWithData.data) {
|
|
218
154
|
// prettier-ignore
|
|
219
|
-
switch (
|
|
220
|
-
case '1d': this.setTexture1DData(
|
|
221
|
-
case '2d': this.setTexture2DData(
|
|
222
|
-
case '3d': this.setTexture3DData(
|
|
223
|
-
case 'cube': this.setTextureCubeData(
|
|
224
|
-
case '2d-array': this.setTextureArrayData(
|
|
225
|
-
case 'cube-array': this.setTextureCubeArrayData(
|
|
155
|
+
switch (propsWithData.dimension) {
|
|
156
|
+
case '1d': this.setTexture1DData(propsWithData.data); break;
|
|
157
|
+
case '2d': this.setTexture2DData(propsWithData.data); break;
|
|
158
|
+
case '3d': this.setTexture3DData(propsWithData.data); break;
|
|
159
|
+
case 'cube': this.setTextureCubeData(propsWithData.data); break;
|
|
160
|
+
case '2d-array': this.setTextureArrayData(propsWithData.data); break;
|
|
161
|
+
case 'cube-array': this.setTextureCubeArrayData(propsWithData.data); break;
|
|
226
162
|
// @ts-expect-error
|
|
227
|
-
default: throw new Error(
|
|
163
|
+
default: throw new Error(propsWithData.dimension);
|
|
228
164
|
}
|
|
229
165
|
}
|
|
230
166
|
|
|
231
|
-
this.mipmaps = Boolean(props.mipmaps);
|
|
232
|
-
|
|
233
167
|
if (this.mipmaps) {
|
|
234
168
|
this.generateMipmap();
|
|
235
169
|
}
|
|
236
|
-
|
|
237
|
-
// if (isVideo) {
|
|
238
|
-
// this._video = {
|
|
239
|
-
// video: data,
|
|
240
|
-
// // TODO - should we be using the sampler parameters here?
|
|
241
|
-
// parameters: {},
|
|
242
|
-
// // @ts-expect-error HTMLVideoElement.HAVE_CURRENT_DATA is not declared
|
|
243
|
-
// lastTime: data.readyState >= HTMLVideoElement.HAVE_CURRENT_DATA ? data.currentTime : -1
|
|
244
|
-
// };
|
|
245
|
-
// }
|
|
246
170
|
}
|
|
247
171
|
|
|
248
|
-
/*
|
|
249
|
-
initializeCube(props?: TextureProps): void {
|
|
250
|
-
const {mipmaps = true} = props; // , parameters = {} as Record<GL, any>} = props;
|
|
251
|
-
|
|
252
|
-
// Store props for accessors
|
|
253
|
-
// this.props = props;
|
|
254
|
-
|
|
255
|
-
// @ts-expect-error
|
|
256
|
-
this.setCubeMapData(props).then(() => {
|
|
257
|
-
// TODO - should genMipmap() be called on the cubemap or on the faces?
|
|
258
|
-
// TODO - without generateMipmap() cube textures do not work at all!!! Why?
|
|
259
|
-
if (mipmaps) {
|
|
260
|
-
this.generateMipmap(props);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
this.setSampler(props.sampler);
|
|
264
|
-
|
|
265
|
-
// v8 compatibility?
|
|
266
|
-
// const {parameters = {} as Record<GL, any>} = props;
|
|
267
|
-
// this._setSamplerParameters(parameters);
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
*/
|
|
271
|
-
|
|
272
172
|
override destroy(): void {
|
|
273
173
|
if (this.handle) {
|
|
274
174
|
this.gl.deleteTexture(this.handle);
|
|
@@ -279,10 +179,6 @@ export class WEBGLTexture extends Texture {
|
|
|
279
179
|
}
|
|
280
180
|
}
|
|
281
181
|
|
|
282
|
-
override toString(): string {
|
|
283
|
-
return `Texture(${this.id},${this.width}x${this.height})`;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
182
|
createView(props: TextureViewProps): WEBGLTextureView {
|
|
287
183
|
return new WEBGLTextureView(this.device, {...props, texture: this});
|
|
288
184
|
}
|
|
@@ -301,37 +197,25 @@ export class WEBGLTexture extends Texture {
|
|
|
301
197
|
this._setSamplerParameters(parameters);
|
|
302
198
|
}
|
|
303
199
|
|
|
304
|
-
/** Update external texture (video frame or canvas) */
|
|
305
|
-
update(): void {
|
|
306
|
-
log.warn('Texture.update() not implemented');
|
|
307
|
-
// if (this._video) {
|
|
308
|
-
// const {video, parameters, lastTime} = this._video;
|
|
309
|
-
// // @ts-expect-error
|
|
310
|
-
// if (lastTime === video.currentTime || video.readyState < HTMLVideoElement.HAVE_CURRENT_DATA) {
|
|
311
|
-
// return;
|
|
312
|
-
// }
|
|
313
|
-
// this.setSubImageData({
|
|
314
|
-
// data: video,
|
|
315
|
-
// parameters
|
|
316
|
-
// });
|
|
317
|
-
// if (this.mipmaps) {
|
|
318
|
-
// this.generateMipmap();
|
|
319
|
-
// }
|
|
320
|
-
// this._video.lastTime = video.currentTime;
|
|
321
|
-
// }
|
|
322
|
-
}
|
|
323
|
-
|
|
324
200
|
// Call to regenerate mipmaps after modifying texture(s)
|
|
325
201
|
generateMipmap(params = {}): void {
|
|
326
|
-
if (
|
|
327
|
-
|
|
202
|
+
if (
|
|
203
|
+
!this.device.isTextureFormatRenderable(this.props.format) ||
|
|
204
|
+
!this.device.isTextureFormatFilterable(this.props.format)
|
|
205
|
+
) {
|
|
206
|
+
log.warn(`${this} is not renderable or filterable, may not be able to generate mipmaps`)();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
this.gl.bindTexture(this.glTarget, this.handle);
|
|
211
|
+
withGLParameters(this.gl, params, () => {
|
|
212
|
+
this.gl.generateMipmap(this.glTarget);
|
|
213
|
+
});
|
|
214
|
+
} catch (error) {
|
|
215
|
+
log.warn(`Error generating mipmap for ${this}: ${(error as Error).message}`)();
|
|
216
|
+
} finally {
|
|
217
|
+
this.gl.bindTexture(this.glTarget, null);
|
|
328
218
|
}
|
|
329
|
-
this.mipmaps = true;
|
|
330
|
-
this.gl.bindTexture(this.glTarget, this.handle);
|
|
331
|
-
withGLParameters(this.gl, params, () => {
|
|
332
|
-
this.gl.generateMipmap(this.glTarget);
|
|
333
|
-
});
|
|
334
|
-
this.gl.bindTexture(this.glTarget, null);
|
|
335
219
|
}
|
|
336
220
|
|
|
337
221
|
// Image Data Setters
|
|
@@ -349,11 +233,12 @@ export class WEBGLTexture extends Texture {
|
|
|
349
233
|
aspect?: 'all' | 'stencil-only' | 'depth-only';
|
|
350
234
|
colorSpace?: 'srgb';
|
|
351
235
|
premultipliedAlpha?: boolean;
|
|
236
|
+
flipY?: boolean;
|
|
352
237
|
}): {width: number; height: number} {
|
|
353
238
|
const size = Texture.getExternalImageSize(options.image);
|
|
354
239
|
const opts = {...Texture.defaultCopyExternalImageOptions, ...size, ...options};
|
|
355
240
|
|
|
356
|
-
const {image, depth, mipLevel, x, y, z} = opts;
|
|
241
|
+
const {image, depth, mipLevel, x, y, z, flipY} = opts;
|
|
357
242
|
let {width, height} = opts;
|
|
358
243
|
const {dimension, glTarget, glFormat, glInternalFormat, glType} = this;
|
|
359
244
|
|
|
@@ -361,12 +246,9 @@ export class WEBGLTexture extends Texture {
|
|
|
361
246
|
width = Math.min(width, size.width - x);
|
|
362
247
|
height = Math.min(height, size.height - y);
|
|
363
248
|
|
|
364
|
-
// WebGL does not yet support sourceX/sourceY in copyExternalImage; requires copyTexSubImage2D from a framebuffer'
|
|
365
|
-
|
|
366
249
|
if (options.sourceX || options.sourceY) {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
);
|
|
250
|
+
// requires copyTexSubImage2D from a framebuffer'
|
|
251
|
+
throw new Error('WebGL does not support sourceX/sourceY)');
|
|
370
252
|
}
|
|
371
253
|
|
|
372
254
|
copyExternalImageToMipLevel(this.device.gl, this.handle, image, {
|
|
@@ -381,7 +263,8 @@ export class WEBGLTexture extends Texture {
|
|
|
381
263
|
glFormat,
|
|
382
264
|
glInternalFormat,
|
|
383
265
|
glType,
|
|
384
|
-
glTarget
|
|
266
|
+
glTarget,
|
|
267
|
+
flipY
|
|
385
268
|
});
|
|
386
269
|
|
|
387
270
|
return {width: opts.width, height: opts.height};
|
|
@@ -395,7 +278,7 @@ export class WEBGLTexture extends Texture {
|
|
|
395
278
|
setTexture2DData(lodData: Texture2DData, depth = 0): void {
|
|
396
279
|
this.bind();
|
|
397
280
|
|
|
398
|
-
const lodArray = normalizeTextureData(lodData, this);
|
|
281
|
+
const lodArray = Texture.normalizeTextureData(lodData, this);
|
|
399
282
|
|
|
400
283
|
// If the user provides multiple LODs, then automatic mipmap
|
|
401
284
|
// generation generateMipmap() should be disabled to avoid overwriting them.
|
|
@@ -474,6 +357,13 @@ export class WEBGLTexture extends Texture {
|
|
|
474
357
|
this.setTexture2DData(lodData, faceDepth);
|
|
475
358
|
}
|
|
476
359
|
|
|
360
|
+
// DEPRECATED METHODS
|
|
361
|
+
|
|
362
|
+
/** Update external texture (video frame or canvas) @deprecated Use ExternalTexture */
|
|
363
|
+
update(): void {
|
|
364
|
+
throw new Error('Texture.update() not implemented. Use ExternalTexture');
|
|
365
|
+
}
|
|
366
|
+
|
|
477
367
|
// INTERNAL METHODS
|
|
478
368
|
|
|
479
369
|
/** @todo update this method to accept LODs */
|
|
@@ -528,7 +418,7 @@ export class WEBGLTexture extends Texture {
|
|
|
528
418
|
* Sets sampler parameters on texture
|
|
529
419
|
*/
|
|
530
420
|
_setSamplerParameters(parameters: GLSamplerParameters): void {
|
|
531
|
-
log.log(1,
|
|
421
|
+
log.log(1, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
|
|
532
422
|
|
|
533
423
|
this.gl.bindTexture(this.glTarget, this.handle);
|
|
534
424
|
for (const [pname, pvalue] of Object.entries(parameters)) {
|
|
@@ -566,63 +456,6 @@ export class WEBGLTexture extends Texture {
|
|
|
566
456
|
this.gl.bindTexture(this.glTarget, null);
|
|
567
457
|
}
|
|
568
458
|
|
|
569
|
-
// CLASSIC
|
|
570
|
-
|
|
571
|
-
/*
|
|
572
|
-
setCubeMapData(options: {
|
|
573
|
-
width: number;
|
|
574
|
-
height: number;
|
|
575
|
-
data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
|
|
576
|
-
format?: any;
|
|
577
|
-
type?: any;
|
|
578
|
-
/** @deprecated Use .data *
|
|
579
|
-
pixels: any;
|
|
580
|
-
}): void {
|
|
581
|
-
const {gl} = this;
|
|
582
|
-
|
|
583
|
-
const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
|
|
584
|
-
|
|
585
|
-
// pixel data (imageDataMap) is an Object from Face to Image or Promise.
|
|
586
|
-
// For example:
|
|
587
|
-
// {
|
|
588
|
-
// GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
|
|
589
|
-
// GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
|
|
590
|
-
// ... }
|
|
591
|
-
// To provide multiple level-of-details (LODs) this can be Face to Array
|
|
592
|
-
// of Image or Promise, like this
|
|
593
|
-
// {
|
|
594
|
-
// GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
|
|
595
|
-
// GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
|
|
596
|
-
// ... }
|
|
597
|
-
|
|
598
|
-
const imageDataMap = this._getImageDataMap(pixels || data);
|
|
599
|
-
|
|
600
|
-
const resolvedFaces = WEBGLTexture.FACES.map(face => {
|
|
601
|
-
const facePixels = imageDataMap[face];
|
|
602
|
-
return Array.isArray(facePixels) ? facePixels : [facePixels];
|
|
603
|
-
});
|
|
604
|
-
this.bind();
|
|
605
|
-
|
|
606
|
-
WEBGLTexture.FACES.forEach((face, index) => {
|
|
607
|
-
if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
|
|
608
|
-
// If the user provides multiple LODs, then automatic mipmap
|
|
609
|
-
// generation generateMipmap() should be disabled to avoid overwritting them.
|
|
610
|
-
log.warn(`${this.id} has mipmap and multiple LODs.`)();
|
|
611
|
-
}
|
|
612
|
-
resolvedFaces[index].forEach((image, lodLevel) => {
|
|
613
|
-
// TODO: adjust width & height for LOD!
|
|
614
|
-
if (width && height) {
|
|
615
|
-
gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
|
|
616
|
-
} else {
|
|
617
|
-
gl.texImage2D(face, lodLevel, format, format, type, image);
|
|
618
|
-
}
|
|
619
|
-
});
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
this.unbind();
|
|
623
|
-
}
|
|
624
|
-
*/
|
|
625
|
-
|
|
626
459
|
// INTERNAL SETTERS
|
|
627
460
|
|
|
628
461
|
/**
|
|
@@ -645,7 +478,8 @@ export class WEBGLTexture extends Texture {
|
|
|
645
478
|
...this,
|
|
646
479
|
depth,
|
|
647
480
|
mipLevel,
|
|
648
|
-
glTarget
|
|
481
|
+
glTarget,
|
|
482
|
+
flipY: this.props.flipY
|
|
649
483
|
});
|
|
650
484
|
return;
|
|
651
485
|
}
|
|
@@ -693,3 +527,60 @@ export class WEBGLTexture extends Texture {
|
|
|
693
527
|
return textureUnit;
|
|
694
528
|
}
|
|
695
529
|
}
|
|
530
|
+
|
|
531
|
+
// TODO - Remove when texture refactor is complete
|
|
532
|
+
|
|
533
|
+
/*
|
|
534
|
+
setCubeMapData(options: {
|
|
535
|
+
width: number;
|
|
536
|
+
height: number;
|
|
537
|
+
data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
|
|
538
|
+
format?: any;
|
|
539
|
+
type?: any;
|
|
540
|
+
/** @deprecated Use .data *
|
|
541
|
+
pixels: any;
|
|
542
|
+
}): void {
|
|
543
|
+
const {gl} = this;
|
|
544
|
+
|
|
545
|
+
const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
|
|
546
|
+
|
|
547
|
+
// pixel data (imageDataMap) is an Object from Face to Image or Promise.
|
|
548
|
+
// For example:
|
|
549
|
+
// {
|
|
550
|
+
// GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
|
|
551
|
+
// GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
|
|
552
|
+
// ... }
|
|
553
|
+
// To provide multiple level-of-details (LODs) this can be Face to Array
|
|
554
|
+
// of Image or Promise, like this
|
|
555
|
+
// {
|
|
556
|
+
// GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
|
|
557
|
+
// GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
|
|
558
|
+
// ... }
|
|
559
|
+
|
|
560
|
+
const imageDataMap = this._getImageDataMap(pixels || data);
|
|
561
|
+
|
|
562
|
+
const resolvedFaces = WEBGLTexture.FACES.map(face => {
|
|
563
|
+
const facePixels = imageDataMap[face];
|
|
564
|
+
return Array.isArray(facePixels) ? facePixels : [facePixels];
|
|
565
|
+
});
|
|
566
|
+
this.bind();
|
|
567
|
+
|
|
568
|
+
WEBGLTexture.FACES.forEach((face, index) => {
|
|
569
|
+
if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
|
|
570
|
+
// If the user provides multiple LODs, then automatic mipmap
|
|
571
|
+
// generation generateMipmap() should be disabled to avoid overwritting them.
|
|
572
|
+
log.warn(`${this.id} has mipmap and multiple LODs.`)();
|
|
573
|
+
}
|
|
574
|
+
resolvedFaces[index].forEach((image, lodLevel) => {
|
|
575
|
+
// TODO: adjust width & height for LOD!
|
|
576
|
+
if (width && height) {
|
|
577
|
+
gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
|
|
578
|
+
} else {
|
|
579
|
+
gl.texImage2D(face, lodLevel, format, format, type, image);
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
this.unbind();
|
|
585
|
+
}
|
|
586
|
+
*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {Adapter, Device, DeviceProps,
|
|
5
|
+
import {Adapter, Device, DeviceProps, log} from '@luma.gl/core';
|
|
6
6
|
import {WebGLDevice} from './webgl-device';
|
|
7
7
|
import {enforceWebGL2} from '../context/polyfills/polyfill-webgl1-extensions';
|
|
8
8
|
import {loadSpectorJS, DEFAULT_SPECTOR_PROPS} from '../context/debug/spector';
|
|
@@ -52,7 +52,7 @@ export class WebGLAdapter extends Adapter {
|
|
|
52
52
|
if (!isWebGL(gl)) {
|
|
53
53
|
throw new Error('Invalid WebGL2RenderingContext');
|
|
54
54
|
}
|
|
55
|
-
return new WebGLDevice({
|
|
55
|
+
return new WebGLDevice({_handle: gl as WebGL2RenderingContext});
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
async create(props: DeviceProps = {}): Promise<WebGLDevice> {
|
|
@@ -61,20 +61,14 @@ export class WebGLAdapter extends Adapter {
|
|
|
61
61
|
const promises: Promise<unknown>[] = [];
|
|
62
62
|
|
|
63
63
|
// Load webgl and spector debug scripts from CDN if requested
|
|
64
|
-
if (props.debug) {
|
|
64
|
+
if (props.debugWebGL || props.debug) {
|
|
65
65
|
promises.push(loadWebGLDeveloperTools());
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if (props.
|
|
68
|
+
if (props.debugSpectorJS) {
|
|
69
69
|
promises.push(loadSpectorJS(props));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
// Wait for page to load: if canvas is a string we need to query the DOM for the canvas element.
|
|
73
|
-
// We only wait when props.canvas is string to avoids setting the global page onload callback unless necessary.
|
|
74
|
-
if (typeof props.canvas === 'string') {
|
|
75
|
-
promises.push(CanvasContext.pageLoaded);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
72
|
// Wait for all the loads to settle before creating the context.
|
|
79
73
|
// The Device.create() functions are async, so in contrast to the constructor, we can `await` here.
|
|
80
74
|
const results = await Promise.allSettled(promises);
|
|
@@ -84,8 +78,6 @@ export class WebGLAdapter extends Adapter {
|
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
80
|
|
|
87
|
-
log.probe(LOG_LEVEL + 1, 'DOM is loaded')();
|
|
88
|
-
|
|
89
81
|
const device = new WebGLDevice(props);
|
|
90
82
|
|
|
91
83
|
// Log some debug info about the newly created context
|