@gjsify/webgl 0.1.1 → 0.1.3

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 (59) hide show
  1. package/lib/esm/canvas-webgl-widget.js +12 -0
  2. package/lib/esm/conformance/attribs.spec.js +296 -0
  3. package/lib/esm/conformance/buffers.spec.js +203 -0
  4. package/lib/esm/conformance/context.spec.js +302 -0
  5. package/lib/esm/conformance/programs.spec.js +468 -0
  6. package/lib/esm/conformance/rendering-basic.spec.js +136 -0
  7. package/lib/esm/conformance/rendering.spec.js +424 -0
  8. package/lib/esm/conformance/setup.js +36 -0
  9. package/lib/esm/conformance/state.spec.js +348 -0
  10. package/lib/esm/conformance/textures.spec.js +354 -0
  11. package/lib/esm/conformance/uniforms.spec.js +305 -0
  12. package/lib/esm/conformance-test.js +23 -0
  13. package/lib/esm/extensions/ext-color-buffer-float.js +13 -0
  14. package/lib/esm/extensions/ext-color-buffer-half-float.js +13 -0
  15. package/lib/esm/extensions/oes-texture-half-float.js +19 -0
  16. package/lib/esm/index.js +5 -0
  17. package/lib/esm/test-utils.js +65 -0
  18. package/lib/esm/test.js +2 -2
  19. package/lib/esm/webgl-buffer.js +1 -1
  20. package/lib/esm/webgl-context-base.js +3371 -0
  21. package/lib/esm/webgl-framebuffer.js +1 -1
  22. package/lib/esm/webgl-program.js +1 -1
  23. package/lib/esm/webgl-renderbuffer.js +1 -1
  24. package/lib/esm/webgl-rendering-context.js +95 -3253
  25. package/lib/esm/webgl-shader.js +2 -1
  26. package/lib/esm/webgl-texture.js +1 -1
  27. package/lib/esm/{index.spec.js → webgl1.spec.js} +2 -2
  28. package/lib/esm/webgl2-rendering-context.js +617 -27
  29. package/lib/esm/webgl2.spec.js +573 -1
  30. package/lib/types/conformance/setup.d.ts +14 -0
  31. package/lib/types/extensions/ext-blend-minmax.d.ts +2 -2
  32. package/lib/types/extensions/ext-color-buffer-float.d.ts +4 -0
  33. package/lib/types/extensions/ext-color-buffer-half-float.d.ts +4 -0
  34. package/lib/types/extensions/ext-texture-filter-anisotropic.d.ts +2 -2
  35. package/lib/types/extensions/oes-element-index-unit.d.ts +2 -2
  36. package/lib/types/extensions/oes-standard-derivatives.d.ts +2 -2
  37. package/lib/types/extensions/oes-texture-float-linear.d.ts +2 -2
  38. package/lib/types/extensions/oes-texture-float.d.ts +2 -2
  39. package/lib/types/extensions/oes-texture-half-float.d.ts +5 -0
  40. package/lib/types/extensions/stackgl-destroy-context.d.ts +3 -3
  41. package/lib/types/extensions/stackgl-resize-drawing-buffer.d.ts +3 -3
  42. package/lib/types/index.d.ts +1 -0
  43. package/lib/types/test-utils.d.ts +24 -0
  44. package/lib/types/types/extension.d.ts +2 -2
  45. package/lib/types/utils.d.ts +9 -10
  46. package/lib/types/webgl-buffer.d.ts +3 -3
  47. package/lib/types/webgl-context-base.d.ts +267 -0
  48. package/lib/types/webgl-framebuffer.d.ts +3 -3
  49. package/lib/types/webgl-program.d.ts +3 -3
  50. package/lib/types/webgl-renderbuffer.d.ts +3 -3
  51. package/lib/types/webgl-rendering-context.d.ts +5 -250
  52. package/lib/types/webgl-shader.d.ts +4 -3
  53. package/lib/types/webgl-texture-unit.d.ts +3 -3
  54. package/lib/types/webgl-texture.d.ts +3 -3
  55. package/lib/types/webgl-vertex-attribute.d.ts +5 -5
  56. package/lib/types/webgl2-rendering-context.d.ts +95 -6
  57. package/package.json +13 -11
  58. package/prebuilds/linux-x86_64/Gwebgl-0.1.typelib +0 -0
  59. package/prebuilds/linux-x86_64/libgwebgl.so +0 -0
@@ -1,830 +1,20 @@
1
- import "@girs/gdkpixbuf-2.0";
2
- import * as bits from "bit-twiddle";
3
- import tokenize from "glsl-tokenizer/string";
4
1
  import Gwebgl from "@girs/gwebgl-0.1";
