webgl2 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -6
- package/src/webgl2_context.js +1103 -0
- package/src/webgl2_resources.js +51 -0
- package/src/webgl2_texture.js +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webgl2",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "WebGL2 tools to derisk large GPU projects on the web beyond toys and demos.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -11,11 +11,6 @@
|
|
|
11
11
|
"test": "node --test test/*.test.js",
|
|
12
12
|
"test:smoke": "npm run build && node ./test/smoke.js"
|
|
13
13
|
},
|
|
14
|
-
"wasmBuild": {
|
|
15
|
-
"outDir": "wasm",
|
|
16
|
-
"target": "wasm32-unknown-unknown",
|
|
17
|
-
"profile": "release"
|
|
18
|
-
},
|
|
19
14
|
"repository": {
|
|
20
15
|
"type": "git",
|
|
21
16
|
"url": "git+https://github.com/mavity/webgl2"
|
|
@@ -27,6 +22,7 @@
|
|
|
27
22
|
,
|
|
28
23
|
"files": [
|
|
29
24
|
"index.js",
|
|
25
|
+
"src/*.js",
|
|
30
26
|
"wasm",
|
|
31
27
|
"README.md",
|
|
32
28
|
"LICENSE"
|
|
@@ -0,0 +1,1103 @@
|
|
|
1
|
+
// Thin forwarding WasmWebGL2RenderingContext and helpers
|
|
2
|
+
// This module contains the class and small helpers that operate on the
|
|
3
|
+
// WebAssembly instance. It is intentionally minimal: JS forwards calls to
|
|
4
|
+
// WASM and reads last-error strings when needed.
|
|
5
|
+
|
|
6
|
+
/** @typedef {number} u32 */
|
|
7
|
+
|
|
8
|
+
// Errno constants (must match src/webgl2_context.rs)
|
|
9
|
+
export const ERR_OK = 0;
|
|
10
|
+
export const ERR_INVALID_HANDLE = 1;
|
|
11
|
+
export const ERR_OOM = 2;
|
|
12
|
+
export const ERR_INVALID_ARGS = 3;
|
|
13
|
+
export const ERR_NOT_IMPLEMENTED = 4;
|
|
14
|
+
export const ERR_GL = 5;
|
|
15
|
+
export const ERR_INTERNAL = 6;
|
|
16
|
+
|
|
17
|
+
import { WasmWebGLTexture } from './webgl2_texture.js';
|
|
18
|
+
import { WasmWebGLShader, WasmWebGLProgram, WasmWebGLBuffer } from './webgl2_resources.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @implements {WebGL2RenderingContext}
|
|
22
|
+
*/
|
|
23
|
+
export class WasmWebGL2RenderingContext {
|
|
24
|
+
// Constants
|
|
25
|
+
FRAGMENT_SHADER = 0x8B30;
|
|
26
|
+
VERTEX_SHADER = 0x8B31;
|
|
27
|
+
TRIANGLES = 0x0004;
|
|
28
|
+
COLOR_BUFFER_BIT = 0x00004000;
|
|
29
|
+
DEPTH_BUFFER_BIT = 0x00000100;
|
|
30
|
+
STENCIL_BUFFER_BIT = 0x00000400;
|
|
31
|
+
COMPILE_STATUS = 0x8B81;
|
|
32
|
+
LINK_STATUS = 0x8B82;
|
|
33
|
+
DELETE_STATUS = 0x8B80;
|
|
34
|
+
VALIDATE_STATUS = 0x8B83;
|
|
35
|
+
ARRAY_BUFFER = 0x8892;
|
|
36
|
+
ELEMENT_ARRAY_BUFFER = 0x8893;
|
|
37
|
+
STATIC_DRAW = 0x88E4;
|
|
38
|
+
FLOAT = 0x1406;
|
|
39
|
+
UNSIGNED_SHORT = 0x1403;
|
|
40
|
+
UNSIGNED_BYTE = 0x1401;
|
|
41
|
+
RGBA = 0x1908;
|
|
42
|
+
VIEWPORT = 0x0BA2;
|
|
43
|
+
COLOR_CLEAR_VALUE = 0x0C22;
|
|
44
|
+
BUFFER_SIZE = 0x8764;
|
|
45
|
+
NO_ERROR = 0;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {WebAssembly.Instance} instance
|
|
49
|
+
* @param {u32} ctxHandle
|
|
50
|
+
*/
|
|
51
|
+
constructor(instance, ctxHandle) {
|
|
52
|
+
this._instance = instance;
|
|
53
|
+
this._ctxHandle = ctxHandle;
|
|
54
|
+
this._destroyed = false;
|
|
55
|
+
/** @type {import('./webgl2_resources.js').WasmWebGLProgram | null} */
|
|
56
|
+
this._currentProgram = null;
|
|
57
|
+
|
|
58
|
+
WasmWebGL2RenderingContext.activeContext = this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_executeShader(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) {
|
|
62
|
+
if (!this._currentProgram) {
|
|
63
|
+
console.log("DEBUG: No current program");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const shaderInstance = type === this.VERTEX_SHADER ? this._currentProgram._vsInstance : this._currentProgram._fsInstance;
|
|
67
|
+
if (shaderInstance && shaderInstance.exports.main) {
|
|
68
|
+
try {
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
shaderInstance.exports.main(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.error(`Shader execution error in ${type === this.VERTEX_SHADER ? 'VS' : 'FS'}:`, e);
|
|
73
|
+
console.error(` attrPtr: ${attrPtr}, uniformPtr: ${uniformPtr}, varyingPtr: ${varyingPtr}, privatePtr: ${privatePtr}, texturePtr: ${texturePtr}`);
|
|
74
|
+
throw e;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
destroy() {
|
|
80
|
+
if (this._destroyed) return;
|
|
81
|
+
const ex = this._instance.exports;
|
|
82
|
+
if (ex && typeof ex.wasm_ctx_destroy_context === 'function') {
|
|
83
|
+
if (typeof ex.wasm_destroy_context === 'function') {
|
|
84
|
+
const code = ex.wasm_destroy_context(this._ctxHandle);
|
|
85
|
+
_checkErr(code, this._instance);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this._destroyed = true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
_assertNotDestroyed() {
|
|
92
|
+
if (this._destroyed) throw new Error('context has been destroyed');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
createTexture() {
|
|
96
|
+
this._assertNotDestroyed();
|
|
97
|
+
const ex = this._instance.exports;
|
|
98
|
+
if (!ex || typeof ex.wasm_ctx_create_texture !== 'function') {
|
|
99
|
+
throw new Error('wasm_ctx_create_texture not found');
|
|
100
|
+
}
|
|
101
|
+
const handle = ex.wasm_ctx_create_texture(this._ctxHandle);
|
|
102
|
+
if (handle === 0) {
|
|
103
|
+
const msg = readErrorMessage(this._instance);
|
|
104
|
+
throw new Error(`Failed to create texture: ${msg}`);
|
|
105
|
+
}
|
|
106
|
+
// Return a thin wrapper object representing the texture.
|
|
107
|
+
return new WasmWebGLTexture(this, handle);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
deleteTexture(tex) {
|
|
111
|
+
this._assertNotDestroyed();
|
|
112
|
+
const ex = this._instance.exports;
|
|
113
|
+
if (!ex || typeof ex.wasm_ctx_delete_texture !== 'function') {
|
|
114
|
+
throw new Error('wasm_ctx_delete_texture not found');
|
|
115
|
+
}
|
|
116
|
+
const handle = tex && typeof tex === 'object' && typeof tex._handle === 'number' ? tex._handle : (tex >>> 0);
|
|
117
|
+
const code = ex.wasm_ctx_delete_texture(this._ctxHandle, handle);
|
|
118
|
+
_checkErr(code, this._instance);
|
|
119
|
+
// If a wrapper object was passed, mark it as deleted.
|
|
120
|
+
if (tex && typeof tex === 'object') {
|
|
121
|
+
try { tex._handle = 0; tex._deleted = true; } catch (e) { /* ignore */ }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
bindTexture(target, tex) {
|
|
126
|
+
this._assertNotDestroyed();
|
|
127
|
+
const ex = this._instance.exports;
|
|
128
|
+
if (!ex || typeof ex.wasm_ctx_bind_texture !== 'function') {
|
|
129
|
+
throw new Error('wasm_ctx_bind_texture not found');
|
|
130
|
+
}
|
|
131
|
+
const handle = tex && typeof tex === 'object' && typeof tex._handle === 'number' ? tex._handle : (tex >>> 0);
|
|
132
|
+
const code = ex.wasm_ctx_bind_texture(this._ctxHandle, target >>> 0, handle);
|
|
133
|
+
_checkErr(code, this._instance);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
texImage2D(target, level, internalFormat, width, height, border, format, type_, pixels) {
|
|
137
|
+
this._assertNotDestroyed();
|
|
138
|
+
const ex = this._instance.exports;
|
|
139
|
+
if (!ex || typeof ex.wasm_ctx_tex_image_2d !== 'function') {
|
|
140
|
+
throw new Error('wasm_ctx_tex_image_2d not found');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let data = pixels;
|
|
144
|
+
if (!data) data = new Uint8Array(width * height * 4);
|
|
145
|
+
else if (!(data instanceof Uint8Array)) data = new Uint8Array(data);
|
|
146
|
+
|
|
147
|
+
const len = data.length;
|
|
148
|
+
const ptr = ex.wasm_alloc(len);
|
|
149
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for pixel data');
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
153
|
+
mem.set(data, ptr);
|
|
154
|
+
|
|
155
|
+
const code = ex.wasm_ctx_tex_image_2d(
|
|
156
|
+
this._ctxHandle,
|
|
157
|
+
target >>> 0,
|
|
158
|
+
level >>> 0,
|
|
159
|
+
internalFormat >>> 0,
|
|
160
|
+
width >>> 0,
|
|
161
|
+
height >>> 0,
|
|
162
|
+
border >>> 0,
|
|
163
|
+
format >>> 0,
|
|
164
|
+
type_ >>> 0,
|
|
165
|
+
ptr >>> 0,
|
|
166
|
+
len >>> 0
|
|
167
|
+
);
|
|
168
|
+
_checkErr(code, this._instance);
|
|
169
|
+
} finally {
|
|
170
|
+
ex.wasm_free(ptr);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
createFramebuffer() {
|
|
175
|
+
this._assertNotDestroyed();
|
|
176
|
+
const ex = this._instance.exports;
|
|
177
|
+
if (!ex || typeof ex.wasm_ctx_create_framebuffer !== 'function') {
|
|
178
|
+
throw new Error('wasm_ctx_create_framebuffer not found');
|
|
179
|
+
}
|
|
180
|
+
const handle = ex.wasm_ctx_create_framebuffer(this._ctxHandle);
|
|
181
|
+
if (handle === 0) {
|
|
182
|
+
const msg = readErrorMessage(this._instance);
|
|
183
|
+
throw new Error(`Failed to create framebuffer: ${msg}`);
|
|
184
|
+
}
|
|
185
|
+
return handle;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
deleteFramebuffer(fb) {
|
|
189
|
+
this._assertNotDestroyed();
|
|
190
|
+
const ex = this._instance.exports;
|
|
191
|
+
if (!ex || typeof ex.wasm_ctx_delete_framebuffer !== 'function') {
|
|
192
|
+
throw new Error('wasm_ctx_delete_framebuffer not found');
|
|
193
|
+
}
|
|
194
|
+
const code = ex.wasm_ctx_delete_framebuffer(this._ctxHandle, fb);
|
|
195
|
+
_checkErr(code, this._instance);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
bindFramebuffer(target, fb) {
|
|
199
|
+
this._assertNotDestroyed();
|
|
200
|
+
const ex = this._instance.exports;
|
|
201
|
+
if (!ex || typeof ex.wasm_ctx_bind_framebuffer !== 'function') {
|
|
202
|
+
throw new Error('wasm_ctx_bind_framebuffer not found');
|
|
203
|
+
}
|
|
204
|
+
const code = ex.wasm_ctx_bind_framebuffer(this._ctxHandle, target >>> 0, fb >>> 0);
|
|
205
|
+
_checkErr(code, this._instance);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
framebufferTexture2D(target, attachment, textarget, texture, level) {
|
|
209
|
+
this._assertNotDestroyed();
|
|
210
|
+
const ex = this._instance.exports;
|
|
211
|
+
if (!ex || typeof ex.wasm_ctx_framebuffer_texture2d !== 'function') {
|
|
212
|
+
throw new Error('wasm_ctx_framebuffer_texture2d not found');
|
|
213
|
+
}
|
|
214
|
+
const texHandle = texture && typeof texture === 'object' && typeof texture._handle === 'number' ? texture._handle : (texture >>> 0);
|
|
215
|
+
const code = ex.wasm_ctx_framebuffer_texture2d(
|
|
216
|
+
this._ctxHandle,
|
|
217
|
+
target >>> 0,
|
|
218
|
+
attachment >>> 0,
|
|
219
|
+
textarget >>> 0,
|
|
220
|
+
texHandle,
|
|
221
|
+
level >>> 0
|
|
222
|
+
);
|
|
223
|
+
_checkErr(code, this._instance);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
readPixels(x, y, width, height, format, type_, out) {
|
|
227
|
+
this._assertNotDestroyed();
|
|
228
|
+
const ex = this._instance.exports;
|
|
229
|
+
if (!ex || typeof ex.wasm_ctx_read_pixels !== 'function') {
|
|
230
|
+
throw new Error('wasm_ctx_read_pixels not found');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const len = width * height * 4;
|
|
234
|
+
if (!out || out.length < len) {
|
|
235
|
+
throw new Error(`output buffer too small (need ${len}, have ${out ? out.length : 0})`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const ptr = ex.wasm_alloc(len);
|
|
239
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for readPixels output');
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const code = ex.wasm_ctx_read_pixels(
|
|
243
|
+
this._ctxHandle,
|
|
244
|
+
x >>> 0,
|
|
245
|
+
y >>> 0,
|
|
246
|
+
width >>> 0,
|
|
247
|
+
height >>> 0,
|
|
248
|
+
format >>> 0,
|
|
249
|
+
type_ >>> 0,
|
|
250
|
+
ptr >>> 0,
|
|
251
|
+
len >>> 0
|
|
252
|
+
);
|
|
253
|
+
_checkErr(code, this._instance);
|
|
254
|
+
|
|
255
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
256
|
+
const src = mem.subarray(ptr, ptr + len);
|
|
257
|
+
out.set(src);
|
|
258
|
+
} finally {
|
|
259
|
+
ex.wasm_free(ptr);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// --- Stubs for unimplemented WebGL2 methods (forwarding API surface) ---
|
|
264
|
+
// These are intentionally not implemented in the prototype. They allow
|
|
265
|
+
// callers to detect missing functionality early with a uniform error.
|
|
266
|
+
|
|
267
|
+
createShader(type) {
|
|
268
|
+
this._assertNotDestroyed();
|
|
269
|
+
const ex = this._instance.exports;
|
|
270
|
+
if (!ex || typeof ex.wasm_ctx_create_shader !== 'function') {
|
|
271
|
+
throw new Error('wasm_ctx_create_shader not found');
|
|
272
|
+
}
|
|
273
|
+
const handle = ex.wasm_ctx_create_shader(this._ctxHandle, type >>> 0);
|
|
274
|
+
if (handle === 0) {
|
|
275
|
+
const msg = readErrorMessage(this._instance);
|
|
276
|
+
throw new Error(`Failed to create shader: ${msg}`);
|
|
277
|
+
}
|
|
278
|
+
return new WasmWebGLShader(this, handle);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
shaderSource(shader, source) {
|
|
282
|
+
this._assertNotDestroyed();
|
|
283
|
+
const ex = this._instance.exports;
|
|
284
|
+
if (!ex || typeof ex.wasm_ctx_shader_source !== 'function') {
|
|
285
|
+
throw new Error('wasm_ctx_shader_source not found');
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
289
|
+
const sourceStr = String(source);
|
|
290
|
+
const bytes = new TextEncoder().encode(sourceStr);
|
|
291
|
+
const len = bytes.length;
|
|
292
|
+
const ptr = ex.wasm_alloc(len);
|
|
293
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for shaderSource');
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
297
|
+
mem.set(bytes, ptr);
|
|
298
|
+
const code = ex.wasm_ctx_shader_source(this._ctxHandle, shaderHandle, ptr, len);
|
|
299
|
+
_checkErr(code, this._instance);
|
|
300
|
+
} finally {
|
|
301
|
+
ex.wasm_free(ptr);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
compileShader(shader) {
|
|
306
|
+
this._assertNotDestroyed();
|
|
307
|
+
const ex = this._instance.exports;
|
|
308
|
+
if (!ex || typeof ex.wasm_ctx_compile_shader !== 'function') {
|
|
309
|
+
throw new Error('wasm_ctx_compile_shader not found');
|
|
310
|
+
}
|
|
311
|
+
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
312
|
+
const code = ex.wasm_ctx_compile_shader(this._ctxHandle, shaderHandle);
|
|
313
|
+
_checkErr(code, this._instance);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
deleteShader(shader) {
|
|
317
|
+
this._assertNotDestroyed();
|
|
318
|
+
const ex = this._instance.exports;
|
|
319
|
+
if (!ex || typeof ex.wasm_ctx_delete_shader !== 'function') {
|
|
320
|
+
throw new Error('wasm_ctx_delete_shader not found');
|
|
321
|
+
}
|
|
322
|
+
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
323
|
+
const code = ex.wasm_ctx_delete_shader(this._ctxHandle, shaderHandle);
|
|
324
|
+
_checkErr(code, this._instance);
|
|
325
|
+
if (shader && typeof shader === 'object') {
|
|
326
|
+
try { shader._handle = 0; shader._deleted = true; } catch (e) { /* ignore */ }
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
createProgram() {
|
|
331
|
+
this._assertNotDestroyed();
|
|
332
|
+
const ex = this._instance.exports;
|
|
333
|
+
if (!ex || typeof ex.wasm_ctx_create_program !== 'function') {
|
|
334
|
+
throw new Error('wasm_ctx_create_program not found');
|
|
335
|
+
}
|
|
336
|
+
const handle = ex.wasm_ctx_create_program(this._ctxHandle);
|
|
337
|
+
if (handle === 0) {
|
|
338
|
+
const msg = readErrorMessage(this._instance);
|
|
339
|
+
throw new Error(`Failed to create program: ${msg}`);
|
|
340
|
+
}
|
|
341
|
+
return new WasmWebGLProgram(this, handle);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
attachShader(program, shader) {
|
|
345
|
+
this._assertNotDestroyed();
|
|
346
|
+
const ex = this._instance.exports;
|
|
347
|
+
if (!ex || typeof ex.wasm_ctx_attach_shader !== 'function') {
|
|
348
|
+
throw new Error('wasm_ctx_attach_shader not found');
|
|
349
|
+
}
|
|
350
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
351
|
+
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
352
|
+
const code = ex.wasm_ctx_attach_shader(this._ctxHandle, programHandle, shaderHandle);
|
|
353
|
+
_checkErr(code, this._instance);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
detachShader(program, shader) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
357
|
+
|
|
358
|
+
linkProgram(program) {
|
|
359
|
+
this._assertNotDestroyed();
|
|
360
|
+
const ex = this._instance.exports;
|
|
361
|
+
if (!ex || typeof ex.wasm_ctx_link_program !== 'function') {
|
|
362
|
+
throw new Error('wasm_ctx_link_program not found');
|
|
363
|
+
}
|
|
364
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
365
|
+
const code = ex.wasm_ctx_link_program(this._ctxHandle, programHandle);
|
|
366
|
+
_checkErr(code, this._instance);
|
|
367
|
+
|
|
368
|
+
// After linking, we need to instantiate the WASM modules on the host
|
|
369
|
+
if (program && typeof program === 'object') {
|
|
370
|
+
this._instantiateProgramShaders(program);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
_instantiateProgramShaders(program) {
|
|
375
|
+
const vsWasm = this.getProgramWasm(program, this.VERTEX_SHADER);
|
|
376
|
+
const fsWasm = this.getProgramWasm(program, this.FRAGMENT_SHADER);
|
|
377
|
+
|
|
378
|
+
if (vsWasm) {
|
|
379
|
+
try {
|
|
380
|
+
const vsModule = new WebAssembly.Module(vsWasm);
|
|
381
|
+
program._vsInstance = new WebAssembly.Instance(vsModule, {
|
|
382
|
+
env: {
|
|
383
|
+
memory: this._instance.exports.memory
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
} catch (e) {
|
|
387
|
+
console.log(`DEBUG: VS Instance creation failed: ${e}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (fsWasm) {
|
|
391
|
+
try {
|
|
392
|
+
const fsModule = new WebAssembly.Module(fsWasm);
|
|
393
|
+
program._fsInstance = new WebAssembly.Instance(fsModule, {
|
|
394
|
+
env: {
|
|
395
|
+
memory: this._instance.exports.memory
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
} catch (e) {
|
|
399
|
+
console.log(`DEBUG: FS Instance creation failed: ${e}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
deleteProgram(program) {
|
|
405
|
+
this._assertNotDestroyed();
|
|
406
|
+
const ex = this._instance.exports;
|
|
407
|
+
if (!ex || typeof ex.wasm_ctx_delete_program !== 'function') {
|
|
408
|
+
throw new Error('wasm_ctx_delete_program not found');
|
|
409
|
+
}
|
|
410
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
411
|
+
const code = ex.wasm_ctx_delete_program(this._ctxHandle, programHandle);
|
|
412
|
+
_checkErr(code, this._instance);
|
|
413
|
+
if (program && typeof program === 'object') {
|
|
414
|
+
try { program._handle = 0; program._deleted = true; } catch (e) { /* ignore */ }
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
useProgram(program) {
|
|
419
|
+
this._assertNotDestroyed();
|
|
420
|
+
const ex = this._instance.exports;
|
|
421
|
+
if (!ex || typeof ex.wasm_ctx_use_program !== 'function') {
|
|
422
|
+
throw new Error('wasm_ctx_use_program not found');
|
|
423
|
+
}
|
|
424
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
425
|
+
const code = ex.wasm_ctx_use_program(this._ctxHandle, programHandle);
|
|
426
|
+
_checkErr(code, this._instance);
|
|
427
|
+
this._currentProgram = program;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
getShaderParameter(shader, pname) {
|
|
431
|
+
this._assertNotDestroyed();
|
|
432
|
+
const ex = this._instance.exports;
|
|
433
|
+
if (!ex || typeof ex.wasm_ctx_get_shader_parameter !== 'function') {
|
|
434
|
+
throw new Error('wasm_ctx_get_shader_parameter not found');
|
|
435
|
+
}
|
|
436
|
+
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
437
|
+
const val = ex.wasm_ctx_get_shader_parameter(this._ctxHandle, shaderHandle, pname >>> 0);
|
|
438
|
+
|
|
439
|
+
// WebGL returns boolean for status parameters
|
|
440
|
+
if (pname === 0x8B81 /* COMPILE_STATUS */ || pname === 0x8B80 /* DELETE_STATUS */) {
|
|
441
|
+
return !!val;
|
|
442
|
+
}
|
|
443
|
+
return val;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
getProgramParameter(program, pname) {
|
|
447
|
+
this._assertNotDestroyed();
|
|
448
|
+
const ex = this._instance.exports;
|
|
449
|
+
if (!ex || typeof ex.wasm_ctx_get_program_parameter !== 'function') {
|
|
450
|
+
throw new Error('wasm_ctx_get_program_parameter not found');
|
|
451
|
+
}
|
|
452
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
453
|
+
const val = ex.wasm_ctx_get_program_parameter(this._ctxHandle, programHandle, pname >>> 0);
|
|
454
|
+
|
|
455
|
+
// WebGL returns boolean for status parameters
|
|
456
|
+
if (pname === 0x8B82 /* LINK_STATUS */ || pname === 0x8B80 /* DELETE_STATUS */ || pname === 0x8B83 /* VALIDATE_STATUS */) {
|
|
457
|
+
return !!val;
|
|
458
|
+
}
|
|
459
|
+
return val;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
getShaderInfoLog(shader) {
|
|
463
|
+
this._assertNotDestroyed();
|
|
464
|
+
const ex = this._instance.exports;
|
|
465
|
+
if (!ex || typeof ex.wasm_ctx_get_shader_info_log !== 'function') {
|
|
466
|
+
throw new Error('wasm_ctx_get_shader_info_log not found');
|
|
467
|
+
}
|
|
468
|
+
const shaderHandle = shader && typeof shader === 'object' && typeof shader._handle === 'number' ? shader._handle : (shader >>> 0);
|
|
469
|
+
|
|
470
|
+
const maxLen = 1024;
|
|
471
|
+
const ptr = ex.wasm_alloc(maxLen);
|
|
472
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for getShaderInfoLog');
|
|
473
|
+
|
|
474
|
+
try {
|
|
475
|
+
const len = ex.wasm_ctx_get_shader_info_log(this._ctxHandle, shaderHandle, ptr, maxLen);
|
|
476
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
477
|
+
const bytes = mem.subarray(ptr, ptr + len);
|
|
478
|
+
return new TextDecoder().decode(bytes);
|
|
479
|
+
} finally {
|
|
480
|
+
ex.wasm_free(ptr);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
getProgramInfoLog(program) {
|
|
485
|
+
this._assertNotDestroyed();
|
|
486
|
+
const ex = this._instance.exports;
|
|
487
|
+
if (!ex || typeof ex.wasm_ctx_get_program_info_log !== 'function') {
|
|
488
|
+
throw new Error('wasm_ctx_get_program_info_log not found');
|
|
489
|
+
}
|
|
490
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
491
|
+
|
|
492
|
+
const maxLen = 1024;
|
|
493
|
+
const ptr = ex.wasm_alloc(maxLen);
|
|
494
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for getProgramInfoLog');
|
|
495
|
+
|
|
496
|
+
try {
|
|
497
|
+
const len = ex.wasm_ctx_get_program_info_log(this._ctxHandle, programHandle, ptr, maxLen);
|
|
498
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
499
|
+
const bytes = mem.subarray(ptr, ptr + len);
|
|
500
|
+
return new TextDecoder().decode(bytes);
|
|
501
|
+
} finally {
|
|
502
|
+
ex.wasm_free(ptr);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
getProgramWasm(program, shaderType) {
|
|
507
|
+
this._assertNotDestroyed();
|
|
508
|
+
const ex = this._instance.exports;
|
|
509
|
+
if (!ex || typeof ex.wasm_ctx_get_program_wasm_len !== 'function') {
|
|
510
|
+
throw new Error('wasm_ctx_get_program_wasm_len not found');
|
|
511
|
+
}
|
|
512
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
513
|
+
const len = ex.wasm_ctx_get_program_wasm_len(this._ctxHandle, programHandle, shaderType);
|
|
514
|
+
if (len === 0) return null;
|
|
515
|
+
|
|
516
|
+
const ptr = ex.wasm_alloc(len);
|
|
517
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for getProgramWasm');
|
|
518
|
+
|
|
519
|
+
try {
|
|
520
|
+
const actualLen = ex.wasm_ctx_get_program_wasm(this._ctxHandle, programHandle, shaderType, ptr, len);
|
|
521
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
522
|
+
return new Uint8Array(mem.buffer, ptr, actualLen).slice();
|
|
523
|
+
} finally {
|
|
524
|
+
ex.wasm_free(ptr);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
getAttribLocation(program, name) {
|
|
529
|
+
this._assertNotDestroyed();
|
|
530
|
+
const ex = this._instance.exports;
|
|
531
|
+
if (!ex || typeof ex.wasm_ctx_get_attrib_location !== 'function') {
|
|
532
|
+
throw new Error('wasm_ctx_get_attrib_location not found');
|
|
533
|
+
}
|
|
534
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
535
|
+
const nameStr = String(name);
|
|
536
|
+
const bytes = new TextEncoder().encode(nameStr);
|
|
537
|
+
const len = bytes.length;
|
|
538
|
+
const ptr = ex.wasm_alloc(len);
|
|
539
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for getAttribLocation');
|
|
540
|
+
|
|
541
|
+
try {
|
|
542
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
543
|
+
mem.set(bytes, ptr);
|
|
544
|
+
return ex.wasm_ctx_get_attrib_location(this._ctxHandle, programHandle, ptr, len);
|
|
545
|
+
} finally {
|
|
546
|
+
ex.wasm_free(ptr);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
bindAttribLocation(program, index, name) {
|
|
551
|
+
this._assertNotDestroyed();
|
|
552
|
+
const ex = this._instance.exports;
|
|
553
|
+
if (!ex || typeof ex.wasm_ctx_bind_attrib_location !== 'function') {
|
|
554
|
+
throw new Error('wasm_ctx_bind_attrib_location not found');
|
|
555
|
+
}
|
|
556
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
557
|
+
const nameStr = String(name);
|
|
558
|
+
const bytes = new TextEncoder().encode(nameStr);
|
|
559
|
+
const len = bytes.length;
|
|
560
|
+
const ptr = ex.wasm_alloc(len);
|
|
561
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for bindAttribLocation');
|
|
562
|
+
|
|
563
|
+
try {
|
|
564
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
565
|
+
mem.set(bytes, ptr);
|
|
566
|
+
const code = ex.wasm_ctx_bind_attrib_location(this._ctxHandle, programHandle, index >>> 0, ptr, len);
|
|
567
|
+
_checkErr(code, this._instance);
|
|
568
|
+
} finally {
|
|
569
|
+
ex.wasm_free(ptr);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
enableVertexAttribArray(index) {
|
|
574
|
+
this._assertNotDestroyed();
|
|
575
|
+
const ex = this._instance.exports;
|
|
576
|
+
if (!ex || typeof ex.wasm_ctx_enable_vertex_attrib_array !== 'function') {
|
|
577
|
+
throw new Error('wasm_ctx_enable_vertex_attrib_array not found');
|
|
578
|
+
}
|
|
579
|
+
const code = ex.wasm_ctx_enable_vertex_attrib_array(this._ctxHandle, index >>> 0);
|
|
580
|
+
_checkErr(code, this._instance);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
disableVertexAttribArray(index) {
|
|
584
|
+
this._assertNotDestroyed();
|
|
585
|
+
const ex = this._instance.exports;
|
|
586
|
+
if (!ex || typeof ex.wasm_ctx_disable_vertex_attrib_array !== 'function') {
|
|
587
|
+
throw new Error('wasm_ctx_disable_vertex_attrib_array not found');
|
|
588
|
+
}
|
|
589
|
+
const code = ex.wasm_ctx_disable_vertex_attrib_array(this._ctxHandle, index >>> 0);
|
|
590
|
+
_checkErr(code, this._instance);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
vertexAttribPointer(index, size, type, normalized, stride, offset) {
|
|
594
|
+
this._assertNotDestroyed();
|
|
595
|
+
const ex = this._instance.exports;
|
|
596
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib_pointer !== 'function') {
|
|
597
|
+
throw new Error('wasm_ctx_vertex_attrib_pointer not found');
|
|
598
|
+
}
|
|
599
|
+
const code = ex.wasm_ctx_vertex_attrib_pointer(
|
|
600
|
+
this._ctxHandle,
|
|
601
|
+
index >>> 0,
|
|
602
|
+
size >>> 0,
|
|
603
|
+
type >>> 0,
|
|
604
|
+
normalized ? 1 : 0,
|
|
605
|
+
stride >>> 0,
|
|
606
|
+
offset >>> 0
|
|
607
|
+
);
|
|
608
|
+
_checkErr(code, this._instance);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
vertexAttrib1f(index, v0) {
|
|
612
|
+
this._assertNotDestroyed();
|
|
613
|
+
const ex = this._instance.exports;
|
|
614
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib1f !== 'function') {
|
|
615
|
+
throw new Error('wasm_ctx_vertex_attrib1f not found');
|
|
616
|
+
}
|
|
617
|
+
const code = ex.wasm_ctx_vertex_attrib1f(this._ctxHandle, index >>> 0, +v0);
|
|
618
|
+
_checkErr(code, this._instance);
|
|
619
|
+
}
|
|
620
|
+
vertexAttrib2f(index, v0, v1) {
|
|
621
|
+
this._assertNotDestroyed();
|
|
622
|
+
const ex = this._instance.exports;
|
|
623
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib2f !== 'function') {
|
|
624
|
+
throw new Error('wasm_ctx_vertex_attrib2f not found');
|
|
625
|
+
}
|
|
626
|
+
const code = ex.wasm_ctx_vertex_attrib2f(this._ctxHandle, index >>> 0, +v0, +v1);
|
|
627
|
+
_checkErr(code, this._instance);
|
|
628
|
+
}
|
|
629
|
+
vertexAttrib3f(index, v0, v1, v2) {
|
|
630
|
+
this._assertNotDestroyed();
|
|
631
|
+
const ex = this._instance.exports;
|
|
632
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib3f !== 'function') {
|
|
633
|
+
throw new Error('wasm_ctx_vertex_attrib3f not found');
|
|
634
|
+
}
|
|
635
|
+
const code = ex.wasm_ctx_vertex_attrib3f(this._ctxHandle, index >>> 0, +v0, +v1, +v2);
|
|
636
|
+
_checkErr(code, this._instance);
|
|
637
|
+
}
|
|
638
|
+
vertexAttrib4f(index, v0, v1, v2, v3) {
|
|
639
|
+
this._assertNotDestroyed();
|
|
640
|
+
const ex = this._instance.exports;
|
|
641
|
+
if (!ex || typeof ex.wasm_ctx_vertex_attrib4f !== 'function') {
|
|
642
|
+
throw new Error('wasm_ctx_vertex_attrib4f not found');
|
|
643
|
+
}
|
|
644
|
+
const code = ex.wasm_ctx_vertex_attrib4f(this._ctxHandle, index >>> 0, +v0, +v1, +v2, +v3);
|
|
645
|
+
_checkErr(code, this._instance);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
vertexAttribDivisor(index, divisor) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
649
|
+
|
|
650
|
+
createBuffer() {
|
|
651
|
+
this._assertNotDestroyed();
|
|
652
|
+
const ex = this._instance.exports;
|
|
653
|
+
if (!ex || typeof ex.wasm_ctx_create_buffer !== 'function') {
|
|
654
|
+
throw new Error('wasm_ctx_create_buffer not found');
|
|
655
|
+
}
|
|
656
|
+
const handle = ex.wasm_ctx_create_buffer(this._ctxHandle);
|
|
657
|
+
if (handle === 0) {
|
|
658
|
+
const msg = readErrorMessage(this._instance);
|
|
659
|
+
throw new Error(`Failed to create buffer: ${msg}`);
|
|
660
|
+
}
|
|
661
|
+
return new WasmWebGLBuffer(this, handle);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
bindBuffer(target, buffer) {
|
|
665
|
+
this._assertNotDestroyed();
|
|
666
|
+
const ex = this._instance.exports;
|
|
667
|
+
if (!ex || typeof ex.wasm_ctx_bind_buffer !== 'function') {
|
|
668
|
+
throw new Error('wasm_ctx_bind_buffer not found');
|
|
669
|
+
}
|
|
670
|
+
const handle = buffer && typeof buffer === 'object' && typeof buffer._handle === 'number' ? buffer._handle : (buffer >>> 0);
|
|
671
|
+
const code = ex.wasm_ctx_bind_buffer(this._ctxHandle, target >>> 0, handle);
|
|
672
|
+
_checkErr(code, this._instance);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
deleteBuffer(buffer) {
|
|
676
|
+
this._assertNotDestroyed();
|
|
677
|
+
const ex = this._instance.exports;
|
|
678
|
+
if (!ex || typeof ex.wasm_ctx_delete_buffer !== 'function') {
|
|
679
|
+
throw new Error('wasm_ctx_delete_buffer not found');
|
|
680
|
+
}
|
|
681
|
+
const handle = buffer && typeof buffer === 'object' && typeof buffer._handle === 'number' ? buffer._handle : (buffer >>> 0);
|
|
682
|
+
const code = ex.wasm_ctx_delete_buffer(this._ctxHandle, handle);
|
|
683
|
+
_checkErr(code, this._instance); if (buffer && typeof buffer === 'object') {
|
|
684
|
+
try { buffer._handle = 0; buffer._deleted = true; } catch (e) { /* ignore */ }
|
|
685
|
+
} }
|
|
686
|
+
|
|
687
|
+
bufferData(target, data, usage) {
|
|
688
|
+
this._assertNotDestroyed();
|
|
689
|
+
const ex = this._instance.exports;
|
|
690
|
+
if (!ex || typeof ex.wasm_ctx_buffer_data !== 'function') {
|
|
691
|
+
throw new Error('wasm_ctx_buffer_data not found');
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
let bytes;
|
|
695
|
+
if (data instanceof ArrayBuffer) {
|
|
696
|
+
bytes = new Uint8Array(data);
|
|
697
|
+
} else if (ArrayBuffer.isView(data)) {
|
|
698
|
+
bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
699
|
+
} else if (typeof data === 'number') {
|
|
700
|
+
bytes = new Uint8Array(data);
|
|
701
|
+
} else {
|
|
702
|
+
throw new Error('Invalid data type for bufferData');
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
const len = bytes.length;
|
|
706
|
+
const ptr = ex.wasm_alloc(len);
|
|
707
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for bufferData');
|
|
708
|
+
|
|
709
|
+
try {
|
|
710
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
711
|
+
mem.set(bytes, ptr);
|
|
712
|
+
const code = ex.wasm_ctx_buffer_data(this._ctxHandle, target >>> 0, ptr, len, usage >>> 0);
|
|
713
|
+
_checkErr(code, this._instance);
|
|
714
|
+
} finally {
|
|
715
|
+
ex.wasm_free(ptr);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
bufferSubData(target, offset, data) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
720
|
+
copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
721
|
+
getBufferParameter(target, pname) {
|
|
722
|
+
this._assertNotDestroyed();
|
|
723
|
+
const ex = this._instance.exports;
|
|
724
|
+
if (!ex || typeof ex.wasm_ctx_get_buffer_parameter !== 'function') {
|
|
725
|
+
throw new Error('wasm_ctx_get_buffer_parameter not found');
|
|
726
|
+
}
|
|
727
|
+
const val = ex.wasm_ctx_get_buffer_parameter(this._ctxHandle, target >>> 0, pname >>> 0);
|
|
728
|
+
if (val < 0) {
|
|
729
|
+
const msg = readErrorMessage(this._instance);
|
|
730
|
+
throw new Error(`getBufferParameter failed: ${msg}`);
|
|
731
|
+
}
|
|
732
|
+
return val;
|
|
733
|
+
}
|
|
734
|
+
isBuffer(buffer) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
735
|
+
|
|
736
|
+
drawArrays(mode, first, count) {
|
|
737
|
+
this._assertNotDestroyed();
|
|
738
|
+
const ex = this._instance.exports;
|
|
739
|
+
if (!ex || typeof ex.wasm_ctx_draw_arrays !== 'function') {
|
|
740
|
+
throw new Error('wasm_ctx_draw_arrays not found');
|
|
741
|
+
}
|
|
742
|
+
const code = ex.wasm_ctx_draw_arrays(this._ctxHandle, mode >>> 0, first >>> 0, count >>> 0);
|
|
743
|
+
_checkErr(code, this._instance);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
drawElements(mode, count, type, offset) {
|
|
747
|
+
this._assertNotDestroyed();
|
|
748
|
+
const ex = this._instance.exports;
|
|
749
|
+
if (!ex || typeof ex.wasm_ctx_draw_elements !== 'function') {
|
|
750
|
+
throw new Error('wasm_ctx_draw_elements not found');
|
|
751
|
+
}
|
|
752
|
+
const code = ex.wasm_ctx_draw_elements(this._ctxHandle, mode >>> 0, count >>> 0, type >>> 0, offset >>> 0);
|
|
753
|
+
_checkErr(code, this._instance);
|
|
754
|
+
}
|
|
755
|
+
drawArraysInstanced(mode, first, count, instanceCount) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
756
|
+
drawElementsInstanced(mode, count, type, offset, instanceCount) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
757
|
+
drawRangeElements(mode, start, end, count, type, offset) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
758
|
+
drawBuffers(buffers) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
759
|
+
|
|
760
|
+
createVertexArray() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
761
|
+
bindVertexArray(vao) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
762
|
+
deleteVertexArray(vao) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
763
|
+
isVertexArray(vao) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
764
|
+
|
|
765
|
+
createTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
766
|
+
bindTransformFeedback(target, tf) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
767
|
+
beginTransformFeedback(primitiveMode) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
768
|
+
pauseTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
769
|
+
resumeTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
770
|
+
endTransformFeedback() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
771
|
+
transformFeedbackVaryings(program, varyings, bufferMode) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
772
|
+
getTransformFeedbackVarying(program, index) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
773
|
+
|
|
774
|
+
createQuery() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
775
|
+
deleteQuery(q) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
776
|
+
beginQuery(target, id) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
777
|
+
endQuery(target) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
778
|
+
getQueryParameter(query, pname) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
779
|
+
|
|
780
|
+
fenceSync(condition, flags) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
781
|
+
clientWaitSync(sync, flags, timeout) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
782
|
+
waitSync(sync, flags, timeout) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
783
|
+
deleteSync(sync) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
784
|
+
getSyncParameter(sync, pname) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
785
|
+
|
|
786
|
+
createSampler() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
787
|
+
deleteSampler(s) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
788
|
+
bindSampler(unit, sampler) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
789
|
+
samplerParameteri(sampler, pname, param) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
790
|
+
samplerParameterf(sampler, pname, param) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
791
|
+
|
|
792
|
+
activeTexture(texture) {
|
|
793
|
+
this._assertNotDestroyed();
|
|
794
|
+
const ex = this._instance.exports;
|
|
795
|
+
if (!ex || typeof ex.wasm_ctx_active_texture !== 'function') {
|
|
796
|
+
throw new Error('wasm_ctx_active_texture not found');
|
|
797
|
+
}
|
|
798
|
+
const code = ex.wasm_ctx_active_texture(this._ctxHandle, texture >>> 0);
|
|
799
|
+
_checkErr(code, this._instance);
|
|
800
|
+
}
|
|
801
|
+
texParameteri(target, pname, param) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
802
|
+
generateMipmap(target) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
803
|
+
copyTexImage2D(target, level, internalformat, x, y, width, height, border) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
804
|
+
copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
805
|
+
texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
806
|
+
|
|
807
|
+
createRenderbuffer() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
808
|
+
bindRenderbuffer(target, rb) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
809
|
+
deleteRenderbuffer(rb) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
810
|
+
renderbufferStorage(target, internalformat, width, height) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
811
|
+
framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
812
|
+
checkFramebufferStatus(target) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
813
|
+
blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
814
|
+
readBuffer(src) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
815
|
+
|
|
816
|
+
pixelStorei(pname, param) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
817
|
+
getExtension(name) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
818
|
+
getSupportedExtensions() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
819
|
+
|
|
820
|
+
getUniformLocation(program, name) {
|
|
821
|
+
this._assertNotDestroyed();
|
|
822
|
+
const ex = this._instance.exports;
|
|
823
|
+
if (!ex || typeof ex.wasm_ctx_get_uniform_location !== 'function') {
|
|
824
|
+
throw new Error('wasm_ctx_get_uniform_location not found');
|
|
825
|
+
}
|
|
826
|
+
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
827
|
+
const nameStr = String(name);
|
|
828
|
+
const bytes = new TextEncoder().encode(nameStr);
|
|
829
|
+
const len = bytes.length;
|
|
830
|
+
const ptr = ex.wasm_alloc(len);
|
|
831
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for getUniformLocation');
|
|
832
|
+
|
|
833
|
+
try {
|
|
834
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
835
|
+
mem.set(bytes, ptr);
|
|
836
|
+
const loc = ex.wasm_ctx_get_uniform_location(this._ctxHandle, programHandle, ptr, len);
|
|
837
|
+
return loc === -1 ? null : loc;
|
|
838
|
+
} finally {
|
|
839
|
+
ex.wasm_free(ptr);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
uniform1f(loc, x) {
|
|
844
|
+
this._assertNotDestroyed();
|
|
845
|
+
const ex = this._instance.exports;
|
|
846
|
+
if (!ex || typeof ex.wasm_ctx_uniform1f !== 'function') {
|
|
847
|
+
throw new Error('wasm_ctx_uniform1f not found');
|
|
848
|
+
}
|
|
849
|
+
const locHandle = loc === null ? -1 : (typeof loc === 'number' ? loc : (loc._handle >>> 0));
|
|
850
|
+
const code = ex.wasm_ctx_uniform1f(this._ctxHandle, locHandle, +x);
|
|
851
|
+
_checkErr(code, this._instance);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
uniform2f(loc, x, y) {
|
|
855
|
+
this._assertNotDestroyed();
|
|
856
|
+
const ex = this._instance.exports;
|
|
857
|
+
if (!ex || typeof ex.wasm_ctx_uniform2f !== 'function') {
|
|
858
|
+
throw new Error('wasm_ctx_uniform2f not found');
|
|
859
|
+
}
|
|
860
|
+
const locHandle = loc === null ? -1 : (typeof loc === 'number' ? loc : (loc._handle >>> 0));
|
|
861
|
+
const code = ex.wasm_ctx_uniform2f(this._ctxHandle, locHandle, +x, +y);
|
|
862
|
+
_checkErr(code, this._instance);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
uniform3f(loc, x, y, z) {
|
|
866
|
+
this._assertNotDestroyed();
|
|
867
|
+
const ex = this._instance.exports;
|
|
868
|
+
if (!ex || typeof ex.wasm_ctx_uniform3f !== 'function') {
|
|
869
|
+
throw new Error('wasm_ctx_uniform3f not found');
|
|
870
|
+
}
|
|
871
|
+
const locHandle = loc === null ? -1 : (typeof loc === 'number' ? loc : (loc._handle >>> 0));
|
|
872
|
+
const code = ex.wasm_ctx_uniform3f(this._ctxHandle, locHandle, +x, +y, +z);
|
|
873
|
+
_checkErr(code, this._instance);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
uniform4f(loc, x, y, z, w) {
|
|
877
|
+
this._assertNotDestroyed();
|
|
878
|
+
const ex = this._instance.exports;
|
|
879
|
+
if (!ex || typeof ex.wasm_ctx_uniform4f !== 'function') {
|
|
880
|
+
throw new Error('wasm_ctx_uniform4f not found');
|
|
881
|
+
}
|
|
882
|
+
const locHandle = loc === null ? -1 : (typeof loc === 'number' ? loc : (loc._handle >>> 0));
|
|
883
|
+
const code = ex.wasm_ctx_uniform4f(this._ctxHandle, locHandle, +x, +y, +z, +w);
|
|
884
|
+
_checkErr(code, this._instance);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
uniform1i(loc, x) {
|
|
888
|
+
this._assertNotDestroyed();
|
|
889
|
+
const ex = this._instance.exports;
|
|
890
|
+
if (!ex || typeof ex.wasm_ctx_uniform1i !== 'function') {
|
|
891
|
+
throw new Error('wasm_ctx_uniform1i not found');
|
|
892
|
+
}
|
|
893
|
+
const locHandle = loc === null ? -1 : (typeof loc === 'number' ? loc : (loc._handle >>> 0));
|
|
894
|
+
const code = ex.wasm_ctx_uniform1i(this._ctxHandle, locHandle, x | 0);
|
|
895
|
+
_checkErr(code, this._instance);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
uniformMatrix4fv(loc, transpose, value) {
|
|
899
|
+
this._assertNotDestroyed();
|
|
900
|
+
const ex = this._instance.exports;
|
|
901
|
+
if (!ex || typeof ex.wasm_ctx_uniform_matrix_4fv !== 'function') {
|
|
902
|
+
throw new Error('wasm_ctx_uniform_matrix_4fv not found');
|
|
903
|
+
}
|
|
904
|
+
const locHandle = loc === null ? -1 : (typeof loc === 'number' ? loc : (loc._handle >>> 0));
|
|
905
|
+
|
|
906
|
+
let bytes;
|
|
907
|
+
if (value instanceof Float32Array) {
|
|
908
|
+
bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
909
|
+
} else {
|
|
910
|
+
bytes = new Uint8Array(new Float32Array(value).buffer);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
const len = bytes.length;
|
|
914
|
+
const ptr = ex.wasm_alloc(len);
|
|
915
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for uniformMatrix4fv');
|
|
916
|
+
|
|
917
|
+
try {
|
|
918
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
919
|
+
mem.set(bytes, ptr);
|
|
920
|
+
const code = ex.wasm_ctx_uniform_matrix_4fv(this._ctxHandle, locHandle, transpose ? 1 : 0, ptr, len);
|
|
921
|
+
_checkErr(code, this._instance);
|
|
922
|
+
} finally {
|
|
923
|
+
ex.wasm_free(ptr);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
getActiveUniform(program, index) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
927
|
+
getActiveAttrib(program, index) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
928
|
+
|
|
929
|
+
getParameter(pname) {
|
|
930
|
+
this._assertNotDestroyed();
|
|
931
|
+
const ex = this._instance.exports;
|
|
932
|
+
if (!ex || typeof ex.wasm_ctx_get_parameter_v !== 'function') {
|
|
933
|
+
throw new Error('wasm_ctx_get_parameter_v not found');
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
if (pname === 0x0BA2 /* VIEWPORT */) {
|
|
937
|
+
const ptr = ex.wasm_alloc(16);
|
|
938
|
+
try {
|
|
939
|
+
const code = ex.wasm_ctx_get_parameter_v(this._ctxHandle, pname, ptr, 16);
|
|
940
|
+
_checkErr(code, this._instance);
|
|
941
|
+
const mem = new Int32Array(ex.memory.buffer, ptr, 4);
|
|
942
|
+
return new Int32Array(mem);
|
|
943
|
+
} finally {
|
|
944
|
+
ex.wasm_free(ptr, 16);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
if (pname === 0x0C22 /* COLOR_CLEAR_VALUE */) {
|
|
949
|
+
const ptr = ex.wasm_alloc(16);
|
|
950
|
+
try {
|
|
951
|
+
const code = ex.wasm_ctx_get_parameter_v(this._ctxHandle, pname, ptr, 16);
|
|
952
|
+
_checkErr(code, this._instance);
|
|
953
|
+
const mem = new Float32Array(ex.memory.buffer, ptr, 4);
|
|
954
|
+
return new Float32Array(mem);
|
|
955
|
+
} finally {
|
|
956
|
+
ex.wasm_free(ptr, 16);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
throw new Error(`getParameter for ${pname} not implemented`);
|
|
961
|
+
}
|
|
962
|
+
getError() {
|
|
963
|
+
this._assertNotDestroyed();
|
|
964
|
+
const ex = this._instance.exports;
|
|
965
|
+
if (!ex || typeof ex.wasm_ctx_get_error !== 'function') {
|
|
966
|
+
throw new Error('wasm_ctx_get_error not found');
|
|
967
|
+
}
|
|
968
|
+
return ex.wasm_ctx_get_error(this._ctxHandle);
|
|
969
|
+
}
|
|
970
|
+
finish() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
971
|
+
flush() { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
972
|
+
|
|
973
|
+
isTexture(tex) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
974
|
+
isFramebuffer(fb) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
975
|
+
isProgram(p) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
976
|
+
isShader(s) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
977
|
+
enable(cap) {
|
|
978
|
+
this._assertNotDestroyed();
|
|
979
|
+
const ex = this._instance.exports;
|
|
980
|
+
if (!ex || typeof ex.wasm_ctx_enable !== 'function') {
|
|
981
|
+
throw new Error('wasm_ctx_enable not found');
|
|
982
|
+
}
|
|
983
|
+
const code = ex.wasm_ctx_enable(this._ctxHandle, cap >>> 0);
|
|
984
|
+
_checkErr(code, this._instance);
|
|
985
|
+
}
|
|
986
|
+
disable(cap) {
|
|
987
|
+
this._assertNotDestroyed();
|
|
988
|
+
const ex = this._instance.exports;
|
|
989
|
+
if (!ex || typeof ex.wasm_ctx_disable !== 'function') {
|
|
990
|
+
throw new Error('wasm_ctx_disable not found');
|
|
991
|
+
}
|
|
992
|
+
const code = ex.wasm_ctx_disable(this._ctxHandle, cap >>> 0);
|
|
993
|
+
_checkErr(code, this._instance);
|
|
994
|
+
}
|
|
995
|
+
isEnabled(cap) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
996
|
+
|
|
997
|
+
viewport(x, y, width, height) {
|
|
998
|
+
this._assertNotDestroyed();
|
|
999
|
+
const ex = this._instance.exports;
|
|
1000
|
+
if (!ex || typeof ex.wasm_ctx_viewport !== 'function') {
|
|
1001
|
+
throw new Error('wasm_ctx_viewport not found');
|
|
1002
|
+
}
|
|
1003
|
+
const code = ex.wasm_ctx_viewport(this._ctxHandle, x >>> 0, y >>> 0, width >>> 0, height >>> 0);
|
|
1004
|
+
_checkErr(code, this._instance);
|
|
1005
|
+
}
|
|
1006
|
+
scissor(x, y, width, height) {
|
|
1007
|
+
this._assertNotDestroyed();
|
|
1008
|
+
const ex = this._instance.exports;
|
|
1009
|
+
if (!ex || typeof ex.wasm_ctx_scissor !== 'function') {
|
|
1010
|
+
throw new Error('wasm_ctx_scissor not found');
|
|
1011
|
+
}
|
|
1012
|
+
const code = ex.wasm_ctx_scissor(this._ctxHandle, x | 0, y | 0, width >>> 0, height >>> 0);
|
|
1013
|
+
_checkErr(code, this._instance);
|
|
1014
|
+
}
|
|
1015
|
+
clear(mask) {
|
|
1016
|
+
this._assertNotDestroyed();
|
|
1017
|
+
const ex = this._instance.exports;
|
|
1018
|
+
if (!ex || typeof ex.wasm_ctx_clear !== 'function') {
|
|
1019
|
+
throw new Error('wasm_ctx_clear not found');
|
|
1020
|
+
}
|
|
1021
|
+
const code = ex.wasm_ctx_clear(this._ctxHandle, mask >>> 0);
|
|
1022
|
+
_checkErr(code, this._instance);
|
|
1023
|
+
}
|
|
1024
|
+
clearColor(r, g, b, a) {
|
|
1025
|
+
this._assertNotDestroyed();
|
|
1026
|
+
const ex = this._instance.exports;
|
|
1027
|
+
if (!ex || typeof ex.wasm_ctx_clear_color !== 'function') {
|
|
1028
|
+
throw new Error('wasm_ctx_clear_color not found');
|
|
1029
|
+
}
|
|
1030
|
+
const code = ex.wasm_ctx_clear_color(this._ctxHandle, +r, +g, +b, +a);
|
|
1031
|
+
_checkErr(code, this._instance);
|
|
1032
|
+
}
|
|
1033
|
+
clearDepth(depth) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1034
|
+
depthFunc(func) {
|
|
1035
|
+
this._assertNotDestroyed();
|
|
1036
|
+
const ex = this._instance.exports;
|
|
1037
|
+
if (!ex || typeof ex.wasm_ctx_depth_func !== 'function') {
|
|
1038
|
+
throw new Error('wasm_ctx_depth_func not found');
|
|
1039
|
+
}
|
|
1040
|
+
const code = ex.wasm_ctx_depth_func(this._ctxHandle, func >>> 0);
|
|
1041
|
+
_checkErr(code, this._instance);
|
|
1042
|
+
}
|
|
1043
|
+
depthMask(flag) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1044
|
+
colorMask(r, g, b, a) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1045
|
+
polygonOffset(factor, units) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1046
|
+
sampleCoverage(value, invert) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1047
|
+
stencilFunc(func, ref, mask) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1048
|
+
stencilOp(fail, zfail, zpass) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1049
|
+
stencilMask(mask) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1050
|
+
blendFunc(sfactor, dfactor) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1051
|
+
blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1052
|
+
blendEquation(mode) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1053
|
+
blendEquationSeparate(modeRGB, modeAlpha) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1054
|
+
|
|
1055
|
+
get verbosity() {
|
|
1056
|
+
this._assertNotDestroyed();
|
|
1057
|
+
// We don't have a getter in WASM yet, so we'd need to track it or add one.
|
|
1058
|
+
// For now, let's just return a default or track it in JS.
|
|
1059
|
+
return this._verbosity || 0;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
set verbosity(level) {
|
|
1063
|
+
this._assertNotDestroyed();
|
|
1064
|
+
const ex = this._instance.exports;
|
|
1065
|
+
if (ex && typeof ex.wasm_ctx_set_verbosity === 'function') {
|
|
1066
|
+
ex.wasm_ctx_set_verbosity(this._ctxHandle, level >>> 0);
|
|
1067
|
+
}
|
|
1068
|
+
this._verbosity = level;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/**
|
|
1073
|
+
* Thin wrapper for a WebGLTexture handle returned from WASM.
|
|
1074
|
+
* Holds a reference to the originating WasmWebGL2RenderingContext and the numeric handle.
|
|
1075
|
+
*/
|
|
1076
|
+
// WebGLTexture wrapper moved to `src/webgl2_texture.js`.
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* Read an error message from WASM memory and return it as string.
|
|
1080
|
+
* Exported so callers outside this module can report errors.
|
|
1081
|
+
* @param {WebAssembly.Instance} instance
|
|
1082
|
+
* @returns {string}
|
|
1083
|
+
*/
|
|
1084
|
+
export function readErrorMessage(instance) {
|
|
1085
|
+
const ex = instance.exports;
|
|
1086
|
+
if (!ex || typeof ex.wasm_last_error_ptr !== 'function' || typeof ex.wasm_last_error_len !== 'function') {
|
|
1087
|
+
return '(no error message available)';
|
|
1088
|
+
}
|
|
1089
|
+
const ptr = ex.wasm_last_error_ptr();
|
|
1090
|
+
const len = ex.wasm_last_error_len();
|
|
1091
|
+
if (ptr === 0 || len === 0) {
|
|
1092
|
+
return '';
|
|
1093
|
+
}
|
|
1094
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
1095
|
+
const bytes = mem.subarray(ptr, ptr + len);
|
|
1096
|
+
return new TextDecoder('utf-8').decode(bytes);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
function _checkErr(code, instance) {
|
|
1100
|
+
if (code === ERR_OK) return;
|
|
1101
|
+
const msg = readErrorMessage(instance);
|
|
1102
|
+
throw new Error(`WASM error ${code}: ${msg}`);
|
|
1103
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrapper for a WebGLShader handle returned from WASM.
|
|
3
|
+
* @implements {WebGLShader}
|
|
4
|
+
*/
|
|
5
|
+
export class WasmWebGLShader {
|
|
6
|
+
/**
|
|
7
|
+
* @param {import('./webgl2_context.js').WasmWebGL2RenderingContext} ctx
|
|
8
|
+
* @param {number} handle
|
|
9
|
+
*/
|
|
10
|
+
constructor(ctx, handle) {
|
|
11
|
+
this._ctx = ctx;
|
|
12
|
+
this._handle = handle;
|
|
13
|
+
this._deleted = false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Thin wrapper for a WebGLProgram handle returned from WASM.
|
|
19
|
+
* @implements {WebGLProgram}
|
|
20
|
+
*/
|
|
21
|
+
export class WasmWebGLProgram {
|
|
22
|
+
/**
|
|
23
|
+
* @param {import('./webgl2_context.js').WasmWebGL2RenderingContext} ctx
|
|
24
|
+
* @param {number} handle
|
|
25
|
+
*/
|
|
26
|
+
constructor(ctx, handle) {
|
|
27
|
+
this._ctx = ctx;
|
|
28
|
+
this._handle = handle;
|
|
29
|
+
this._deleted = false;
|
|
30
|
+
/** @type {WebAssembly.Instance | null} */
|
|
31
|
+
this._vsInstance = null;
|
|
32
|
+
/** @type {WebAssembly.Instance | null} */
|
|
33
|
+
this._fsInstance = null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Thin wrapper for a WebGLBuffer handle returned from WASM.
|
|
39
|
+
* @implements {WebGLBuffer}
|
|
40
|
+
*/
|
|
41
|
+
export class WasmWebGLBuffer {
|
|
42
|
+
/**
|
|
43
|
+
* @param {import('./webgl2_context.js').WasmWebGL2RenderingContext} ctx
|
|
44
|
+
* @param {number} handle
|
|
45
|
+
*/
|
|
46
|
+
constructor(ctx, handle) {
|
|
47
|
+
this._ctx = ctx;
|
|
48
|
+
this._handle = handle;
|
|
49
|
+
this._deleted = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrapper for a WebGLTexture handle returned from WASM.
|
|
3
|
+
* @implements {WebGLTexture}
|
|
4
|
+
*/
|
|
5
|
+
export class WasmWebGLTexture {
|
|
6
|
+
/**
|
|
7
|
+
* @param {import('./webgl2_context.js').WasmWebGL2RenderingContext} ctx
|
|
8
|
+
* @param {number} handle
|
|
9
|
+
*/
|
|
10
|
+
constructor(ctx, handle) {
|
|
11
|
+
this._ctx = ctx;
|
|
12
|
+
this._handle = handle;
|
|
13
|
+
this._deleted = false;
|
|
14
|
+
}
|
|
15
|
+
}
|