@gjsify/webgl 0.0.3 → 0.1.0

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