@gjsify/webgl 0.3.16 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/lib/esm/conformance/attribs.spec.js +3 -315
  2. package/lib/esm/conformance/buffers.spec.js +1 -220
  3. package/lib/esm/conformance/context.spec.js +3 -302
  4. package/lib/esm/conformance/programs.spec.js +3 -477
  5. package/lib/esm/conformance/rendering-basic.spec.js +3 -141
  6. package/lib/esm/conformance/rendering.spec.js +7 -514
  7. package/lib/esm/conformance/setup.js +1 -47
  8. package/lib/esm/conformance/state.spec.js +1 -365
  9. package/lib/esm/conformance/textures.spec.js +3 -337
  10. package/lib/esm/conformance/uniforms.spec.js +1 -484
  11. package/lib/esm/conformance-test.js +1 -25
  12. package/lib/esm/extensions/ext-blend-minmax.js +1 -18
  13. package/lib/esm/extensions/ext-color-buffer-float.js +1 -12
  14. package/lib/esm/extensions/ext-color-buffer-half-float.js +1 -12
  15. package/lib/esm/extensions/ext-texture-filter-anisotropic.js +1 -18
  16. package/lib/esm/extensions/oes-element-index-unit.js +1 -13
  17. package/lib/esm/extensions/oes-standard-derivatives.js +1 -17
  18. package/lib/esm/extensions/oes-texture-float-linear.js +1 -13
  19. package/lib/esm/extensions/oes-texture-float.js +1 -13
  20. package/lib/esm/extensions/oes-texture-half-float.js +1 -19
  21. package/lib/esm/extensions/stackgl-destroy-context.js +1 -12
  22. package/lib/esm/extensions/stackgl-resize-drawing-buffer.js +1 -12
  23. package/lib/esm/html-canvas-element.js +1 -65
  24. package/lib/esm/index.js +1 -33
  25. package/lib/esm/linkable.js +1 -50
  26. package/lib/esm/test-utils.js +4 -186
  27. package/lib/esm/test.js +1 -11
  28. package/lib/esm/types/index.js +1 -5
  29. package/lib/esm/utils.js +1 -201
  30. package/lib/esm/webgl-active-info.js +1 -11
  31. package/lib/esm/webgl-bridge.js +1 -167
  32. package/lib/esm/webgl-buffer.js +1 -19
  33. package/lib/esm/webgl-context-attributes.js +1 -24
  34. package/lib/esm/webgl-context-base.js +8 -3069
  35. package/lib/esm/webgl-drawing-buffer-wrapper.js +1 -11
  36. package/lib/esm/webgl-framebuffer.js +1 -110
  37. package/lib/esm/webgl-program.js +1 -27
  38. package/lib/esm/webgl-query.js +1 -17
  39. package/lib/esm/webgl-renderbuffer.js +1 -25
  40. package/lib/esm/webgl-rendering-context.js +1 -175
  41. package/lib/esm/webgl-sampler.js +1 -17
  42. package/lib/esm/webgl-shader-precision-format.js +1 -11
  43. package/lib/esm/webgl-shader.js +1 -25
  44. package/lib/esm/webgl-sync.js +1 -17
  45. package/lib/esm/webgl-texture-unit.js +1 -13
  46. package/lib/esm/webgl-texture.js +1 -23
  47. package/lib/esm/webgl-transform-feedback.js +1 -17
  48. package/lib/esm/webgl-uniform-location.js +1 -15
  49. package/lib/esm/webgl-vertex-array-object.js +1 -23
  50. package/lib/esm/webgl-vertex-attribute.js +1 -151
  51. package/lib/esm/webgl1.spec.js +10 -1044
  52. package/lib/esm/webgl2-rendering-context.js +1 -1218
  53. package/lib/esm/webgl2.spec.js +45 -1288
  54. package/lib/types/webgl-bridge.d.ts +9 -9
  55. package/package.json +9 -9
@@ -1,526 +1,19 @@
1
- import { destroyTestFBO, destroyTestFBOWithDepth, drawTriangle, makeProgram, makeTestFBO, makeTestFBOWithDepth, pixelClose } from "../test-utils.js";
2
- import { createGLSetup } from "./setup.js";
3
- import { beforeEach, describe, expect, it, on } from "@gjsify/unit";
4
-
5
- //#region src/ts/conformance/rendering.spec.ts
6
- const VS = `
1
+ import{destroyTestFBO as e,destroyTestFBOWithDepth as t,drawTriangle as n,makeProgram as r,makeTestFBO as i,makeTestFBOWithDepth as a,pixelClose as o}from"../test-utils.js";import{createGLSetup as s}from"./setup.js";import{beforeEach as c,describe as l,expect as u,it as d,on as f}from"@gjsify/unit";const p=`
7
2
  precision mediump float;
8
3
  attribute vec2 position;
9
- void main() { gl_Position = vec4(position, 0.0, 1.0); }`;
10
- const VS_DEPTH = `
4
+ void main() { gl_Position = vec4(position, 0.0, 1.0); }`,m=`
11
5
  attribute vec2 position;