5
- import GdkPixbuf from "gi://GdkPixbuf?version=2.0";
6
- import { WebGLContextAttributes } from "./webgl-context-attributes.js";
7
- import {
8
- extractImageData,
9
- checkObject,
10
- checkFormat,
11
- checkUniform,
12
- convertPixels,
13
- validCubeTarget,
14
- formatSize,
15
- isTypedArray,
16
- arrayToUint8Array,
17
- flag,
18
- listToArray,
19
- isValidString,
20
- uniformTypeSize,
21
- vertexCount,
22
- typeSize,
23
- Uint8ArrayToVariant
24
- } from "./utils.js";
25
- import { getOESElementIndexUint } from "./extensions/oes-element-index-unit.js";
26
- import { getOESStandardDerivatives } from "./extensions/oes-standard-derivatives.js";
27
- import { getOESTextureFloat } from "./extensions/oes-texture-float.js";
28
- import { getOESTextureFloatLinear } from "./extensions/oes-texture-float-linear.js";
29
- import { getSTACKGLDestroyContext } from "./extensions/stackgl-destroy-context.js";
30
- import { getSTACKGLResizeDrawingBuffer } from "./extensions/stackgl-resize-drawing-buffer.js";
31
- import { getEXTBlendMinMax } from "./extensions/ext-blend-minmax.js";
32
- import { getEXTTextureFilterAnisotropic } from "./extensions/ext-texture-filter-anisotropic.js";
33
- import { WebGLActiveInfo } from "./webgl-active-info.js";
34
- import { WebGLFramebuffer } from "./webgl-framebuffer.js";
35
- import { WebGLBuffer } from "./webgl-buffer.js";
36
- import { WebGLDrawingBufferWrapper } from "./webgl-drawing-buffer-wrapper.js";
37
- import { WebGLProgram } from "./webgl-program.js";
38
- import { WebGLRenderbuffer } from "./webgl-renderbuffer.js";
39
- import { WebGLShader } from "./webgl-shader.js";
40
- import { WebGLShaderPrecisionFormat } from "./webgl-shader-precision-format.js";
41
- import { WebGLTextureUnit } from "./webgl-texture-unit.js";
42
- import { WebGLTexture } from "./webgl-texture.js";
43
- import { WebGLUniformLocation } from "./webgl-uniform-location.js";
44
- import { WebGLVertexArrayObjectState, WebGLVertexArrayGlobalState } from "./webgl-vertex-attribute.js";
45
- import { warnNotImplemented } from "@gjsify/utils";
46
- const VERSION = "0.0.1";
47
- let CONTEXT_COUNTER = 0;
48
- const MAX_UNIFORM_LENGTH = 256;
49
- const MAX_ATTRIBUTE_LENGTH = 256;
50
- const availableExtensions = {
51
- // angle_instanced_arrays: getANGLEInstancedArrays,
52
- oes_element_index_uint: getOESElementIndexUint,
53
- oes_texture_float: getOESTextureFloat,
54
- oes_texture_float_linear: getOESTextureFloatLinear,
55
- oes_standard_derivatives: getOESStandardDerivatives,
56
- // oes_vertex_array_object: getOESVertexArrayObject,
57
- stackgl_destroy_context: getSTACKGLDestroyContext,
58
- stackgl_resize_drawingbuffer: getSTACKGLResizeDrawingBuffer,
59
- // webgl_draw_buffers: getWebGLDrawBuffers,
60
- ext_blend_minmax: getEXTBlendMinMax,
61
- ext_texture_filter_anisotropic: getEXTTextureFilterAnisotropic
62
- };
63
- class WebGLRenderingContext {
2
+ import { WebGLContextBase } from "./webgl-context-base.js";
3
+ import { Uint8ArrayToVariant, vertexCount } from "./utils.js";
4
+ import { WebGLContextBase as WebGLContextBase2 } from "./webgl-context-base.js";
5
+ class WebGLRenderingContext extends WebGLContextBase {
64
6
  constructor(canvas, options = {}) {
65
- this.unpackColorSpace = "srgb";
66
- this.RGBA8 = 32856;
67
- this.DEFAULT_ATTACHMENTS = [];
68
- this.DEFAULT_COLOR_ATTACHMENTS = [];
69
- /** context counter */
70
- this._ = 0;
71
- this._extensions = {};
72
- this._programs = {};
73
- this._shaders = {};
74
- this._textures = {};
75
- this._framebuffers = {};
76
- this._renderbuffers = {};
77
- this._buffers = {};
78
- this._activeProgram = null;
79
- this._activeFramebuffer = null;
80
- this._activeRenderbuffer = null;
81
- this._checkStencil = false;
82
- this._stencilState = true;
83
- this._activeTextureUnit = 0;
84
- this._errorStack = [];
85
- // Store limits
86
- this._maxTextureSize = 0;
87
- this._maxTextureLevel = 0;
88
- this._maxCubeMapSize = 0;
89
- this._maxCubeMapLevel = 0;
90
- // Unpack alignment
91
- this._unpackAlignment = 4;
92
- this._packAlignment = 4;
93
- // Viewport and scissor — tracked in JS to avoid crashing native getParameterx for array returns
94
- this._viewport = new Int32Array([0, 0, 0, 0]);
95
- this._scissorBox = new Int32Array([0, 0, 0, 0]);
7
+ super(canvas, options);
96
8
  this._attrib0Buffer = null;
97
- this._textureUnits = [];
98
- this._drawingBuffer = null;
99
9
  this._native = new Gwebgl.WebGLRenderingContext({});
100
- this._initGLConstants();
101
- this.DEFAULT_ATTACHMENTS = [
102
- this.COLOR_ATTACHMENT0,
103
- this.DEPTH_ATTACHMENT,
104
- this.STENCIL_ATTACHMENT,
105
- this.DEPTH_STENCIL_ATTACHMENT
106
- ];
107
- this.DEFAULT_COLOR_ATTACHMENTS = [this.COLOR_ATTACHMENT0];
108
- this.canvas = canvas;
109
- this._contextAttributes = new WebGLContextAttributes(
110
- flag(options, "alpha", true),
111
- flag(options, "depth", true),
112
- flag(options, "stencil", false),
113
- false,
114
- // flag(options, 'antialias', true),
115
- flag(options, "premultipliedAlpha", true),
116
- flag(options, "preserveDrawingBuffer", false),
117
- flag(options, "preferLowPowerToHighPerformance", false),
118
- flag(options, "failIfMajorPerformanceCaveat", false)
119
- );
120
- const width = this.drawingBufferWidth || options.width || 0;
121
- const height = this.drawingBufferHeight || options.height || 0;
122
- this._contextAttributes.premultipliedAlpha = this._contextAttributes.premultipliedAlpha && this._contextAttributes.alpha;
123
- this._ = CONTEXT_COUNTER++;
124
- const numTextures = this.getParameter(this.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
125
- this._textureUnits = new Array(numTextures);
126
- for (let i = 0; i < numTextures; ++i) {
127
- this._textureUnits[i] = new WebGLTextureUnit(this, i);
128
- }
129
- this.activeTexture(this.TEXTURE0);
130
- this._defaultVertexObjectState = new WebGLVertexArrayObjectState(this);
131
- this._vertexObjectState = this._defaultVertexObjectState;
132
- this._vertexGlobalState = new WebGLVertexArrayGlobalState(this);
133
- this._maxTextureSize = this.getParameter(this.MAX_TEXTURE_SIZE);
134
- this._maxTextureLevel = bits.log2(bits.nextPow2(this._maxTextureSize));
135
- this._maxCubeMapSize = this.getParameter(this.MAX_CUBE_MAP_TEXTURE_SIZE);
136
- this._maxCubeMapLevel = bits.log2(bits.nextPow2(this._maxCubeMapSize));
137
- this._unpackAlignment = 4;
138
- this._packAlignment = 4;
10
+ this._init();
139
11
  const attrib0Buffer = this.createBuffer();
140
12
  this._attrib0Buffer = attrib0Buffer;
141
- this.bindBuffer(this.ARRAY_BUFFER, null);
142
- this.bindBuffer(this.ELEMENT_ARRAY_BUFFER, null);
143
- this.bindFramebuffer(this.FRAMEBUFFER, null);
144
- this.bindRenderbuffer(this.RENDERBUFFER, null);
145
- this.viewport(0, 0, width, height);
146
- this.scissor(0, 0, width, height);
147
- this.clearDepth(1);
148
- this.clearColor(0, 0, 0, 0);
149
- this.clearStencil(0);
150
- this.clear(this.COLOR_BUFFER_BIT | this.DEPTH_BUFFER_BIT | this.STENCIL_BUFFER_BIT);
151
- return this;
152
- }
153
- get drawingBufferHeight() {
154
- return this.canvas.height || 0;
155
- }
156
- get drawingBufferWidth() {
157
- return this.canvas.width || 0;
158
- }
159
- _initGLConstants() {
160
- const giBaseClass = new Gwebgl.WebGLRenderingContextBase();
161
- const hash = giBaseClass.get_webgl_constants();
162
- for (const [k, v] of Object.entries(hash)) {
163
- Object.defineProperty(this, k, { value: v });
164
- }
165
- }
166
- _getGlslVersion(es) {
167
- return es ? "100" : "120";
168
- }
169
- // extWEBGL_draw_buffers() {
170
- // return this._native.extWEBGL_draw_buffers().deepUnpack<Record<string, number>>();
171
- // }
172
- _checkDimensions(target, width, height, level) {
173
- if (level < 0 || width < 0 || height < 0) {
174
- this.setError(this.INVALID_VALUE);
175
- return false;
176
- }
177
- if (target === this.TEXTURE_2D) {
178
- if (width > this._maxTextureSize || height > this._maxTextureSize || level > this._maxTextureLevel) {
179
- this.setError(this.INVALID_VALUE);
180
- return false;
181
- }
182
- } else if (this._validCubeTarget(target)) {
183
- if (width > this._maxCubeMapSize || height > this._maxCubeMapSize || level > this._maxCubeMapLevel) {
184
- this.setError(this.INVALID_VALUE);
185
- return false;
186
- }
187
- } else {
188
- this.setError(this.INVALID_ENUM);
189
- return false;
190
- }
191
- return true;
192
- }
193
- _checkLocation(location) {
194
- if (!(location instanceof WebGLUniformLocation)) {
195
- this.setError(this.INVALID_VALUE);
196
- return false;
197
- } else if (location._program._ctx !== this || location._linkCount !== location._program._linkCount) {
198
- this.setError(this.INVALID_OPERATION);
199
- return false;
200
- }
201
- return true;
202
- }
203
- _checkLocationActive(location) {
204
- if (!location) {
205
- return false;
206
- } else if (!this._checkLocation(location)) {
207
- return false;
208
- } else if (location._program !== this._activeProgram) {
209
- this.setError(this.INVALID_OPERATION);
210
- return false;
211
- }
212
- return true;
213
- }
214
- _checkOwns(object) {
215
- return typeof object === "object" && object._ctx === this;
216
- }
217
- _checkShaderSource(shader) {
218
- const source = shader._source;
219
- const tokens = tokenize(source);
220
- let errorStatus = false;
221
- const errorLog = [];
222
- for (let i = 0; i < tokens.length; ++i) {
223
- const tok = tokens[i];
224
- if (!tok) continue;
225
- switch (tok.type) {
226
- case "ident":
227
- if (!this._validGLSLIdentifier(tok.data)) {
228
- errorStatus = true;
229
- errorLog.push(tok.line + ":" + tok.column + " invalid identifier - " + tok.data);
230
- }
231
- break;
232
- case "preprocessor": {
233
- const match = tok.data.match(/^\s*#\s*(.*)$/);
234
- if (!match || match?.length < 2) {
235
- break;
236
- }
237
- const bodyToks = tokenize(match[1]);
238
- for (let j = 0; j < bodyToks.length; ++j) {
239
- const btok = bodyToks[j];
240
- if (btok.type === "ident" || btok.type === void 0) {
241
- if (!this._validGLSLIdentifier(btok.data)) {
242
- errorStatus = true;
243
- errorLog.push(tok.line + ":" + btok.column + " invalid identifier - " + btok.data);
244
- }
245
- }
246
- }
247
- break;
248
- }
249
- case "keyword":
250
- switch (tok.data) {
251
- case "do":
252
- errorStatus = true;
253
- errorLog.push(tok.line + ":" + tok.column + " do not supported");
254
- break;
255
- }
256
- break;
257
- case "builtin":
258
- switch (tok.data) {
259
- case "dFdx":
260
- case "dFdy":
261
- case "fwidth":
262
- if (!this._extensions.oes_standard_derivatives && this._getGlslVersion(true) === "100") {
263
- errorStatus = true;
264
- errorLog.push(tok.line + ":" + tok.column + " " + tok.data + " not supported");
265
- }
266
- break;
267
- }
268
- }
269
- }
270
- if (errorStatus) {
271
- shader._compileInfo = errorLog.join("\n");
272
- }
273
- return !errorStatus;
274
- }
275
- _checkStencilState() {
276
- if (!this._checkStencil) {
277
- return this._stencilState;
278
- }
279
- this._checkStencil = false;
280
- this._stencilState = true;
281
- if (this.getParameter(this.STENCIL_WRITEMASK) !== this.getParameter(this.STENCIL_BACK_WRITEMASK) || this.getParameter(this.STENCIL_VALUE_MASK) !== this.getParameter(this.STENCIL_BACK_VALUE_MASK) || this.getParameter(this.STENCIL_REF) !== this.getParameter(this.STENCIL_BACK_REF)) {
282
- this.setError(this.INVALID_OPERATION);
283
- this._stencilState = false;
284
- }
285
- return this._stencilState;
286
- }
287
- _checkTextureTarget(target) {
288
- const unit = this._getActiveTextureUnit();
289
- let tex = null;
290
- if (target === this.TEXTURE_2D) {
291
- tex = unit._bind2D;
292
- } else if (target === this.TEXTURE_CUBE_MAP) {
293
- tex = unit._bindCube;
294
- } else {
295
- this.setError(this.INVALID_ENUM);
296
- return false;
297
- }
298
- if (!tex) {
299
- this.setError(this.INVALID_OPERATION);
300
- return false;
301
- }
302
- return true;
303
- }
304
- _checkWrapper(object, Wrapper) {
305
- if (!this._checkValid(object, Wrapper)) {
306
- this.setError(this.INVALID_VALUE);
307
- return false;
308
- } else if (!this._checkOwns(object)) {
309
- this.setError(this.INVALID_OPERATION);
310
- return false;
311
- }
312
- return true;
313
- }
314
- _checkValid(object, Type) {
315
- return object instanceof Type && object._ !== 0;
316
- }
317
- _checkVertexAttribState(maxIndex) {
318
- const program = this._activeProgram;
319
- if (!program) {
320
- this.setError(this.INVALID_OPERATION);
321
- return false;
322
- }
323
- const attribs = this._vertexObjectState._attribs;
324
- for (let i = 0; i < attribs.length; ++i) {
325
- const attrib = attribs[i];
326
- if (attrib._isPointer) {
327
- const buffer = attrib._pointerBuffer;
328
- if (!buffer) {
329
- this.setError(this.INVALID_OPERATION);
330
- return false;
331
- }
332
- if (program._attributes.indexOf(i) >= 0) {
333
- let maxByte = 0;
334
- if (attrib._divisor) {
335
- maxByte = attrib._pointerSize + attrib._pointerOffset;
336
- } else {
337
- maxByte = attrib._pointerStride * maxIndex + attrib._pointerSize + attrib._pointerOffset;
338
- }
339
- if (maxByte > buffer._size) {
340
- this.setError(this.INVALID_OPERATION);
341
- return false;
342
- }
343
- }
344
- }
345
- }
346
- return true;
347
- }
348
- _checkVertexIndex(index) {
349
- if (index < 0 || index >= this._vertexObjectState._attribs.length) {
350
- this.setError(this.INVALID_VALUE);
351
- return false;
352
- }
353
- return true;
354
- }
355
- _computePixelSize(type, internalFormat) {
356
- const pixelSize = formatSize(this, internalFormat);
357
- if (pixelSize === 0) {
358
- this.setError(this.INVALID_ENUM);
359
- return 0;
360
- }
361
- switch (type) {
362
- case this.UNSIGNED_BYTE:
363
- return pixelSize;
364
- case this.UNSIGNED_SHORT_5_6_5:
365
- if (internalFormat !== this.RGB) {
366
- this.setError(this.INVALID_OPERATION);
367
- break;
368
- }
369
- return 2;
370
- case this.UNSIGNED_SHORT_4_4_4_4:
371
- case this.UNSIGNED_SHORT_5_5_5_1:
372
- if (internalFormat !== this.RGBA) {
373
- this.setError(this.INVALID_OPERATION);
374
- break;
375
- }
376
- return 2;
377
- case this.FLOAT:
378
- return 1;
379
- }
380
- this.setError(this.INVALID_ENUM);
381
- return 0;
382
- }
383
- _computeRowStride(width, pixelSize) {
384
- let rowStride = width * pixelSize;
385
- if (rowStride % this._unpackAlignment) {
386
- rowStride += this._unpackAlignment - rowStride % this._unpackAlignment;
387
- }
388
- return rowStride;
389
- }
390
- _fixupLink(program) {
391
- if (!this._native.getProgramParameter(program._, this.LINK_STATUS)) {
392
- program._linkInfoLog = this._native.getProgramInfoLog(program._);
393
- return false;
394
- }
395
- const numAttribs = this.getProgramParameter(program, this.ACTIVE_ATTRIBUTES);
396
- const names = new Array(numAttribs);
397
- program._attributes.length = numAttribs;
398
- for (let i = 0; i < numAttribs; ++i) {
399
- names[i] = this.getActiveAttrib(program, i)?.name;
400
- program._attributes[i] = this.getAttribLocation(program, names[i]) | 0;
401
- }
402
- for (let i = 0; i < names.length; ++i) {
403
- if (names[i].length > MAX_ATTRIBUTE_LENGTH) {
404
- program._linkInfoLog = "attribute " + names[i] + " is too long";
405
- return false;
406
- }
407
- }
408
- for (let i = 0; i < numAttribs; ++i) {
409
- if (program._attributes[i] < 0) continue;
410
- this._native.bindAttribLocation(
411
- program._ | 0,
412
- program._attributes[i],
413
- names[i]
414
- );
415
- }
416
- this._native.linkProgram(program._ | 0);
417
- const numUniforms = this.getProgramParameter(program, this.ACTIVE_UNIFORMS);
418
- program._uniforms.length = numUniforms;
419
- for (let i = 0; i < numUniforms; ++i) {
420
- const info = this.getActiveUniform(program, i);
421
- if (info) program._uniforms[i] = info;
422
- }
423
- for (let i = 0; i < program._uniforms.length; ++i) {
424
- if (program._uniforms[i].name.length > MAX_UNIFORM_LENGTH) {
425
- program._linkInfoLog = "uniform " + program._uniforms[i].name + " is too long";
426
- return false;
427
- }
428
- }
429
- program._linkInfoLog = "";
430
- return true;
431
- }
432
- _framebufferOk() {
433
- const framebuffer = this._activeFramebuffer;
434
- if (framebuffer && this._preCheckFramebufferStatus(framebuffer) !== this.FRAMEBUFFER_COMPLETE) {
435
- this.setError(this.INVALID_FRAMEBUFFER_OPERATION);
436
- return false;
437
- }
438
- return true;
439
- }
440
- _getActiveBuffer(target) {
441
- if (target === this.ARRAY_BUFFER) {
442
- return this._vertexGlobalState._arrayBufferBinding;
443
- } else if (target === this.ELEMENT_ARRAY_BUFFER) {
444
- return this._vertexObjectState._elementArrayBufferBinding;
445
- }
446
- return null;
447
- }
448
- _getActiveTextureUnit() {
449
- return this._textureUnits[this._activeTextureUnit];
450
- }
451
- _getActiveTexture(target) {
452
- const activeUnit = this._getActiveTextureUnit();
453
- if (target === this.TEXTURE_2D) {
454
- return activeUnit._bind2D;
455
- } else if (target === this.TEXTURE_CUBE_MAP) {
456
- return activeUnit._bindCube;
457
- }
458
- return null;
459
- }
460
- _getAttachments() {
461
- return this._extensions.webgl_draw_buffers ? this._extensions.webgl_draw_buffers._ALL_ATTACHMENTS : this.DEFAULT_ATTACHMENTS;
462
- }
463
- _getColorAttachments() {
464
- return this._extensions.webgl_draw_buffers ? this._extensions.webgl_draw_buffers._ALL_COLOR_ATTACHMENTS : this.DEFAULT_COLOR_ATTACHMENTS;
465
- }
466
- _getParameterDirect(pname) {
467
- return this._native.getParameterx(pname)?.deepUnpack();
468
- }
469
- _getTexImage(target) {
470
- const unit = this._getActiveTextureUnit();
471
- if (target === this.TEXTURE_2D) {
472
- return unit._bind2D;
473
- } else if (validCubeTarget(this, target)) {
474
- return unit._bindCube;
475
- }
476
- this.setError(this.INVALID_ENUM);
477
- return null;
478
- }
479
- _preCheckFramebufferStatus(framebuffer) {
480
- const attachments = framebuffer._attachments;
481
- const width = [];
482
- const height = [];
483
- const depthAttachment = attachments[this.DEPTH_ATTACHMENT];
484
- const depthStencilAttachment = attachments[this.DEPTH_STENCIL_ATTACHMENT];
485
- const stencilAttachment = attachments[this.STENCIL_ATTACHMENT];
486
- if (depthStencilAttachment && (stencilAttachment || depthAttachment) || stencilAttachment && depthAttachment) {
487
- return this.FRAMEBUFFER_UNSUPPORTED;
488
- }
489
- const colorAttachments = this._getColorAttachments();
490
- let colorAttachmentCount = 0;
491
- for (const attachmentEnum in attachments) {
492
- if (attachments[attachmentEnum] && colorAttachments.indexOf(Number(attachmentEnum)) !== -1) {
493
- colorAttachmentCount++;
494
- }
495
- }
496
- if (colorAttachmentCount === 0) {
497
- return this.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
498
- }
499
- if (depthStencilAttachment instanceof WebGLTexture) {
500
- return this.FRAMEBUFFER_UNSUPPORTED;
501
- } else if (depthStencilAttachment instanceof WebGLRenderbuffer) {
502
- if (depthStencilAttachment._format !== this.DEPTH_STENCIL) {
503
- return this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
504
- }
505
- width.push(depthStencilAttachment._width);
506
- height.push(depthStencilAttachment._height);
507
- }
508
- if (depthAttachment instanceof WebGLTexture) {
509
- return this.FRAMEBUFFER_UNSUPPORTED;
510
- } else if (depthAttachment instanceof WebGLRenderbuffer) {
511
- if (depthAttachment._format !== this.DEPTH_COMPONENT16) {
512
- return this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
513
- }
514
- width.push(depthAttachment._width);
515
- height.push(depthAttachment._height);
516
- }
517
- if (stencilAttachment instanceof WebGLTexture) {
518
- return this.FRAMEBUFFER_UNSUPPORTED;
519
- } else if (stencilAttachment instanceof WebGLRenderbuffer) {
520
- if (stencilAttachment._format !== this.STENCIL_INDEX8) {
521
- return this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
522
- }
523
- width.push(stencilAttachment._width);
524
- height.push(stencilAttachment._height);
525
- }
526
- let colorAttached = false;
527
- for (let i = 0; i < colorAttachments.length; ++i) {
528
- const colorAttachment = attachments[colorAttachments[i]];
529
- if (colorAttachment instanceof WebGLTexture) {
530
- if (colorAttachment._format !== this.RGBA || !(colorAttachment._type === this.UNSIGNED_BYTE || colorAttachment._type === this.FLOAT)) {
531
- return this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
532
- }
533
- colorAttached = true;
534
- const level = framebuffer._attachmentLevel[this.COLOR_ATTACHMENT0];
535
- if (level === null) throw new TypeError("level is null!");
536
- width.push(colorAttachment._levelWidth[level]);
537
- height.push(colorAttachment._levelHeight[level]);
538
- } else if (colorAttachment instanceof WebGLRenderbuffer) {
539
- const format = colorAttachment._format;
540
- if (format !== this.RGBA4 && format !== this.RGB565 && format !== this.RGB5_A1) {
541
- return this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
542
- }
543
- colorAttached = true;
544
- width.push(colorAttachment._width);
545
- height.push(colorAttachment._height);
546
- }
547
- }
548
- if (!colorAttached && !stencilAttachment && !depthAttachment && !depthStencilAttachment) {
549
- return this.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
550
- }
551
- if (width.length <= 0 || height.length <= 0) {
552
- return this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
553
- }
554
- for (let i = 1; i < width.length; ++i) {
555
- if (width[i - 1] !== width[i] || height[i - 1] !== height[i]) {
556
- return this.FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
557
- }
558
- }
559
- if (width[0] === 0 || height[0] === 0) {
560
- return this.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
561
- }
562
- framebuffer._width = width[0];
563
- framebuffer._height = height[0];
564
- return this.FRAMEBUFFER_COMPLETE;
565
- }
566
- _isConstantBlendFunc(factor) {
567
- return factor === this.CONSTANT_COLOR || factor === this.ONE_MINUS_CONSTANT_COLOR || factor === this.CONSTANT_ALPHA || factor === this.ONE_MINUS_CONSTANT_ALPHA;
568
- }
569
- _isObject(object, method, Wrapper) {
570
- if (!(object === null || object === void 0) && !(object instanceof Wrapper)) {
571
- throw new TypeError(method + "(" + Wrapper.name + ")");
572
- }
573
- if (this._checkValid(object, Wrapper) && this._checkOwns(object)) {
574
- return true;
575
- }
576
- return false;
577
- }
578
- _resizeDrawingBuffer(width, height) {
579
- const prevFramebuffer = this._activeFramebuffer;
580
- const prevTexture = this._getActiveTexture(this.TEXTURE_2D);
581
- const prevRenderbuffer = this._activeRenderbuffer;
582
- const contextAttributes = this._contextAttributes;
583
- const drawingBuffer = this._drawingBuffer;
584
- if (drawingBuffer?._framebuffer) {
585
- this._native.bindFramebuffer(this.FRAMEBUFFER, drawingBuffer?._framebuffer);
586
- }
587
- const attachments = this._getAttachments();
588
- for (let i = 0; i < attachments.length; ++i) {
589
- this._native.framebufferTexture2D(
590
- this.FRAMEBUFFER,
591
- attachments[i],
592
- this.TEXTURE_2D,
593
- 0,
594
- 0
595
- );
596
- }
597
- if (drawingBuffer?._color) {
598
- this._native.bindTexture(this.TEXTURE_2D, drawingBuffer?._color);
599
- }
600
- const colorFormat = contextAttributes.alpha ? this.RGBA : this.RGB;
601
- this._native.texImage2D(
602
- this.TEXTURE_2D,
603
- 0,
604
- colorFormat,
605
- width,
606
- height,
607
- 0,
608
- colorFormat,
609
- this.UNSIGNED_BYTE,
610
- Uint8ArrayToVariant(null)
611
- );
612
- this._native.texParameteri(this.TEXTURE_2D, this.TEXTURE_MIN_FILTER, this.NEAREST);
613
- this._native.texParameteri(this.TEXTURE_2D, this.TEXTURE_MAG_FILTER, this.NEAREST);
614
- if (drawingBuffer?._color) {
615
- this._native.framebufferTexture2D(
616
- this.FRAMEBUFFER,
617
- this.COLOR_ATTACHMENT0,
618
- this.TEXTURE_2D,
619
- drawingBuffer?._color,
620
- 0
621
- );
622
- }
623
- let storage = 0;
624
- let attachment = 0;
625
- if (contextAttributes.depth && contextAttributes.stencil) {
626
- storage = this.DEPTH_STENCIL;
627
- attachment = this.DEPTH_STENCIL_ATTACHMENT;
628
- } else if (contextAttributes.depth) {
629
- storage = 33191;
630
- attachment = this.DEPTH_ATTACHMENT;
631
- } else if (contextAttributes.stencil) {
632
- storage = this.STENCIL_INDEX8;
633
- attachment = this.STENCIL_ATTACHMENT;
634
- }
635
- if (storage) {
636
- if (drawingBuffer?._depthStencil) {
637
- this._native.bindRenderbuffer(
638
- this.RENDERBUFFER,
639
- drawingBuffer?._depthStencil
640
- );
641
- }
642
- this._native.renderbufferStorage(
643
- this.RENDERBUFFER,
644
- storage,
645
- width,
646
- height
647
- );
648
- if (drawingBuffer?._depthStencil) {
649
- this._native.framebufferRenderbuffer(
650
- this.FRAMEBUFFER,
651
- attachment,
652
- this.RENDERBUFFER,
653
- drawingBuffer?._depthStencil
654
- );
655
- }
656
- }
657
- this.bindFramebuffer(this.FRAMEBUFFER, prevFramebuffer);
658
- this.bindTexture(this.TEXTURE_2D, prevTexture);
659
- this.bindRenderbuffer(this.RENDERBUFFER, prevRenderbuffer);
660
- }
661
- _restoreError(lastError) {
662
- const topError = this._errorStack.pop();
663
- if (topError === this.NO_ERROR) {
664
- this.setError(lastError);
665
- } else if (topError) {
666
- this.setError(topError);
667
- }
668
- }
669
- _saveError() {
670
- this._errorStack.push(this.getError());
671
- }
672
- _switchActiveProgram(active) {
673
- if (active) {
674
- active._refCount -= 1;
675
- active._checkDelete();
676
- }
677
- }
678
- _tryDetachFramebuffer(framebuffer, renderbuffer) {
679
- if (framebuffer && framebuffer._linked(renderbuffer)) {
680
- const attachments = this._getAttachments();
681
- const framebufferAttachments = Object.keys(framebuffer._attachments);
682
- for (let i = 0; i < framebufferAttachments.length; ++i) {
683
- if (framebuffer._attachments[attachments[i]] === renderbuffer) {
684
- this.framebufferTexture2D(
685
- this.FRAMEBUFFER,
686
- attachments[i] | 0,
687
- this.TEXTURE_2D,
688
- null
689
- );
690
- }
691
- }
692
- }
693
- }
694
- _updateFramebufferAttachments(framebuffer) {
695
- if (!framebuffer) {
696
- return;
697
- }
698
- const prevStatus = framebuffer._status;
699
- const attachments = this._getAttachments();
700
- framebuffer._status = this._preCheckFramebufferStatus(framebuffer);
701
- if (framebuffer._status !== this.FRAMEBUFFER_COMPLETE) {
702
- if (prevStatus === this.FRAMEBUFFER_COMPLETE) {
703
- for (let i = 0; i < attachments.length; ++i) {
704
- const attachmentEnum = attachments[i];
705
- this._native.framebufferTexture2D(
706
- this.FRAMEBUFFER,
707
- attachmentEnum,
708
- framebuffer._attachmentFace[attachmentEnum] || 0,
709
- 0,
710
- framebuffer._attachmentLevel[attachmentEnum] || 0
711
- );
712
- }
713
- }
714
- return;
715
- }
716
- for (let i = 0; i < attachments.length; ++i) {
717
- const attachmentEnum = attachments[i];
718
- this._native.framebufferTexture2D(
719
- this.FRAMEBUFFER,
720
- attachmentEnum,
721
- framebuffer._attachmentFace[attachmentEnum] || 0,
722
- 0,
723
- framebuffer._attachmentLevel[attachmentEnum] || 0
724
- );
725
- }
726
- for (let i = 0; i < attachments.length; ++i) {
727
- const attachmentEnum = attachments[i];
728
- const attachment = framebuffer._attachments[attachmentEnum];
729
- if (attachment instanceof WebGLTexture) {
730
- this._native.framebufferTexture2D(
731
- this.FRAMEBUFFER,
732
- attachmentEnum,
733
- framebuffer._attachmentFace[attachmentEnum] || 0,
734
- attachment._ | 0,
735
- framebuffer._attachmentLevel[attachmentEnum] || 0
736
- );
737
- } else if (attachment instanceof WebGLRenderbuffer) {
738
- this._native.framebufferRenderbuffer(
739
- this.FRAMEBUFFER,
740
- attachmentEnum,
741
- this.RENDERBUFFER,
742
- attachment._ | 0
743
- );
744
- }
745
- }
746
- }
747
- _validBlendFunc(factor) {
748
- return factor === this.ZERO || factor === this.ONE || factor === this.SRC_COLOR || factor === this.ONE_MINUS_SRC_COLOR || factor === this.DST_COLOR || factor === this.ONE_MINUS_DST_COLOR || factor === this.SRC_ALPHA || factor === this.ONE_MINUS_SRC_ALPHA || factor === this.DST_ALPHA || factor === this.ONE_MINUS_DST_ALPHA || factor === this.SRC_ALPHA_SATURATE || factor === this.CONSTANT_COLOR || factor === this.ONE_MINUS_CONSTANT_COLOR || factor === this.CONSTANT_ALPHA || factor === this.ONE_MINUS_CONSTANT_ALPHA;
749
- }
750
- _validBlendMode(mode) {
751
- return mode === this.FUNC_ADD || mode === this.FUNC_SUBTRACT || mode === this.FUNC_REVERSE_SUBTRACT || this._extensions.ext_blend_minmax && (mode === this._extensions.ext_blend_minmax.MIN_EXT || mode === this._extensions.ext_blend_minmax.MAX_EXT);
752
- }
753
- _validCubeTarget(target) {
754
- return target === this.TEXTURE_CUBE_MAP_POSITIVE_X || target === this.TEXTURE_CUBE_MAP_NEGATIVE_X || target === this.TEXTURE_CUBE_MAP_POSITIVE_Y || target === this.TEXTURE_CUBE_MAP_NEGATIVE_Y || target === this.TEXTURE_CUBE_MAP_POSITIVE_Z || target === this.TEXTURE_CUBE_MAP_NEGATIVE_Z;
755
13
  }
756
- _validFramebufferAttachment(attachment) {
757
- switch (attachment) {
758
- case this.DEPTH_ATTACHMENT:
759
- case this.STENCIL_ATTACHMENT:
760
- case this.DEPTH_STENCIL_ATTACHMENT:
761
- case this.COLOR_ATTACHMENT0:
762
- return true;
763
- }
764
- if (this._extensions.webgl_draw_buffers) {
765
- const { webgl_draw_buffers } = this._extensions;
766
- return attachment < webgl_draw_buffers.COLOR_ATTACHMENT0_WEBGL + webgl_draw_buffers._maxDrawBuffers;
767
- }
768
- return false;
769
- }
770
- _validGLSLIdentifier(str) {
771
- return !(str.indexOf("webgl_") === 0 || str.indexOf("_webgl_") === 0 || str.length > 256);
772
- }
773
- _validTextureTarget(target) {
774
- return target === this.TEXTURE_2D || target === this.TEXTURE_CUBE_MAP;
775
- }
776
- _verifyTextureCompleteness(target, pname, param) {
777
- const unit = this._getActiveTextureUnit();
778
- let texture = null;
779
- if (target === this.TEXTURE_2D) {
780
- texture = unit._bind2D;
781
- } else if (this._validCubeTarget(target)) {
782
- texture = unit._bindCube;
783
- }
784
- if (this._extensions.oes_texture_float && !this._extensions.oes_texture_float_linear && texture && texture._type === this.FLOAT && (pname === this.TEXTURE_MAG_FILTER || pname === this.TEXTURE_MIN_FILTER) && (param === this.LINEAR || param === this.LINEAR_MIPMAP_NEAREST || param === this.NEAREST_MIPMAP_LINEAR || param === this.LINEAR_MIPMAP_LINEAR)) {
785
- texture._complete = false;
786
- this.bindTexture(target, texture);
787
- return;
788
- }
789
- if (texture && texture._complete === false) {
790
- texture._complete = true;
791
- this.bindTexture(target, texture);
792
- }
793
- }
794
- _wrapShader(_type, source) {
795
- const hasVersion = source.startsWith("#version") || source.includes("\n#version");
796
- let preamble = "";
797
- if (!this._extensions.oes_standard_derivatives && /#ifdef\s+GL_OES_standard_derivatives/.test(source)) {
798
- preamble += "#undef GL_OES_standard_derivatives\n";
799
- }
800
- if (!this._extensions.webgl_draw_buffers) {
801
- preamble += "#define gl_MaxDrawBuffers 1\n";
802
- }
803
- if (hasVersion) {
804
- if (preamble) {
805
- const newline = source.indexOf("\n");
806
- if (newline !== -1) {
807
- source = source.slice(0, newline + 1) + preamble + source.slice(newline + 1);
808
- } else {
809
- source = source + "\n" + preamble;
810
- }
811
- }
812
- } else {
813
- if (this.canvas) {
814
- const glArea = this.canvas.getGlArea();
815
- const es = glArea.get_use_es();
816
- const version = this._getGlslVersion(es);
817
- if (version) {
818
- source = "#version " + version + "\n" + preamble + source;
819
- } else if (preamble) {
820
- source = preamble + source;
821
- }
822
- } else if (preamble) {
823
- source = preamble + source;
824
- }
825
- }
826
- return source;
14
+ get _gl() {
15
+ return this._native;
827
16
  }
17
+ // ─── Attrib0 Hack (WebGL1 / GLES2 only) ─────────────────────────────
828
18
  _beginAttrib0Hack() {
829
19
  this._native.bindBuffer(this.ARRAY_BUFFER, this._attrib0Buffer?._ || 0);
830
20
  const uInt8Data = new Uint8Array(this._vertexGlobalState._attribs[0]._data.buffer);
@@ -860,2488 +50,140 @@ class WebGLRenderingContext {
860
50
  this._native.bindBuffer(this.ARRAY_BUFFER, 0);
861
51
  }
862
52
  }
863
- _allocateDrawingBuffer(width, height) {
864
- this._drawingBuffer = new WebGLDrawingBufferWrapper(
865
- this._native.createFramebuffer(),
866
- this._native.createTexture(),
867
- this._native.createRenderbuffer()
868
- );
869
- this._resizeDrawingBuffer(width, height);
870
- }
871
- /**
872
- * The `WebGLRenderingContext.getContextAttributes()` method returns a `WebGLContextAttributes` object that contains the actual context parameters.
873
- * Might return `null`, if the context is lost.
874
- * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getContextAttributes
875
- * @returns A `WebGLContextAttributes` object that contains the actual context parameters, or `null` if the context is lost.
876
- */
877
- getContextAttributes() {
878
- return this._contextAttributes;
879
- }
880
- getExtension(name) {
881
- const str = name.toLowerCase();
882
- if (str in this._extensions) {
883
- return this._extensions[str];
884
- }
885
- const ext = availableExtensions[str] ? availableExtensions[str](this) : null;
886
- if (ext) {
887
- this._extensions[str] = ext;
53
+ // ─── drawArrays / drawElements with attrib0 hack ─────────────────────
54
+ drawArrays(mode = 0, first = 0, count = 0) {
55
+ if (first < 0 || count < 0) {
56
+ this.setError(this.INVALID_VALUE);
57
+ return;
888
58
  }
889
- return ext;
890
- }
891
- bufferData(target = 0, dataOrSize, usage = 0) {
892
- let size = 0;
893
- let data = null;
894
- if (typeof dataOrSize === "number") {
895
- size = dataOrSize;
896
- } else if (typeof dataOrSize === "object") {
897
- data = dataOrSize;
59
+ if (!this._checkStencilState()) {
60
+ return;
898
61
  }
899
- if (usage !== this.STREAM_DRAW && usage !== this.STATIC_DRAW && usage !== this.DYNAMIC_DRAW) {
62
+ const reducedCount = vertexCount(this, mode, count);
63
+ if (reducedCount < 0) {
900
64
  this.setError(this.INVALID_ENUM);
901
65
  return;
902
66
  }
903
- if (target !== this.ARRAY_BUFFER && target !== this.ELEMENT_ARRAY_BUFFER) {
904
- this.setError(this.INVALID_ENUM);
67
+ if (!this._framebufferOk()) {
905
68
  return;
906
69
  }
907
- const active = this._getActiveBuffer(target);
908
- if (!active) {
909
- this.setError(this.INVALID_OPERATION);
70
+ if (count === 0) {
910
71
  return;
911
72
  }
912
- if (data) {
913
- let u8Data = null;
914
- if (isTypedArray(data) || data instanceof DataView) {
915
- u8Data = arrayToUint8Array(data);
73
+ let maxIndex = first;
74
+ if (count > 0) {
75
+ maxIndex = count + first - 1 >>> 0;
76
+ }
77
+ if (this._checkVertexAttribState(maxIndex)) {
78
+ if (this._vertexObjectState._attribs[0]._isPointer || this._extensions.webgl_draw_buffers && this._extensions.webgl_draw_buffers._buffersState && this._extensions.webgl_draw_buffers._buffersState.length > 0) {
79
+ return this._native.drawArrays(mode, first, reducedCount);
916
80
  } else {
917
- this.setError(this.INVALID_VALUE);
918
- return;
919
- }
920
- this._saveError();
921
- this._native.bufferData(
922
- target,
923
- Uint8ArrayToVariant(u8Data),
924
- usage
925
- );
926
- const error = this.getError();
927
- this._restoreError(error);
928
- if (error !== this.NO_ERROR) {
929
- return;
930
- }
931
- active._size = u8Data.length;
932
- if (target === this.ELEMENT_ARRAY_BUFFER) {
933
- active._elements = new Uint8Array(u8Data);
934
- }
935
- } else if (typeof dataOrSize === "number") {
936
- if (size < 0) {
937
- this.setError(this.INVALID_VALUE);
938
- return;
939
- }
940
- this._saveError();
941
- this._native.bufferDataSizeOnly(
942
- target,
943
- size,
944
- usage
945
- );
946
- const error = this.getError();
947
- this._restoreError(error);
948
- if (error !== this.NO_ERROR) {
949
- return;
950
- }
951
- active._size = size;
952
- if (target === this.ELEMENT_ARRAY_BUFFER) {
953
- active._elements = new Uint8Array(size);
81
+ this._beginAttrib0Hack();
82
+ this._native._drawArraysInstanced(mode, first, reducedCount, 1);
83
+ this._endAttrib0Hack();
954
84
  }
955
- } else {
956
- this.setError(this.INVALID_VALUE);
957
85
  }
958
86
  }
959
- bufferSubData(target = 0, offset = 0, data) {
960
- if (target !== this.ARRAY_BUFFER && target !== this.ELEMENT_ARRAY_BUFFER) {
961
- this.setError(this.INVALID_ENUM);
962
- return;
963
- }
964
- if (data === null) {
965
- return;
966
- }
967
- if (!data || typeof data !== "object") {
968
- this.setError(this.INVALID_VALUE);
969
- return;
970
- }
971
- const active = this._getActiveBuffer(target);
972
- if (!active) {
973
- this.setError(this.INVALID_OPERATION);
974
- return;
975
- }
976
- if (offset < 0 || offset >= active._size) {
87
+ drawElements(mode = 0, count = 0, type = 0, ioffset = 0) {
88
+ if (count < 0 || ioffset < 0) {
977
89
  this.setError(this.INVALID_VALUE);
978
90
  return;
979
91
  }
980
- let u8Data = null;
981
- if (isTypedArray(data) || data instanceof DataView) {
982
- u8Data = arrayToUint8Array(data);
983
- } else {
984
- this.setError(this.INVALID_VALUE);
92
+ if (!this._checkStencilState()) {
985
93
  return;
986
94
  }
987
- if (offset + u8Data.length > active._size) {
988
- this.setError(this.INVALID_VALUE);
95
+ const elementBuffer = this._vertexObjectState._elementArrayBufferBinding;
96
+ if (!elementBuffer) {
97
+ this.setError(this.INVALID_OPERATION);
989
98
  return;
990
99
  }
991
- if (target === this.ELEMENT_ARRAY_BUFFER) {
992
- active._elements.set(u8Data, offset);
993
- }
994
- this._native.bufferSubData(target, offset, Uint8ArrayToVariant(u8Data));
995
- }
996
- compressedTexImage2D(target, level, internalFormat, width, height, border, data) {
997
- return this._native.compressedTexImage2D(target, level, internalFormat, width, height, border, Uint8ArrayToVariant(arrayToUint8Array(data)));
998
- }
999
- compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data) {
1000
- return this._native.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, Uint8ArrayToVariant(arrayToUint8Array(data)));
1001
- }
1002
- readPixels(x = 0, y = 0, width = 0, height = 0, format = 0, type = 0, pixels) {
1003
- if (!pixels) return;
1004
- if (!(this._extensions.oes_texture_float && type === this.FLOAT && format === this.RGBA)) {
1005
- if (format === this.RGB || format === this.ALPHA || type !== this.UNSIGNED_BYTE) {
100
+ let elementData = null;
101
+ let offset = ioffset;
102
+ if (type === this.UNSIGNED_SHORT) {
103
+ if (offset % 2) {
1006
104
  this.setError(this.INVALID_OPERATION);
1007
105
  return;
1008
- } else if (format !== this.RGBA) {
1009
- this.setError(this.INVALID_ENUM);
1010
- return;
1011
- } else if (width < 0 || height < 0 || !(pixels instanceof Uint8Array)) {
1012
- this.setError(this.INVALID_VALUE);
106
+ }
107
+ offset >>= 1;
108
+ elementData = new Uint16Array(elementBuffer._elements.buffer);
109
+ } else if (this._extensions.oes_element_index_uint && type === this.UNSIGNED_INT) {
110
+ if (offset % 4) {
111
+ this.setError(this.INVALID_OPERATION);
1013
112
  return;
1014
113
  }
1015
- }
1016
- if (!this._framebufferOk()) {
1017
- console.error("framebuffer is not okay!");
1018
- return;
1019
- }
1020
- let rowStride = width * 4;
1021
- if (rowStride % this._packAlignment !== 0) {
1022
- rowStride += this._packAlignment - rowStride % this._packAlignment;
1023
- }
1024
- const imageSize = rowStride * (height - 1) + width * 4;
1025
- if (imageSize <= 0) {
1026
- return;
1027
- }
1028
- const pixelsLength = pixels.length || pixels.byteLength || 0;
1029
- if (pixelsLength < imageSize) {
1030
- this.setError(this.INVALID_VALUE);
114
+ offset >>= 2;
115
+ elementData = new Uint32Array(elementBuffer._elements.buffer);
116
+ } else if (type === this.UNSIGNED_BYTE) {
117
+ elementData = elementBuffer._elements;
118
+ } else {
119
+ this.setError(this.INVALID_ENUM);
1031
120
  return;
1032
121
  }
1033
- let viewWidth = this.drawingBufferWidth;
1034
- let viewHeight = this.drawingBufferHeight;
1035
- if (this._activeFramebuffer) {
1036
- viewWidth = this._activeFramebuffer._width;
1037
- viewHeight = this._activeFramebuffer._height;
1038
- }
1039
- const pixelData = arrayToUint8Array(pixels);
1040
- if (x >= viewWidth || x + width <= 0 || y >= viewHeight || y + height <= 0) {
1041
- for (let i = 0; i < pixelData.length; ++i) {
1042
- pixelData[i] = 0;
1043
- }
1044
- } else if (x < 0 || x + width > viewWidth || y < 0 || y + height > viewHeight) {
1045
- for (let i = 0; i < pixelData.length; ++i) {
1046
- pixelData[i] = 0;
1047
- }
1048
- let nx = x;
1049
- let nWidth = width;
1050
- if (x < 0) {
1051
- nWidth += x;
1052
- nx = 0;
1053
- }
1054
- if (nx + width > viewWidth) {
1055
- nWidth = viewWidth - nx;
1056
- }
1057
- let ny = y;
1058
- let nHeight = height;
1059
- if (y < 0) {
1060
- nHeight += y;
1061
- ny = 0;
1062
- }
1063
- if (ny + height > viewHeight) {
1064
- nHeight = viewHeight - ny;
1065
- }
1066
- let nRowStride = nWidth * 4;
1067
- if (nRowStride % this._packAlignment !== 0) {
1068
- nRowStride += this._packAlignment - nRowStride % this._packAlignment;
1069
- }
1070
- if (nWidth > 0 && nHeight > 0) {
1071
- const subPixels = new Uint8Array(nRowStride * nHeight);
1072
- const result = this._native.readPixels(
1073
- nx,
1074
- ny,
1075
- nWidth,
1076
- nHeight,
1077
- format,
1078
- type,
1079
- Uint8ArrayToVariant(subPixels)
1080
- );
1081
- const src = result && result.length > 0 ? result : subPixels;
1082
- const offset = 4 * (nx - x) + (ny - y) * rowStride;
1083
- for (let j = 0; j < nHeight; ++j) {
1084
- for (let i = 0; i < nWidth; ++i) {
1085
- for (let k = 0; k < 4; ++k) {
1086
- pixelData[offset + j * rowStride + 4 * i + k] = src[j * nRowStride + 4 * i + k];
1087
- }
1088
- }
1089
- }
1090
- }
1091
- } else {
1092
- const result = this._native.readPixels(
1093
- x,
1094
- y,
1095
- width,
1096
- height,
1097
- format,
1098
- type,
1099
- Uint8ArrayToVariant(pixelData)
1100
- );
1101
- if (result && result.length > 0) {
1102
- pixelData.set(result);
1103
- }
1104
- }
1105
- }
1106
- // https://github.com/stackgl/headless-gl/blob/ce1c08c0ef0c31d8c308cb828fd2f172c0bf5084/src/javascript/webgl-rendering-context.js#L3131
1107
- texImage2D(target = 0, level = 0, internalFormat = 0, formatOrWidth = 0, typeOrHeight = 0, sourceOrBorder = 0, _format = 0, type = 0, pixels) {
1108
- let width = 0;
1109
- let height = 0;
1110
- let format = 0;
1111
- let source;
1112
- let pixbuf;
1113
- let border = 0;
1114
- if (arguments.length === 6) {
1115
- type = typeOrHeight;
1116
- format = formatOrWidth;
1117
- if (sourceOrBorder instanceof GdkPixbuf.Pixbuf) {
1118
- pixbuf = sourceOrBorder;
1119
- width = pixbuf.get_width();
1120
- height = pixbuf.get_height();
1121
- ;
1122
- pixels = pixbuf.get_pixels();
1123
- } else {
1124
- source = sourceOrBorder;
1125
- const imageData = extractImageData(source);
1126
- if (imageData == null) {
1127
- throw new TypeError("texImage2D(GLenum, GLint, GLenum, GLint, GLenum, GLenum, ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement)");
1128
- }
1129
- width = imageData.width;
1130
- height = imageData.height;
1131
- pixels = imageData.data;
1132
- }
1133
- } else if (arguments.length === 9) {
1134
- width = formatOrWidth;
1135
- height = typeOrHeight;
1136
- border = sourceOrBorder;
1137
- format = _format;
1138
- type = type;
1139
- pixels = pixels;
1140
- }
1141
- if (typeof pixels !== "object" && pixels !== void 0) {
1142
- throw new TypeError("texImage2D(GLenum, GLint, GLenum, GLint, GLint, GLint, GLenum, GLenum, Uint8Array)");
1143
- }
1144
- if (!checkFormat(this, format) || !checkFormat(this, internalFormat)) {
1145
- this.setError(this.INVALID_ENUM);
1146
- return;
1147
- }
1148
- if (type === this.FLOAT && !this._extensions.oes_texture_float) {
1149
- this.setError(this.INVALID_ENUM);
1150
- return;
1151
- }
1152
- const texture = this._getTexImage(target);
1153
- if (!texture || format !== internalFormat) {
1154
- this.setError(this.INVALID_OPERATION);
1155
- return;
1156
- }
1157
- const pixelSize = this._computePixelSize(type, format);
1158
- if (pixelSize === 0) {
1159
- return;
1160
- }
1161
- if (!this._checkDimensions(
1162
- target,
1163
- width,
1164
- height,
1165
- level
1166
- )) {
1167
- return;
1168
- }
1169
- const data = convertPixels(pixels);
1170
- const rowStride = this._computeRowStride(width, pixelSize);
1171
- const imageSize = rowStride * height;
1172
- if (data && data.length < imageSize) {
1173
- this.setError(this.INVALID_OPERATION);
1174
- return;
1175
- }
1176
- if (border !== 0 || validCubeTarget(this, target) && width !== height) {
1177
- this.setError(this.INVALID_VALUE);
1178
- return;
1179
- }
1180
- this._saveError();
1181
- this._native.texImage2D(target, level, internalFormat, width, height, border, format, type, Uint8ArrayToVariant(data));
1182
- const error = this.getError();
1183
- this._restoreError(error);
1184
- if (error !== this.NO_ERROR) {
1185
- return;
1186
- }
1187
- texture._levelWidth[level] = width;
1188
- texture._levelHeight[level] = height;
1189
- texture._format = format;
1190
- texture._type = type;
1191
- const activeFramebuffer = this._activeFramebuffer;
1192
- if (activeFramebuffer) {
1193
- let needsUpdate = false;
1194
- const attachments = this._getAttachments();
1195
- for (let i = 0; i < attachments.length; ++i) {
1196
- if (activeFramebuffer._attachments[attachments[i]] === texture) {
1197
- needsUpdate = true;
1198
- break;
1199
- }
1200
- }
1201
- if (needsUpdate && this._activeFramebuffer) {
1202
- this._updateFramebufferAttachments(this._activeFramebuffer);
1203
- }
1204
- }
1205
- }
1206
- texSubImage2D(target = 0, level = 0, xoffset = 0, yoffset = 0, formatOrWidth = 0, typeOrHeight = 0, sourceOrFormat = 0, type = 0, pixels) {
1207
- let width = 0;
1208
- let height = 0;
1209
- let format = 0;
1210
- let source;
1211
- let pixbuf;
1212
- if (arguments.length === 7) {
1213
- type = typeOrHeight;
1214
- format = formatOrWidth;
1215
- if (sourceOrFormat instanceof GdkPixbuf.Pixbuf) {
1216
- pixbuf = sourceOrFormat;
1217
- width = pixbuf.get_width();
1218
- height = pixbuf.get_height();
1219
- ;
1220
- pixels = pixbuf.get_pixels();
1221
- } else {
1222
- source = sourceOrFormat;
1223
- const imageData = extractImageData(source);
1224
- if (imageData == null) {
1225
- throw new TypeError("texSubImage2D(GLenum, GLint, GLint, GLint, GLenum, GLenum, ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement)");
1226
- }
1227
- width = imageData.width;
1228
- height = imageData.height;
1229
- pixels = imageData.data;
1230
- }
1231
- } else {
1232
- width = formatOrWidth;
1233
- height = typeOrHeight;
1234
- format = sourceOrFormat;
1235
- }
1236
- if (typeof pixels !== "object") {
1237
- throw new TypeError("texSubImage2D(GLenum, GLint, GLint, GLint, GLint, GLint, GLenum, GLenum, Uint8Array)");
1238
- }
1239
- const texture = this._getTexImage(target);
1240
- if (!texture) {
1241
- this.setError(this.INVALID_OPERATION);
1242
- return;
1243
- }
1244
- if (type === this.FLOAT && !this._extensions.oes_texture_float) {
1245
- this.setError(this.INVALID_ENUM);
1246
- return;
1247
- }
1248
- const pixelSize = this._computePixelSize(type, format);
1249
- if (pixelSize === 0) {
1250
- return;
1251
- }
1252
- if (!this._checkDimensions(
1253
- target,
1254
- width,
1255
- height,
1256
- level
1257
- )) {
1258
- return;
1259
- }
1260
- if (xoffset < 0 || yoffset < 0) {
1261
- this.setError(this.INVALID_VALUE);
1262
- return;
1263
- }
1264
- const data = convertPixels(pixels);
1265
- const rowStride = this._computeRowStride(width, pixelSize);
1266
- const imageSize = rowStride * height;
1267
- if (!data || data.length < imageSize) {
1268
- this.setError(this.INVALID_OPERATION);
1269
- return;
1270
- }
1271
- this._native.texSubImage2D(
1272
- target,
1273
- level,
1274
- xoffset,
1275
- yoffset,
1276
- width,
1277
- height,
1278
- format,
1279
- type,
1280
- Uint8ArrayToVariant(data)
1281
- );
1282
- }
1283
- _checkUniformValid(location, v0, name, count, type) {
1284
- if (!checkObject(location)) {
1285
- throw new TypeError(`${name}(WebGLUniformLocation, ...)`);
1286
- } else if (!location) {
1287
- return false;
1288
- } else if (this._checkLocationActive(location)) {
1289
- const utype = location._activeInfo.type;
1290
- if (utype === this.SAMPLER_2D || utype === this.SAMPLER_CUBE) {
1291
- if (count !== 1) {
1292
- this.setError(this.INVALID_VALUE);
1293
- return;
1294
- }
1295
- if (type !== "i") {
1296
- this.setError(this.INVALID_OPERATION);
1297
- return;
1298
- }
1299
- if (v0 < 0 || v0 >= this._textureUnits.length) {
1300
- this.setError(this.INVALID_VALUE);
1301
- return false;
1302
- }
1303
- }
1304
- if (uniformTypeSize(this, utype) > count) {
1305
- this.setError(this.INVALID_OPERATION);
1306
- return false;
1307
- }
1308
- return true;
1309
- }
1310
- return false;
1311
- }
1312
- _checkUniformValueValid(location, value, name, count, _type) {
1313
- if (!checkObject(location) || !checkObject(value)) {
1314
- throw new TypeError(`${name}v(WebGLUniformLocation, Array)`);
1315
- } else if (!location) {
1316
- return false;
1317
- } else if (!this._checkLocationActive(location)) {
1318
- return false;
1319
- } else if (typeof value !== "object" || !value || typeof value.length !== "number") {
1320
- throw new TypeError(`Second argument to ${name} must be array`);
1321
- } else if (uniformTypeSize(this, location._activeInfo.type) > count) {
1322
- this.setError(this.INVALID_OPERATION);
1323
- return false;
1324
- } else if (value.length >= count && value.length % count === 0) {
1325
- if (location._array) {
1326
- return true;
1327
- } else if (value.length === count) {
1328
- return true;
1329
- } else {
1330
- this.setError(this.INVALID_OPERATION);
1331
- return false;
1332
- }
1333
- }
1334
- this.setError(this.INVALID_VALUE);
1335
- return false;
1336
- }
1337
- uniform1fv(location, value) {
1338
- if (!location || !this._checkUniformValueValid(location, value, "uniform1fv", 1, "f")) return;
1339
- if (location?._array) {
1340
- const locs = location._array;
1341
- for (let i = 0; i < locs.length && i < value.length; ++i) {
1342
- const loc = locs[i];
1343
- if (loc) {
1344
- this._native.uniform1f(loc, value[i]);
1345
- }
1346
- }
1347
- return;
1348
- }
1349
- this._native.uniform1f(location?._ | 0, value[0]);
1350
- }
1351
- uniform1iv(location, v) {
1352
- if (!this._checkUniformValueValid(location, v, "uniform1iv", 1, "i")) return;
1353
- if (location?._array) {
1354
- const locs = location._array;
1355
- for (let i = 0; i < locs.length && i < v.length; ++i) {
1356
- const loc = locs[i];
1357
- if (loc) {
1358
- this._native.uniform1i(loc, v[i]);
1359
- }
1360
- }
1361
- return;
1362
- }
1363
- this.uniform1i(location, v[0]);
1364
- }
1365
- uniform2fv(location, v) {
1366
- if (!this._checkUniformValueValid(location, v, "uniform2fv", 2, "f")) return;
1367
- if (location?._array) {
1368
- const locs = location._array;
1369
- for (let i = 0; i < locs.length && 2 * i < v.length; ++i) {
1370
- const loc = locs[i];
1371
- if (loc) {
1372
- this._native.uniform2f(loc, v[2 * i], v[2 * i + 1]);
1373
- }
1374
- }
1375
- return;
1376
- }
1377
- this._native.uniform2f(location?._ || 0, v[0], v[1]);
1378
- }
1379
- uniform2iv(location, v) {
1380
- if (!this._checkUniformValueValid(location, v, "uniform2iv", 2, "i")) return;
1381
- if (location?._array) {
1382
- const locs = location._array;
1383
- for (let i = 0; i < locs.length && 2 * i < v.length; ++i) {
1384
- const loc = locs[i];
1385
- if (loc) {
1386
- this._native.uniform2i(loc, v[2 * i], v[2 * i + 1]);
1387
- }
1388
- }
1389
- return;
1390
- }
1391
- this.uniform2i(location, v[0], v[1]);
1392
- }
1393
- uniform3fv(location, v) {
1394
- if (!this._checkUniformValueValid(location, v, "uniform3fv", 3, "f")) return;
1395
- if (location?._array) {
1396
- const locs = location._array;
1397
- for (let i = 0; i < locs.length && 3 * i < v.length; ++i) {
1398
- const loc = locs[i];
1399
- if (loc) {
1400
- this._native.uniform3f(loc, v[3 * i], v[3 * i + 1], v[3 * i + 2]);
1401
- }
1402
- }
1403
- return;
1404
- }
1405
- this._native.uniform3f(location?._ || 0, v[0], v[1], v[2]);
1406
- }
1407
- uniform3iv(location, v) {
1408
- if (!this._checkUniformValueValid(location, v, "uniform3iv", 3, "i")) return;
1409
- if (location?._array) {
1410
- const locs = location._array;
1411
- for (let i = 0; i < locs.length && 3 * i < v.length; ++i) {
1412
- const loc = locs[i];
1413
- if (loc) {
1414
- this._native.uniform3i(loc, v[3 * i], v[3 * i + 1], v[3 * i + 2]);
1415
- }
1416
- }
1417
- return;
1418
- }
1419
- this.uniform3i(location, v[0], v[1], v[2]);
1420
- }
1421
- uniform4fv(location, v) {
1422
- if (!this._checkUniformValueValid(location, v, "uniform4fv", 4, "f")) return;
1423
- if (location?._array) {
1424
- const locs = location._array;
1425
- for (let i = 0; i < locs.length && 4 * i < v.length; ++i) {
1426
- const loc = locs[i];
1427
- if (loc) {
1428
- this._native.uniform4f(loc, v[4 * i], v[4 * i + 1], v[4 * i + 2], v[4 * i + 3]);
1429
- }
1430
- }
1431
- return;
1432
- }
1433
- this._native.uniform4f(location?._ || 0, v[0], v[1], v[2], v[3]);
1434
- }
1435
- uniform4iv(location, v) {
1436
- if (!this._checkUniformValueValid(location, v, "uniform4iv", 4, "i")) return;
1437
- if (location?._array) {
1438
- const locs = location._array;
1439
- for (let i = 0; i < locs.length && 4 * i < v.length; ++i) {
1440
- const loc = locs[i];
1441
- if (loc) {
1442
- this._native.uniform4i(loc, v[4 * i], v[4 * i + 1], v[4 * i + 2], v[4 * i + 3]);
1443
- }
1444
- }
1445
- return;
1446
- }
1447
- this.uniform4i(location, v[0], v[1], v[2], v[3]);
1448
- }
1449
- _checkUniformMatrix(location, transpose, value, name, count) {
1450
- if (!checkObject(location) || typeof value !== "object") {
1451
- throw new TypeError(name + "(WebGLUniformLocation, Boolean, Array)");
1452
- } else if (!!transpose || typeof value !== "object" || value === null || !value.length || value.length % count * count !== 0) {
1453
- this.setError(this.INVALID_VALUE);
1454
- return false;
1455
- }
1456
- if (!location) {
1457
- return false;
1458
- }
1459
- if (!this._checkLocationActive(location)) {
1460
- return false;
1461
- }
1462
- if (value.length === count * count) {
1463
- return true;
1464
- } else if (location._array) {
1465
- return true;
1466
- }
1467
- this.setError(this.INVALID_VALUE);
1468
- return false;
1469
- }
1470
- uniformMatrix2fv(location, transpose, value) {
1471
- if (!this._checkUniformMatrix(location, transpose, value, "uniformMatrix2fv", 2)) return;
1472
- const data = new Float32Array(value);
1473
- this._native.uniformMatrix2fv(
1474
- location?._ || 0,
1475
- !!transpose,
1476
- listToArray(data)
1477
- );
1478
- }
1479
- uniformMatrix3fv(location, transpose, value) {
1480
- if (!this._checkUniformMatrix(location, transpose, value, "uniformMatrix3fv", 3)) return;
1481
- const data = new Float32Array(value);
1482
- this._native.uniformMatrix3fv(
1483
- location?._ || 0,
1484
- !!transpose,
1485
- listToArray(data)
1486
- );
1487
- }
1488
- uniformMatrix4fv(location, transpose, value) {
1489
- if (!this._checkUniformMatrix(location, transpose, value, "uniformMatrix4fv", 4)) return;
1490
- const data = new Float32Array(value);
1491
- this._native.uniformMatrix4fv(
1492
- location?._ || 0,
1493
- !!transpose,
1494
- listToArray(data)
1495
- );
1496
- }
1497
- //////////// BASE ////////////
1498
- activeTexture(texture = 0) {
1499
- const texNum = texture - this.TEXTURE0;
1500
- if (texNum >= 0 && texNum < this._textureUnits.length) {
1501
- this._activeTextureUnit = texNum;
1502
- return this._native.activeTexture(texture);
1503
- }
1504
- this.setError(this.INVALID_ENUM);
1505
- }
1506
- attachShader(program, shader) {
1507
- if (!checkObject(program) || !checkObject(shader)) {
1508
- throw new TypeError("attachShader(WebGLProgram, WebGLShader)");
1509
- }
1510
- if (!program || !shader) {
1511
- this.setError(this.INVALID_VALUE);
1512
- return;
1513
- } else if (program instanceof WebGLProgram && shader instanceof WebGLShader && this._checkOwns(program) && this._checkOwns(shader)) {
1514
- if (!program._linked(shader)) {
1515
- this._saveError();
1516
- this._native.attachShader(
1517
- program._ | 0,
1518
- shader._ | 0
1519
- );
1520
- const error = this.getError();
1521
- this._restoreError(error);
1522
- if (error === this.NO_ERROR) {
1523
- program._link(shader);
1524
- }
1525
- return;
1526
- }
1527
- }
1528
- this.setError(this.INVALID_OPERATION);
1529
- }
1530
- bindAttribLocation(program, index, name) {
1531
- if (!checkObject(program) || typeof name !== "string") {
1532
- throw new TypeError("bindAttribLocation(WebGLProgram, GLint, String)");
1533
- }
1534
- name += "";
1535
- if (!isValidString(name) || name.length > MAX_ATTRIBUTE_LENGTH) {
1536
- this.setError(this.INVALID_VALUE);
1537
- } else if (/^_?webgl_a/.test(name)) {
1538
- this.setError(this.INVALID_OPERATION);
1539
- } else if (this._checkWrapper(program, WebGLProgram)) {
1540
- return this._native.bindAttribLocation(
1541
- program._ | 0,
1542
- index | 0,
1543
- name
1544
- );
1545
- }
1546
- }
1547
- bindBuffer(target = 0, buffer) {
1548
- if (!checkObject(buffer)) {
1549
- throw new TypeError("bindBuffer(GLenum, WebGLBuffer)");
1550
- }
1551
- if (target !== this.ARRAY_BUFFER && target !== this.ELEMENT_ARRAY_BUFFER) {
1552
- this.setError(this.INVALID_ENUM);
1553
- return;
1554
- }
1555
- if (!buffer) {
1556
- buffer = null;
1557
- this._native.bindBuffer(target, 0);
1558
- } else if (buffer._pendingDelete) {
1559
- return;
1560
- } else if (this._checkWrapper(buffer, WebGLBuffer)) {
1561
- if (buffer._binding && buffer._binding !== target) {
1562
- this.setError(this.INVALID_OPERATION);
1563
- return;
1564
- }
1565
- buffer._binding = target | 0;
1566
- this._native.bindBuffer(target, buffer._ | 0);
1567
- } else {
1568
- return;
1569
- }
1570
- if (target === this.ARRAY_BUFFER) {
1571
- this._vertexGlobalState.setArrayBuffer(buffer);
1572
- } else {
1573
- this._vertexObjectState.setElementArrayBuffer(buffer);
1574
- }
1575
- }
1576
- bindFramebuffer(target, framebuffer) {
1577
- if (!checkObject(framebuffer)) {
1578
- throw new TypeError("bindFramebuffer(GLenum, WebGLFramebuffer)");
1579
- }
1580
- if (target !== this.FRAMEBUFFER) {
1581
- this.setError(this.INVALID_ENUM);
1582
- return;
1583
- }
1584
- if (!framebuffer) {
1585
- if (this._drawingBuffer?._framebuffer) {
1586
- this._native.bindFramebuffer(
1587
- this.FRAMEBUFFER,
1588
- this._drawingBuffer._framebuffer
1589
- );
1590
- }
1591
- } else if (framebuffer._pendingDelete) {
1592
- return;
1593
- } else if (this._checkWrapper(framebuffer, WebGLFramebuffer)) {
1594
- this._native.bindFramebuffer(
1595
- this.FRAMEBUFFER,
1596
- framebuffer._ | 0
1597
- );
1598
- } else {
1599
- return;
1600
- }
1601
- const activeFramebuffer = this._activeFramebuffer;
1602
- if (activeFramebuffer !== framebuffer) {
1603
- if (activeFramebuffer) {
1604
- activeFramebuffer._refCount -= 1;
1605
- activeFramebuffer._checkDelete();
1606
- }
1607
- if (framebuffer) {
1608
- framebuffer._refCount += 1;
1609
- }
1610
- }
1611
- this._activeFramebuffer = framebuffer;
1612
- if (framebuffer) {
1613
- this._updateFramebufferAttachments(framebuffer);
1614
- }
1615
- }
1616
- bindRenderbuffer(target, renderbuffer) {
1617
- if (!checkObject(renderbuffer)) {
1618
- throw new TypeError("bindRenderbuffer(GLenum, WebGLRenderbuffer)");
1619
- }
1620
- if (target !== this.RENDERBUFFER) {
1621
- this.setError(this.INVALID_ENUM);
1622
- return;
1623
- }
1624
- if (!renderbuffer) {
1625
- this._native.bindRenderbuffer(
1626
- target | 0,
1627
- 0
1628
- );
1629
- } else if (renderbuffer._pendingDelete) {
1630
- return;
1631
- } else if (this._checkWrapper(renderbuffer, WebGLRenderbuffer)) {
1632
- this._native.bindRenderbuffer(
1633
- target | 0,
1634
- renderbuffer._ | 0
1635
- );
1636
- } else {
1637
- return;
1638
- }
1639
- const active = this._activeRenderbuffer;
1640
- if (active !== renderbuffer) {
1641
- if (active) {
1642
- active._refCount -= 1;
1643
- active._checkDelete();
1644
- }
1645
- if (renderbuffer) {
1646
- renderbuffer._refCount += 1;
1647
- }
1648
- }
1649
- this._activeRenderbuffer = renderbuffer;
1650
- }
1651
- bindTexture(target = 0, texture) {
1652
- if (!checkObject(texture)) {
1653
- throw new TypeError("bindTexture(GLenum, WebGLTexture)");
1654
- }
1655
- if (!this._validTextureTarget(target)) {
1656
- this.setError(this.INVALID_ENUM);
1657
- return;
1658
- }
1659
- let textureId = 0;
1660
- if (!texture) {
1661
- texture = null;
1662
- } else if (texture instanceof WebGLTexture && texture._pendingDelete) {
1663
- return;
1664
- } else if (this._checkWrapper(texture, WebGLTexture)) {
1665
- if (texture._binding && texture._binding !== target) {
1666
- this.setError(this.INVALID_OPERATION);
1667
- return;
1668
- }
1669
- texture._binding = target;
1670
- if (texture._complete) {
1671
- textureId = texture._ | 0;
1672
- }
1673
- } else {
1674
- return;
1675
- }
1676
- this._saveError();
1677
- this._native.bindTexture(
1678
- target,
1679
- textureId
1680
- );
1681
- const error = this.getError();
1682
- this._restoreError(error);
1683
- if (error !== this.NO_ERROR) {
1684
- return;
1685
- }
1686
- const activeUnit = this._getActiveTextureUnit();
1687
- const activeTex = this._getActiveTexture(target);
1688
- if (activeTex !== texture) {
1689
- if (activeTex) {
1690
- activeTex._refCount -= 1;
1691
- activeTex._checkDelete();
1692
- }
1693
- if (texture) {
1694
- texture._refCount += 1;
1695
- }
1696
- }
1697
- if (target === this.TEXTURE_2D) {
1698
- activeUnit._bind2D = texture;
1699
- } else if (target === this.TEXTURE_CUBE_MAP) {
1700
- activeUnit._bindCube = texture;
1701
- }
1702
- }
1703
- blendColor(red = 0, green = 0, blue = 0, alpha = 0) {
1704
- return this._native.blendColor(+red, +green, +blue, +alpha);
1705
- }
1706
- blendEquation(mode = 0) {
1707
- if (this._validBlendMode(mode)) {
1708
- return this._native.blendEquation(mode);
1709
- }
1710
- this.setError(this.INVALID_ENUM);
1711
- }
1712
- blendEquationSeparate(modeRGB = 0, modeAlpha = 0) {
1713
- if (this._validBlendMode(modeRGB) && this._validBlendMode(modeAlpha)) {
1714
- return this._native.blendEquationSeparate(modeRGB, modeAlpha);
1715
- }
1716
- this.setError(this.INVALID_ENUM);
1717
- }
1718
- blendFunc(sfactor = 0, dfactor = 0) {
1719
- if (!this._validBlendFunc(sfactor) || !this._validBlendFunc(dfactor)) {
1720
- this.setError(this.INVALID_ENUM);
1721
- return;
1722
- }
1723
- if (this._isConstantBlendFunc(sfactor) && this._isConstantBlendFunc(dfactor)) {
1724
- this.setError(this.INVALID_OPERATION);
1725
- return;
1726
- }
1727
- this._native.blendFunc(sfactor, dfactor);
1728
- }
1729
- blendFuncSeparate(srcRGB = 0, dstRGB = 0, srcAlpha = 0, dstAlpha = 0) {
1730
- if (!(this._validBlendFunc(srcRGB) && this._validBlendFunc(dstRGB) && this._validBlendFunc(srcAlpha) && this._validBlendFunc(dstAlpha))) {
1731
- this.setError(this.INVALID_ENUM);
1732
- return;
1733
- }
1734
- if (this._isConstantBlendFunc(srcRGB) && this._isConstantBlendFunc(dstRGB) || this._isConstantBlendFunc(srcAlpha) && this._isConstantBlendFunc(dstAlpha)) {
1735
- this.setError(this.INVALID_OPERATION);
1736
- return;
1737
- }
1738
- this._native.blendFuncSeparate(
1739
- srcRGB,
1740
- dstRGB,
1741
- srcAlpha,
1742
- dstAlpha
1743
- );
1744
- }
1745
- checkFramebufferStatus(target) {
1746
- if (target !== this.FRAMEBUFFER) {
1747
- this.setError(this.INVALID_ENUM);
1748
- return 0;
1749
- }
1750
- const framebuffer = this._activeFramebuffer;
1751
- if (!framebuffer) {
1752
- return this.FRAMEBUFFER_COMPLETE;
1753
- }
1754
- return this._preCheckFramebufferStatus(framebuffer);
1755
- }
1756
- clear(mask = 0) {
1757
- if (!this._framebufferOk()) {
1758
- return;
1759
- }
1760
- return this._native.clear(mask);
1761
- }
1762
- clearColor(red, green, blue, alpha) {
1763
- return this._native.clearColor(+red, +green, +blue, +alpha);
1764
- }
1765
- clearDepth(depth) {
1766
- return this._native.clearDepth(+depth);
1767
- }
1768
- clearStencil(s = 0) {
1769
- this._checkStencil = false;
1770
- return this._native.clearStencil(s);
1771
- }
1772
- colorMask(red, green, blue, alpha) {
1773
- return this._native.colorMask(!!red, !!green, !!blue, !!alpha);
1774
- }
1775
- compileShader(shader) {
1776
- if (!checkObject(shader)) {
1777
- throw new TypeError("compileShader(WebGLShader)");
1778
- }
1779
- if (this._checkWrapper(shader, WebGLShader) && this._checkShaderSource(shader)) {
1780
- const prevError = this.getError();
1781
- this._native.compileShader(shader._ | 0);
1782
- const error = this.getError();
1783
- shader._compileStatus = !!this._native.getShaderParameter(
1784
- shader._ | 0,
1785
- this.COMPILE_STATUS
1786
- );
1787
- shader._compileInfo = this._native.getShaderInfoLog(shader._ | 0) || "null";
1788
- this.getError();
1789
- this.setError(prevError || error);
1790
- }
1791
- }
1792
- copyTexImage2D(target = 0, level = 0, internalFormat = 0, x = 0, y = 0, width = 0, height = 0, border = 0) {
1793
- const texture = this._getTexImage(target);
1794
- if (!texture) {
1795
- this.setError(this.INVALID_OPERATION);
1796
- return;
1797
- }
1798
- if (internalFormat !== this.RGBA && internalFormat !== this.RGB && internalFormat !== this.ALPHA && internalFormat !== this.LUMINANCE && internalFormat !== this.LUMINANCE_ALPHA) {
1799
- this.setError(this.INVALID_ENUM);
1800
- return;
1801
- }
1802
- if (level < 0 || width < 0 || height < 0 || border !== 0) {
1803
- this.setError(this.INVALID_VALUE);
1804
- return;
1805
- }
1806
- if (level > 0 && !(bits.isPow2(width) && bits.isPow2(height))) {
1807
- this.setError(this.INVALID_VALUE);
1808
- return;
1809
- }
1810
- this._saveError();
1811
- this._native.copyTexImage2D(
1812
- target,
1813
- level,
1814
- internalFormat,
1815
- x,
1816
- y,
1817
- width,
1818
- height,
1819
- border
1820
- );
1821
- const error = this.getError();
1822
- this._restoreError(error);
1823
- if (error === this.NO_ERROR) {
1824
- texture._levelWidth[level] = width;
1825
- texture._levelHeight[level] = height;
1826
- texture._format = this.RGBA;
1827
- texture._type = this.UNSIGNED_BYTE;
1828
- }
1829
- }
1830
- copyTexSubImage2D(target = 0, level = 0, xoffset = 0, yoffset = 0, x = 0, y = 0, width = 0, height = 0) {
1831
- const texture = this._getTexImage(target);
1832
- if (!texture) {
1833
- this.setError(this.INVALID_OPERATION);
1834
- return;
1835
- }
1836
- if (width < 0 || height < 0 || xoffset < 0 || yoffset < 0 || level < 0) {
1837
- this.setError(this.INVALID_VALUE);
1838
- return;
1839
- }
1840
- this._native.copyTexSubImage2D(
1841
- target,
1842
- level,
1843
- xoffset,
1844
- yoffset,
1845
- x,
1846
- y,
1847
- width,
1848
- height
1849
- );
1850
- }
1851
- createBuffer() {
1852
- const id = this._native.createBuffer();
1853
- if (!id || id <= 0) return null;
1854
- const webGLBuffer = new WebGLBuffer(id, this);
1855
- this._buffers[id] = webGLBuffer;
1856
- return webGLBuffer;
1857
- }
1858
- createFramebuffer() {
1859
- const id = this._native.createFramebuffer();
1860
- if (id <= 0) return null;
1861
- const webGLFramebuffer = new WebGLFramebuffer(id, this);
1862
- this._framebuffers[id] = webGLFramebuffer;
1863
- return webGLFramebuffer;
1864
- }
1865
- createProgram() {
1866
- const id = this._native.createProgram();
1867
- if (id <= 0) return null;
1868
- const webGLProgram = new WebGLProgram(id, this);
1869
- this._programs[id] = webGLProgram;
1870
- return webGLProgram;
1871
- }
1872
- createRenderbuffer() {
1873
- const id = this._native.createRenderbuffer();
1874
- if (id <= 0) return null;
1875
- const webGLRenderbuffer = new WebGLRenderbuffer(id, this);
1876
- this._renderbuffers[id] = webGLRenderbuffer;
1877
- return webGLRenderbuffer;
1878
- }
1879
- createShader(type = 0) {
1880
- if (type !== this.FRAGMENT_SHADER && type !== this.VERTEX_SHADER) {
1881
- this.setError(this.INVALID_ENUM);
1882
- return null;
1883
- }
1884
- const id = this._native.createShader(type);
1885
- if (id < 0) {
1886
- return null;
1887
- }
1888
- const result = new WebGLShader(id, this, type);
1889
- this._shaders[id] = result;
1890
- return result;
1891
- }
1892
- createTexture() {
1893
- const id = this._native.createTexture();
1894
- if (id <= 0) return null;
1895
- const webGlTexture = new WebGLTexture(id, this);
1896
- this._textures[id] = webGlTexture;
1897
- return webGlTexture;
1898
- }
1899
- cullFace(mode) {
1900
- return this._native.cullFace(mode | 0);
1901
- }
1902
- deleteBuffer(buffer) {
1903
- if (!checkObject(buffer) || buffer !== null && !(buffer instanceof WebGLBuffer)) {
1904
- throw new TypeError("deleteBuffer(WebGLBuffer)");
1905
- }
1906
- if (!(buffer instanceof WebGLBuffer && this._checkOwns(buffer))) {
1907
- this.setError(this.INVALID_OPERATION);
1908
- return;
1909
- }
1910
- if (this._vertexGlobalState._arrayBufferBinding === buffer) {
1911
- this.bindBuffer(this.ARRAY_BUFFER, null);
1912
- }
1913
- if (this._vertexObjectState._elementArrayBufferBinding === buffer) {
1914
- this.bindBuffer(this.ELEMENT_ARRAY_BUFFER, null);
1915
- }
1916
- if (this._vertexObjectState === this._defaultVertexObjectState) {
1917
- this._vertexObjectState.releaseArrayBuffer(buffer);
1918
- }
1919
- buffer._pendingDelete = true;
1920
- buffer._checkDelete();
1921
- }
1922
- deleteFramebuffer(framebuffer) {
1923
- if (!checkObject(framebuffer)) {
1924
- throw new TypeError("deleteFramebuffer(WebGLFramebuffer)");
1925
- }
1926
- if (!(framebuffer instanceof WebGLFramebuffer && this._checkOwns(framebuffer))) {
1927
- this.setError(this.INVALID_OPERATION);
1928
- return;
1929
- }
1930
- if (this._activeFramebuffer === framebuffer) {
1931
- this.bindFramebuffer(this.FRAMEBUFFER, null);
1932
- }
1933
- framebuffer._pendingDelete = true;
1934
- framebuffer._checkDelete();
1935
- }
1936
- _deleteLinkable(name, object, Type) {
1937
- if (!checkObject(object)) {
1938
- throw new TypeError(name + "(" + Type.name + ")");
1939
- }
1940
- if (object instanceof Type && this._checkOwns(object)) {
1941
- object._pendingDelete = true;
1942
- object._checkDelete();
1943
- return;
1944
- }
1945
- this.setError(this.INVALID_OPERATION);
1946
- }
1947
- deleteProgram(program) {
1948
- return this._deleteLinkable("deleteProgram", program, WebGLProgram);
1949
- }
1950
- // Need to handle textures and render buffers as a special case:
1951
- // When a texture gets deleted, we need to do the following extra steps:
1952
- // 1. Is it bound to the current texture unit?
1953
- // If so, then unbind it
1954
- // 2. Is it attached to the active fbo?
1955
- // If so, then detach it
1956
- //
1957
- // For renderbuffers only need to do second step
1958
- //
1959
- // After this, proceed with the usual deletion algorithm
1960
- //
1961
- deleteRenderbuffer(renderbuffer) {
1962
- if (!checkObject(renderbuffer)) {
1963
- throw new TypeError("deleteRenderbuffer(WebGLRenderbuffer)");
1964
- }
1965
- if (!(renderbuffer instanceof WebGLRenderbuffer && this._checkOwns(renderbuffer))) {
1966
- this.setError(this.INVALID_OPERATION);
1967
- return;
1968
- }
1969
- if (this._activeRenderbuffer === renderbuffer) {
1970
- this.bindRenderbuffer(this.RENDERBUFFER, null);
1971
- }
1972
- const activeFramebuffer = this._activeFramebuffer;
1973
- this._tryDetachFramebuffer(activeFramebuffer, renderbuffer);
1974
- renderbuffer._pendingDelete = true;
1975
- renderbuffer._checkDelete();
1976
- }
1977
- deleteShader(shader) {
1978
- return this._deleteLinkable("deleteShader", shader, WebGLShader);
1979
- }
1980
- deleteTexture(texture) {
1981
- if (!checkObject(texture)) {
1982
- throw new TypeError("deleteTexture(WebGLTexture)");
1983
- }
1984
- if (texture instanceof WebGLTexture) {
1985
- if (!this._checkOwns(texture)) {
1986
- this.setError(this.INVALID_OPERATION);
1987
- return;
1988
- }
1989
- } else {
1990
- return;
1991
- }
1992
- const curActive = this._activeTextureUnit;
1993
- for (let i = 0; i < this._textureUnits.length; ++i) {
1994
- const unit = this._textureUnits[i];
1995
- if (unit._bind2D === texture) {
1996
- this.activeTexture(this.TEXTURE0 + i);
1997
- this.bindTexture(this.TEXTURE_2D, null);
1998
- } else if (unit._bindCube === texture) {
1999
- this.activeTexture(this.TEXTURE0 + i);
2000
- this.bindTexture(this.TEXTURE_CUBE_MAP, null);
2001
- }
2002
- }
2003
- this.activeTexture(this.TEXTURE0 + curActive);
2004
- const ctx = this;
2005
- const activeFramebuffer = this._activeFramebuffer;
2006
- const tryDetach = (framebuffer) => {
2007
- if (framebuffer && framebuffer._linked(texture)) {
2008
- const attachments = ctx._getAttachments();
2009
- for (let i = 0; i < attachments.length; ++i) {
2010
- const attachment = attachments[i];
2011
- if (framebuffer._attachments[attachment] === texture) {
2012
- ctx.framebufferTexture2D(
2013
- this.FRAMEBUFFER,
2014
- attachment,
2015
- this.TEXTURE_2D,
2016
- null
2017
- );
2018
- }
2019
- }
2020
- }
2021
- };
2022
- tryDetach(activeFramebuffer);
2023
- texture._pendingDelete = true;
2024
- texture._checkDelete();
2025
- }
2026
- depthFunc(func) {
2027
- func |= 0;
2028
- switch (func) {
2029
- case this.NEVER:
2030
- case this.LESS:
2031
- case this.EQUAL:
2032
- case this.LEQUAL:
2033
- case this.GREATER:
2034
- case this.NOTEQUAL:
2035
- case this.GEQUAL:
2036
- case this.ALWAYS:
2037
- return this._native.depthFunc(func);
2038
- default:
2039
- this.setError(this.INVALID_ENUM);
2040
- }
2041
- }
2042
- depthMask(flag2) {
2043
- return this._native.depthMask(!!flag2);
2044
- }
2045
- depthRange(zNear, zFar) {
2046
- zNear = +zNear;
2047
- zFar = +zFar;
2048
- if (zNear <= zFar) {
2049
- return this._native.depthRange(zNear, zFar);
2050
- }
2051
- this.setError(this.INVALID_OPERATION);
2052
- }
2053
- destroy() {
2054
- warnNotImplemented("destroy");
2055
- }
2056
- detachShader(program, shader) {
2057
- if (!checkObject(program) || !checkObject(shader)) {
2058
- throw new TypeError("detachShader(WebGLProgram, WebGLShader)");
2059
- }
2060
- if (this._checkWrapper(program, WebGLProgram) && this._checkWrapper(shader, WebGLShader)) {
2061
- if (program._linked(shader)) {
2062
- this._native.detachShader(program._, shader._);
2063
- program._unlink(shader);
2064
- } else {
2065
- this.setError(this.INVALID_OPERATION);
2066
- }
2067
- }
2068
- }
2069
- disable(cap = 0) {
2070
- this._native.disable(cap);
2071
- if (cap === this.TEXTURE_2D || cap === this.TEXTURE_CUBE_MAP) {
2072
- const active = this._getActiveTextureUnit();
2073
- if (active._mode === cap) {
2074
- active._mode = 0;
2075
- }
2076
- }
2077
- }
2078
- disableVertexAttribArray(index = 0) {
2079
- if (index < 0 || index >= this._vertexObjectState._attribs.length) {
2080
- this.setError(this.INVALID_VALUE);
2081
- return;
2082
- }
2083
- this._native.disableVertexAttribArray(index);
2084
- this._vertexObjectState._attribs[index]._isPointer = false;
2085
- }
2086
- drawArrays(mode = 0, first = 0, count = 0) {
2087
- if (first < 0 || count < 0) {
2088
- this.setError(this.INVALID_VALUE);
2089
- return;
2090
- }
2091
- if (!this._checkStencilState()) {
2092
- return;
2093
- }
2094
- const reducedCount = vertexCount(this, mode, count);
2095
- if (reducedCount < 0) {
2096
- this.setError(this.INVALID_ENUM);
2097
- return;
2098
- }
2099
- if (!this._framebufferOk()) {
2100
- return;
2101
- }
2102
- if (count === 0) {
2103
- return;
2104
- }
2105
- let maxIndex = first;
2106
- if (count > 0) {
2107
- maxIndex = count + first - 1 >>> 0;
2108
- }
2109
- if (this._checkVertexAttribState(maxIndex)) {
2110
- if (this._vertexObjectState._attribs[0]._isPointer || this._extensions.webgl_draw_buffers && this._extensions.webgl_draw_buffers._buffersState && this._extensions.webgl_draw_buffers._buffersState.length > 0) {
2111
- return this._native.drawArrays(mode, first, reducedCount);
2112
- } else {
2113
- this._beginAttrib0Hack();
2114
- this._native._drawArraysInstanced(mode, first, reducedCount, 1);
2115
- this._endAttrib0Hack();
2116
- }
2117
- }
2118
- }
2119
- drawElements(mode = 0, count = 0, type = 0, ioffset = 0) {
2120
- if (count < 0 || ioffset < 0) {
2121
- this.setError(this.INVALID_VALUE);
2122
- return;
2123
- }
2124
- if (!this._checkStencilState()) {
2125
- return;
2126
- }
2127
- const elementBuffer = this._vertexObjectState._elementArrayBufferBinding;
2128
- if (!elementBuffer) {
2129
- this.setError(this.INVALID_OPERATION);
2130
- return;
2131
- }
2132
- let elementData = null;
2133
- let offset = ioffset;
2134
- if (type === this.UNSIGNED_SHORT) {
2135
- if (offset % 2) {
2136
- this.setError(this.INVALID_OPERATION);
2137
- return;
2138
- }
2139
- offset >>= 1;
2140
- elementData = new Uint16Array(elementBuffer._elements.buffer);
2141
- } else if (this._extensions.oes_element_index_uint && type === this.UNSIGNED_INT) {
2142
- if (offset % 4) {
2143
- this.setError(this.INVALID_OPERATION);
2144
- return;
2145
- }
2146
- offset >>= 2;
2147
- elementData = new Uint32Array(elementBuffer._elements.buffer);
2148
- } else if (type === this.UNSIGNED_BYTE) {
2149
- elementData = elementBuffer._elements;
2150
- } else {
2151
- this.setError(this.INVALID_ENUM);
2152
- return;
2153
- }
2154
- let reducedCount = count;
2155
- switch (mode) {
2156
- case this.TRIANGLES:
2157
- if (count % 3) {
2158
- reducedCount -= count % 3;
2159
- }
2160
- break;
2161
- case this.LINES:
2162
- if (count % 2) {
2163
- reducedCount -= count % 2;
2164
- }
2165
- break;
2166
- case this.POINTS:
2167
- break;
2168
- case this.LINE_LOOP:
2169
- case this.LINE_STRIP:
2170
- if (count < 2) {
2171
- this.setError(this.INVALID_OPERATION);
2172
- return;
2173
- }
2174
- break;
2175
- case this.TRIANGLE_FAN:
2176
- case this.TRIANGLE_STRIP:
2177
- if (count < 3) {
2178
- this.setError(this.INVALID_OPERATION);
2179
- return;
2180
- }
2181
- break;
2182
- default:
2183
- this.setError(this.INVALID_ENUM);
2184
- return;
2185
- }
2186
- if (!this._framebufferOk()) {
2187
- return;
2188
- }
2189
- if (count === 0) {
2190
- this._checkVertexAttribState(0);
2191
- return;
2192
- }
2193
- if (count + offset >>> 0 > elementData.length) {
2194
- this.setError(this.INVALID_OPERATION);
2195
- return;
2196
- }
2197
- let maxIndex = -1;
2198
- for (let i = offset; i < offset + count; ++i) {
2199
- maxIndex = Math.max(maxIndex, elementData[i]);
2200
- }
2201
- if (maxIndex < 0) {
2202
- this._checkVertexAttribState(0);
2203
- return;
2204
- }
2205
- if (this._checkVertexAttribState(maxIndex)) {
2206
- if (reducedCount > 0) {
2207
- if (this._vertexObjectState._attribs[0]._isPointer) {
2208
- return this._native.drawElements(mode, reducedCount, type, ioffset);
2209
- } else {
2210
- this._beginAttrib0Hack();
2211
- this._native._drawElementsInstanced(mode, reducedCount, type, ioffset, 1);
2212
- this._endAttrib0Hack();
2213
- }
2214
- }
2215
- }
2216
- }
2217
- enable(cap = 0) {
2218
- return this._native.enable(cap);
2219
- }
2220
- enableVertexAttribArray(index) {
2221
- if (index < 0 || index >= this._vertexObjectState._attribs.length) {
2222
- this.setError(this.INVALID_VALUE);
2223
- return;
2224
- }
2225
- this._native.enableVertexAttribArray(index);
2226
- this._vertexObjectState._attribs[index]._isPointer = true;
2227
- }
2228
- finish() {
2229
- return this._native.finish();
2230
- }
2231
- flush() {
2232
- return this._native.flush();
2233
- }
2234
- framebufferRenderbuffer(target, attachment, renderbufferTarget, renderbuffer) {
2235
- if (!checkObject(renderbuffer)) {
2236
- throw new TypeError("framebufferRenderbuffer(GLenum, GLenum, GLenum, WebGLRenderbuffer)");
2237
- }
2238
- if (target !== this.FRAMEBUFFER || !this._validFramebufferAttachment(attachment) || renderbufferTarget !== this.RENDERBUFFER) {
2239
- this.setError(this.INVALID_ENUM);
2240
- return;
2241
- }
2242
- const framebuffer = this._activeFramebuffer;
2243
- if (!framebuffer) {
2244
- this.setError(this.INVALID_OPERATION);
2245
- return;
2246
- }
2247
- if (renderbuffer && !this._checkWrapper(renderbuffer, WebGLRenderbuffer)) {
2248
- return;
2249
- }
2250
- framebuffer._setAttachment(renderbuffer, attachment);
2251
- this._updateFramebufferAttachments(framebuffer);
2252
- }
2253
- framebufferTexture2D(target, attachment, textarget, texture, level = 0) {
2254
- target |= 0;
2255
- attachment |= 0;
2256
- textarget |= 0;
2257
- level |= 0;
2258
- if (!checkObject(texture)) {
2259
- throw new TypeError("framebufferTexture2D(GLenum, GLenum, GLenum, WebGLTexture, GLint)");
2260
- }
2261
- if (target !== this.FRAMEBUFFER || !this._validFramebufferAttachment(attachment)) {
2262
- this.setError(this.INVALID_ENUM);
2263
- return;
2264
- }
2265
- if (level !== 0) {
2266
- this.setError(this.INVALID_VALUE);
2267
- return;
2268
- }
2269
- if (texture && !this._checkWrapper(texture, WebGLTexture)) {
2270
- return;
2271
- }
2272
- if (textarget === this.TEXTURE_2D) {
2273
- if (texture && texture._binding !== this.TEXTURE_2D) {
2274
- this.setError(this.INVALID_OPERATION);
2275
- return;
2276
- }
2277
- } else if (this._validCubeTarget(textarget)) {
2278
- if (texture && texture._binding !== this.TEXTURE_CUBE_MAP) {
2279
- this.setError(this.INVALID_OPERATION);
2280
- return;
2281
- }
2282
- } else {
2283
- this.setError(this.INVALID_ENUM);
2284
- return;
2285
- }
2286
- const framebuffer = this._activeFramebuffer;
2287
- if (!framebuffer) {
2288
- this.setError(this.INVALID_OPERATION);
2289
- return;
2290
- }
2291
- framebuffer._attachmentLevel[attachment] = level;
2292
- framebuffer._attachmentFace[attachment] = textarget;
2293
- framebuffer._setAttachment(texture, attachment);
2294
- this._updateFramebufferAttachments(framebuffer);
2295
- }
2296
- frontFace(mode = 0) {
2297
- return this._native.frontFace(mode);
2298
- }
2299
- generateMipmap(target = 0) {
2300
- return this._native.generateMipmap(target);
2301
- }
2302
- getActiveAttrib(program, index) {
2303
- if (!checkObject(program)) {
2304
- throw new TypeError("getActiveAttrib(WebGLProgram)");
2305
- } else if (!program) {
2306
- this.setError(this.INVALID_VALUE);
2307
- } else if (this._checkWrapper(program, WebGLProgram)) {
2308
- const info = this._native.getActiveAttrib(program._ | 0, index | 0);
2309
- if (info) {
2310
- return new WebGLActiveInfo(info);
2311
- }
2312
- }
2313
- return null;
2314
- }
2315
- getActiveUniform(program, index) {
2316
- if (!checkObject(program)) {
2317
- throw new TypeError("getActiveUniform(WebGLProgram, GLint)");
2318
- } else if (!program) {
2319
- this.setError(this.INVALID_VALUE);
2320
- } else if (this._checkWrapper(program, WebGLProgram)) {
2321
- const info = this._native.getActiveUniform(program._ | 0, index | 0);
2322
- if (info) {
2323
- return new WebGLActiveInfo(info);
2324
- }
2325
- }
2326
- return null;
2327
- }
2328
- getAttachedShaders(program) {
2329
- if (!checkObject(program) || typeof program === "object" && program !== null && !(program instanceof WebGLProgram)) {
2330
- throw new TypeError("getAttachedShaders(WebGLProgram)");
2331
- }
2332
- if (!program) {
2333
- this.setError(this.INVALID_VALUE);
2334
- } else if (this._checkWrapper(program, WebGLProgram)) {
2335
- const shaderArray = this._native.getAttachedShaders(program._ | 0);
2336
- if (!shaderArray) {
2337
- return null;
2338
- }
2339
- const unboxedShaders = new Array(shaderArray.length);
2340
- for (let i = 0; i < shaderArray.length; ++i) {
2341
- unboxedShaders[i] = this._shaders[shaderArray[i]];
2342
- }
2343
- return unboxedShaders;
2344
- }
2345
- return null;
2346
- }
2347
- getAttribLocation(program, name) {
2348
- if (!checkObject(program)) {
2349
- throw new TypeError("getAttribLocation(WebGLProgram, String)");
2350
- }
2351
- name += "";
2352
- if (!isValidString(name) || name.length > MAX_ATTRIBUTE_LENGTH) {
2353
- this.setError(this.INVALID_VALUE);
2354
- } else if (this._checkWrapper(program, WebGLProgram)) {
2355
- return this._native.getAttribLocation(program._ | 0, name + "");
2356
- }
2357
- return -1;
2358
- }
2359
- getBufferParameter(target = 0, pname = 0) {
2360
- if (target !== this.ARRAY_BUFFER && target !== this.ELEMENT_ARRAY_BUFFER) {
2361
- this.setError(this.INVALID_ENUM);
2362
- return null;
2363
- }
2364
- switch (pname) {
2365
- case this.BUFFER_SIZE:
2366
- case this.BUFFER_USAGE:
2367
- return this._native.getBufferParameteriv(target | 0, pname | 0)[0];
2368
- default:
2369
- this.setError(this.INVALID_ENUM);
2370
- return null;
2371
- }
2372
- }
2373
- getError() {
2374
- return this._native.getError();
2375
- }
2376
- setError(error) {
2377
- if (error > 0) {
2378
- console.error("setError", error);
2379
- }
2380
- this._native.setError(error);
2381
- }
2382
- getFramebufferAttachmentParameter(target = 0, attachment = 0, pname = 0) {
2383
- if (target !== this.FRAMEBUFFER || !this._validFramebufferAttachment(attachment)) {
2384
- this.setError(this.INVALID_ENUM);
2385
- return null;
2386
- }
2387
- const framebuffer = this._activeFramebuffer;
2388
- if (!framebuffer) {
2389
- this.setError(this.INVALID_OPERATION);
2390
- return null;
2391
- }
2392
- const object = framebuffer._attachments[attachment];
2393
- if (object === null) {
2394
- if (pname === this.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) {
2395
- return this.NONE;
2396
- }
2397
- } else if (object instanceof WebGLTexture) {
2398
- switch (pname) {
2399
- case this.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2400
- return object;
2401
- case this.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2402
- return this.TEXTURE;
2403
- case this.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2404
- return framebuffer._attachmentLevel[attachment];
2405
- case this.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: {
2406
- const face = framebuffer._attachmentFace[attachment];
2407
- if (face === this.TEXTURE_2D) {
2408
- return 0;
2409
- }
2410
- return face;
2411
- }
2412
- }
2413
- } else if (object instanceof WebGLRenderbuffer) {
2414
- switch (pname) {
2415
- case this.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2416
- return object;
2417
- case this.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2418
- return this.RENDERBUFFER;
2419
- }
2420
- }
2421
- this.setError(this.INVALID_ENUM);
2422
- return null;
2423
- }
2424
- getParameter(pname = 0) {
2425
- switch (pname) {
2426
- case this.ARRAY_BUFFER_BINDING:
2427
- return this._vertexGlobalState._arrayBufferBinding;
2428
- case this.ELEMENT_ARRAY_BUFFER_BINDING:
2429
- return this._vertexObjectState._elementArrayBufferBinding;
2430
- case this.CURRENT_PROGRAM:
2431
- return this._activeProgram;
2432
- case this.FRAMEBUFFER_BINDING:
2433
- return this._activeFramebuffer;
2434
- case this.RENDERBUFFER_BINDING:
2435
- return this._activeRenderbuffer;
2436
- case this.TEXTURE_BINDING_2D:
2437
- return this._getActiveTextureUnit()._bind2D;
2438
- case this.TEXTURE_BINDING_CUBE_MAP:
2439
- return this._getActiveTextureUnit()._bindCube;
2440
- case this.VERSION:
2441
- return "WebGL 1.0 " + VERSION;
2442
- case this.VENDOR:
2443
- return "";
2444
- case this.RENDERER:
2445
- return "ANGLE";
2446
- case this.SHADING_LANGUAGE_VERSION:
2447
- return "WebGL GLSL ES 1.0 ";
2448
- case this.COMPRESSED_TEXTURE_FORMATS:
2449
- return new Uint32Array(0);
2450
- // Int arrays — tracked in JS (native getParameterx crashes for array returns)
2451
- case this.SCISSOR_BOX:
2452
- return new Int32Array(this._scissorBox);
2453
- case this.VIEWPORT:
2454
- return new Int32Array(this._viewport);
2455
- case this.MAX_VIEWPORT_DIMS:
2456
- return new Int32Array([32767, 32767]);
2457
- // Float arrays — return safe defaults (native getParameterx crashes for these)
2458
- case this.ALIASED_LINE_WIDTH_RANGE:
2459
- case this.ALIASED_POINT_SIZE_RANGE:
2460
- return new Float32Array([1, 1]);
2461
- case this.DEPTH_RANGE:
2462
- return new Float32Array([0, 1]);
2463
- case this.BLEND_COLOR:
2464
- case this.COLOR_CLEAR_VALUE:
2465
- return new Float32Array([0, 0, 0, 0]);
2466
- case this.COLOR_WRITEMASK:
2467
- return this._native.getParameterbv(pname, 16);
2468
- // return boolArray(this._native.getParameterbv(pname, 16));
2469
- case this.DEPTH_CLEAR_VALUE:
2470
- case this.LINE_WIDTH:
2471
- case this.POLYGON_OFFSET_FACTOR:
2472
- case this.POLYGON_OFFSET_UNITS:
2473
- case this.SAMPLE_COVERAGE_VALUE:
2474
- return +this._getParameterDirect(pname);
2475
- case this.BLEND:
2476
- case this.CULL_FACE:
2477
- case this.DEPTH_TEST:
2478
- case this.DEPTH_WRITEMASK:
2479
- case this.DITHER:
2480
- case this.POLYGON_OFFSET_FILL:
2481
- case this.SAMPLE_COVERAGE_INVERT:
2482
- case this.SCISSOR_TEST:
2483
- case this.STENCIL_TEST:
2484
- case this.UNPACK_FLIP_Y_WEBGL:
2485
- case this.UNPACK_PREMULTIPLY_ALPHA_WEBGL:
2486
- return !!this._getParameterDirect(pname);
2487
- case this.ACTIVE_TEXTURE:
2488
- case this.ALPHA_BITS:
2489
- case this.BLEND_DST_ALPHA:
2490
- case this.BLEND_DST_RGB:
2491
- case this.BLEND_EQUATION_ALPHA:
2492
- case this.BLEND_EQUATION_RGB:
2493
- case this.BLEND_SRC_ALPHA:
2494
- case this.BLEND_SRC_RGB:
2495
- case this.BLUE_BITS:
2496
- case this.CULL_FACE_MODE:
2497
- case this.DEPTH_BITS:
2498
- case this.DEPTH_FUNC:
2499
- case this.FRONT_FACE:
2500
- case this.GENERATE_MIPMAP_HINT:
2501
- case this.GREEN_BITS:
2502
- case this.MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2503
- case this.MAX_CUBE_MAP_TEXTURE_SIZE:
2504
- case this.MAX_FRAGMENT_UNIFORM_VECTORS:
2505
- case this.MAX_RENDERBUFFER_SIZE:
2506
- case this.MAX_TEXTURE_IMAGE_UNITS:
2507
- case this.MAX_TEXTURE_SIZE:
2508
- case this.MAX_VARYING_VECTORS:
2509
- case this.MAX_VERTEX_ATTRIBS:
2510
- case this.MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2511
- case this.MAX_VERTEX_UNIFORM_VECTORS:
2512
- case this.PACK_ALIGNMENT:
2513
- case this.RED_BITS:
2514
- case this.SAMPLE_BUFFERS:
2515
- case this.SAMPLES:
2516
- case this.STENCIL_BACK_FAIL:
2517
- case this.STENCIL_BACK_FUNC:
2518
- case this.STENCIL_BACK_PASS_DEPTH_FAIL:
2519
- case this.STENCIL_BACK_PASS_DEPTH_PASS:
2520
- case this.STENCIL_BACK_REF:
2521
- case this.STENCIL_BACK_VALUE_MASK:
2522
- case this.STENCIL_BACK_WRITEMASK:
2523
- case this.STENCIL_BITS:
2524
- case this.STENCIL_CLEAR_VALUE:
2525
- case this.STENCIL_FAIL:
2526
- case this.STENCIL_FUNC:
2527
- case this.STENCIL_PASS_DEPTH_FAIL:
2528
- case this.STENCIL_PASS_DEPTH_PASS:
2529
- case this.STENCIL_REF:
2530
- case this.STENCIL_VALUE_MASK:
2531
- case this.STENCIL_WRITEMASK:
2532
- case this.SUBPIXEL_BITS:
2533
- case this.UNPACK_ALIGNMENT:
2534
- case this.UNPACK_COLORSPACE_CONVERSION_WEBGL:
2535
- return this._getParameterDirect(pname) | 0;
2536
- case this.IMPLEMENTATION_COLOR_READ_FORMAT:
2537
- case this.IMPLEMENTATION_COLOR_READ_TYPE:
2538
- return this._getParameterDirect(pname);
2539
- default:
2540
- if (this._extensions.webgl_draw_buffers) {
2541
- const ext = this._extensions.webgl_draw_buffers;
2542
- switch (pname) {
2543
- case ext.DRAW_BUFFER0_WEBGL:
2544
- case ext.DRAW_BUFFER1_WEBGL:
2545
- case ext.DRAW_BUFFER2_WEBGL:
2546
- case ext.DRAW_BUFFER3_WEBGL:
2547
- case ext.DRAW_BUFFER4_WEBGL:
2548
- case ext.DRAW_BUFFER5_WEBGL:
2549
- case ext.DRAW_BUFFER6_WEBGL:
2550
- case ext.DRAW_BUFFER7_WEBGL:
2551
- case ext.DRAW_BUFFER8_WEBGL:
2552
- case ext.DRAW_BUFFER9_WEBGL:
2553
- case ext.DRAW_BUFFER10_WEBGL:
2554
- case ext.DRAW_BUFFER11_WEBGL:
2555
- case ext.DRAW_BUFFER12_WEBGL:
2556
- case ext.DRAW_BUFFER13_WEBGL:
2557
- case ext.DRAW_BUFFER14_WEBGL:
2558
- case ext.DRAW_BUFFER15_WEBGL:
2559
- if (ext._buffersState.length === 1 && ext._buffersState[0] === this.BACK) {
2560
- return this.BACK;
2561
- }
2562
- return this._getParameterDirect(pname);
2563
- case ext.MAX_DRAW_BUFFERS_WEBGL:
2564
- case ext.MAX_COLOR_ATTACHMENTS_WEBGL:
2565
- return this._getParameterDirect(pname);
2566
- }
2567
- }
2568
- if (this._extensions.oes_standard_derivatives && pname === this._extensions.oes_standard_derivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) {
2569
- return this._getParameterDirect(pname);
2570
- }
2571
- if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT) {
2572
- return this._getParameterDirect(pname);
2573
- }
2574
- if (this._extensions.oes_vertex_array_object && pname === this._extensions.oes_vertex_array_object.VERTEX_ARRAY_BINDING_OES) {
2575
- return this._extensions.oes_vertex_array_object._activeVertexArrayObject;
2576
- }
2577
- this.setError(this.INVALID_ENUM);
2578
- return null;
2579
- }
2580
- }
2581
- getProgramInfoLog(program) {
2582
- if (!checkObject(program)) {
2583
- throw new TypeError("getProgramInfoLog(WebGLProgram)");
2584
- } else if (this._checkWrapper(program, WebGLProgram)) {
2585
- return program._linkInfoLog;
2586
- }
2587
- return null;
2588
- }
2589
- getProgramParameter(program, pname = 0) {
2590
- if (!checkObject(program)) {
2591
- throw new TypeError("getProgramParameter(WebGLProgram, GLenum)");
2592
- } else if (this._checkWrapper(program, WebGLProgram)) {
2593
- switch (pname) {
2594
- case this.DELETE_STATUS:
2595
- return program._pendingDelete;
2596
- case this.LINK_STATUS:
2597
- return program._linkStatus;
2598
- case this.VALIDATE_STATUS:
2599
- return !!this._native.getProgramParameter(program._, pname);
2600
- case this.ATTACHED_SHADERS:
2601
- case this.ACTIVE_ATTRIBUTES:
2602
- case this.ACTIVE_UNIFORMS:
2603
- return this._native.getProgramParameter(program._, pname);
2604
- }
2605
- this.setError(this.INVALID_ENUM);
2606
- }
2607
- return null;
2608
- }
2609
- getRenderbufferParameter(target = 0, pname = 0) {
2610
- if (target !== this.RENDERBUFFER) {
2611
- this.setError(this.INVALID_ENUM);
2612
- return null;
2613
- }
2614
- const renderbuffer = this._activeRenderbuffer;
2615
- if (!renderbuffer) {
2616
- this.setError(this.INVALID_OPERATION);
2617
- return null;
2618
- }
2619
- switch (pname) {
2620
- case this.RENDERBUFFER_INTERNAL_FORMAT:
2621
- return renderbuffer._format;
2622
- case this.RENDERBUFFER_WIDTH:
2623
- return renderbuffer._width;
2624
- case this.RENDERBUFFER_HEIGHT:
2625
- return renderbuffer._height;
2626
- case this.MAX_RENDERBUFFER_SIZE:
2627
- // TODO?
2628
- case this.RENDERBUFFER_RED_SIZE:
2629
- case this.RENDERBUFFER_GREEN_SIZE:
2630
- case this.RENDERBUFFER_BLUE_SIZE:
2631
- case this.RENDERBUFFER_ALPHA_SIZE:
2632
- case this.RENDERBUFFER_DEPTH_SIZE:
2633
- case this.RENDERBUFFER_STENCIL_SIZE:
2634
- return this._native.getRenderbufferParameter(target, pname);
2635
- }
2636
- this.setError(this.INVALID_ENUM);
2637
- return null;
2638
- }
2639
- getShaderInfoLog(shader) {
2640
- if (!checkObject(shader)) {
2641
- throw new TypeError("getShaderInfoLog(WebGLShader)");
2642
- } else if (this._checkWrapper(shader, WebGLShader)) {
2643
- return shader._compileInfo;
2644
- }
2645
- return null;
2646
- }
2647
- getShaderParameter(shader, pname = 0) {
2648
- if (!checkObject(shader)) {
2649
- throw new TypeError("getShaderParameter(WebGLShader, GLenum)");
2650
- } else if (this._checkWrapper(shader, WebGLShader)) {
2651
- switch (pname) {
2652
- case this.DELETE_STATUS:
2653
- return shader._pendingDelete;
2654
- case this.COMPILE_STATUS:
2655
- return shader._compileStatus;
2656
- case this.SHADER_TYPE:
2657
- return shader._type;
2658
- }
2659
- this.setError(this.INVALID_ENUM);
2660
- }
2661
- return null;
2662
- }
2663
- getShaderPrecisionFormat(shaderType = 0, precisionType = 0) {
2664
- if (!(shaderType === this.FRAGMENT_SHADER || shaderType === this.VERTEX_SHADER) || !(precisionType === this.LOW_FLOAT || precisionType === this.MEDIUM_FLOAT || precisionType === this.HIGH_FLOAT || precisionType === this.LOW_INT || precisionType === this.MEDIUM_INT || precisionType === this.HIGH_INT)) {
2665
- this.setError(this.INVALID_ENUM);
2666
- return null;
2667
- }
2668
- const format = this._native.getShaderPrecisionFormat(shaderType, precisionType);
2669
- if (!format) {
2670
- return null;
2671
- }
2672
- return new WebGLShaderPrecisionFormat(format);
2673
- }
2674
- getShaderSource(shader) {
2675
- if (!checkObject(shader)) {
2676
- throw new TypeError("Input to getShaderSource must be an object");
2677
- } else if (this._checkWrapper(shader, WebGLShader)) {
2678
- return shader._source;
2679
- }
2680
- return null;
2681
- }
2682
- getSupportedExtensions() {
2683
- const exts = [
2684
- "ANGLE_instanced_arrays",
2685
- "STACKGL_resize_drawingbuffer",
2686
- "STACKGL_destroy_context"
2687
- ];
2688
- const supportedExts = this._native.getSupportedExtensions();
2689
- if (!supportedExts) {
2690
- return exts;
2691
- }
2692
- if (supportedExts.indexOf("GL_OES_element_index_uint") >= 0) {
2693
- exts.push("OES_element_index_uint");
2694
- }
2695
- if (supportedExts.indexOf("GL_OES_standard_derivatives") >= 0) {
2696
- exts.push("OES_standard_derivatives");
2697
- }
2698
- if (supportedExts.indexOf("GL_OES_texture_float") >= 0) {
2699
- exts.push("OES_texture_float");
2700
- }
2701
- if (supportedExts.indexOf("GL_OES_texture_float_linear") >= 0) {
2702
- exts.push("OES_texture_float_linear");
2703
- }
2704
- if (supportedExts.indexOf("EXT_draw_buffers") >= 0) {
2705
- exts.push("WEBGL_draw_buffers");
2706
- }
2707
- if (supportedExts.indexOf("EXT_blend_minmax") >= 0) {
2708
- exts.push("EXT_blend_minmax");
2709
- }
2710
- if (supportedExts.indexOf("EXT_texture_filter_anisotropic") >= 0) {
2711
- exts.push("EXT_texture_filter_anisotropic");
2712
- }
2713
- if (supportedExts.indexOf("GL_OES_vertex_array_object") >= 0) {
2714
- exts.push("OES_vertex_array_object");
2715
- }
2716
- return exts;
2717
- }
2718
- _getTexParameterDirect(target = 0, pname = 0) {
2719
- return this._native.getTexParameterx(target, pname)?.unpack();
2720
- }
2721
- getTexParameter(target = 0, pname = 0) {
2722
- if (!this._checkTextureTarget(target)) {
2723
- return null;
2724
- }
2725
- const unit = this._getActiveTextureUnit();
2726
- if (target === this.TEXTURE_2D && !unit._bind2D || target === this.TEXTURE_CUBE_MAP && !unit._bindCube) {
2727
- this.setError(this.INVALID_OPERATION);
2728
- return null;
2729
- }
2730
- switch (pname) {
2731
- case this.TEXTURE_MAG_FILTER:
2732
- case this.TEXTURE_MIN_FILTER:
2733
- case this.TEXTURE_WRAP_S:
2734
- case this.TEXTURE_WRAP_T:
2735
- return this._getTexParameterDirect(target, pname);
2736
- }
2737
- if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) {
2738
- return this._getTexParameterDirect(target, pname);
2739
- }
2740
- this.setError(this.INVALID_ENUM);
2741
- return null;
2742
- }
2743
- getUniform(program, location) {
2744
- if (!checkObject(program) || !checkObject(location)) {
2745
- throw new TypeError("getUniform(WebGLProgram, WebGLUniformLocation)");
2746
- } else if (!program) {
2747
- this.setError(this.INVALID_VALUE);
2748
- return null;
2749
- } else if (!location) {
2750
- return null;
2751
- } else if (this._checkWrapper(program, WebGLProgram)) {
2752
- if (!checkUniform(program, location)) {
2753
- this.setError(this.INVALID_OPERATION);
2754
- return null;
2755
- }
2756
- const data = this._native.getUniform(program._ | 0, location._ | 0);
2757
- if (!data) {
2758
- return null;
2759
- }
2760
- switch (location._activeInfo.type) {
2761
- case this.FLOAT:
2762
- return data[0];
2763
- case this.FLOAT_VEC2:
2764
- return new Float32Array(data.slice(0, 2));
2765
- case this.FLOAT_VEC3:
2766
- return new Float32Array(data.slice(0, 3));
2767
- case this.FLOAT_VEC4:
2768
- return new Float32Array(data.slice(0, 4));
2769
- case this.INT:
2770
- return data[0] | 0;
2771
- case this.INT_VEC2:
2772
- return new Int32Array(data.slice(0, 2));
2773
- case this.INT_VEC3:
2774
- return new Int32Array(data.slice(0, 3));
2775
- case this.INT_VEC4:
2776
- return new Int32Array(data.slice(0, 4));
2777
- case this.BOOL:
2778
- return !!data[0];
2779
- case this.BOOL_VEC2:
2780
- return [!!data[0], !!data[1]];
2781
- case this.BOOL_VEC3:
2782
- return [!!data[0], !!data[1], !!data[2]];
2783
- case this.BOOL_VEC4:
2784
- return [!!data[0], !!data[1], !!data[2], !!data[3]];
2785
- case this.FLOAT_MAT2:
2786
- return new Float32Array(data.slice(0, 4));
2787
- case this.FLOAT_MAT3:
2788
- return new Float32Array(data.slice(0, 9));
2789
- case this.FLOAT_MAT4:
2790
- return new Float32Array(data.slice(0, 16));
2791
- case this.SAMPLER_2D:
2792
- case this.SAMPLER_CUBE:
2793
- return data[0] | 0;
2794
- default:
2795
- return null;
2796
- }
2797
- }
2798
- return null;
2799
- }
2800
- getUniformLocation(program, name) {
2801
- if (!checkObject(program)) {
2802
- throw new TypeError("getUniformLocation(WebGLProgram, String)");
2803
- }
2804
- name += "";
2805
- if (!isValidString(name)) {
2806
- this.setError(this.INVALID_VALUE);
2807
- return null;
2808
- }
2809
- if (this._checkWrapper(program, WebGLProgram)) {
2810
- const loc = this._native.getUniformLocation(program._ | 0, name);
2811
- if (loc !== null && loc >= 0) {
2812
- let searchName = name;
2813
- if (/\[\d+\]$/.test(name)) {
2814
- searchName = name.replace(/\[\d+\]$/, "[0]");
122
+ let reducedCount = count;
123
+ switch (mode) {
124
+ case this.TRIANGLES:
125
+ if (count % 3) {
126
+ reducedCount -= count % 3;
2815
127
  }
2816
- let info = null;
2817
- for (let i = 0; i < program._uniforms.length; ++i) {
2818
- const infoItem = program._uniforms[i];
2819
- if (infoItem.name === searchName) {
2820
- info = {
2821
- size: infoItem.size,
2822
- type: infoItem.type,
2823
- name: infoItem.name
2824
- };
2825
- }
128
+ break;
129
+ case this.LINES:
130
+ if (count % 2) {
131
+ reducedCount -= count % 2;
2826
132
  }
2827
- if (!info) {
2828
- return null;
133
+ break;
134
+ case this.POINTS:
135
+ break;
136
+ case this.LINE_LOOP:
137
+ case this.LINE_STRIP:
138
+ if (count < 2) {
139
+ this.setError(this.INVALID_OPERATION);
140
+ return;
2829
141
  }
2830
- const result = new WebGLUniformLocation(
2831
- loc,
2832
- program,
2833
- info
2834
- );
2835
- if (/\[0\]$/.test(name)) {
2836
- const baseName = name.replace(/\[0\]$/, "");
2837
- const arrayLocs = [];
2838
- this._saveError();
2839
- for (let i = 0; this.getError() === this.NO_ERROR; ++i) {
2840
- const xloc = this._native.getUniformLocation(
2841
- program._ | 0,
2842
- baseName + "[" + i + "]"
2843
- );
2844
- if (this.getError() !== this.NO_ERROR || !xloc || xloc < 0) {
2845
- break;
2846
- }
2847
- arrayLocs.push(xloc);
2848
- }
2849
- this._restoreError(this.NO_ERROR);
2850
- result._array = arrayLocs;
2851
- } else if (name && /\[(\d+)\]$/.test(name)) {
2852
- const _regexExec = /\[(\d+)\]$/.exec(name);
2853
- if (!_regexExec || _regexExec.length <= 0) {
2854
- return null;
2855
- }
2856
- const offset = +_regexExec[1];
2857
- if (offset < 0 || offset >= info.size) {
2858
- return null;
2859
- }
142
+ break;
143
+ case this.TRIANGLE_FAN:
144
+ case this.TRIANGLE_STRIP:
145
+ if (count < 3) {
146
+ this.setError(this.INVALID_OPERATION);
147
+ return;
2860
148
  }
2861
- return result;
2862
- }
2863
- }
2864
- return null;
2865
- }
2866
- getVertexAttrib(index = 0, pname = 0) {
2867
- if (index < 0 || index >= this._vertexObjectState._attribs.length) {
2868
- this.setError(this.INVALID_VALUE);
2869
- return null;
2870
- }
2871
- const attrib = this._vertexObjectState._attribs[index];
2872
- const vertexAttribValue = this._vertexGlobalState._attribs[index]._data;
2873
- const extInstancing = this._extensions.angle_instanced_arrays;
2874
- if (extInstancing) {
2875
- if (pname === extInstancing.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE) {
2876
- return attrib._divisor;
2877
- }
2878
- }
2879
- switch (pname) {
2880
- case this.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2881
- return attrib._pointerBuffer;
2882
- case this.VERTEX_ATTRIB_ARRAY_ENABLED:
2883
- return attrib._isPointer;
2884
- case this.VERTEX_ATTRIB_ARRAY_SIZE:
2885
- return attrib._inputSize;
2886
- case this.VERTEX_ATTRIB_ARRAY_STRIDE:
2887
- return attrib._inputStride;
2888
- case this.VERTEX_ATTRIB_ARRAY_TYPE:
2889
- return attrib._pointerType;
2890
- case this.VERTEX_ATTRIB_ARRAY_NORMALIZED:
2891
- return attrib._pointerNormal;
2892
- case this.CURRENT_VERTEX_ATTRIB:
2893
- return new Float32Array(vertexAttribValue);
149
+ break;
2894
150
  default:
2895
151
  this.setError(this.INVALID_ENUM);
2896
- return null;
2897
- }
2898
- }
2899
- getVertexAttribOffset(index = 0, pname = 0) {
2900
- if (index < 0 || index >= this._vertexObjectState._attribs.length) {
2901
- this.setError(this.INVALID_VALUE);
2902
- return -1;
2903
- }
2904
- if (pname === this.VERTEX_ATTRIB_ARRAY_POINTER) {
2905
- return this._vertexObjectState._attribs[index]._pointerOffset;
2906
- } else {
2907
- this.setError(this.INVALID_ENUM);
2908
- return -1;
2909
- }
2910
- }
2911
- hint(target = 0, mode = 0) {
2912
- if (!(target === this.GENERATE_MIPMAP_HINT || this._extensions.oes_standard_derivatives && target === this._extensions.oes_standard_derivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES)) {
2913
- this.setError(this.INVALID_ENUM);
2914
- return;
2915
- }
2916
- if (mode !== this.FASTEST && mode !== this.NICEST && mode !== this.DONT_CARE) {
2917
- this.setError(this.INVALID_ENUM);
2918
- return;
152
+ return;
2919
153
  }
2920
- return this._native.hint(target, mode);
2921
- }
2922
- isBuffer(buffer) {
2923
- if (!this._isObject(buffer, "isBuffer", WebGLBuffer)) return false;
2924
- return this._native.isBuffer(buffer?._);
2925
- }
2926
- isContextLost() {
2927
- return false;
2928
- }
2929
- isEnabled(cap = 0) {
2930
- return this._native.isEnabled(cap);
2931
- }
2932
- isFramebuffer(framebuffer) {
2933
- if (!this._isObject(framebuffer, "isFramebuffer", WebGLFramebuffer)) return false;
2934
- return this._native.isFramebuffer(framebuffer?._);
2935
- }
2936
- isProgram(program) {
2937
- if (!this._isObject(program, "isProgram", WebGLProgram)) return false;
2938
- return this._native.isProgram(program?._);
2939
- }
2940
- isRenderbuffer(renderbuffer) {
2941
- if (!this._isObject(renderbuffer, "isRenderbuffer", WebGLRenderbuffer)) return false;
2942
- return this._native.isRenderbuffer(renderbuffer?._);
2943
- }
2944
- isShader(shader) {
2945
- if (!this._isObject(shader, "isShader", WebGLShader)) return false;
2946
- return this._native.isShader(shader?._);
2947
- }
2948
- isTexture(texture) {
2949
- if (!this._isObject(texture, "isTexture", WebGLTexture)) return false;
2950
- return this._native.isTexture(texture?._);
2951
- }
2952
- lineWidth(width) {
2953
- if (isNaN(width)) {
2954
- this.setError(this.INVALID_VALUE);
154
+ if (!this._framebufferOk()) {
2955
155
  return;
2956
156
  }
2957
- return this._native.lineWidth(+width);
2958
- }
2959
- linkProgram(program) {
2960
- if (!checkObject(program)) {
2961
- throw new TypeError("linkProgram(WebGLProgram)");
2962
- }
2963
- if (this._checkWrapper(program, WebGLProgram)) {
2964
- program._linkCount += 1;
2965
- program._attributes = [];
2966
- const prevError = this.getError();
2967
- this._native.linkProgram(program._ | 0);
2968
- const error = this.getError();
2969
- if (error === this.NO_ERROR) {
2970
- program._linkStatus = this._fixupLink(program);
2971
- }
2972
- this.getError();
2973
- this.setError(prevError || error);
2974
- }
2975
- }
2976
- /** The `WebGLRenderingContext.pixelStorei()` method of the WebGL API specifies the pixel storage modes. */
2977
- pixelStorei(pname = 0, param = 0) {
2978
- if (typeof param === "boolean") {
2979
- param = param === false ? 0 : 1;
2980
- }
2981
- if (pname === this.UNPACK_ALIGNMENT) {
2982
- if (param === 1 || param === 2 || param === 4 || param === 8) {
2983
- this._unpackAlignment = param;
2984
- } else {
2985
- this.setError(this.INVALID_VALUE);
2986
- return;
2987
- }
2988
- } else if (pname === this.PACK_ALIGNMENT) {
2989
- if (param === 1 || param === 2 || param === 4 || param === 8) {
2990
- this._packAlignment = param;
2991
- } else {
2992
- this.setError(this.INVALID_VALUE);
2993
- return;
2994
- }
2995
- } else if (pname === this.UNPACK_COLORSPACE_CONVERSION_WEBGL) {
2996
- if (!(param === this.NONE || param === this.BROWSER_DEFAULT_WEBGL)) {
2997
- this.setError(this.INVALID_VALUE);
2998
- return;
2999
- }
3000
- }
3001
- return this._native.pixelStorei(pname, param);
3002
- }
3003
- polygonOffset(factor, units) {
3004
- return this._native.polygonOffset(+factor, +units);
3005
- }
3006
- renderbufferStorage(target = 0, internalFormat = 0, width = 0, height = 0) {
3007
- if (target !== this.RENDERBUFFER) {
3008
- this.setError(this.INVALID_ENUM);
157
+ if (count === 0) {
158
+ this._checkVertexAttribState(0);
3009
159
  return;
3010
160
  }
3011
- const renderbuffer = this._activeRenderbuffer;
3012
- if (!renderbuffer) {
161
+ if (count + offset >>> 0 > elementData.length) {
3013
162
  this.setError(this.INVALID_OPERATION);
3014
163
  return;
3015
164
  }
3016
- if (internalFormat !== this.RGBA4 && internalFormat !== this.RGB565 && internalFormat !== this.RGB5_A1 && internalFormat !== this.DEPTH_COMPONENT16 && internalFormat !== this.STENCIL_INDEX && internalFormat !== this.STENCIL_INDEX8 && internalFormat !== this.DEPTH_STENCIL) {
3017
- this.setError(this.INVALID_ENUM);
3018
- return;
165
+ let maxIndex = -1;
166
+ for (let i = offset; i < offset + count; ++i) {
167
+ maxIndex = Math.max(maxIndex, elementData[i]);
3019
168
  }
3020
- this._saveError();
3021
- this._native.renderbufferStorage(
3022
- target,
3023
- internalFormat,
3024
- width,
3025
- height
3026
- );
3027
- const error = this.getError();
3028
- this._restoreError(error);
3029
- if (error !== this.NO_ERROR) {
169
+ if (maxIndex < 0) {
170
+ this._checkVertexAttribState(0);
3030
171
  return;
3031
172
  }
3032
- renderbuffer._width = width;
3033
- renderbuffer._height = height;
3034
- renderbuffer._format = internalFormat;
3035
- const activeFramebuffer = this._activeFramebuffer;
3036
- if (activeFramebuffer) {
3037
- let needsUpdate = false;
3038
- const attachments = this._getAttachments();
3039
- for (let i = 0; i < attachments.length; ++i) {
3040
- if (activeFramebuffer._attachments[attachments[i]] === renderbuffer) {
3041
- needsUpdate = true;
3042
- break;
173
+ if (this._checkVertexAttribState(maxIndex)) {
174
+ if (reducedCount > 0) {
175
+ if (this._vertexObjectState._attribs[0]._isPointer) {
176
+ return this._native.drawElements(mode, reducedCount, type, ioffset);
177
+ } else {
178
+ this._beginAttrib0Hack();
179
+ this._native._drawElementsInstanced(mode, reducedCount, type, ioffset, 1);
180
+ this._endAttrib0Hack();
3043
181
  }
3044
182
  }
3045
- if (needsUpdate) {
3046
- this._updateFramebufferAttachments(this._activeFramebuffer);
3047
- }
3048
- }
3049
- }
3050
- resize(width = 0, height = 0) {
3051
- width = width | 0;
3052
- height = height | 0;
3053
- if (!(width > 0 && height > 0)) {
3054
- throw new Error("Invalid surface dimensions");
3055
- } else if (width !== this.drawingBufferWidth || height !== this.drawingBufferHeight) {
3056
- this._resizeDrawingBuffer(width, height);
3057
- }
3058
- }
3059
- sampleCoverage(value, invert) {
3060
- return this._native.sampleCoverage(+value, !!invert);
3061
- }
3062
- scissor(x, y, width, height) {
3063
- this._scissorBox[0] = x | 0;
3064
- this._scissorBox[1] = y | 0;
3065
- this._scissorBox[2] = width | 0;
3066
- this._scissorBox[3] = height | 0;
3067
- return this._native.scissor(x | 0, y | 0, width | 0, height | 0);
3068
- }
3069
- shaderSource(shader, source) {
3070
- if (!checkObject(shader)) {
3071
- throw new TypeError("shaderSource(WebGLShader, String)");
3072
- }
3073
- if (!shader || !source && typeof source !== "string") {
3074
- this.setError(this.INVALID_VALUE);
3075
- return;
3076
- }
3077
- if (!isValidString(source)) {
3078
- this.setError(this.INVALID_VALUE);
3079
- } else if (this._checkWrapper(shader, WebGLShader)) {
3080
- source = this._wrapShader(shader._type, source);
3081
- this._native.shaderSource(shader._ | 0, source);
3082
- shader._source = source;
3083
- }
3084
- }
3085
- stencilFunc(func, ref, mask) {
3086
- this._checkStencil = true;
3087
- return this._native.stencilFunc(func | 0, ref | 0, mask | 0);
3088
- }
3089
- stencilFuncSeparate(face, func, ref, mask) {
3090
- this._checkStencil = true;
3091
- return this._native.stencilFuncSeparate(face | 0, func | 0, ref | 0, mask | 0);
3092
- }
3093
- stencilMask(mask) {
3094
- this._checkStencil = true;
3095
- return this._native.stencilMask(mask >>> 0);
3096
- }
3097
- stencilMaskSeparate(face, mask) {
3098
- this._checkStencil = true;
3099
- return this._native.stencilMaskSeparate(face | 0, mask >>> 0);
3100
- }
3101
- stencilOp(fail, zfail, zpass) {
3102
- this._checkStencil = true;
3103
- return this._native.stencilOp(fail | 0, zfail | 0, zpass | 0);
3104
- }
3105
- stencilOpSeparate(face, fail, zfail, zpass) {
3106
- this._checkStencil = true;
3107
- return this._native.stencilOpSeparate(face | 0, fail | 0, zfail | 0, zpass | 0);
3108
- }
3109
- texParameterf(target = 0, pname = 0, param) {
3110
- param = +param;
3111
- if (this._checkTextureTarget(target)) {
3112
- this._verifyTextureCompleteness(target, pname, param);
3113
- switch (pname) {
3114
- case this.TEXTURE_MIN_FILTER:
3115
- case this.TEXTURE_MAG_FILTER:
3116
- case this.TEXTURE_WRAP_S:
3117
- case this.TEXTURE_WRAP_T:
3118
- return this._native.texParameterf(target, pname, param);
3119
- }
3120
- if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) {
3121
- return this._native.texParameterf(target, pname, param);
3122
- }
3123
- this.setError(this.INVALID_ENUM);
3124
- }
3125
- }
3126
- texParameteri(target = 0, pname = 0, param = 0) {
3127
- if (this._checkTextureTarget(target)) {
3128
- this._verifyTextureCompleteness(target, pname, param);
3129
- switch (pname) {
3130
- case this.TEXTURE_MIN_FILTER:
3131
- case this.TEXTURE_MAG_FILTER:
3132
- case this.TEXTURE_WRAP_S:
3133
- case this.TEXTURE_WRAP_T:
3134
- return this._native.texParameteri(target, pname, param);
3135
- }
3136
- if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) {
3137
- return this._native.texParameteri(target, pname, param);
3138
- }
3139
- this.setError(this.INVALID_ENUM);
3140
- }
3141
- }
3142
- uniform1f(location, x) {
3143
- if (!this._checkUniformValid(location, x, "uniform1f", 1, "f")) return;
3144
- return this._native.uniform1f(location?._ || 0, x);
3145
- }
3146
- uniform1i(location, x) {
3147
- return this._native.uniform1i(location?._ || 0, x);
3148
- }
3149
- uniform2f(location, x, y) {
3150
- if (!this._checkUniformValid(location, x, "uniform2f", 2, "f")) return;
3151
- return this._native.uniform2f(location?._ || 0, x, y);
3152
- }
3153
- uniform2i(location, x, y) {
3154
- if (!this._checkUniformValid(location, x, "uniform2i", 2, "i")) return;
3155
- this._native.uniform2i(location?._ || 0, x, y);
3156
- }
3157
- uniform3f(location, x, y, z) {
3158
- if (!this._checkUniformValid(location, x, "uniform3f", 3, "f")) return;
3159
- return this._native.uniform3f(location?._ || 0, x, y, z);
3160
- }
3161
- uniform3i(location, x, y, z) {
3162
- if (!this._checkUniformValid(location, x, "uniform3i", 3, "i")) return;
3163
- return this._native.uniform3i(location?._ || 0, x, y, z);
3164
- }
3165
- uniform4f(location, x, y, z, w) {
3166
- if (!this._checkUniformValid(location, x, "uniform4f", 4, "f")) {
3167
- console.error("uniform4f is not valid!");
3168
- return;
3169
- }
3170
- return this._native.uniform4f(location?._ || 0, x, y, z, w);
3171
- }
3172
- uniform4i(location, x, y, z, w) {
3173
- if (!this._checkUniformValid(location, x, "uniform4i", 4, "i")) return;
3174
- return this._native.uniform4i(location?._ || 0, x, y, z, w);
3175
- }
3176
- useProgram(program) {
3177
- if (!checkObject(program)) {
3178
- throw new TypeError("useProgram(WebGLProgram)");
3179
- } else if (!program) {
3180
- this._switchActiveProgram(this._activeProgram);
3181
- this._activeProgram = null;
3182
- return this._native.useProgram(0);
3183
- } else if (this._checkWrapper(program, WebGLProgram)) {
3184
- if (this._activeProgram !== program) {
3185
- this._switchActiveProgram(this._activeProgram);
3186
- this._activeProgram = program;
3187
- program._refCount += 1;
3188
- }
3189
- return this._native.useProgram(program._ | 0);
3190
- }
3191
- }
3192
- validateProgram(program) {
3193
- if (this._checkWrapper(program, WebGLProgram)) {
3194
- this._native.validateProgram(program._ | 0);
3195
- const error = this.getError();
3196
- if (error === this.NO_ERROR) {
3197
- program._linkInfoLog = this._native.getProgramInfoLog(program._ | 0);
3198
- }
3199
- this.getError();
3200
- this.setError(error);
3201
- }
3202
- }
3203
- vertexAttrib1f(index, x) {
3204
- index |= 0;
3205
- if (!this._checkVertexIndex(index)) return;
3206
- const data = this._vertexGlobalState._attribs[index]._data;
3207
- data[3] = 1;
3208
- data[1] = data[2] = 0;
3209
- data[0] = x;
3210
- return this._native.vertexAttrib1f(index | 0, +x);
3211
- }
3212
- vertexAttrib1fv(index, values) {
3213
- if (typeof values !== "object" || values === null || values.length < 1) {
3214
- this.setError(this.INVALID_OPERATION);
3215
- return;
3216
- }
3217
- const data = this._vertexGlobalState._attribs[index]._data;
3218
- data[3] = 1;
3219
- data[2] = 0;
3220
- data[1] = 0;
3221
- data[0] = values[0];
3222
- return this._native.vertexAttrib1f(index | 0, +values[0]);
3223
- }
3224
- vertexAttrib2f(index, x, y) {
3225
- index |= 0;
3226
- if (!this._checkVertexIndex(index)) return;
3227
- const data = this._vertexGlobalState._attribs[index]._data;
3228
- data[3] = 1;
3229
- data[2] = 0;
3230
- data[1] = y;
3231
- data[0] = x;
3232
- return this._native.vertexAttrib2f(index | 0, +x, +y);
3233
- }
3234
- vertexAttrib2fv(index, values) {
3235
- if (typeof values !== "object" || values === null || values.length < 2) {
3236
- this.setError(this.INVALID_OPERATION);
3237
- return;
3238
- }
3239
- const data = this._vertexGlobalState._attribs[index]._data;
3240
- data[3] = 1;
3241
- data[2] = 0;
3242
- data[1] = values[1];
3243
- data[0] = values[0];
3244
- return this._native.vertexAttrib2f(index | 0, +values[0], +values[1]);
3245
- }
3246
- vertexAttrib3f(index, x, y, z) {
3247
- index |= 0;
3248
- if (!this._checkVertexIndex(index)) return;
3249
- const data = this._vertexGlobalState._attribs[index]._data;
3250
- data[3] = 1;
3251
- data[2] = z;
3252
- data[1] = y;
3253
- data[0] = x;
3254
- return this._native.vertexAttrib3f(index | 0, +x, +y, +z);
3255
- }
3256
- vertexAttrib3fv(index, values) {
3257
- if (typeof values !== "object" || values === null || values.length < 3) {
3258
- this.setError(this.INVALID_OPERATION);
3259
- return;
3260
- }
3261
- const data = this._vertexGlobalState._attribs[index]._data;
3262
- data[3] = 1;
3263
- data[2] = values[2];
3264
- data[1] = values[1];
3265
- data[0] = values[0];
3266
- return this._native.vertexAttrib3f(index | 0, +values[0], +values[1], +values[2]);
3267
- }
3268
- vertexAttrib4f(index = 0, x, y, z, w) {
3269
- if (!this._checkVertexIndex(index)) return;
3270
- const data = this._vertexGlobalState._attribs[index]._data;
3271
- data[3] = w;
3272
- data[2] = z;
3273
- data[1] = y;
3274
- data[0] = x;
3275
- return this._native.vertexAttrib4f(index | 0, +x, +y, +z, +w);
3276
- }
3277
- vertexAttrib4fv(index, values) {
3278
- if (typeof values !== "object" || values === null || values.length < 4) {
3279
- this.setError(this.INVALID_OPERATION);
3280
- return;
3281
- }
3282
- const data = this._vertexGlobalState._attribs[index]._data;
3283
- data[3] = values[3];
3284
- data[2] = values[2];
3285
- data[1] = values[1];
3286
- data[0] = values[0];
3287
- return this._native.vertexAttrib4f(index | 0, +values[0], +values[1], +values[2], +values[3]);
3288
- }
3289
- vertexAttribPointer(index = 0, size = 0, type = 0, normalized = false, stride = 0, offset = 0) {
3290
- if (stride < 0 || offset < 0) {
3291
- this.setError(this.INVALID_VALUE);
3292
- return;
3293
- }
3294
- if (stride < 0 || offset < 0 || index < 0 || index >= this._vertexObjectState._attribs.length || !(size === 1 || size === 2 || size === 3 || size === 4)) {
3295
- this.setError(this.INVALID_VALUE);
3296
- return;
3297
- }
3298
- if (this._vertexGlobalState._arrayBufferBinding === null) {
3299
- this.setError(this.INVALID_OPERATION);
3300
- return;
3301
- }
3302
- const byteSize = typeSize(this, type);
3303
- if (byteSize === 0 || type === this.INT || type === this.UNSIGNED_INT) {
3304
- this.setError(this.INVALID_ENUM);
3305
- return;
3306
183
  }
3307
- if (stride > 255 || stride < 0) {
3308
- this.setError(this.INVALID_VALUE);
3309
- return;
3310
- }
3311
- if (stride % byteSize !== 0 || offset % byteSize !== 0) {
3312
- this.setError(this.INVALID_OPERATION);
3313
- return;
3314
- }
3315
- this._native.vertexAttribPointer(index, size, type, normalized, stride, offset);
3316
- this._vertexObjectState.setVertexAttribPointer(
3317
- /* buffer */
3318
- this._vertexGlobalState._arrayBufferBinding,
3319
- /* index */
3320
- index,
3321
- /* pointerSize */
3322
- size * byteSize,
3323
- /* pointerOffset */
3324
- offset,
3325
- /* pointerStride */
3326
- stride || size * byteSize,
3327
- /* pointerType */
3328
- type,
3329
- /* pointerNormal */
3330
- normalized,
3331
- /* inputStride */
3332
- stride,
3333
- /* inputSize */
3334
- size
3335
- );
3336
- }
3337
- viewport(x, y, width, height) {
3338
- this._viewport[0] = x | 0;
3339
- this._viewport[1] = y | 0;
3340
- this._viewport[2] = width | 0;
3341
- this._viewport[3] = height | 0;
3342
- return this._native.viewport(x, y, width, height);
3343
184
  }
3344
185
  }
3345
186
  export {
187
+ WebGLContextBase2 as WebGLContextBase,
3346
188
  WebGLRenderingContext
3347
189
  };