@gjsify/webgl 0.3.12 → 0.3.14

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 (55) hide show
  1. package/lib/esm/conformance/attribs.spec.js +312 -293
  2. package/lib/esm/conformance/buffers.spec.js +217 -200
  3. package/lib/esm/conformance/context.spec.js +295 -295
  4. package/lib/esm/conformance/programs.spec.js +458 -445
  5. package/lib/esm/conformance/rendering-basic.spec.js +134 -128
  6. package/lib/esm/conformance/rendering.spec.js +502 -400
  7. package/lib/esm/conformance/setup.js +42 -31
  8. package/lib/esm/conformance/state.spec.js +360 -343
  9. package/lib/esm/conformance/textures.spec.js +330 -338
  10. package/lib/esm/conformance/uniforms.spec.js +465 -309
  11. package/lib/esm/conformance-test.js +24 -22
  12. package/lib/esm/extensions/ext-blend-minmax.js +16 -16
  13. package/lib/esm/extensions/ext-color-buffer-float.js +10 -11
  14. package/lib/esm/extensions/ext-color-buffer-half-float.js +10 -11
  15. package/lib/esm/extensions/ext-texture-filter-anisotropic.js +16 -16
  16. package/lib/esm/extensions/oes-element-index-unit.js +11 -12
  17. package/lib/esm/extensions/oes-standard-derivatives.js +15 -15
  18. package/lib/esm/extensions/oes-texture-float-linear.js +11 -12
  19. package/lib/esm/extensions/oes-texture-float.js +11 -12
  20. package/lib/esm/extensions/oes-texture-half-float.js +17 -17
  21. package/lib/esm/extensions/stackgl-destroy-context.js +10 -10
  22. package/lib/esm/extensions/stackgl-resize-drawing-buffer.js +10 -10
  23. package/lib/esm/html-canvas-element.js +64 -64
  24. package/lib/esm/index.js +29 -26
  25. package/lib/esm/linkable.js +49 -49
  26. package/lib/esm/test-utils.js +158 -107
  27. package/lib/esm/test.js +8 -4
  28. package/lib/esm/types/index.js +5 -5
  29. package/lib/esm/utils.js +164 -187
  30. package/lib/esm/webgl-active-info.js +10 -9
  31. package/lib/esm/webgl-bridge.js +162 -147
  32. package/lib/esm/webgl-buffer.js +17 -15
  33. package/lib/esm/webgl-context-attributes.js +23 -22
  34. package/lib/esm/webgl-context-base.js +3039 -3351
  35. package/lib/esm/webgl-drawing-buffer-wrapper.js +10 -9
  36. package/lib/esm/webgl-framebuffer.js +108 -106
  37. package/lib/esm/webgl-program.js +25 -23
  38. package/lib/esm/webgl-query.js +15 -13
  39. package/lib/esm/webgl-renderbuffer.js +23 -21
  40. package/lib/esm/webgl-rendering-context.js +173 -187
  41. package/lib/esm/webgl-sampler.js +15 -13
  42. package/lib/esm/webgl-shader-precision-format.js +10 -9
  43. package/lib/esm/webgl-shader.js +23 -21
  44. package/lib/esm/webgl-sync.js +15 -13
  45. package/lib/esm/webgl-texture-unit.js +12 -11
  46. package/lib/esm/webgl-texture.js +21 -19
  47. package/lib/esm/webgl-transform-feedback.js +15 -13
  48. package/lib/esm/webgl-uniform-location.js +14 -13
  49. package/lib/esm/webgl-vertex-array-object.js +20 -18
  50. package/lib/esm/webgl-vertex-attribute.js +149 -145
  51. package/lib/esm/webgl1.spec.js +1039 -650
  52. package/lib/esm/webgl2-rendering-context.js +1210 -1273
  53. package/lib/esm/webgl2.spec.js +1284 -1252
  54. package/package.json +9 -9
  55. package/lib/esm/@types/glsl-tokenizer/index.d.js +0 -0
@@ -1,9 +1,11 @@
1
- import { describe, it, expect, beforeEach, on } from "@gjsify/unit";
2
1
  import { makeProgram } from "../test-utils.js";
3
2
  import { createGLSetup } from "./setup.js";
3
+ import { beforeEach, describe, expect, it, on } from "@gjsify/unit";
4
+
5
+ //#region src/ts/conformance/uniforms.spec.ts
4
6
  const VS = `attribute vec4 a_position; void main() { gl_Position = a_position; }`;
5
7
  function makeFS(body) {
6
- return `precision mediump float; ${body}`;
8
+ return `precision mediump float; ${body}`;
7
9
  }
8
10
  const FS_FLOAT = makeFS("uniform float u_f; void main() { gl_FragColor = vec4(u_f,0,0,1); }");
9
11
  const FS_INT = makeFS("uniform int u_i; void main() { gl_FragColor = vec4(float(u_i),0,0,1); }");