12
6
  uniform float depth;
13
- void main() { gl_Position = vec4(position, depth, 1.0); }`;
14
- const FS_COLOR = `
7
+ void main() { gl_Position = vec4(position, depth, 1.0); }`,h=`
15
8
  precision mediump float;
16
9
  uniform vec4 color;
17
- void main() { gl_FragColor = color; }`;
18
- var rendering_spec_default = async () => {
19
- await on("Display", async () => {
20
- const setup = createGLSetup();
21
- if (!setup) {
22
- console.warn("WebGL context not available — skipping conformance/rendering tests");
23
- return;
24
- }
25
- const { gl, glArea } = setup;
26
- glArea.make_current();
27
- await describe("rendering/blending", async () => {
28
- beforeEach(async () => {
29
- glArea.make_current();
30
- });
31
- const W = 2, H = 2;
32
- function runBlendTest(t) {
33
- const fbo = makeTestFBO(gl, W, H);
34
- const fsSrc = `
10
+ void main() { gl_FragColor = color; }`;var g=async()=>{await f(`Display`,async()=>{let f=s();if(!f){console.warn(`WebGL context not available — skipping conformance/rendering tests`);return}let{gl:g,glArea:_}=f;_.make_current(),await l(`rendering/blending`,async()=>{c(async()=>{_.make_current()});function t(t){let a=i(g,2,2),s=`
35
11
  precision mediump float;