@@ -16,313 +18,467 @@ const FS_MAT3 = makeFS("uniform mat3 u_m3; void main() { gl_FragColor = vec4(u_m
16
18
  const FS_MAT4 = makeFS("uniform mat4 u_m4; void main() { gl_FragColor = u_m4[0]; }");
17
19
  const FS_ARR = makeFS("uniform float u_arr[3]; void main() { gl_FragColor = vec4(u_arr[0]+u_arr[1]+u_arr[2],0,0,1); }");
18
20
  const FS_VEC4ARR = makeFS("uniform vec4 u_v4arr[3]; void main() { gl_FragColor = u_v4arr[0]+u_v4arr[1]+u_v4arr[2]; }");
19
- function floatArrayClose(a, b, tol = 1e-3) {
20
- if (a.length !== b.length) return false;
21
- for (let i = 0; i < b.length; i++) {
22
- if (Math.abs(a[i] - b[i]) > tol) return false;
23
- }
24
- return true;
21
+ function floatArrayClose(a, b, tol = .001) {
22
+ if (a.length !== b.length) return false;
23
+ for (let i = 0; i < b.length; i++) {
24
+ if (Math.abs(a[i] - b[i]) > tol) return false;
25
+ }
26
+ return true;
25
27
  }
26
28
  var uniforms_spec_default = async () => {
27
- await on("Display", async () => {
28
- const setup = createGLSetup();
29
- if (!setup) {
30
- console.warn("WebGL context not available \u2014 skipping conformance/uniforms tests");
31
- return;
32
- }
33
- const { gl, glArea } = setup;
34
- glArea.make_current();
35
- await describe("conformance/uniforms/null-uniform-location", async () => {
36
- beforeEach(async () => {
37
- glArea.make_current();
38
- });
39
- await it("uniform* with null location generates NO_ERROR", async () => {
40
- const prog = makeProgram(gl, VS, FS_FLOAT);
41
- gl.useProgram(prog);
42
- gl.uniform1f(null, 1);
43
- gl.getError();
44
- gl.uniform1fv(null, [1]);
45
- gl.getError();
46
- gl.uniform1i(null, 1);
47
- gl.getError();
48
- gl.uniform1iv(null, [1]);
49
- gl.getError();
50
- gl.uniform2f(null, 1, 2);
51
- gl.getError();
52
- gl.uniform2fv(null, [1, 2]);
53
- gl.getError();
54
- gl.uniform2i(null, 1, 2);
55
- gl.getError();
56
- gl.uniform2iv(null, [1, 2]);
57
- gl.getError();
58
- gl.uniform3f(null, 1, 2, 3);
59
- gl.getError();
60
- gl.uniform3fv(null, [1, 2, 3]);
61
- gl.getError();
62
- gl.uniform3i(null, 1, 2, 3);
63
- gl.getError();
64
- gl.uniform3iv(null, [1, 2, 3]);
65
- gl.getError();
66
- gl.uniform4f(null, 1, 2, 3, 4);
67
- gl.getError();
68
- gl.uniform4fv(null, [1, 2, 3, 4]);
69
- gl.getError();
70
- gl.uniform4i(null, 1, 2, 3, 4);
71
- gl.getError();
72
- gl.uniform4iv(null, [1, 2, 3, 4]);
73
- gl.getError();
74
- gl.uniformMatrix2fv(null, false, [1, 0, 0, 1]);
75
- gl.getError();
76
- gl.uniformMatrix3fv(null, false, [1, 0, 0, 0, 1, 0, 0, 0, 1]);
77
- gl.getError();
78
- gl.uniformMatrix4fv(null, false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
79
- gl.getError();
80
- expect(gl.getError()).toBe(gl.NO_ERROR);
81
- });
82
- });
83
- await describe("conformance/uniforms/gl-unknown-uniform", async () => {
84
- beforeEach(async () => {
85
- glArea.make_current();
86
- });
87
- await it("getUniformLocation for unknown uniform returns null", async () => {
88
- const prog = makeProgram(gl, VS, FS_FLOAT);
89
- gl.useProgram(prog);
90
- const loc = gl.getUniformLocation(prog, "someUnknownUniform");
91
- expect(loc).toBeNull();
92
- expect(gl.getError()).toBe(gl.NO_ERROR);
93
- });
94
- await it("uniform1f with null location (unknown) generates NO_ERROR", async () => {
95
- const prog = makeProgram(gl, VS, FS_FLOAT);
96
- gl.useProgram(prog);
97
- gl.uniform1f(null, 42);
98
- expect(gl.getError()).toBe(gl.NO_ERROR);
99
- });
100
- });
101
- await describe("conformance/uniforms/gl-uniform-bool", async () => {
102
- beforeEach(async () => {
103
- glArea.make_current();
104
- });
105
- await it("setting a bool uniform via uniform1i succeeds", async () => {
106
- const prog = makeProgram(gl, VS, FS_BOOL);
107
- gl.useProgram(prog);
108
- const loc = gl.getUniformLocation(prog, "u_b");
109
- expect(loc).not.toBeNull();
110
- gl.uniform1i(loc, 1);
111
- expect(gl.getError()).toBe(gl.NO_ERROR);
112
- });
113
- });
114
- await describe("conformance/uniforms/scalar-vector-round-trip", async () => {
115
- beforeEach(async () => {
116
- glArea.make_current();
117
- });
118
- await it("uniform1f / getUniform round-trips a float", async () => {
119
- const prog = makeProgram(gl, VS, FS_FLOAT);
120
- gl.useProgram(prog);
121
- const loc = gl.getUniformLocation(prog, "u_f");
122
- gl.uniform1f(loc, 0.5);
123
- expect(gl.getError()).toBe(gl.NO_ERROR);
124
- const val = gl.getUniform(prog, loc);
125
- expect(Math.abs(val - 0.5) < 1e-3).toBe(true);
126
- });
127
- await it("uniform1i / getUniform round-trips an int", async () => {
128
- const prog = makeProgram(gl, VS, FS_INT);
129
- gl.useProgram(prog);
130
- const loc = gl.getUniformLocation(prog, "u_i");
131
- gl.uniform1i(loc, 7);
132
- expect(gl.getError()).toBe(gl.NO_ERROR);
133
- const val = gl.getUniform(prog, loc);
134
- expect(val).toBe(7);
135
- });
136
- await it("uniform2fv / getUniform round-trips a vec2", async () => {
137
- const prog = makeProgram(gl, VS, FS_VEC2);
138
- gl.useProgram(prog);
139
- const loc = gl.getUniformLocation(prog, "u_v2");
140
- gl.uniform2fv(loc, [0.25, 0.75]);
141
- expect(gl.getError()).toBe(gl.NO_ERROR);
142
- const val = gl.getUniform(prog, loc);
143
- expect(floatArrayClose(val, [0.25, 0.75])).toBe(true);
144
- });
145
- await it("uniform3fv / getUniform round-trips a vec3", async () => {
146
- const prog = makeProgram(gl, VS, FS_VEC3);
147
- gl.useProgram(prog);
148
- const loc = gl.getUniformLocation(prog, "u_v3");
149
- gl.uniform3fv(loc, [0.1, 0.2, 0.3]);
150
- expect(gl.getError()).toBe(gl.NO_ERROR);
151
- const val = gl.getUniform(prog, loc);
152
- expect(floatArrayClose(val, [0.1, 0.2, 0.3])).toBe(true);
153
- });
154
- await it("uniform4fv / getUniform round-trips a vec4", async () => {
155
- const prog = makeProgram(gl, VS, FS_VEC4);
156
- gl.useProgram(prog);
157
- const loc = gl.getUniformLocation(prog, "u_v4");
158
- gl.uniform4fv(loc, [0.1, 0.2, 0.3, 0.4]);
159
- expect(gl.getError()).toBe(gl.NO_ERROR);
160
- const val = gl.getUniform(prog, loc);
161
- expect(floatArrayClose(val, [0.1, 0.2, 0.3, 0.4])).toBe(true);
162
- });
163
- });
164
- await describe("conformance/uniforms/gl-uniformmatrix4fv", async () => {
165
- beforeEach(async () => {
166
- glArea.make_current();
167
- });
168
- await it("uniformMatrix2fv with correct size (4 elements) succeeds", async () => {
169
- const prog = makeProgram(gl, VS, FS_MAT2);
170
- gl.useProgram(prog);
171
- const loc = gl.getUniformLocation(prog, "u_m2");
172
- gl.uniformMatrix2fv(loc, false, [1, 0, 0, 1]);
173
- expect(gl.getError()).toBe(gl.NO_ERROR);
174
- });
175
- await it("uniformMatrix2fv with too few elements generates INVALID_VALUE", async () => {
176
- const prog = makeProgram(gl, VS, FS_MAT2);
177
- gl.useProgram(prog);
178
- const loc = gl.getUniformLocation(prog, "u_m2");
179
- gl.uniformMatrix2fv(loc, false, [1, 0, 0]);
180
- expect(gl.getError()).toBe(gl.INVALID_VALUE);
181
- });
182
- await it("uniformMatrix3fv with correct size (9 elements) succeeds", async () => {
183
- const prog = makeProgram(gl, VS, FS_MAT3);
184
- gl.useProgram(prog);
185
- const loc = gl.getUniformLocation(prog, "u_m3");
186
- gl.uniformMatrix3fv(loc, false, [1, 0, 0, 0, 1, 0, 0, 0, 1]);
187
- expect(gl.getError()).toBe(gl.NO_ERROR);
188
- });
189
- await it("uniformMatrix4fv with correct size (16 elements) succeeds", async () => {
190
- const prog = makeProgram(gl, VS, FS_MAT4);
191
- gl.useProgram(prog);
192
- const loc = gl.getUniformLocation(prog, "u_m4");
193
- gl.uniformMatrix4fv(loc, false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
194
- expect(gl.getError()).toBe(gl.NO_ERROR);
195
- });
196
- await it("uniformMatrix4fv with transpose=true generates INVALID_VALUE in WebGL1", async () => {
197
- const prog = makeProgram(gl, VS, FS_MAT4);
198
- gl.useProgram(prog);
199
- const loc = gl.getUniformLocation(prog, "u_m4");
200
- gl.uniformMatrix4fv(loc, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
201
- expect(gl.getError()).toBe(gl.INVALID_VALUE);
202
- });
203
- await it("uniformMatrix4fv / getUniform round-trips a mat4", async () => {
204
- const prog = makeProgram(gl, VS, FS_MAT4);
205
- gl.useProgram(prog);
206
- const loc = gl.getUniformLocation(prog, "u_m4");
207
- const identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
208
- gl.uniformMatrix4fv(loc, false, identity);
209
- expect(gl.getError()).toBe(gl.NO_ERROR);
210
- const val = gl.getUniform(prog, loc);
211
- expect(floatArrayClose(val, identity)).toBe(true);
212
- });
213
- });
214
- await describe("conformance/uniforms/gl-uniform-arrays", async () => {
215
- beforeEach(async () => {
216
- glArea.make_current();
217
- });
218
- await it("uniform1fv sets a float array and getUniform retrieves element [0]", async () => {
219
- const prog = makeProgram(gl, VS, FS_ARR);
220
- gl.useProgram(prog);
221
- const loc = gl.getUniformLocation(prog, "u_arr[0]");
222
- expect(loc).not.toBeNull();
223
- gl.uniform1fv(loc, [0.1, 0.2, 0.3]);
224
- expect(gl.getError()).toBe(gl.NO_ERROR);
225
- const val = gl.getUniform(prog, loc);
226
- expect(Math.abs(val - 0.1) < 1e-3).toBe(true);
227
- });
228
- await it("uniform1fv with fewer values than array size (partial update) succeeds", async () => {
229
- const prog = makeProgram(gl, VS, FS_ARR);
230
- gl.useProgram(prog);
231
- const loc = gl.getUniformLocation(prog, "u_arr[0]");
232
- gl.uniform1fv(loc, [0.5, 0.6]);
233
- expect(gl.getError()).toBe(gl.NO_ERROR);
234
- });
235
- await it("uniform4fv sets a vec4 array", async () => {
236
- const prog = makeProgram(gl, VS, FS_VEC4ARR);
237
- gl.useProgram(prog);
238
- const loc = gl.getUniformLocation(prog, "u_v4arr[0]");
239
- expect(loc).not.toBeNull();
240
- gl.uniform4fv(loc, [
241
- 0.1,
242
- 0.2,
243
- 0.3,
244
- 0.4,
245
- 0.5,
246
- 0.6,
247
- 0.7,
248
- 0.8,
249
- 0.9,
250
- 1,
251
- 0,
252
- 0
253
- ]);
254
- expect(gl.getError()).toBe(gl.NO_ERROR);
255
- });
256
- await it("getUniformLocation resolves bare array name (without [0] suffix)", async () => {
257
- const prog = makeProgram(gl, VS, FS_ARR);
258
- gl.useProgram(prog);
259
- const locBare = gl.getUniformLocation(prog, "u_arr");
260
- expect(locBare).not.toBeNull();
261
- expect(gl.getError()).toBe(gl.NO_ERROR);
262
- gl.uniform1fv(locBare, [0.7, 0.8, 0.9]);
263
- expect(gl.getError()).toBe(gl.NO_ERROR);
264
- const val = gl.getUniform(prog, locBare);
265
- expect(Math.abs(val - 0.7) < 1e-3).toBe(true);
266
- });
267
- await it("bare array name and indexed [0] name resolve to equivalent locations", async () => {
268
- const prog = makeProgram(gl, VS, FS_ARR);
269
- gl.useProgram(prog);
270
- const locBare = gl.getUniformLocation(prog, "u_arr");
271
- const locIndexed = gl.getUniformLocation(prog, "u_arr[0]");
272
- expect(locBare).not.toBeNull();
273
- expect(locIndexed).not.toBeNull();
274
- gl.uniform1fv(locBare, [0.42, 0.43, 0.44]);
275
- expect(gl.getError()).toBe(gl.NO_ERROR);
276
- const val = gl.getUniform(prog, locIndexed);
277
- expect(Math.abs(val - 0.42) < 1e-3).toBe(true);
278
- });
279
- await it("calling uniform* before useProgram generates INVALID_OPERATION", async () => {
280
- const prog = makeProgram(gl, VS, FS_ARR);
281
- gl.useProgram(null);
282
- const loc = gl.getUniformLocation(prog, "u_arr[0]");
283
- if (loc !== null) {
284
- gl.uniform1fv(loc, [1, 2, 3]);
285
- expect(gl.getError()).toBe(gl.INVALID_OPERATION);
286
- } else {
287
- expect(gl.getError()).toBe(gl.NO_ERROR);
288
- }
289
- });
290
- });
291
- await describe("conformance/uniforms/uniform-location", async () => {
292
- beforeEach(async () => {
293
- glArea.make_current();
294
- });
295
- await it("getUniformLocation returns non-null for known uniform", async () => {
296
- const prog = makeProgram(gl, VS, FS_FLOAT);
297
- gl.useProgram(prog);
298
- const loc = gl.getUniformLocation(prog, "u_f");
299
- expect(loc).not.toBeNull();
300
- expect(gl.getError()).toBe(gl.NO_ERROR);
301
- });
302
- await it("location from different program generates INVALID_OPERATION", async () => {
303
- const prog1 = makeProgram(gl, VS, FS_FLOAT);
304
- const prog2 = makeProgram(gl, VS, FS_FLOAT);
305
- const loc = gl.getUniformLocation(prog1, "u_f");
306
- gl.useProgram(prog2);
307
- gl.uniform1f(loc, 1);
308
- expect(gl.getError()).toBe(gl.INVALID_OPERATION);
309
- });
310
- await it("location becomes invalid after relinkProgram", async () => {
311
- const prog = makeProgram(gl, VS, FS_FLOAT);
312
- gl.useProgram(prog);
313
- const locBefore = gl.getUniformLocation(prog, "u_f");
314
- expect(locBefore).not.toBeNull();
315
- gl.linkProgram(prog);
316
- gl.uniform1f(locBefore, 1);
317
- expect(gl.getError()).toBe(gl.INVALID_OPERATION);
318
- const locAfter = gl.getUniformLocation(prog, "u_f");
319
- expect(locAfter).not.toBeNull();
320
- gl.uniform1f(locAfter, 1);
321
- expect(gl.getError()).toBe(gl.NO_ERROR);
322
- });
323
- });
324
- });
325
- };
326
- export {
327
- uniforms_spec_default as default
29
+ await on("Display", async () => {
30
+ const setup = createGLSetup();
31
+ if (!setup) {
32
+ console.warn("WebGL context not available skipping conformance/uniforms tests");
33
+ return;
34
+ }
35
+ const { gl, glArea } = setup;
36
+ glArea.make_current();
37
+ await describe("conformance/uniforms/null-uniform-location", async () => {
38
+ beforeEach(async () => {
39
+ glArea.make_current();
40
+ });
41
+ await it("uniform* with null location generates NO_ERROR", async () => {
42
+ const prog = makeProgram(gl, VS, FS_FLOAT);
43
+ gl.useProgram(prog);
44
+ gl.uniform1f(null, 1);
45
+ gl.getError();
46
+ gl.uniform1fv(null, [1]);
47
+ gl.getError();
48
+ gl.uniform1i(null, 1);
49
+ gl.getError();
50
+ gl.uniform1iv(null, [1]);
51
+ gl.getError();
52
+ gl.uniform2f(null, 1, 2);
53
+ gl.getError();
54
+ gl.uniform2fv(null, [1, 2]);
55
+ gl.getError();
56
+ gl.uniform2i(null, 1, 2);
57
+ gl.getError();
58
+ gl.uniform2iv(null, [1, 2]);
59
+ gl.getError();
60
+ gl.uniform3f(null, 1, 2, 3);
61
+ gl.getError();
62
+ gl.uniform3fv(null, [
63
+ 1,
64
+ 2,
65
+ 3
66
+ ]);
67
+ gl.getError();
68
+ gl.uniform3i(null, 1, 2, 3);
69
+ gl.getError();
70
+ gl.uniform3iv(null, [
71
+ 1,
72
+ 2,
73
+ 3
74
+ ]);
75
+ gl.getError();
76
+ gl.uniform4f(null, 1, 2, 3, 4);
77
+ gl.getError();
78
+ gl.uniform4fv(null, [
79
+ 1,
80
+ 2,
81
+ 3,
82
+ 4
83
+ ]);
84
+ gl.getError();
85
+ gl.uniform4i(null, 1, 2, 3, 4);
86
+ gl.getError();
87
+ gl.uniform4iv(null, [
88
+ 1,
89
+ 2,
90
+ 3,
91
+ 4
92
+ ]);
93
+ gl.getError();
94
+ gl.uniformMatrix2fv(null, false, [
95
+ 1,
96
+ 0,
97
+ 0,
98
+ 1
99
+ ]);
100
+ gl.getError();
101
+ gl.uniformMatrix3fv(null, false, [
102
+ 1,
103
+ 0,
104
+ 0,
105
+ 0,
106
+ 1,
107
+ 0,
108
+ 0,
109
+ 0,
110
+ 1
111
+ ]);
112
+ gl.getError();
113
+ gl.uniformMatrix4fv(null, false, [
114
+ 1,
115
+ 0,
116
+ 0,
117
+ 0,
118
+ 0,
119
+ 1,
120
+ 0,
121
+ 0,
122
+ 0,
123
+ 0,
124
+ 1,
125
+ 0,
126
+ 0,
127
+ 0,
128
+ 0,
129
+ 1
130
+ ]);
131
+ gl.getError();
132
+ expect(gl.getError()).toBe(gl.NO_ERROR);
133
+ });
134
+ });
135
+ await describe("conformance/uniforms/gl-unknown-uniform", async () => {
136
+ beforeEach(async () => {
137
+ glArea.make_current();
138
+ });
139
+ await it("getUniformLocation for unknown uniform returns null", async () => {
140
+ const prog = makeProgram(gl, VS, FS_FLOAT);
141
+ gl.useProgram(prog);
142
+ const loc = gl.getUniformLocation(prog, "someUnknownUniform");
143
+ expect(loc).toBeNull();
144
+ expect(gl.getError()).toBe(gl.NO_ERROR);
145
+ });
146
+ await it("uniform1f with null location (unknown) generates NO_ERROR", async () => {
147
+ const prog = makeProgram(gl, VS, FS_FLOAT);
148
+ gl.useProgram(prog);
149
+ gl.uniform1f(null, 42);
150
+ expect(gl.getError()).toBe(gl.NO_ERROR);
151
+ });
152
+ });
153
+ await describe("conformance/uniforms/gl-uniform-bool", async () => {
154
+ beforeEach(async () => {
155
+ glArea.make_current();
156
+ });
157
+ await it("setting a bool uniform via uniform1i succeeds", async () => {
158
+ const prog = makeProgram(gl, VS, FS_BOOL);
159
+ gl.useProgram(prog);
160
+ const loc = gl.getUniformLocation(prog, "u_b");
161
+ expect(loc).not.toBeNull();
162
+ gl.uniform1i(loc, 1);
163
+ expect(gl.getError()).toBe(gl.NO_ERROR);
164
+ });
165
+ });
166
+ await describe("conformance/uniforms/scalar-vector-round-trip", async () => {
167
+ beforeEach(async () => {
168
+ glArea.make_current();
169
+ });
170
+ await it("uniform1f / getUniform round-trips a float", async () => {
171
+ const prog = makeProgram(gl, VS, FS_FLOAT);
172
+ gl.useProgram(prog);
173
+ const loc = gl.getUniformLocation(prog, "u_f");
174
+ gl.uniform1f(loc, .5);
175
+ expect(gl.getError()).toBe(gl.NO_ERROR);
176
+ const val = gl.getUniform(prog, loc);
177
+ expect(Math.abs(val - .5) < .001).toBe(true);
178
+ });
179
+ await it("uniform1i / getUniform round-trips an int", async () => {
180
+ const prog = makeProgram(gl, VS, FS_INT);
181
+ gl.useProgram(prog);
182
+ const loc = gl.getUniformLocation(prog, "u_i");
183
+ gl.uniform1i(loc, 7);
184
+ expect(gl.getError()).toBe(gl.NO_ERROR);
185
+ const val = gl.getUniform(prog, loc);
186
+ expect(val).toBe(7);
187
+ });
188
+ await it("uniform2fv / getUniform round-trips a vec2", async () => {
189
+ const prog = makeProgram(gl, VS, FS_VEC2);
190
+ gl.useProgram(prog);
191
+ const loc = gl.getUniformLocation(prog, "u_v2");
192
+ gl.uniform2fv(loc, [.25, .75]);
193
+ expect(gl.getError()).toBe(gl.NO_ERROR);
194
+ const val = gl.getUniform(prog, loc);
195
+ expect(floatArrayClose(val, [.25, .75])).toBe(true);
196
+ });
197
+ await it("uniform3fv / getUniform round-trips a vec3", async () => {
198
+ const prog = makeProgram(gl, VS, FS_VEC3);
199
+ gl.useProgram(prog);
200
+ const loc = gl.getUniformLocation(prog, "u_v3");
201
+ gl.uniform3fv(loc, [
202
+ .1,
203
+ .2,
204
+ .3
205
+ ]);
206
+ expect(gl.getError()).toBe(gl.NO_ERROR);
207
+ const val = gl.getUniform(prog, loc);
208
+ expect(floatArrayClose(val, [
209
+ .1,
210
+ .2,
211
+ .3
212
+ ])).toBe(true);
213
+ });
214
+ await it("uniform4fv / getUniform round-trips a vec4", async () => {
215
+ const prog = makeProgram(gl, VS, FS_VEC4);
216
+ gl.useProgram(prog);
217
+ const loc = gl.getUniformLocation(prog, "u_v4");
218
+ gl.uniform4fv(loc, [
219
+ .1,
220
+ .2,
221
+ .3,
222
+ .4
223
+ ]);
224
+ expect(gl.getError()).toBe(gl.NO_ERROR);
225
+ const val = gl.getUniform(prog, loc);
226
+ expect(floatArrayClose(val, [
227
+ .1,
228
+ .2,
229
+ .3,
230
+ .4
231
+ ])).toBe(true);
232
+ });
233
+ });
234
+ await describe("conformance/uniforms/gl-uniformmatrix4fv", async () => {
235
+ beforeEach(async () => {
236
+ glArea.make_current();
237
+ });
238
+ await it("uniformMatrix2fv with correct size (4 elements) succeeds", async () => {
239
+ const prog = makeProgram(gl, VS, FS_MAT2);
240
+ gl.useProgram(prog);
241
+ const loc = gl.getUniformLocation(prog, "u_m2");
242
+ gl.uniformMatrix2fv(loc, false, [
243
+ 1,
244
+ 0,
245
+ 0,
246
+ 1
247
+ ]);
248
+ expect(gl.getError()).toBe(gl.NO_ERROR);
249
+ });
250
+ await it("uniformMatrix2fv with too few elements generates INVALID_VALUE", async () => {
251
+ const prog = makeProgram(gl, VS, FS_MAT2);
252
+ gl.useProgram(prog);
253
+ const loc = gl.getUniformLocation(prog, "u_m2");
254
+ gl.uniformMatrix2fv(loc, false, [
255
+ 1,
256
+ 0,
257
+ 0
258
+ ]);
259
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
260
+ });
261
+ await it("uniformMatrix3fv with correct size (9 elements) succeeds", async () => {
262
+ const prog = makeProgram(gl, VS, FS_MAT3);
263
+ gl.useProgram(prog);
264
+ const loc = gl.getUniformLocation(prog, "u_m3");
265
+ gl.uniformMatrix3fv(loc, false, [
266
+ 1,
267
+ 0,
268
+ 0,
269
+ 0,
270
+ 1,
271
+ 0,
272
+ 0,
273
+ 0,
274
+ 1
275
+ ]);
276
+ expect(gl.getError()).toBe(gl.NO_ERROR);
277
+ });
278
+ await it("uniformMatrix4fv with correct size (16 elements) succeeds", async () => {
279
+ const prog = makeProgram(gl, VS, FS_MAT4);
280
+ gl.useProgram(prog);
281
+ const loc = gl.getUniformLocation(prog, "u_m4");
282
+ gl.uniformMatrix4fv(loc, false, [
283
+ 1,
284
+ 0,
285
+ 0,
286
+ 0,
287
+ 0,
288
+ 1,
289
+ 0,
290
+ 0,
291
+ 0,
292
+ 0,
293
+ 1,
294
+ 0,
295
+ 0,
296
+ 0,
297
+ 0,
298
+ 1
299
+ ]);
300
+ expect(gl.getError()).toBe(gl.NO_ERROR);
301
+ });
302
+ await it("uniformMatrix4fv with transpose=true generates INVALID_VALUE in WebGL1", async () => {
303
+ const prog = makeProgram(gl, VS, FS_MAT4);
304
+ gl.useProgram(prog);
305
+ const loc = gl.getUniformLocation(prog, "u_m4");
306
+ gl.uniformMatrix4fv(loc, true, [
307
+ 1,
308
+ 0,
309
+ 0,
310
+ 0,
311
+ 0,
312
+ 1,
313
+ 0,
314
+ 0,
315
+ 0,
316
+ 0,
317
+ 1,
318
+ 0,
319
+ 0,
320
+ 0,
321
+ 0,
322
+ 1
323
+ ]);
324
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
325
+ });
326
+ await it("uniformMatrix4fv / getUniform round-trips a mat4", async () => {
327
+ const prog = makeProgram(gl, VS, FS_MAT4);
328
+ gl.useProgram(prog);
329
+ const loc = gl.getUniformLocation(prog, "u_m4");
330
+ const identity = [
331
+ 1,
332
+ 0,
333
+ 0,
334
+ 0,
335
+ 0,
336
+ 1,
337
+ 0,
338
+ 0,
339
+ 0,
340
+ 0,
341
+ 1,
342
+ 0,
343
+ 0,
344
+ 0,
345
+ 0,
346
+ 1
347
+ ];
348
+ gl.uniformMatrix4fv(loc, false, identity);
349
+ expect(gl.getError()).toBe(gl.NO_ERROR);
350
+ const val = gl.getUniform(prog, loc);
351
+ expect(floatArrayClose(val, identity)).toBe(true);
352
+ });
353
+ });
354
+ await describe("conformance/uniforms/gl-uniform-arrays", async () => {
355
+ beforeEach(async () => {
356
+ glArea.make_current();
357
+ });
358
+ await it("uniform1fv sets a float array and getUniform retrieves element [0]", async () => {
359
+ const prog = makeProgram(gl, VS, FS_ARR);
360
+ gl.useProgram(prog);
361
+ const loc = gl.getUniformLocation(prog, "u_arr[0]");
362
+ expect(loc).not.toBeNull();
363
+ gl.uniform1fv(loc, [
364
+ .1,
365
+ .2,
366
+ .3
367
+ ]);
368
+ expect(gl.getError()).toBe(gl.NO_ERROR);
369
+ const val = gl.getUniform(prog, loc);
370
+ expect(Math.abs(val - .1) < .001).toBe(true);
371
+ });
372
+ await it("uniform1fv with fewer values than array size (partial update) succeeds", async () => {
373
+ const prog = makeProgram(gl, VS, FS_ARR);
374
+ gl.useProgram(prog);
375
+ const loc = gl.getUniformLocation(prog, "u_arr[0]");
376
+ gl.uniform1fv(loc, [.5, .6]);
377
+ expect(gl.getError()).toBe(gl.NO_ERROR);
378
+ });
379
+ await it("uniform4fv sets a vec4 array", async () => {
380
+ const prog = makeProgram(gl, VS, FS_VEC4ARR);
381
+ gl.useProgram(prog);
382
+ const loc = gl.getUniformLocation(prog, "u_v4arr[0]");
383
+ expect(loc).not.toBeNull();
384
+ gl.uniform4fv(loc, [
385
+ .1,
386
+ .2,
387
+ .3,
388
+ .4,
389
+ .5,
390
+ .6,
391
+ .7,
392
+ .8,
393
+ .9,
394
+ 1,
395
+ 0,
396
+ 0
397
+ ]);
398
+ expect(gl.getError()).toBe(gl.NO_ERROR);
399
+ });
400
+ await it("getUniformLocation resolves bare array name (without [0] suffix)", async () => {
401
+ const prog = makeProgram(gl, VS, FS_ARR);
402
+ gl.useProgram(prog);
403
+ const locBare = gl.getUniformLocation(prog, "u_arr");
404
+ expect(locBare).not.toBeNull();
405
+ expect(gl.getError()).toBe(gl.NO_ERROR);
406
+ gl.uniform1fv(locBare, [
407
+ .7,
408
+ .8,
409
+ .9
410
+ ]);
411
+ expect(gl.getError()).toBe(gl.NO_ERROR);
412
+ const val = gl.getUniform(prog, locBare);
413
+ expect(Math.abs(val - .7) < .001).toBe(true);
414
+ });
415
+ await it("bare array name and indexed [0] name resolve to equivalent locations", async () => {
416
+ const prog = makeProgram(gl, VS, FS_ARR);
417
+ gl.useProgram(prog);
418
+ const locBare = gl.getUniformLocation(prog, "u_arr");
419
+ const locIndexed = gl.getUniformLocation(prog, "u_arr[0]");
420
+ expect(locBare).not.toBeNull();
421
+ expect(locIndexed).not.toBeNull();
422
+ gl.uniform1fv(locBare, [
423
+ .42,
424
+ .43,
425
+ .44
426
+ ]);
427
+ expect(gl.getError()).toBe(gl.NO_ERROR);
428
+ const val = gl.getUniform(prog, locIndexed);
429
+ expect(Math.abs(val - .42) < .001).toBe(true);
430
+ });
431
+ await it("calling uniform* before useProgram generates INVALID_OPERATION", async () => {
432
+ const prog = makeProgram(gl, VS, FS_ARR);
433
+ gl.useProgram(null);
434
+ const loc = gl.getUniformLocation(prog, "u_arr[0]");
435
+ if (loc !== null) {
436
+ gl.uniform1fv(loc, [
437
+ 1,
438
+ 2,
439
+ 3
440
+ ]);
441
+ expect(gl.getError()).toBe(gl.INVALID_OPERATION);
442
+ } else {
443
+ expect(gl.getError()).toBe(gl.NO_ERROR);
444
+ }
445
+ });
446
+ });
447
+ await describe("conformance/uniforms/uniform-location", async () => {
448
+ beforeEach(async () => {
449
+ glArea.make_current();
450
+ });
451
+ await it("getUniformLocation returns non-null for known uniform", async () => {
452
+ const prog = makeProgram(gl, VS, FS_FLOAT);
453
+ gl.useProgram(prog);
454
+ const loc = gl.getUniformLocation(prog, "u_f");
455
+ expect(loc).not.toBeNull();
456
+ expect(gl.getError()).toBe(gl.NO_ERROR);
457
+ });
458
+ await it("location from different program generates INVALID_OPERATION", async () => {
459
+ const prog1 = makeProgram(gl, VS, FS_FLOAT);
460
+ const prog2 = makeProgram(gl, VS, FS_FLOAT);
461
+ const loc = gl.getUniformLocation(prog1, "u_f");
462
+ gl.useProgram(prog2);
463
+ gl.uniform1f(loc, 1);
464
+ expect(gl.getError()).toBe(gl.INVALID_OPERATION);
465
+ });
466
+ await it("location becomes invalid after relinkProgram", async () => {
467
+ const prog = makeProgram(gl, VS, FS_FLOAT);
468
+ gl.useProgram(prog);
469
+ const locBefore = gl.getUniformLocation(prog, "u_f");
470
+ expect(locBefore).not.toBeNull();
471
+ gl.linkProgram(prog);
472
+ gl.uniform1f(locBefore, 1);
473
+ expect(gl.getError()).toBe(gl.INVALID_OPERATION);
474
+ const locAfter = gl.getUniformLocation(prog, "u_f");
475
+ expect(locAfter).not.toBeNull();
476
+ gl.uniform1f(locAfter, 1);
477
+ expect(gl.getError()).toBe(gl.NO_ERROR);
478
+ });
479
+ });
480
+ });
328
481
  };
482
+
483
+ //#endregion
484
+ export { uniforms_spec_default as default };