36
- void main() { gl_FragColor = vec4(${t.srcColor[0]},${t.srcColor[1]},${t.srcColor[2]},${t.srcColor[3]}); }`;
37
- gl.clearColor(t.dstColor[0], t.dstColor[1], t.dstColor[2], t.dstColor[3]);
38
- gl.clear(gl.COLOR_BUFFER_BIT);
39
- const prog = makeProgram(gl, VS, fsSrc);
40
- gl.useProgram(prog);
41
- gl.enable(gl.BLEND);
42
- gl.blendEquation(t.equation);
43
- gl.blendFunc(t.srcFactor, t.dstFactor);
44
- drawTriangle(gl);
45
- gl.disable(gl.BLEND);
46
- const pixels = new Uint8Array(W * H * 4);
47
- gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
48
- destroyTestFBO(gl, fbo);
49
- const expected255 = t.expected.map((v) => Math.round(v * 255));
50
- for (let i = 0; i < W * H * 4; i += 4) {
51
- if (!pixelClose(pixels.subarray(i, i + 4), expected255, 4)) {
52
- return false;
53
- }
54
- }
55
- return true;
56
- }
57
- await it("FUNC_ADD ONE ONE: dst=[0.5,0.5,0.5,1] + src=[0.5,0.5,0.5,1] = [1,1,1,1]", async () => {
58
- expect(runBlendTest({
59
- name: "ADD ONE ONE",
60
- equation: gl.FUNC_ADD,
61
- srcFactor: gl.ONE,
62
- dstFactor: gl.ONE,
63
- dstColor: [
64
- .5,
65
- .5,
66
- .5,
67
- 1
68
- ],
69
- srcColor: [
70
- .5,
71
- .5,
72
- .5,
73
- 1
74
- ],
75
- expected: [
76
- 1,
77
- 1,
78
- 1,
79
- 1
80
- ]
81
- })).toBe(true);
82
- expect(gl.getError()).toBe(gl.NO_ERROR);
83
- });
84
- await it("FUNC_ADD ONE ZERO: dst=[0.5,0.5,0.5,0.5] + src=[0.2,0.2,0.2,1] = [0.2,0.2,0.2,1]", async () => {
85
- expect(runBlendTest({
86
- name: "ADD ONE ZERO",
87
- equation: gl.FUNC_ADD,
88
- srcFactor: gl.ONE,
89
- dstFactor: gl.ZERO,
90
- dstColor: [
91
- .5,
92
- .5,
93
- .5,
94
- .5
95
- ],
96
- srcColor: [
97
- .2,
98
- .2,
99
- .2,
100
- 1
101
- ],
102
- expected: [
103
- .2,
104
- .2,
105
- .2,
106
- 1
107
- ]
108
- })).toBe(true);
109
- expect(gl.getError()).toBe(gl.NO_ERROR);
110
- });
111
- await it("FUNC_ADD ZERO SRC_COLOR: dst=[0.8,0.8,0.8,1] * src=[0.5,0.5,0.5,0.5] = [0.4,0.4,0.4,0.5]", async () => {
112
- expect(runBlendTest({
113
- name: "ADD ZERO SRC_COLOR",
114
- equation: gl.FUNC_ADD,
115
- srcFactor: gl.ZERO,
116
- dstFactor: gl.SRC_COLOR,
117
- dstColor: [
118
- .8,
119
- .8,
120
- .8,
121
- 1
122
- ],
123
- srcColor: [
124
- .5,
125
- .5,
126
- .5,
127
- .5
128
- ],
129
- expected: [
130
- .4,
131
- .4,
132
- .4,
133
- .5
134
- ]
135
- })).toBe(true);
136
- expect(gl.getError()).toBe(gl.NO_ERROR);
137
- });
138
- await it("FUNC_ADD DST_COLOR ZERO: dst=[0.8,0.8,0.8,1] src=[0.5,0.5,0.5,0.5] = [0.4,0.4,0.4,0.5]", async () => {
139
- expect(runBlendTest({
140
- name: "ADD DST_COLOR ZERO",
141
- equation: gl.FUNC_ADD,
142
- srcFactor: gl.DST_COLOR,
143
- dstFactor: gl.ZERO,
144
- dstColor: [
145
- .8,
146
- .8,
147
- .8,
148
- 1
149
- ],
150
- srcColor: [
151
- .5,
152
- .5,
153
- .5,
154
- .5
155
- ],
156
- expected: [
157
- .4,
158
- .4,
159
- .4,
160
- .5
161
- ]
162
- })).toBe(true);
163
- expect(gl.getError()).toBe(gl.NO_ERROR);
164
- });
165
- await it("FUNC_ADD SRC_ALPHA ONE_MINUS_SRC_ALPHA: alpha=0.5 blend", async () => {
166
- expect(runBlendTest({
167
- name: "ADD SRC_ALPHA ONE_MINUS_SRC_ALPHA",
168
- equation: gl.FUNC_ADD,
169
- srcFactor: gl.SRC_ALPHA,
170
- dstFactor: gl.ONE_MINUS_SRC_ALPHA,
171
- dstColor: [
172
- .5,
173
- 0,
174
- .5,
175
- 1
176
- ],
177
- srcColor: [
178
- .5,
179
- 1,
180
- 0,
181
- .5
182
- ],
183
- expected: [
184
- .5,
185
- .5,
186
- .25,
187
- .75
188
- ]
189
- })).toBe(true);
190
- expect(gl.getError()).toBe(gl.NO_ERROR);
191
- });
192
- });
193
- await describe("rendering/depth-buffer", async () => {
194
- beforeEach(async () => {
195
- glArea.make_current();
196
- });
197
- await it("DEPTH_TEST NOTEQUAL: both passes render because depths differ", async () => {
198
- const W = 50, H = 50;
199
- const fbo = makeTestFBOWithDepth(gl, W, H);
200
- gl.clearColor(0, 0, 0, 0);
201
- gl.clearDepth(1);
202
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
203
- gl.enable(gl.DEPTH_TEST);
204
- gl.depthFunc(gl.NOTEQUAL);
205
- const prog = makeProgram(gl, VS_DEPTH, FS_COLOR);
206
- gl.useProgram(prog);
207
- gl.uniform1f(gl.getUniformLocation(prog, "depth"), 0);
208
- gl.uniform4f(gl.getUniformLocation(prog, "color"), 1, 0, 0, 1);
209
- drawTriangle(gl);
210
- gl.uniform1f(gl.getUniformLocation(prog, "depth"), 1);
211
- gl.uniform4f(gl.getUniformLocation(prog, "color"), 0, 1, 0, 1);
212
- drawTriangle(gl);
213
- gl.disable(gl.DEPTH_TEST);
214
- const pixels = new Uint8Array(W * H * 4);
215
- gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
216
- destroyTestFBOWithDepth(gl, fbo);
217
- let allGreen = true;
218
- for (let i = 0; i < W * H * 4; i += 4) {
219
- if (!pixelClose(pixels.subarray(i, i + 4), [
220
- 0,
221
- 255,
222
- 0,
223
- 255
224
- ], 3)) {
225
- allGreen = false;
226
- break;
227
- }
228
- }
229
- expect(allGreen).toBe(true);
230
- expect(gl.getError()).toBe(gl.NO_ERROR);
231
- });
232
- await it("DEPTH_TEST LESS: closer triangle overwrites farther", async () => {
233
- const W = 20, H = 20;
234
- const fbo = makeTestFBOWithDepth(gl, W, H);
235
- gl.clearColor(0, 0, 0, 0);
236
- gl.clearDepth(1);
237
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
238
- gl.enable(gl.DEPTH_TEST);
239
- gl.depthFunc(gl.LESS);
240
- const prog = makeProgram(gl, VS_DEPTH, FS_COLOR);
241
- gl.useProgram(prog);
242
- gl.uniform1f(gl.getUniformLocation(prog, "depth"), .5);
243
- gl.uniform4f(gl.getUniformLocation(prog, "color"), 0, 0, 1, 1);
244
- drawTriangle(gl);
245
- gl.uniform1f(gl.getUniformLocation(prog, "depth"), .25);
246
- gl.uniform4f(gl.getUniformLocation(prog, "color"), 0, 1, 0, 1);
247
- drawTriangle(gl);
248
- gl.uniform1f(gl.getUniformLocation(prog, "depth"), .75);
249
- gl.uniform4f(gl.getUniformLocation(prog, "color"), 1, 0, 0, 1);
250
- drawTriangle(gl);
251
- gl.disable(gl.DEPTH_TEST);
252
- const pixels = new Uint8Array(W * H * 4);
253
- gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
254
- destroyTestFBOWithDepth(gl, fbo);
255
- let allGreen = true;
256
- for (let i = 0; i < W * H * 4; i += 4) {
257
- if (!pixelClose(pixels.subarray(i, i + 4), [
258
- 0,
259
- 255,
260
- 0,
261
- 255
262
- ], 3)) {
263
- allGreen = false;
264
- break;
265
- }
266
- }
267
- expect(allGreen).toBe(true);
268
- expect(gl.getError()).toBe(gl.NO_ERROR);
269
- });
270
- await it("depthMask(false) prevents depth writes", async () => {
271
- const W = 10, H = 10;
272
- const fbo = makeTestFBOWithDepth(gl, W, H);
273
- gl.clearColor(0, 0, 0, 0);
274
- gl.clearDepth(1);
275
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
276
- gl.enable(gl.DEPTH_TEST);
277
- gl.depthFunc(gl.LESS);
278
- const prog = makeProgram(gl, VS_DEPTH, FS_COLOR);
279
- gl.useProgram(prog);
280
- gl.depthMask(false);
281
- gl.uniform1f(gl.getUniformLocation(prog, "depth"), .5);
282
- gl.uniform4f(gl.getUniformLocation(prog, "color"), 1, 0, 0, 1);
283
- drawTriangle(gl);
284
- gl.depthMask(true);
285
- gl.uniform1f(gl.getUniformLocation(prog, "depth"), .75);
286
- gl.uniform4f(gl.getUniformLocation(prog, "color"), 0, 1, 0, 1);
287
- drawTriangle(gl);
288
- gl.disable(gl.DEPTH_TEST);
289
- const pixels = new Uint8Array(W * H * 4);
290
- gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
291
- destroyTestFBOWithDepth(gl, fbo);
292
- let allGreen = true;
293
- for (let i = 0; i < W * H * 4; i += 4) {
294
- if (!pixelClose(pixels.subarray(i, i + 4), [
295
- 0,
296
- 255,
297
- 0,
298
- 255
299
- ], 3)) {
300
- allGreen = false;
301
- break;
302
- }
303
- }
304
- expect(allGreen).toBe(true);
305
- expect(gl.getError()).toBe(gl.NO_ERROR);
306
- });
307
- });
308
- await describe("rendering/scissor", async () => {
309
- beforeEach(async () => {
310
- glArea.make_current();
311
- });
312
- await it("scissor test clips rendering to specified rectangle", async () => {
313
- const W = 20, H = 20;
314
- const fbo = makeTestFBO(gl, W, H);
315
- gl.clearColor(1, 0, 0, 1);
316
- gl.clear(gl.COLOR_BUFFER_BIT);
317
- gl.enable(gl.SCISSOR_TEST);
318
- gl.scissor(0, 0, W / 2, H);
319
- gl.clearColor(0, 1, 0, 1);
320
- gl.clear(gl.COLOR_BUFFER_BIT);
321
- gl.disable(gl.SCISSOR_TEST);
322
- const pixels = new Uint8Array(W * H * 4);
323
- gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
324
- destroyTestFBO(gl, fbo);
325
- let ok = true;
326
- for (let y = 0; y < H; y++) {
327
- for (let x = 0; x < W; x++) {
328
- const i = (y * W + x) * 4;
329
- const pix = pixels.subarray(i, i + 4);
330
- if (x < W / 2) {
331
- if (!pixelClose(pix, [
332
- 0,
333
- 255,
334
- 0,
335
- 255
336
- ])) {
337
- ok = false;
338
- break;
339
- }
340
- } else {
341
- if (!pixelClose(pix, [
342
- 255,
343
- 0,
344
- 0,
345
- 255
346
- ])) {
347
- ok = false;
348
- break;
349
- }
350
- }
351
- }
352
- if (!ok) break;
353
- }
354
- expect(ok).toBe(true);
355
- expect(gl.getError()).toBe(gl.NO_ERROR);
356
- });
357
- });
358
- await describe("rendering/mapbox-ansis", async () => {
359
- beforeEach(async () => {
360
- glArea.make_current();
361
- });
362
- await it("depthRange: green at range(0,0.1) survives blue at range(0.9,1) with LEQUAL", async () => {
363
- const W = 4, H = 4;
364
- const vsSrc = `
12
+ void main() { gl_FragColor = vec4(${t.srcColor[0]},${t.srcColor[1]},${t.srcColor[2]},${t.srcColor[3]}); }`;g.clearColor(t.dstColor[0],t.dstColor[1],t.dstColor[2],t.dstColor[3]),g.clear(g.COLOR_BUFFER_BIT);let c=r(g,p,s);g.useProgram(c),g.enable(g.BLEND),g.blendEquation(t.equation),g.blendFunc(t.srcFactor,t.dstFactor),n(g),g.disable(g.BLEND);let l=new Uint8Array(16);g.readPixels(0,0,2,2,g.RGBA,g.UNSIGNED_BYTE,l),e(g,a);let u=t.expected.map(e=>Math.round(e*255));for(let e=0;e<16;e+=4)if(!o(l.subarray(e,e+4),u,4))return!1;return!0}await d(`FUNC_ADD ONE ONE: dst=[0.5,0.5,0.5,1] + src=[0.5,0.5,0.5,1] = [1,1,1,1]`,async()=>{u(t({name:`ADD ONE ONE`,equation:g.FUNC_ADD,srcFactor:g.ONE,dstFactor:g.ONE,dstColor:[.5,.5,.5,1],srcColor:[.5,.5,.5,1],expected:[1,1,1,1]})).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)}),await d(`FUNC_ADD ONE ZERO: dst=[0.5,0.5,0.5,0.5] + src=[0.2,0.2,0.2,1] = [0.2,0.2,0.2,1]`,async()=>{u(t({name:`ADD ONE ZERO`,equation:g.FUNC_ADD,srcFactor:g.ONE,dstFactor:g.ZERO,dstColor:[.5,.5,.5,.5],srcColor:[.2,.2,.2,1],expected:[.2,.2,.2,1]})).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)}),await d(`FUNC_ADD ZERO SRC_COLOR: dst=[0.8,0.8,0.8,1] * src=[0.5,0.5,0.5,0.5] = [0.4,0.4,0.4,0.5]`,async()=>{u(t({name:`ADD ZERO SRC_COLOR`,equation:g.FUNC_ADD,srcFactor:g.ZERO,dstFactor:g.SRC_COLOR,dstColor:[.8,.8,.8,1],srcColor:[.5,.5,.5,.5],expected:[.4,.4,.4,.5]})).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)}),await d(`FUNC_ADD DST_COLOR ZERO: dst=[0.8,0.8,0.8,1] src=[0.5,0.5,0.5,0.5] = [0.4,0.4,0.4,0.5]`,async()=>{u(t({name:`ADD DST_COLOR ZERO`,equation:g.FUNC_ADD,srcFactor:g.DST_COLOR,dstFactor:g.ZERO,dstColor:[.8,.8,.8,1],srcColor:[.5,.5,.5,.5],expected:[.4,.4,.4,.5]})).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)}),await d(`FUNC_ADD SRC_ALPHA ONE_MINUS_SRC_ALPHA: alpha=0.5 blend`,async()=>{u(t({name:`ADD SRC_ALPHA ONE_MINUS_SRC_ALPHA`,equation:g.FUNC_ADD,srcFactor:g.SRC_ALPHA,dstFactor:g.ONE_MINUS_SRC_ALPHA,dstColor:[.5,0,.5,1],srcColor:[.5,1,0,.5],expected:[.5,.5,.25,.75]})).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)})}),await l(`rendering/depth-buffer`,async()=>{c(async()=>{_.make_current()}),await d(`DEPTH_TEST NOTEQUAL: both passes render because depths differ`,async()=>{let e=a(g,50,50);g.clearColor(0,0,0,0),g.clearDepth(1),g.clear(g.COLOR_BUFFER_BIT|g.DEPTH_BUFFER_BIT),g.enable(g.DEPTH_TEST),g.depthFunc(g.NOTEQUAL);let i=r(g,m,h);g.useProgram(i),g.uniform1f(g.getUniformLocation(i,`depth`),0),g.uniform4f(g.getUniformLocation(i,`color`),1,0,0,1),n(g),g.uniform1f(g.getUniformLocation(i,`depth`),1),g.uniform4f(g.getUniformLocation(i,`color`),0,1,0,1),n(g),g.disable(g.DEPTH_TEST);let s=new Uint8Array(2500*4);g.readPixels(0,0,50,50,g.RGBA,g.UNSIGNED_BYTE,s),t(g,e);let c=!0;for(let e=0;e<2500*4;e+=4)if(!o(s.subarray(e,e+4),[0,255,0,255],3)){c=!1;break}u(c).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)}),await d(`DEPTH_TEST LESS: closer triangle overwrites farther`,async()=>{let e=a(g,20,20);g.clearColor(0,0,0,0),g.clearDepth(1),g.clear(g.COLOR_BUFFER_BIT|g.DEPTH_BUFFER_BIT),g.enable(g.DEPTH_TEST),g.depthFunc(g.LESS);let i=r(g,m,h);g.useProgram(i),g.uniform1f(g.getUniformLocation(i,`depth`),.5),g.uniform4f(g.getUniformLocation(i,`color`),0,0,1,1),n(g),g.uniform1f(g.getUniformLocation(i,`depth`),.25),g.uniform4f(g.getUniformLocation(i,`color`),0,1,0,1),n(g),g.uniform1f(g.getUniformLocation(i,`depth`),.75),g.uniform4f(g.getUniformLocation(i,`color`),1,0,0,1),n(g),g.disable(g.DEPTH_TEST);let s=new Uint8Array(400*4);g.readPixels(0,0,20,20,g.RGBA,g.UNSIGNED_BYTE,s),t(g,e);let c=!0;for(let e=0;e<400*4;e+=4)if(!o(s.subarray(e,e+4),[0,255,0,255],3)){c=!1;break}u(c).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)}),await d(`depthMask(false) prevents depth writes`,async()=>{let e=a(g,10,10);g.clearColor(0,0,0,0),g.clearDepth(1),g.clear(g.COLOR_BUFFER_BIT|g.DEPTH_BUFFER_BIT),g.enable(g.DEPTH_TEST),g.depthFunc(g.LESS);let i=r(g,m,h);g.useProgram(i),g.depthMask(!1),g.uniform1f(g.getUniformLocation(i,`depth`),.5),g.uniform4f(g.getUniformLocation(i,`color`),1,0,0,1),n(g),g.depthMask(!0),g.uniform1f(g.getUniformLocation(i,`depth`),.75),g.uniform4f(g.getUniformLocation(i,`color`),0,1,0,1),n(g),g.disable(g.DEPTH_TEST);let s=new Uint8Array(400);g.readPixels(0,0,10,10,g.RGBA,g.UNSIGNED_BYTE,s),t(g,e);let c=!0;for(let e=0;e<400;e+=4)if(!o(s.subarray(e,e+4),[0,255,0,255],3)){c=!1;break}u(c).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)})}),await l(`rendering/scissor`,async()=>{c(async()=>{_.make_current()}),await d(`scissor test clips rendering to specified rectangle`,async()=>{let t=i(g,20,20);g.clearColor(1,0,0,1),g.clear(g.COLOR_BUFFER_BIT),g.enable(g.SCISSOR_TEST),g.scissor(0,0,20/2,20),g.clearColor(0,1,0,1),g.clear(g.COLOR_BUFFER_BIT),g.disable(g.SCISSOR_TEST);let n=new Uint8Array(400*4);g.readPixels(0,0,20,20,g.RGBA,g.UNSIGNED_BYTE,n),e(g,t);let r=!0;for(let e=0;e<20;e++){for(let t=0;t<20;t++){let i=(e*20+t)*4,a=n.subarray(i,i+4);if(t<20/2){if(!o(a,[0,255,0,255])){r=!1;break}}else if(!o(a,[255,0,0,255])){r=!1;break}}if(!r)break}u(r).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)})}),await l(`rendering/mapbox-ansis`,async()=>{c(async()=>{_.make_current()}),await d(`depthRange: green at range(0,0.1) survives blue at range(0.9,1) with LEQUAL`,async()=>{let e=g.createFramebuffer(),t=g.createTexture();g.bindTexture(g.TEXTURE_2D,t),g.texImage2D(g.TEXTURE_2D,0,g.RGBA,4,4,0,g.RGBA,g.UNSIGNED_BYTE,null),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MIN_FILTER,g.NEAREST),g.texParameteri(g.TEXTURE_2D,g.TEXTURE_MAG_FILTER,g.NEAREST),g.bindTexture(g.TEXTURE_2D,null);let n=g.createRenderbuffer();g.bindRenderbuffer(g.RENDERBUFFER,n),g.renderbufferStorage(g.RENDERBUFFER,g.DEPTH_COMPONENT16,4,4),g.bindRenderbuffer(g.RENDERBUFFER,null),g.bindFramebuffer(g.FRAMEBUFFER,e),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,t,0),g.framebufferRenderbuffer(g.FRAMEBUFFER,g.DEPTH_ATTACHMENT,g.RENDERBUFFER,n),g.viewport(0,0,4,4),g.clearColor(1,0,0,1),g.clearDepth(1),g.clear(g.COLOR_BUFFER_BIT|g.DEPTH_BUFFER_BIT),g.enable(g.DEPTH_TEST),g.depthFunc(g.LEQUAL);let i=r(g,`
365
13
  precision mediump float;
366
14
  uniform float u_z;
367
15
  attribute vec2 a_position;
368
- void main() { gl_Position = vec4(a_position, u_z, 1.0); }`;
369
- const fsSrc = `
16
+ void main() { gl_Position = vec4(a_position, u_z, 1.0); }`,`
370
17
  precision mediump float;
371
18
  uniform vec4 u_color;
372
- void main() { gl_FragColor = u_color; }`;
373
- const fb = gl.createFramebuffer();
374
- const colorTex = gl.createTexture();
375
- gl.bindTexture(gl.TEXTURE_2D, colorTex);
376
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, W, H, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
377
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
378
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
379
- gl.bindTexture(gl.TEXTURE_2D, null);
380
- const depthRb = gl.createRenderbuffer();
381
- gl.bindRenderbuffer(gl.RENDERBUFFER, depthRb);
382
- gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, W, H);
383
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
384
- gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
385
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
386
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRb);
387
- gl.viewport(0, 0, W, H);
388
- gl.clearColor(1, 0, 0, 1);
389
- gl.clearDepth(1);
390
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
391
- gl.enable(gl.DEPTH_TEST);
392
- gl.depthFunc(gl.LEQUAL);
393
- const prog = makeProgram(gl, vsSrc, fsSrc);
394
- gl.useProgram(prog);
395
- const buf = gl.createBuffer();
396
- gl.bindBuffer(gl.ARRAY_BUFFER, buf);
397
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
398
- -1,
399
- -1,
400
- 1,
401
- -1,
402
- -1,
403
- 1,
404
- -1,
405
- 1,
406
- 1,
407
- -1,
408
- 1,
409
- 1
410
- ]), gl.STATIC_DRAW);
411
- const aPos = gl.getAttribLocation(prog, "a_position");
412
- gl.enableVertexAttribArray(aPos);
413
- gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
414
- const uColor = gl.getUniformLocation(prog, "u_color");
415
- const uZ = gl.getUniformLocation(prog, "u_z");
416
- gl.uniform1f(uZ, .5);
417
- gl.uniform4fv(uColor, [
418
- 0,
419
- 1,
420
- 0,
421
- 1
422
- ]);
423
- gl.depthRange(0, .1);
424
- gl.drawArrays(gl.TRIANGLES, 0, 6);
425
- gl.uniform1f(uZ, .5);
426
- gl.uniform4fv(uColor, [
427
- 0,
428
- 0,
429
- 1,
430
- 1
431
- ]);
432
- gl.depthRange(.9, 1);
433
- gl.drawArrays(gl.TRIANGLES, 0, 6);
434
- gl.depthRange(0, 1);
435
- gl.disable(gl.DEPTH_TEST);
436
- const pixels = new Uint8Array(W * H * 4);
437
- gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
438
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
439
- gl.deleteBuffer(buf);
440
- gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
441
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
442
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
443
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
444
- gl.deleteTexture(colorTex);
445
- gl.deleteRenderbuffer(depthRb);
446
- gl.deleteFramebuffer(fb);
447
- expect(gl.getError()).toBe(gl.NO_ERROR);
448
- let allGreen = true;
449
- for (let i = 0; i < W * H * 4; i += 4) {
450
- if (pixels[i] !== 0 || pixels[i + 1] !== 255 || pixels[i + 2] !== 0 || pixels[i + 3] !== 255) {
451
- allGreen = false;
452
- break;
453
- }
454
- }
455
- expect(allGreen).toBe(true);
456
- });
457
- });
458
- await describe("rendering/viewport", async () => {
459
- beforeEach(async () => {
460
- glArea.make_current();
461
- });
462
- await it("viewport restricts rendering region", async () => {
463
- const W = 20, H = 20;
464
- const fbo = makeTestFBO(gl, W, H);
465
- gl.clearColor(1, 0, 0, 1);
466
- gl.clear(gl.COLOR_BUFFER_BIT);
467
- const HW = W / 2;
468
- gl.viewport(0, 0, HW, H / 2);
469
- const fsGreen = `precision mediump float; void main() { gl_FragColor = vec4(0,1,0,1); }`;
470
- const prog = makeProgram(gl, VS, fsGreen);
471
- gl.useProgram(prog);
472
- drawTriangle(gl);
473
- gl.viewport(0, 0, W, H);
474
- const pixels = new Uint8Array(W * H * 4);
475
- gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
476
- destroyTestFBO(gl, fbo);
477
- let ok = true;
478
- for (let y = 0; y < H; y++) {
479
- for (let x = 0; x < W; x++) {
480
- const i = (y * W + x) * 4;
481
- const pix = pixels.subarray(i, i + 4);
482
- if (x < HW && y < H / 2) {
483
- if (!pixelClose(pix, [
484
- 0,
485
- 255,
486
- 0,
487
- 255
488
- ])) {
489
- ok = false;
490
- break;
491
- }
492
- } else {
493
- if (!pixelClose(pix, [
494
- 255,
495
- 0,
496
- 0,
497
- 255
498
- ])) {
499
- ok = false;
500
- break;
501
- }
502
- }
503
- }
504
- if (!ok) break;
505
- }
506
- expect(ok).toBe(true);
507
- expect(gl.getError()).toBe(gl.NO_ERROR);
508
- });
509
- await it("getParameter(VIEWPORT) returns current viewport", async () => {
510
- const fbo = makeTestFBO(gl, 16, 16);
511
- gl.viewport(2, 3, 10, 12);
512
- const v = gl.getParameter(gl.VIEWPORT);
513
- expect(v[0]).toBe(2);
514
- expect(v[1]).toBe(3);
515
- expect(v[2]).toBe(10);
516
- expect(v[3]).toBe(12);
517
- gl.viewport(0, 0, 16, 16);
518
- destroyTestFBO(gl, fbo);
519
- expect(gl.getError()).toBe(gl.NO_ERROR);
520
- });
521
- });
522
- });
523
- };
524
-
525
- //#endregion
526
- export { rendering_spec_default as default };
19
+ void main() { gl_FragColor = u_color; }`);g.useProgram(i);let a=g.createBuffer();g.bindBuffer(g.ARRAY_BUFFER,a),g.bufferData(g.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),g.STATIC_DRAW);let o=g.getAttribLocation(i,`a_position`);g.enableVertexAttribArray(o),g.vertexAttribPointer(o,2,g.FLOAT,!1,0,0);let s=g.getUniformLocation(i,`u_color`),c=g.getUniformLocation(i,`u_z`);g.uniform1f(c,.5),g.uniform4fv(s,[0,1,0,1]),g.depthRange(0,.1),g.drawArrays(g.TRIANGLES,0,6),g.uniform1f(c,.5),g.uniform4fv(s,[0,0,1,1]),g.depthRange(.9,1),g.drawArrays(g.TRIANGLES,0,6),g.depthRange(0,1),g.disable(g.DEPTH_TEST);let l=new Uint8Array(64);g.readPixels(0,0,4,4,g.RGBA,g.UNSIGNED_BYTE,l),g.bindBuffer(g.ARRAY_BUFFER,null),g.deleteBuffer(a),g.bindFramebuffer(g.FRAMEBUFFER,e),g.framebufferTexture2D(g.FRAMEBUFFER,g.COLOR_ATTACHMENT0,g.TEXTURE_2D,null,0),g.framebufferRenderbuffer(g.FRAMEBUFFER,g.DEPTH_ATTACHMENT,g.RENDERBUFFER,null),g.bindFramebuffer(g.FRAMEBUFFER,null),g.deleteTexture(t),g.deleteRenderbuffer(n),g.deleteFramebuffer(e),u(g.getError()).toBe(g.NO_ERROR);let d=!0;for(let e=0;e<64;e+=4)if(l[e]!==0||l[e+1]!==255||l[e+2]!==0||l[e+3]!==255){d=!1;break}u(d).toBe(!0)})}),await l(`rendering/viewport`,async()=>{c(async()=>{_.make_current()}),await d(`viewport restricts rendering region`,async()=>{let t=i(g,20,20);g.clearColor(1,0,0,1),g.clear(g.COLOR_BUFFER_BIT),g.viewport(0,0,10,20/2);let a=r(g,p,`precision mediump float; void main() { gl_FragColor = vec4(0,1,0,1); }`);g.useProgram(a),n(g),g.viewport(0,0,20,20);let s=new Uint8Array(400*4);g.readPixels(0,0,20,20,g.RGBA,g.UNSIGNED_BYTE,s),e(g,t);let c=!0;for(let e=0;e<20;e++){for(let t=0;t<20;t++){let n=(e*20+t)*4,r=s.subarray(n,n+4);if(t<10&&e<20/2){if(!o(r,[0,255,0,255])){c=!1;break}}else if(!o(r,[255,0,0,255])){c=!1;break}}if(!c)break}u(c).toBe(!0),u(g.getError()).toBe(g.NO_ERROR)}),await d(`getParameter(VIEWPORT) returns current viewport`,async()=>{let t=i(g,16,16);g.viewport(2,3,10,12);let n=g.getParameter(g.VIEWPORT);u(n[0]).toBe(2),u(n[1]).toBe(3),u(n[2]).toBe(10),u(n[3]).toBe(12),g.viewport(0,0,16,16),e(g,t),u(g.getError()).toBe(g.NO_ERROR)})})})};export{g as default};
@@ -1,47 +1 @@
1
- import { WebGLBridge } from "@gjsify/webgl";
2
- import GLib from "@girs/glib-2.0";
3
- import Gtk from "@girs/gtk-4.0";
4
-
5
- //#region src/ts/conformance/setup.ts
6
- /**
7
- * Synchronously initialises a GTK window + WebGLBridge and blocks until
8
- * the GL context is ready (or 10 s timeout).
9
- * Returns null when no display is available.
10
- */
11
- function createGLSetup() {
12
- Gtk.init();
13
- let result = null;
14
- const readyLoop = new GLib.MainLoop(null, false);
15
- const win = new Gtk.Window({});
16
- win.set_default_size(200, 200);
17
- const glArea = new WebGLBridge();
18
- glArea.onReady((canvas, g) => {
19
- try {
20
- const gl = g;
21
- let gl2 = null;
22
- try {
23
- gl2 = canvas.getContext("webgl2");
24
- } catch (_) {}
25
- result = {
26
- gl,
27
- gl2,
28
- glArea,
29
- win
30
- };
31
- } finally {
32
- readyLoop.quit();
33
- }
34
- });
35
- win.set_child(glArea);
36
- win.present();
37
- const giveUpId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1e4, () => {
38
- readyLoop.quit();
39
- return GLib.SOURCE_REMOVE;
40
- });
41
- readyLoop.run();
42
- GLib.source_remove(giveUpId);
43
- return result;
44
- }
45
-
46
- //#endregion
47
- export { createGLSetup };
1
+ import{WebGLBridge as e}from"@gjsify/webgl";import t from"@girs/glib-2.0";import n from"@girs/gtk-4.0";function r(){n.init();let r=null,i=new t.MainLoop(null,!1),a=new n.Window({});a.set_default_size(200,200);let o=new e;o.onReady((e,t)=>{try{let n=t,i=null;try{i=e.getContext(`webgl2`)}catch{}r={gl:n,gl2:i,glArea:o,win:a}}finally{i.quit()}}),a.set_child(o),a.present();let s=t.timeout_add(t.PRIORITY_DEFAULT,1e4,()=>(i.quit(),t.SOURCE_REMOVE));return i.run(),t.source_remove(s),r}export{r as createGLSetup};