@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.
- package/lib/esm/conformance/attribs.spec.js +312 -293
- package/lib/esm/conformance/buffers.spec.js +217 -200
- package/lib/esm/conformance/context.spec.js +295 -295
- package/lib/esm/conformance/programs.spec.js +458 -445
- package/lib/esm/conformance/rendering-basic.spec.js +134 -128
- package/lib/esm/conformance/rendering.spec.js +502 -400
- package/lib/esm/conformance/setup.js +42 -31
- package/lib/esm/conformance/state.spec.js +360 -343
- package/lib/esm/conformance/textures.spec.js +330 -338
- package/lib/esm/conformance/uniforms.spec.js +465 -309
- package/lib/esm/conformance-test.js +24 -22
- package/lib/esm/extensions/ext-blend-minmax.js +16 -16
- package/lib/esm/extensions/ext-color-buffer-float.js +10 -11
- package/lib/esm/extensions/ext-color-buffer-half-float.js +10 -11
- package/lib/esm/extensions/ext-texture-filter-anisotropic.js +16 -16
- package/lib/esm/extensions/oes-element-index-unit.js +11 -12
- package/lib/esm/extensions/oes-standard-derivatives.js +15 -15
- package/lib/esm/extensions/oes-texture-float-linear.js +11 -12
- package/lib/esm/extensions/oes-texture-float.js +11 -12
- package/lib/esm/extensions/oes-texture-half-float.js +17 -17
- package/lib/esm/extensions/stackgl-destroy-context.js +10 -10
- package/lib/esm/extensions/stackgl-resize-drawing-buffer.js +10 -10
- package/lib/esm/html-canvas-element.js +64 -64
- package/lib/esm/index.js +29 -26
- package/lib/esm/linkable.js +49 -49
- package/lib/esm/test-utils.js +158 -107
- package/lib/esm/test.js +8 -4
- package/lib/esm/types/index.js +5 -5
- package/lib/esm/utils.js +164 -187
- package/lib/esm/webgl-active-info.js +10 -9
- package/lib/esm/webgl-bridge.js +162 -147
- package/lib/esm/webgl-buffer.js +17 -15
- package/lib/esm/webgl-context-attributes.js +23 -22
- package/lib/esm/webgl-context-base.js +3039 -3351
- package/lib/esm/webgl-drawing-buffer-wrapper.js +10 -9
- package/lib/esm/webgl-framebuffer.js +108 -106
- package/lib/esm/webgl-program.js +25 -23
- package/lib/esm/webgl-query.js +15 -13
- package/lib/esm/webgl-renderbuffer.js +23 -21
- package/lib/esm/webgl-rendering-context.js +173 -187
- package/lib/esm/webgl-sampler.js +15 -13
- package/lib/esm/webgl-shader-precision-format.js +10 -9
- package/lib/esm/webgl-shader.js +23 -21
- package/lib/esm/webgl-sync.js +15 -13
- package/lib/esm/webgl-texture-unit.js +12 -11
- package/lib/esm/webgl-texture.js +21 -19
- package/lib/esm/webgl-transform-feedback.js +15 -13
- package/lib/esm/webgl-uniform-location.js +14 -13
- package/lib/esm/webgl-vertex-array-object.js +20 -18
- package/lib/esm/webgl-vertex-attribute.js +149 -145
- package/lib/esm/webgl1.spec.js +1039 -650
- package/lib/esm/webgl2-rendering-context.js +1210 -1273
- package/lib/esm/webgl2.spec.js +1284 -1252
- package/package.json +9 -9
- package/lib/esm/@types/glsl-tokenizer/index.d.js +0 -0
package/lib/esm/webgl2.spec.js
CHANGED
|
@@ -1,1256 +1,1288 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
makeProgram,
|
|
5
|
-
drawTriangle,
|
|
6
|
-
readPixel,
|
|
7
|
-
makeTestFBO,
|
|
8
|
-
destroyTestFBO,
|
|
9
|
-
makeTestFBOFloat,
|
|
10
|
-
makeTestFBOWithDepthTexture,
|
|
11
|
-
TEXTURE_VS_300,
|
|
12
|
-
TEXTURE_FS_300
|
|
13
|
-
} from "./test-utils.js";
|
|
1
|
+
import { TEXTURE_FS_300, TEXTURE_VS_300, destroyTestFBO, drawTriangle, makeProgram, makeTestFBO, makeTestFBOFloat, makeTestFBOWithDepthTexture, readPixel } from "./test-utils.js";
|
|
2
|
+
import { beforeEach, describe, expect, it, on } from "@gjsify/unit";
|
|
3
|
+
import { WebGL2RenderingContext, WebGLBridge } from "@gjsify/webgl";
|
|
14
4
|
import GLib from "@girs/glib-2.0";
|
|
15
5
|
import Gtk from "@girs/gtk-4.0";
|
|
6
|
+
|
|
7
|
+
//#region src/ts/webgl2.spec.ts
|
|
16
8
|
var webgl2_spec_default = async () => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
9
|
+
await on("Display", async () => {
|
|
10
|
+
Gtk.init();
|
|
11
|
+
let glArea;
|
|
12
|
+
let gl2;
|
|
13
|
+
const readyLoop = new GLib.MainLoop(null, false);
|
|
14
|
+
const win = new Gtk.Window({});
|
|
15
|
+
win.set_default_size(200, 200);
|
|
16
|
+
glArea = new WebGLBridge();
|
|
17
|
+
glArea.onReady((c, _g) => {
|
|
18
|
+
gl2 = c.getContext("webgl2");
|
|
19
|
+
readyLoop.quit();
|
|
20
|
+
});
|
|
21
|
+
win.set_child(glArea);
|
|
22
|
+
win.present();
|
|
23
|
+
const giveUpId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1e4, () => {
|
|
24
|
+
readyLoop.quit();
|
|
25
|
+
return GLib.SOURCE_REMOVE;
|
|
26
|
+
});
|
|
27
|
+
readyLoop.run();
|
|
28
|
+
GLib.source_remove(giveUpId);
|
|
29
|
+
if (!gl2) {
|
|
30
|
+
console.warn("WebGL2 context not available — skipping WebGL2 tests");
|
|
31
|
+
win.destroy();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
glArea.make_current();
|
|
35
|
+
await describe("WebGL2 context", async () => {
|
|
36
|
+
beforeEach(async () => {
|
|
37
|
+
glArea.make_current();
|
|
38
|
+
});
|
|
39
|
+
await it("getContext(\"webgl2\") returns a WebGL2RenderingContext", async () => {
|
|
40
|
+
expect(gl2).toBeInstanceOf(WebGL2RenderingContext);
|
|
41
|
+
});
|
|
42
|
+
await it("VERSION is \"WebGL 2.0\"", async () => {
|
|
43
|
+
expect(gl2.getParameter(gl2.VERSION)).toBe("WebGL 2.0");
|
|
44
|
+
});
|
|
45
|
+
await it("SHADING_LANGUAGE_VERSION is \"WebGL GLSL ES 3.00\"", async () => {
|
|
46
|
+
expect(gl2.getParameter(gl2.SHADING_LANGUAGE_VERSION)).toBe("WebGL GLSL ES 3.00");
|
|
47
|
+
});
|
|
48
|
+
await it("drawingBufferWidth and drawingBufferHeight are positive", async () => {
|
|
49
|
+
expect(gl2.drawingBufferWidth > 0).toBeTruthy();
|
|
50
|
+
expect(gl2.drawingBufferHeight > 0).toBeTruthy();
|
|
51
|
+
});
|
|
52
|
+
await it("getError() returns NO_ERROR initially", async () => {
|
|
53
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
await describe("GLSL ES 3.00 compilation", async () => {
|
|
57
|
+
beforeEach(async () => {
|
|
58
|
+
glArea.make_current();
|
|
59
|
+
});
|
|
60
|
+
const VS300 = [
|
|
61
|
+
"#version 300 es",
|
|
62
|
+
"in vec2 position;",
|
|
63
|
+
"void main() { gl_Position = vec4(position, 0.0, 1.0); }"
|
|
64
|
+
].join("\n");
|
|
65
|
+
const FS300 = [
|
|
66
|
+
"#version 300 es",
|
|
67
|
+
"precision mediump float;",
|
|
68
|
+
"out vec4 fragColor;",
|
|
69
|
+
"void main() { fragColor = vec4(0.0, 1.0, 0.0, 1.0); }"
|
|
70
|
+
].join("\n");
|
|
71
|
+
await it("#version 300 es vertex shader compiles", async () => {
|
|
72
|
+
const sh = gl2.createShader(gl2.VERTEX_SHADER);
|
|
73
|
+
gl2.shaderSource(sh, VS300);
|
|
74
|
+
gl2.compileShader(sh);
|
|
75
|
+
if (!gl2.getShaderParameter(sh, gl2.COMPILE_STATUS)) {
|
|
76
|
+
console.error("VS300 log:", gl2.getShaderInfoLog(sh));
|
|
77
|
+
}
|
|
78
|
+
expect(gl2.getShaderParameter(sh, gl2.COMPILE_STATUS)).toBeTruthy();
|
|
79
|
+
gl2.deleteShader(sh);
|
|
80
|
+
});
|
|
81
|
+
await it("#version 300 es fragment shader compiles", async () => {
|
|
82
|
+
const sh = gl2.createShader(gl2.FRAGMENT_SHADER);
|
|
83
|
+
gl2.shaderSource(sh, FS300);
|
|
84
|
+
gl2.compileShader(sh);
|
|
85
|
+
if (!gl2.getShaderParameter(sh, gl2.COMPILE_STATUS)) {
|
|
86
|
+
console.error("FS300 log:", gl2.getShaderInfoLog(sh));
|
|
87
|
+
}
|
|
88
|
+
expect(gl2.getShaderParameter(sh, gl2.COMPILE_STATUS)).toBeTruthy();
|
|
89
|
+
gl2.deleteShader(sh);
|
|
90
|
+
});
|
|
91
|
+
await it("#version 300 es program links and renders green", async () => {
|
|
92
|
+
const prog = makeProgram(gl2, VS300, FS300);
|
|
93
|
+
if (!gl2.getProgramParameter(prog, gl2.LINK_STATUS)) {
|
|
94
|
+
console.error("Program300 log:", gl2.getProgramInfoLog(prog));
|
|
95
|
+
}
|
|
96
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
97
|
+
const fbo = makeTestFBO(gl2, 4, 4);
|
|
98
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
99
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
100
|
+
gl2.useProgram(prog);
|
|
101
|
+
drawTriangle(gl2);
|
|
102
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
103
|
+
const p = readPixel(gl2, 0, 0);
|
|
104
|
+
destroyTestFBO(gl2, fbo);
|
|
105
|
+
expect(p[0]).toBe(0);
|
|
106
|
+
expect(p[1]).toBe(255);
|
|
107
|
+
expect(p[2]).toBe(0);
|
|
108
|
+
expect(p[3]).toBe(255);
|
|
109
|
+
gl2.deleteProgram(prog);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
await describe("VAO", async () => {
|
|
113
|
+
beforeEach(async () => {
|
|
114
|
+
glArea.make_current();
|
|
115
|
+
});
|
|
116
|
+
await it("createVertexArray returns a non-null object", async () => {
|
|
117
|
+
const vao = gl2.createVertexArray();
|
|
118
|
+
expect(vao).not.toBeNull();
|
|
119
|
+
expect(vao).toBeDefined();
|
|
120
|
+
gl2.deleteVertexArray(vao);
|
|
121
|
+
});
|
|
122
|
+
await it("isVertexArray is true after creation, false after deletion", async () => {
|
|
123
|
+
const vao = gl2.createVertexArray();
|
|
124
|
+
gl2.bindVertexArray(vao);
|
|
125
|
+
expect(gl2.isVertexArray(vao)).toBeTruthy();
|
|
126
|
+
gl2.bindVertexArray(null);
|
|
127
|
+
gl2.deleteVertexArray(vao);
|
|
128
|
+
expect(gl2.isVertexArray(vao)).toBeFalsy();
|
|
129
|
+
});
|
|
130
|
+
await it("VAO preserves vertex attribute state", async () => {
|
|
131
|
+
const VS = [
|
|
132
|
+
"#version 300 es",
|
|
133
|
+
"in vec2 position;",
|
|
134
|
+
"void main() { gl_Position = vec4(position,0.0,1.0); }"
|
|
135
|
+
].join("\n");
|
|
136
|
+
const FS = [
|
|
137
|
+
"#version 300 es",
|
|
138
|
+
"precision mediump float;",
|
|
139
|
+
"out vec4 c;",
|
|
140
|
+
"void main() { c = vec4(0.0,1.0,0.0,1.0); }"
|
|
141
|
+
].join("\n");
|
|
142
|
+
const prog = makeProgram(gl2, VS, FS);
|
|
143
|
+
gl2.useProgram(prog);
|
|
144
|
+
const fbo = makeTestFBO(gl2, 4, 4);
|
|
145
|
+
const vao = gl2.createVertexArray();
|
|
146
|
+
gl2.bindVertexArray(vao);
|
|
147
|
+
const buf = gl2.createBuffer();
|
|
148
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, buf);
|
|
149
|
+
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array([
|
|
150
|
+
-2,
|
|
151
|
+
-2,
|
|
152
|
+
-2,
|
|
153
|
+
4,
|
|
154
|
+
4,
|
|
155
|
+
-2
|
|
156
|
+
]), gl2.STREAM_DRAW);
|
|
157
|
+
gl2.enableVertexAttribArray(0);
|
|
158
|
+
gl2.vertexAttribPointer(0, 2, gl2.FLOAT, false, 0, 0);
|
|
159
|
+
gl2.bindVertexArray(null);
|
|
160
|
+
gl2.bindVertexArray(vao);
|
|
161
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
162
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
163
|
+
gl2.drawArrays(gl2.TRIANGLES, 0, 3);
|
|
164
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
165
|
+
const p = readPixel(gl2, 0, 0);
|
|
166
|
+
destroyTestFBO(gl2, fbo);
|
|
167
|
+
expect(p[1]).toBe(255);
|
|
168
|
+
gl2.bindVertexArray(null);
|
|
169
|
+
gl2.deleteVertexArray(vao);
|
|
170
|
+
gl2.deleteBuffer(buf);
|
|
171
|
+
gl2.deleteProgram(prog);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
await describe("getBufferSubData", async () => {
|
|
175
|
+
beforeEach(async () => {
|
|
176
|
+
glArea.make_current();
|
|
177
|
+
});
|
|
178
|
+
await it("reads back float data written with bufferData", async () => {
|
|
179
|
+
const src = new Float32Array([
|
|
180
|
+
1,
|
|
181
|
+
2,
|
|
182
|
+
3,
|
|
183
|
+
4
|
|
184
|
+
]);
|
|
185
|
+
const buf = gl2.createBuffer();
|
|
186
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, buf);
|
|
187
|
+
gl2.bufferData(gl2.ARRAY_BUFFER, src, gl2.STATIC_READ);
|
|
188
|
+
const dst = new Float32Array(4);
|
|
189
|
+
gl2.getBufferSubData(gl2.ARRAY_BUFFER, 0, dst);
|
|
190
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
191
|
+
expect(dst[0]).toBe(1);
|
|
192
|
+
expect(dst[1]).toBe(2);
|
|
193
|
+
expect(dst[2]).toBe(3);
|
|
194
|
+
expect(dst[3]).toBe(4);
|
|
195
|
+
gl2.deleteBuffer(buf);
|
|
196
|
+
});
|
|
197
|
+
await it("reads a sub-range correctly", async () => {
|
|
198
|
+
const src = new Float32Array([
|
|
199
|
+
10,
|
|
200
|
+
20,
|
|
201
|
+
30,
|
|
202
|
+
40
|
|
203
|
+
]);
|
|
204
|
+
const buf = gl2.createBuffer();
|
|
205
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, buf);
|
|
206
|
+
gl2.bufferData(gl2.ARRAY_BUFFER, src, gl2.STATIC_READ);
|
|
207
|
+
const dst = new Float32Array(2);
|
|
208
|
+
gl2.getBufferSubData(gl2.ARRAY_BUFFER, 8, dst);
|
|
209
|
+
expect(dst[0]).toBe(30);
|
|
210
|
+
expect(dst[1]).toBe(40);
|
|
211
|
+
gl2.deleteBuffer(buf);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
await describe("sync objects", async () => {
|
|
215
|
+
beforeEach(async () => {
|
|
216
|
+
glArea.make_current();
|
|
217
|
+
});
|
|
218
|
+
await it("fenceSync returns a non-null sync", async () => {
|
|
219
|
+
const sync = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
220
|
+
expect(sync).not.toBeNull();
|
|
221
|
+
gl2.deleteSync(sync);
|
|
222
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
223
|
+
});
|
|
224
|
+
await it("isSync is true before deletion, false after", async () => {
|
|
225
|
+
const sync = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
226
|
+
expect(gl2.isSync(sync)).toBeTruthy();
|
|
227
|
+
gl2.deleteSync(sync);
|
|
228
|
+
expect(gl2.isSync(sync)).toBeFalsy();
|
|
229
|
+
});
|
|
230
|
+
await it("clientWaitSync returns TIMEOUT_EXPIRED or CONDITION_SATISFIED", async () => {
|
|
231
|
+
const sync = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
232
|
+
gl2.flush();
|
|
233
|
+
const result = gl2.clientWaitSync(sync, 0, 0);
|
|
234
|
+
const valid = result === gl2.TIMEOUT_EXPIRED || result === gl2.CONDITION_SATISFIED || result === gl2.ALREADY_SIGNALED;
|
|
235
|
+
expect(valid).toBeTruthy();
|
|
236
|
+
gl2.deleteSync(sync);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
await describe("uint uniforms", async () => {
|
|
240
|
+
beforeEach(async () => {
|
|
241
|
+
glArea.make_current();
|
|
242
|
+
});
|
|
243
|
+
const VS_U = [
|
|
244
|
+
"#version 300 es",
|
|
245
|
+
"in vec2 position;",
|
|
246
|
+
"void main() { gl_Position = vec4(position,0.0,1.0); }"
|
|
247
|
+
].join("\n");
|
|
248
|
+
const FS_U = [
|
|
249
|
+
"#version 300 es",
|
|
250
|
+
"precision mediump float;",
|
|
251
|
+
"uniform uint uR; uniform uint uG; uniform uint uB;",
|
|
252
|
+
"out vec4 c;",
|
|
253
|
+
"void main() { c = vec4(float(uR)/255.0, float(uG)/255.0, float(uB)/255.0, 1.0); }"
|
|
254
|
+
].join("\n");
|
|
255
|
+
await it("uniform1ui sets an unsigned int uniform", async () => {
|
|
256
|
+
const prog = makeProgram(gl2, VS_U, FS_U);
|
|
257
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
258
|
+
gl2.useProgram(prog);
|
|
259
|
+
const locR = gl2.getUniformLocation(prog, "uR");
|
|
260
|
+
const locG = gl2.getUniformLocation(prog, "uG");
|
|
261
|
+
const locB = gl2.getUniformLocation(prog, "uB");
|
|
262
|
+
gl2.uniform1ui(locR, 0);
|
|
263
|
+
gl2.uniform1ui(locG, 255);
|
|
264
|
+
gl2.uniform1ui(locB, 0);
|
|
265
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
266
|
+
expect(gl2.getUniform(prog, locR)).toBe(0);
|
|
267
|
+
expect(gl2.getUniform(prog, locG)).toBe(255);
|
|
268
|
+
gl2.deleteProgram(prog);
|
|
269
|
+
});
|
|
270
|
+
await it("uniform2ui, uniform3ui, uniform4ui set without error", async () => {
|
|
271
|
+
const FS2 = [
|
|
272
|
+
"#version 300 es",
|
|
273
|
+
"precision mediump float;",
|
|
274
|
+
"uniform uvec2 u2; uniform uvec3 u3; uniform uvec4 u4;",
|
|
275
|
+
"out vec4 c;",
|
|
276
|
+
"void main() { c = vec4(float(u2.x), float(u3.x), float(u4.x), 1.0)/255.0; }"
|
|
277
|
+
].join("\n");
|
|
278
|
+
const prog = makeProgram(gl2, VS_U, FS2);
|
|
279
|
+
gl2.useProgram(prog);
|
|
280
|
+
gl2.uniform2ui(gl2.getUniformLocation(prog, "u2"), 1, 2);
|
|
281
|
+
gl2.uniform3ui(gl2.getUniformLocation(prog, "u3"), 1, 2, 3);
|
|
282
|
+
gl2.uniform4ui(gl2.getUniformLocation(prog, "u4"), 1, 2, 3, 4);
|
|
283
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
284
|
+
gl2.deleteProgram(prog);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
await describe("non-square matrix uniforms", async () => {
|
|
288
|
+
beforeEach(async () => {
|
|
289
|
+
glArea.make_current();
|
|
290
|
+
});
|
|
291
|
+
const VS_M = [
|
|
292
|
+
"#version 300 es",
|
|
293
|
+
"in vec2 position;",
|
|
294
|
+
"void main() { gl_Position = vec4(position,0.0,1.0); }"
|
|
295
|
+
].join("\n");
|
|
296
|
+
await it("uniformMatrix2x3fv sets a mat2x3 without error", async () => {
|
|
297
|
+
const FS = [
|
|
298
|
+
"#version 300 es",
|
|
299
|
+
"precision mediump float;",
|
|
300
|
+
"uniform mat2x3 m; out vec4 c;",
|
|
301
|
+
"void main() { c = vec4(m[0][0], m[0][1], m[0][2], 1.0); }"
|
|
302
|
+
].join("\n");
|
|
303
|
+
const prog = makeProgram(gl2, VS_M, FS);
|
|
304
|
+
gl2.useProgram(prog);
|
|
305
|
+
gl2.uniformMatrix2x3fv(gl2.getUniformLocation(prog, "m"), false, new Float32Array([
|
|
306
|
+
1,
|
|
307
|
+
0,
|
|
308
|
+
0,
|
|
309
|
+
0,
|
|
310
|
+
1,
|
|
311
|
+
0
|
|
312
|
+
]));
|
|
313
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
314
|
+
gl2.deleteProgram(prog);
|
|
315
|
+
});
|
|
316
|
+
await it("uniformMatrix3x2fv sets a mat3x2 without error", async () => {
|
|
317
|
+
const FS = [
|
|
318
|
+
"#version 300 es",
|
|
319
|
+
"precision mediump float;",
|
|
320
|
+
"uniform mat3x2 m; out vec4 c;",
|
|
321
|
+
"void main() { c = vec4(m[0][0], m[0][1], 0.0, 1.0); }"
|
|
322
|
+
].join("\n");
|
|
323
|
+
const prog = makeProgram(gl2, VS_M, FS);
|
|
324
|
+
gl2.useProgram(prog);
|
|
325
|
+
gl2.uniformMatrix3x2fv(gl2.getUniformLocation(prog, "m"), false, new Float32Array([
|
|
326
|
+
1,
|
|
327
|
+
0,
|
|
328
|
+
0,
|
|
329
|
+
1,
|
|
330
|
+
0,
|
|
331
|
+
0
|
|
332
|
+
]));
|
|
333
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
334
|
+
gl2.deleteProgram(prog);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
await describe("Uniform Buffer Objects", async () => {
|
|
338
|
+
beforeEach(async () => {
|
|
339
|
+
glArea.make_current();
|
|
340
|
+
});
|
|
341
|
+
await it("getUniformBlockIndex + uniformBlockBinding works", async () => {
|
|
342
|
+
const VS = [
|
|
343
|
+
"#version 300 es",
|
|
344
|
+
"layout(std140) uniform Params { vec4 color; };",
|
|
345
|
+
"in vec2 position;",
|
|
346
|
+
"out vec4 vColor;",
|
|
347
|
+
"void main() { vColor = color; gl_Position = vec4(position,0.0,1.0); }"
|
|
348
|
+
].join("\n");
|
|
349
|
+
const FS = [
|
|
350
|
+
"#version 300 es",
|
|
351
|
+
"precision mediump float;",
|
|
352
|
+
"in vec4 vColor; out vec4 c;",
|
|
353
|
+
"void main() { c = vColor; }"
|
|
354
|
+
].join("\n");
|
|
355
|
+
const prog = makeProgram(gl2, VS, FS);
|
|
356
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
357
|
+
const idx = gl2.getUniformBlockIndex(prog, "Params");
|
|
358
|
+
expect(idx).not.toBe(gl2.INVALID_INDEX);
|
|
359
|
+
gl2.uniformBlockBinding(prog, idx, 0);
|
|
360
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
361
|
+
const ubo = gl2.createBuffer();
|
|
362
|
+
gl2.bindBuffer(gl2.UNIFORM_BUFFER, ubo);
|
|
363
|
+
gl2.bufferData(gl2.UNIFORM_BUFFER, new Float32Array([
|
|
364
|
+
0,
|
|
365
|
+
1,
|
|
366
|
+
0,
|
|
367
|
+
1
|
|
368
|
+
]), gl2.STATIC_DRAW);
|
|
369
|
+
gl2.bindBufferBase(gl2.UNIFORM_BUFFER, 0, ubo);
|
|
370
|
+
const fbo = makeTestFBO(gl2, 4, 4);
|
|
371
|
+
gl2.useProgram(prog);
|
|
372
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
373
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
374
|
+
drawTriangle(gl2);
|
|
375
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
376
|
+
const p = readPixel(gl2, 0, 0);
|
|
377
|
+
destroyTestFBO(gl2, fbo);
|
|
378
|
+
expect(p[1]).toBe(255);
|
|
379
|
+
gl2.deleteBuffer(ubo);
|
|
380
|
+
gl2.deleteProgram(prog);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
await describe("instanced drawing", async () => {
|
|
384
|
+
beforeEach(async () => {
|
|
385
|
+
glArea.make_current();
|
|
386
|
+
});
|
|
387
|
+
await it("drawArraysInstanced renders without error", async () => {
|
|
388
|
+
const VS = [
|
|
389
|
+
"#version 300 es",
|
|
390
|
+
"in vec2 position;",
|
|
391
|
+
"void main() { gl_Position = vec4(position,0.0,1.0); }"
|
|
392
|
+
].join("\n");
|
|
393
|
+
const FS = [
|
|
394
|
+
"#version 300 es",
|
|
395
|
+
"precision mediump float;",
|
|
396
|
+
"out vec4 c;",
|
|
397
|
+
"void main() { c = vec4(0.0,1.0,0.0,1.0); }"
|
|
398
|
+
].join("\n");
|
|
399
|
+
const prog = makeProgram(gl2, VS, FS);
|
|
400
|
+
gl2.useProgram(prog);
|
|
401
|
+
const fbo = makeTestFBO(gl2, 4, 4);
|
|
402
|
+
const buf = gl2.createBuffer();
|
|
403
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, buf);
|
|
404
|
+
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array([
|
|
405
|
+
-2,
|
|
406
|
+
-2,
|
|
407
|
+
-2,
|
|
408
|
+
4,
|
|
409
|
+
4,
|
|
410
|
+
-2
|
|
411
|
+
]), gl2.STREAM_DRAW);
|
|
412
|
+
gl2.enableVertexAttribArray(0);
|
|
413
|
+
gl2.vertexAttribPointer(0, 2, gl2.FLOAT, false, 0, 0);
|
|
414
|
+
gl2.vertexAttribDivisor(0, 0);
|
|
415
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
416
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
417
|
+
gl2.drawArraysInstanced(gl2.TRIANGLES, 0, 3, 1);
|
|
418
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
419
|
+
const p = readPixel(gl2, 0, 0);
|
|
420
|
+
destroyTestFBO(gl2, fbo);
|
|
421
|
+
expect(p[1]).toBe(255);
|
|
422
|
+
gl2.disableVertexAttribArray(0);
|
|
423
|
+
gl2.deleteBuffer(buf);
|
|
424
|
+
gl2.deleteProgram(prog);
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
await describe("drawBuffers (MRT)", async () => {
|
|
428
|
+
beforeEach(async () => {
|
|
429
|
+
glArea.make_current();
|
|
430
|
+
});
|
|
431
|
+
await it("drawBuffers with 2 COLOR_ATTACHMENTs renders to both", async () => {
|
|
432
|
+
const VS = [
|
|
433
|
+
"#version 300 es",
|
|
434
|
+
"in vec2 position;",
|
|
435
|
+
"void main() { gl_Position = vec4(position,0.0,1.0); }"
|
|
436
|
+
].join("\n");
|
|
437
|
+
const FS = [
|
|
438
|
+
"#version 300 es",
|
|
439
|
+
"precision mediump float;",
|
|
440
|
+
"layout(location=0) out vec4 c0;",
|
|
441
|
+
"layout(location=1) out vec4 c1;",
|
|
442
|
+
"void main() { c0 = vec4(1.0,0.0,0.0,1.0); c1 = vec4(0.0,0.0,1.0,1.0); }"
|
|
443
|
+
].join("\n");
|
|
444
|
+
const prog = makeProgram(gl2, VS, FS);
|
|
445
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
446
|
+
const fb = gl2.createFramebuffer();
|
|
447
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fb);
|
|
448
|
+
const tex0 = gl2.createTexture();
|
|
449
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex0);
|
|
450
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, 4, 4, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, null);
|
|
451
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, tex0, 0);
|
|
452
|
+
const tex1 = gl2.createTexture();
|
|
453
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex1);
|
|
454
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, 4, 4, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, null);
|
|
455
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT1, gl2.TEXTURE_2D, tex1, 0);
|
|
456
|
+
const status = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
457
|
+
if (status !== gl2.FRAMEBUFFER_COMPLETE) {
|
|
458
|
+
console.warn("MRT framebuffer not complete:", status);
|
|
459
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
460
|
+
gl2.deleteFramebuffer(fb);
|
|
461
|
+
gl2.deleteTexture(tex0);
|
|
462
|
+
gl2.deleteTexture(tex1);
|
|
463
|
+
gl2.deleteProgram(prog);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
gl2.drawBuffers([gl2.COLOR_ATTACHMENT0, gl2.COLOR_ATTACHMENT1]);
|
|
467
|
+
gl2.viewport(0, 0, 4, 4);
|
|
468
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
469
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
470
|
+
gl2.useProgram(prog);
|
|
471
|
+
drawTriangle(gl2);
|
|
472
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
473
|
+
gl2.readBuffer(gl2.COLOR_ATTACHMENT0);
|
|
474
|
+
const p0 = readPixel(gl2, 0, 0);
|
|
475
|
+
expect(p0[0]).toBe(255);
|
|
476
|
+
expect(p0[1]).toBe(0);
|
|
477
|
+
gl2.readBuffer(gl2.COLOR_ATTACHMENT1);
|
|
478
|
+
const p1 = readPixel(gl2, 0, 0);
|
|
479
|
+
expect(p1[0]).toBe(0);
|
|
480
|
+
expect(p1[2]).toBe(255);
|
|
481
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
482
|
+
gl2.deleteFramebuffer(fb);
|
|
483
|
+
gl2.deleteTexture(tex0);
|
|
484
|
+
gl2.deleteTexture(tex1);
|
|
485
|
+
gl2.deleteProgram(prog);
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
await describe("3D texture", async () => {
|
|
489
|
+
beforeEach(async () => {
|
|
490
|
+
glArea.make_current();
|
|
491
|
+
});
|
|
492
|
+
await it("createTexture + TEXTURE_3D binding works", async () => {
|
|
493
|
+
const tex = gl2.createTexture();
|
|
494
|
+
expect(tex).not.toBeNull();
|
|
495
|
+
gl2.bindTexture(gl2.TEXTURE_3D, tex);
|
|
496
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
497
|
+
gl2.deleteTexture(tex);
|
|
498
|
+
});
|
|
499
|
+
await it("texImage3D uploads a 2×2×2 RGBA texture without error", async () => {
|
|
500
|
+
const tex = gl2.createTexture();
|
|
501
|
+
gl2.bindTexture(gl2.TEXTURE_3D, tex);
|
|
502
|
+
gl2.texParameteri(gl2.TEXTURE_3D, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
|
|
503
|
+
gl2.texParameteri(gl2.TEXTURE_3D, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
|
|
504
|
+
gl2.texParameteri(gl2.TEXTURE_3D, gl2.TEXTURE_WRAP_S, gl2.CLAMP_TO_EDGE);
|
|
505
|
+
gl2.texParameteri(gl2.TEXTURE_3D, gl2.TEXTURE_WRAP_T, gl2.CLAMP_TO_EDGE);
|
|
506
|
+
gl2.texParameteri(gl2.TEXTURE_3D, gl2.TEXTURE_WRAP_R, gl2.CLAMP_TO_EDGE);
|
|
507
|
+
const data = new Uint8Array(2 * 2 * 2 * 4).fill(128);
|
|
508
|
+
gl2.texImage3D(gl2.TEXTURE_3D, 0, gl2.RGBA, 2, 2, 2, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, data);
|
|
509
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
510
|
+
gl2.deleteTexture(tex);
|
|
511
|
+
});
|
|
512
|
+
await it("texStorage3D allocates storage without error", async () => {
|
|
513
|
+
const tex = gl2.createTexture();
|
|
514
|
+
gl2.bindTexture(gl2.TEXTURE_3D, tex);
|
|
515
|
+
gl2.texStorage3D(gl2.TEXTURE_3D, 1, gl2.RGBA8, 4, 4, 4);
|
|
516
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
517
|
+
gl2.deleteTexture(tex);
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
await describe("transform feedback", async () => {
|
|
521
|
+
beforeEach(async () => {
|
|
522
|
+
glArea.make_current();
|
|
523
|
+
});
|
|
524
|
+
await it("captures vertex shader output via transform feedback", async () => {
|
|
525
|
+
const VS_TF = [
|
|
526
|
+
"#version 300 es",
|
|
527
|
+
"in float inVal;",
|
|
528
|
+
"out float outVal;",
|
|
529
|
+
"void main() { outVal = inVal * 2.0; gl_Position = vec4(0.0); }"
|
|
530
|
+
].join("\n");
|
|
531
|
+
const FS_TF = [
|
|
532
|
+
"#version 300 es",
|
|
533
|
+
"precision mediump float;",
|
|
534
|
+
"out vec4 c;",
|
|
535
|
+
"void main() { c = vec4(0.0); }"
|
|
536
|
+
].join("\n");
|
|
537
|
+
const vert = gl2.createShader(gl2.VERTEX_SHADER);
|
|
538
|
+
gl2.shaderSource(vert, VS_TF);
|
|
539
|
+
gl2.compileShader(vert);
|
|
540
|
+
if (!gl2.getShaderParameter(vert, gl2.COMPILE_STATUS)) {
|
|
541
|
+
console.error("TF VS:", gl2.getShaderInfoLog(vert));
|
|
542
|
+
}
|
|
543
|
+
const frag = gl2.createShader(gl2.FRAGMENT_SHADER);
|
|
544
|
+
gl2.shaderSource(frag, FS_TF);
|
|
545
|
+
gl2.compileShader(frag);
|
|
546
|
+
const prog = gl2.createProgram();
|
|
547
|
+
gl2.attachShader(prog, vert);
|
|
548
|
+
gl2.attachShader(prog, frag);
|
|
549
|
+
gl2.transformFeedbackVaryings(prog, ["outVal"], gl2.SEPARATE_ATTRIBS);
|
|
550
|
+
gl2.linkProgram(prog);
|
|
551
|
+
if (!gl2.getProgramParameter(prog, gl2.LINK_STATUS)) {
|
|
552
|
+
console.error("TF prog:", gl2.getProgramInfoLog(prog));
|
|
553
|
+
}
|
|
554
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
555
|
+
const inBuf = gl2.createBuffer();
|
|
556
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, inBuf);
|
|
557
|
+
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array([
|
|
558
|
+
1,
|
|
559
|
+
2,
|
|
560
|
+
3,
|
|
561
|
+
4
|
|
562
|
+
]), gl2.STATIC_DRAW);
|
|
563
|
+
const attribLoc = gl2.getAttribLocation(prog, "inVal");
|
|
564
|
+
gl2.enableVertexAttribArray(attribLoc);
|
|
565
|
+
gl2.vertexAttribPointer(attribLoc, 1, gl2.FLOAT, false, 0, 0);
|
|
566
|
+
const outBuf = gl2.createBuffer();
|
|
567
|
+
gl2.bindBuffer(gl2.TRANSFORM_FEEDBACK_BUFFER, outBuf);
|
|
568
|
+
gl2.bufferData(gl2.TRANSFORM_FEEDBACK_BUFFER, 4 * 4, gl2.STATIC_READ);
|
|
569
|
+
const tf = gl2.createTransformFeedback();
|
|
570
|
+
gl2.bindTransformFeedback(gl2.TRANSFORM_FEEDBACK, tf);
|
|
571
|
+
gl2.bindBufferBase(gl2.TRANSFORM_FEEDBACK_BUFFER, 0, outBuf);
|
|
572
|
+
const fbo = makeTestFBO(gl2, 1, 1);
|
|
573
|
+
gl2.useProgram(prog);
|
|
574
|
+
gl2.enable(gl2.RASTERIZER_DISCARD);
|
|
575
|
+
gl2.beginTransformFeedback(gl2.POINTS);
|
|
576
|
+
gl2.drawArrays(gl2.POINTS, 0, 4);
|
|
577
|
+
gl2.endTransformFeedback();
|
|
578
|
+
gl2.disable(gl2.RASTERIZER_DISCARD);
|
|
579
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
580
|
+
gl2.bindTransformFeedback(gl2.TRANSFORM_FEEDBACK, null);
|
|
581
|
+
destroyTestFBO(gl2, fbo);
|
|
582
|
+
const result = new Float32Array(4);
|
|
583
|
+
gl2.bindBuffer(gl2.TRANSFORM_FEEDBACK_BUFFER, outBuf);
|
|
584
|
+
gl2.getBufferSubData(gl2.TRANSFORM_FEEDBACK_BUFFER, 0, result);
|
|
585
|
+
expect(result[0]).toBe(2);
|
|
586
|
+
expect(result[1]).toBe(4);
|
|
587
|
+
expect(result[2]).toBe(6);
|
|
588
|
+
expect(result[3]).toBe(8);
|
|
589
|
+
gl2.disableVertexAttribArray(attribLoc);
|
|
590
|
+
gl2.deleteBuffer(inBuf);
|
|
591
|
+
gl2.deleteBuffer(outBuf);
|
|
592
|
+
gl2.deleteTransformFeedback(tf);
|
|
593
|
+
gl2.deleteProgram(prog);
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
await describe("getStringi", async () => {
|
|
597
|
+
beforeEach(async () => {
|
|
598
|
+
glArea.make_current();
|
|
599
|
+
});
|
|
600
|
+
await it("getStringi(EXTENSIONS, 0) returns a string", async () => {
|
|
601
|
+
const numExts = gl2.getParameter(gl2.NUM_EXTENSIONS);
|
|
602
|
+
if (numExts > 0) {
|
|
603
|
+
const ext = gl2.getStringi(gl2.EXTENSIONS, 0);
|
|
604
|
+
expect(typeof ext).toBe("string");
|
|
605
|
+
expect(ext.length > 0).toBeTruthy();
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
await describe("WebGL2 extensions", async () => {
|
|
610
|
+
beforeEach(async () => {
|
|
611
|
+
glArea.make_current();
|
|
612
|
+
});
|
|
613
|
+
await it("supports EXT_color_buffer_float", async () => {
|
|
614
|
+
const ext = gl2.getExtension("EXT_color_buffer_float");
|
|
615
|
+
expect(ext).toBeTruthy();
|
|
616
|
+
});
|
|
617
|
+
await it("supports EXT_color_buffer_half_float", async () => {
|
|
618
|
+
const ext = gl2.getExtension("EXT_color_buffer_half_float");
|
|
619
|
+
expect(ext).toBeTruthy();
|
|
620
|
+
});
|
|
621
|
+
await it("supports OES_texture_half_float", async () => {
|
|
622
|
+
const ext = gl2.getExtension("OES_texture_half_float");
|
|
623
|
+
expect(ext).toBeTruthy();
|
|
624
|
+
});
|
|
625
|
+
await it("OES_texture_half_float exposes HALF_FLOAT_OES constant", async () => {
|
|
626
|
+
const ext = gl2.getExtension("OES_texture_half_float");
|
|
627
|
+
expect(ext).toBeTruthy();
|
|
628
|
+
expect(ext.HALF_FLOAT_OES).toBe(36193);
|
|
629
|
+
});
|
|
630
|
+
});
|
|
631
|
+
await describe("WebGL2 renderbufferStorage formats", async () => {
|
|
632
|
+
beforeEach(async () => {
|
|
633
|
+
glArea.make_current();
|
|
634
|
+
});
|
|
635
|
+
async function testRbFormat(internalFormat) {
|
|
636
|
+
const rb = gl2.createRenderbuffer();
|
|
637
|
+
gl2.bindRenderbuffer(gl2.RENDERBUFFER, rb);
|
|
638
|
+
gl2.renderbufferStorage(gl2.RENDERBUFFER, internalFormat, 64, 64);
|
|
639
|
+
const err = gl2.getError();
|
|
640
|
+
gl2.deleteRenderbuffer(rb);
|
|
641
|
+
return err;
|
|
642
|
+
}
|
|
643
|
+
await it("accepts RGBA8 (0x8058)", async () => {
|
|
644
|
+
expect(await testRbFormat(32856)).toBe(gl2.NO_ERROR);
|
|
645
|
+
});
|
|
646
|
+
await it("accepts DEPTH_COMPONENT24 (0x81A6)", async () => {
|
|
647
|
+
expect(await testRbFormat(33190)).toBe(gl2.NO_ERROR);
|
|
648
|
+
});
|
|
649
|
+
await it("accepts DEPTH24_STENCIL8 (0x88F0)", async () => {
|
|
650
|
+
expect(await testRbFormat(35056)).toBe(gl2.NO_ERROR);
|
|
651
|
+
});
|
|
652
|
+
});
|
|
653
|
+
await describe("WebGL2 float render target", async () => {
|
|
654
|
+
beforeEach(async () => {
|
|
655
|
+
glArea.make_current();
|
|
656
|
+
});
|
|
657
|
+
await it("can create RGBA16F texture and attach to FBO", async () => {
|
|
658
|
+
const RGBA16F = 34842;
|
|
659
|
+
const HALF_FLOAT = 5131;
|
|
660
|
+
const tex = gl2.createTexture();
|
|
661
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex);
|
|
662
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, RGBA16F, 64, 64, 0, gl2.RGBA, HALF_FLOAT, null);
|
|
663
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
664
|
+
const fbo = gl2.createFramebuffer();
|
|
665
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fbo);
|
|
666
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, tex, 0);
|
|
667
|
+
const status = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
668
|
+
expect(status).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
669
|
+
gl2.clearColor(1, 0, 0, 1);
|
|
670
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
671
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
672
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
673
|
+
gl2.deleteFramebuffer(fbo);
|
|
674
|
+
gl2.deleteTexture(tex);
|
|
675
|
+
});
|
|
676
|
+
await it("can create RGBA8 renderbuffer FBO", async () => {
|
|
677
|
+
const RGBA8 = 32856;
|
|
678
|
+
const rb = gl2.createRenderbuffer();
|
|
679
|
+
gl2.bindRenderbuffer(gl2.RENDERBUFFER, rb);
|
|
680
|
+
gl2.renderbufferStorage(gl2.RENDERBUFFER, RGBA8, 64, 64);
|
|
681
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
682
|
+
const fbo = gl2.createFramebuffer();
|
|
683
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fbo);
|
|
684
|
+
gl2.framebufferRenderbuffer(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.RENDERBUFFER, rb);
|
|
685
|
+
const status = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
686
|
+
expect(status).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
687
|
+
gl2.clearColor(0, 1, 0, 1);
|
|
688
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
689
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
690
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
691
|
+
gl2.deleteFramebuffer(fbo);
|
|
692
|
+
gl2.deleteRenderbuffer(rb);
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
await describe("WebGL2 GLSL 1.0 compatibility", async () => {
|
|
696
|
+
beforeEach(async () => {
|
|
697
|
+
glArea.make_current();
|
|
698
|
+
});
|
|
699
|
+
await it("compiles versionless shaders with attribute/varying", async () => {
|
|
700
|
+
const vs = "attribute vec2 position;\nvarying vec2 vUv;\nvoid main() { vUv = position; gl_Position = vec4(position, 0.0, 1.0); }";
|
|
701
|
+
const fs = "precision mediump float;\nvarying vec2 vUv;\nvoid main() { gl_FragColor = vec4(vUv, 0.0, 1.0); }";
|
|
702
|
+
const prog = makeProgram(gl2, vs, fs);
|
|
703
|
+
expect(prog).toBeTruthy();
|
|
704
|
+
if (prog) {
|
|
705
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
706
|
+
gl2.deleteProgram(prog);
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
});
|
|
710
|
+
await describe("WebGL2 textured rendering", async () => {
|
|
711
|
+
beforeEach(async () => {
|
|
712
|
+
glArea.make_current();
|
|
713
|
+
});
|
|
714
|
+
await it("samples a 2x2 RGBA texture to produce red output", async () => {
|
|
715
|
+
const fbo = makeTestFBO(gl2, 4, 4);
|
|
716
|
+
const tex = gl2.createTexture();
|
|
717
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex);
|
|
718
|
+
const pixels = new Uint8Array([
|
|
719
|
+
255,
|
|
720
|
+
0,
|
|
721
|
+
0,
|
|
722
|
+
255,
|
|
723
|
+
255,
|
|
724
|
+
0,
|
|
725
|
+
0,
|
|
726
|
+
255,
|
|
727
|
+
255,
|
|
728
|
+
0,
|
|
729
|
+
0,
|
|
730
|
+
255,
|
|
731
|
+
255,
|
|
732
|
+
0,
|
|
733
|
+
0,
|
|
734
|
+
255
|
|
735
|
+
]);
|
|
736
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, 2, 2, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, pixels);
|
|
737
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
|
|
738
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
|
|
739
|
+
const prog = makeProgram(gl2, TEXTURE_VS_300, TEXTURE_FS_300);
|
|
740
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
741
|
+
gl2.useProgram(prog);
|
|
742
|
+
const loc = gl2.getUniformLocation(prog, "uTexture");
|
|
743
|
+
gl2.uniform1i(loc, 0);
|
|
744
|
+
gl2.activeTexture(gl2.TEXTURE0);
|
|
745
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex);
|
|
746
|
+
drawTriangle(gl2);
|
|
747
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
748
|
+
const p = readPixel(gl2, 0, 0);
|
|
749
|
+
expect(p[0]).toBe(255);
|
|
750
|
+
expect(p[1]).toBe(0);
|
|
751
|
+
expect(p[2]).toBe(0);
|
|
752
|
+
expect(p[3]).toBe(255);
|
|
753
|
+
gl2.deleteTexture(tex);
|
|
754
|
+
gl2.deleteProgram(prog);
|
|
755
|
+
destroyTestFBO(gl2, fbo);
|
|
756
|
+
});
|
|
757
|
+
});
|
|
758
|
+
await describe("WebGL2 FBO chain (post-processing)", async () => {
|
|
759
|
+
beforeEach(async () => {
|
|
760
|
+
glArea.make_current();
|
|
761
|
+
});
|
|
762
|
+
await it("renders green to FBO1, samples FBO1 texture into FBO2", async () => {
|
|
763
|
+
const VS = [
|
|
764
|
+
"#version 300 es",
|
|
765
|
+
"in vec2 position;",
|
|
766
|
+
"void main() { gl_Position = vec4(position,0.0,1.0); }"
|
|
767
|
+
].join("\n");
|
|
768
|
+
const FS_GREEN = [
|
|
769
|
+
"#version 300 es",
|
|
770
|
+
"precision mediump float;",
|
|
771
|
+
"out vec4 c;",
|
|
772
|
+
"void main() { c = vec4(0.0,1.0,0.0,1.0); }"
|
|
773
|
+
].join("\n");
|
|
774
|
+
const fbo1 = makeTestFBO(gl2, 4, 4);
|
|
775
|
+
const status1 = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
776
|
+
expect(status1).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
777
|
+
const progGreen = makeProgram(gl2, VS, FS_GREEN);
|
|
778
|
+
gl2.useProgram(progGreen);
|
|
779
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
780
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
781
|
+
drawTriangle(gl2);
|
|
782
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
783
|
+
const p1 = readPixel(gl2, 0, 0);
|
|
784
|
+
expect(p1[1]).toBe(255);
|
|
785
|
+
const fbo2 = makeTestFBO(gl2, 4, 4);
|
|
786
|
+
const status2 = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
787
|
+
expect(status2).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
788
|
+
const progTex = makeProgram(gl2, TEXTURE_VS_300, TEXTURE_FS_300);
|
|
789
|
+
gl2.useProgram(progTex);
|
|
790
|
+
const texLoc = gl2.getUniformLocation(progTex, "uTexture");
|
|
791
|
+
gl2.uniform1i(texLoc, 0);
|
|
792
|
+
gl2.activeTexture(gl2.TEXTURE0);
|
|
793
|
+
gl2.bindTexture(gl2.TEXTURE_2D, fbo1.colorTex);
|
|
794
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
795
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
796
|
+
drawTriangle(gl2);
|
|
797
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
798
|
+
const p2 = readPixel(gl2, 0, 0);
|
|
799
|
+
expect(p2[1]).toBe(255);
|
|
800
|
+
gl2.deleteProgram(progGreen);
|
|
801
|
+
gl2.deleteProgram(progTex);
|
|
802
|
+
destroyTestFBO(gl2, fbo2);
|
|
803
|
+
destroyTestFBO(gl2, fbo1);
|
|
804
|
+
});
|
|
805
|
+
});
|
|
806
|
+
await describe("WebGL2 half-float FBO chain", async () => {
|
|
807
|
+
beforeEach(async () => {
|
|
808
|
+
glArea.make_current();
|
|
809
|
+
});
|
|
810
|
+
await it("renders green to RGBA16F FBO, samples into RGBA8 FBO", async () => {
|
|
811
|
+
const VS = [
|
|
812
|
+
"#version 300 es",
|
|
813
|
+
"in vec2 position;",
|
|
814
|
+
"void main() { gl_Position = vec4(position,0.0,1.0); }"
|
|
815
|
+
].join("\n");
|
|
816
|
+
const FS_GREEN = [
|
|
817
|
+
"#version 300 es",
|
|
818
|
+
"precision mediump float;",
|
|
819
|
+
"out vec4 c;",
|
|
820
|
+
"void main() { c = vec4(0.0,1.0,0.0,1.0); }"
|
|
821
|
+
].join("\n");
|
|
822
|
+
const fboFloat = makeTestFBOFloat(gl2, 4, 4);
|
|
823
|
+
const status1 = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
824
|
+
expect(status1).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
825
|
+
const progGreen = makeProgram(gl2, VS, FS_GREEN);
|
|
826
|
+
gl2.useProgram(progGreen);
|
|
827
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
828
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
829
|
+
drawTriangle(gl2);
|
|
830
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
831
|
+
const fbo2 = makeTestFBO(gl2, 4, 4);
|
|
832
|
+
const progTex = makeProgram(gl2, TEXTURE_VS_300, TEXTURE_FS_300);
|
|
833
|
+
gl2.useProgram(progTex);
|
|
834
|
+
const texLoc = gl2.getUniformLocation(progTex, "uTexture");
|
|
835
|
+
gl2.uniform1i(texLoc, 0);
|
|
836
|
+
gl2.activeTexture(gl2.TEXTURE0);
|
|
837
|
+
gl2.bindTexture(gl2.TEXTURE_2D, fboFloat.colorTex);
|
|
838
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
839
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
840
|
+
drawTriangle(gl2);
|
|
841
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
842
|
+
const p = readPixel(gl2, 0, 0);
|
|
843
|
+
expect(p[1]).toBe(255);
|
|
844
|
+
gl2.deleteProgram(progGreen);
|
|
845
|
+
gl2.deleteProgram(progTex);
|
|
846
|
+
destroyTestFBO(gl2, fbo2);
|
|
847
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fboFloat.fb);
|
|
848
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, null, 0);
|
|
849
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
850
|
+
gl2.deleteTexture(fboFloat.colorTex);
|
|
851
|
+
gl2.deleteFramebuffer(fboFloat.fb);
|
|
852
|
+
});
|
|
853
|
+
});
|
|
854
|
+
await describe("WebGL2 depth texture FBO", async () => {
|
|
855
|
+
beforeEach(async () => {
|
|
856
|
+
glArea.make_current();
|
|
857
|
+
});
|
|
858
|
+
await it("creates FBO with depth texture and renders with depth test", async () => {
|
|
859
|
+
const fbo = makeTestFBOWithDepthTexture(gl2, 4, 4);
|
|
860
|
+
const status = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
861
|
+
expect(status).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
862
|
+
const VS = [
|
|
863
|
+
"#version 300 es",
|
|
864
|
+
"in vec2 position;",
|
|
865
|
+
"uniform float uDepth;",
|
|
866
|
+
"void main() { gl_Position = vec4(position, uDepth, 1.0); }"
|
|
867
|
+
].join("\n");
|
|
868
|
+
const FS = [
|
|
869
|
+
"#version 300 es",
|
|
870
|
+
"precision mediump float;",
|
|
871
|
+
"uniform vec4 uColor;",
|
|
872
|
+
"out vec4 c;",
|
|
873
|
+
"void main() { c = uColor; }"
|
|
874
|
+
].join("\n");
|
|
875
|
+
const prog = makeProgram(gl2, VS, FS);
|
|
876
|
+
gl2.useProgram(prog);
|
|
877
|
+
gl2.enable(gl2.DEPTH_TEST);
|
|
878
|
+
gl2.depthFunc(gl2.LESS);
|
|
879
|
+
gl2.clearColor(0, 0, 0, 1);
|
|
880
|
+
gl2.clearDepth(1);
|
|
881
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT | gl2.DEPTH_BUFFER_BIT);
|
|
882
|
+
const colorLoc = gl2.getUniformLocation(prog, "uColor");
|
|
883
|
+
const depthLoc = gl2.getUniformLocation(prog, "uDepth");
|
|
884
|
+
gl2.uniform4f(colorLoc, 1, 0, 0, 1);
|
|
885
|
+
gl2.uniform1f(depthLoc, .5);
|
|
886
|
+
drawTriangle(gl2);
|
|
887
|
+
gl2.uniform4f(colorLoc, 0, 1, 0, 1);
|
|
888
|
+
gl2.uniform1f(depthLoc, 0);
|
|
889
|
+
drawTriangle(gl2);
|
|
890
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
891
|
+
const p = readPixel(gl2, 0, 0);
|
|
892
|
+
expect(p[1]).toBe(255);
|
|
893
|
+
gl2.disable(gl2.DEPTH_TEST);
|
|
894
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fbo.fb);
|
|
895
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, null, 0);
|
|
896
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.DEPTH_ATTACHMENT, gl2.TEXTURE_2D, null, 0);
|
|
897
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
898
|
+
gl2.deleteTexture(fbo.colorTex);
|
|
899
|
+
gl2.deleteTexture(fbo.depthTex);
|
|
900
|
+
gl2.deleteFramebuffer(fbo.fb);
|
|
901
|
+
gl2.deleteProgram(prog);
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
await describe("WebGL2 generateMipmap", async () => {
|
|
905
|
+
beforeEach(async () => {
|
|
906
|
+
glArea.make_current();
|
|
907
|
+
});
|
|
908
|
+
await it("generates mipmaps for a 4x4 texture without error", async () => {
|
|
909
|
+
const tex = gl2.createTexture();
|
|
910
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex);
|
|
911
|
+
const data = new Uint8Array(4 * 4 * 4);
|
|
912
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
913
|
+
data[i] = 255;
|
|
914
|
+
data[i + 3] = 255;
|
|
915
|
+
}
|
|
916
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, 4, 4, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, data);
|
|
917
|
+
gl2.generateMipmap(gl2.TEXTURE_2D);
|
|
918
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
919
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.LINEAR_MIPMAP_LINEAR);
|
|
920
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
921
|
+
const fbo = makeTestFBO(gl2, 4, 4);
|
|
922
|
+
const prog = makeProgram(gl2, TEXTURE_VS_300, TEXTURE_FS_300);
|
|
923
|
+
gl2.useProgram(prog);
|
|
924
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex);
|
|
925
|
+
gl2.uniform1i(gl2.getUniformLocation(prog, "uTexture"), 0);
|
|
926
|
+
drawTriangle(gl2);
|
|
927
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
928
|
+
const p = readPixel(gl2, 0, 0);
|
|
929
|
+
expect(p[0]).toBeGreaterThan(200);
|
|
930
|
+
gl2.deleteTexture(tex);
|
|
931
|
+
gl2.deleteProgram(prog);
|
|
932
|
+
destroyTestFBO(gl2, fbo);
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
await describe("WebGL2 cubemap texture", async () => {
|
|
936
|
+
beforeEach(async () => {
|
|
937
|
+
glArea.make_current();
|
|
938
|
+
});
|
|
939
|
+
await it("creates cubemap and verifies FBO attachment", async () => {
|
|
940
|
+
const tex = gl2.createTexture();
|
|
941
|
+
gl2.bindTexture(gl2.TEXTURE_CUBE_MAP, tex);
|
|
942
|
+
const faces = [
|
|
943
|
+
gl2.TEXTURE_CUBE_MAP_POSITIVE_X,
|
|
944
|
+
gl2.TEXTURE_CUBE_MAP_NEGATIVE_X,
|
|
945
|
+
gl2.TEXTURE_CUBE_MAP_POSITIVE_Y,
|
|
946
|
+
gl2.TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
|
947
|
+
gl2.TEXTURE_CUBE_MAP_POSITIVE_Z,
|
|
948
|
+
gl2.TEXTURE_CUBE_MAP_NEGATIVE_Z
|
|
949
|
+
];
|
|
950
|
+
const colors = [
|
|
951
|
+
[
|
|
952
|
+
255,
|
|
953
|
+
0,
|
|
954
|
+
0,
|
|
955
|
+
255
|
|
956
|
+
],
|
|
957
|
+
[
|
|
958
|
+
0,
|
|
959
|
+
255,
|
|
960
|
+
0,
|
|
961
|
+
255
|
|
962
|
+
],
|
|
963
|
+
[
|
|
964
|
+
0,
|
|
965
|
+
0,
|
|
966
|
+
255,
|
|
967
|
+
255
|
|
968
|
+
],
|
|
969
|
+
[
|
|
970
|
+
255,
|
|
971
|
+
255,
|
|
972
|
+
0,
|
|
973
|
+
255
|
|
974
|
+
],
|
|
975
|
+
[
|
|
976
|
+
255,
|
|
977
|
+
0,
|
|
978
|
+
255,
|
|
979
|
+
255
|
|
980
|
+
],
|
|
981
|
+
[
|
|
982
|
+
0,
|
|
983
|
+
255,
|
|
984
|
+
255,
|
|
985
|
+
255
|
|
986
|
+
]
|
|
987
|
+
];
|
|
988
|
+
for (let i = 0; i < 6; i++) {
|
|
989
|
+
gl2.texImage2D(faces[i], 0, gl2.RGBA, 1, 1, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, new Uint8Array(colors[i]));
|
|
990
|
+
}
|
|
991
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
992
|
+
gl2.texParameteri(gl2.TEXTURE_CUBE_MAP, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
|
|
993
|
+
gl2.texParameteri(gl2.TEXTURE_CUBE_MAP, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
|
|
994
|
+
const fb = gl2.createFramebuffer();
|
|
995
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fb);
|
|
996
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_CUBE_MAP_POSITIVE_X, tex, 0);
|
|
997
|
+
const status = gl2.checkFramebufferStatus(gl2.FRAMEBUFFER);
|
|
998
|
+
expect(status).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
999
|
+
gl2.viewport(0, 0, 1, 1);
|
|
1000
|
+
gl2.clearColor(0, 1, 1, 1);
|
|
1001
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
1002
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1003
|
+
const p = readPixel(gl2, 0, 0);
|
|
1004
|
+
expect(p[0]).toBe(0);
|
|
1005
|
+
expect(p[1]).toBe(255);
|
|
1006
|
+
expect(p[2]).toBe(255);
|
|
1007
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
1008
|
+
gl2.deleteFramebuffer(fb);
|
|
1009
|
+
gl2.deleteTexture(tex);
|
|
1010
|
+
});
|
|
1011
|
+
});
|
|
1012
|
+
await describe("WebGL2 READ_FRAMEBUFFER / DRAW_FRAMEBUFFER", async () => {
|
|
1013
|
+
beforeEach(async () => {
|
|
1014
|
+
glArea.make_current();
|
|
1015
|
+
});
|
|
1016
|
+
await it("bindFramebuffer accepts READ_FRAMEBUFFER and DRAW_FRAMEBUFFER", async () => {
|
|
1017
|
+
const fb1 = gl2.createFramebuffer();
|
|
1018
|
+
const fb2 = gl2.createFramebuffer();
|
|
1019
|
+
gl2.bindFramebuffer(36008, fb1);
|
|
1020
|
+
gl2.bindFramebuffer(36009, fb2);
|
|
1021
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1022
|
+
expect(gl2.getParameter(36010)).toBe(fb1);
|
|
1023
|
+
expect(gl2.getParameter(36006)).toBe(fb2);
|
|
1024
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
1025
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1026
|
+
gl2.deleteFramebuffer(fb1);
|
|
1027
|
+
gl2.deleteFramebuffer(fb2);
|
|
1028
|
+
});
|
|
1029
|
+
});
|
|
1030
|
+
await describe("WebGL2 RGBA8 FBO (sized internal format)", async () => {
|
|
1031
|
+
beforeEach(async () => {
|
|
1032
|
+
glArea.make_current();
|
|
1033
|
+
});
|
|
1034
|
+
await it("renders solid color to RGBA8 FBO, readPixels confirms result", async () => {
|
|
1035
|
+
const RGBA8 = 32856;
|
|
1036
|
+
const w = 4;
|
|
1037
|
+
const h = 4;
|
|
1038
|
+
const fb = gl2.createFramebuffer();
|
|
1039
|
+
const tex = gl2.createTexture();
|
|
1040
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex);
|
|
1041
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, RGBA8, w, h, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, null);
|
|
1042
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
|
|
1043
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
|
|
1044
|
+
gl2.bindTexture(gl2.TEXTURE_2D, null);
|
|
1045
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fb);
|
|
1046
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, tex, 0);
|
|
1047
|
+
expect(gl2.checkFramebufferStatus(gl2.FRAMEBUFFER)).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
1048
|
+
gl2.viewport(0, 0, w, h);
|
|
1049
|
+
gl2.clearColor(0, 1, 0, 1);
|
|
1050
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
1051
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1052
|
+
const pixels = new Uint8Array(4);
|
|
1053
|
+
gl2.readPixels(0, 0, 1, 1, gl2.RGBA, gl2.UNSIGNED_BYTE, pixels);
|
|
1054
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1055
|
+
expect(pixels[0]).toBe(0);
|
|
1056
|
+
expect(pixels[1]).toBe(255);
|
|
1057
|
+
expect(pixels[2]).toBe(0);
|
|
1058
|
+
expect(pixels[3]).toBe(255);
|
|
1059
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fb);
|
|
1060
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, null, 0);
|
|
1061
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
1062
|
+
gl2.deleteTexture(tex);
|
|
1063
|
+
gl2.deleteFramebuffer(fb);
|
|
1064
|
+
});
|
|
1065
|
+
});
|
|
1066
|
+
await describe("WebGL2 RGBA16F FBO draw + FLOAT readPixels", async () => {
|
|
1067
|
+
beforeEach(async () => {
|
|
1068
|
+
glArea.make_current();
|
|
1069
|
+
});
|
|
1070
|
+
await it("renders red triangle to RGBA16F FBO, reads back as FLOAT", async () => {
|
|
1071
|
+
const gl = gl2;
|
|
1072
|
+
const vs = `#version 300 es\nin vec2 position;\nvoid main(){gl_Position=vec4(position,0.,1.);}`;
|
|
1073
|
+
const fs = `#version 300 es\nprecision mediump float;\nout vec4 c;\nvoid main(){c=vec4(1.,0.,0.,1.);}`;
|
|
1074
|
+
const prog = makeProgram(gl, vs, fs);
|
|
1075
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
1076
|
+
const fbo = makeTestFBOFloat(gl2);
|
|
1077
|
+
gl2.useProgram(prog);
|
|
1078
|
+
drawTriangle(gl);
|
|
1079
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1080
|
+
const pixels = new Float32Array(4);
|
|
1081
|
+
gl2.readPixels(0, 0, 1, 1, gl2.RGBA, gl2.FLOAT, pixels);
|
|
1082
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1083
|
+
expect(Math.abs(pixels[0] - 1) < .01).toBeTruthy();
|
|
1084
|
+
expect(Math.abs(pixels[1] - 0) < .01).toBeTruthy();
|
|
1085
|
+
expect(Math.abs(pixels[2] - 0) < .01).toBeTruthy();
|
|
1086
|
+
expect(Math.abs(pixels[3] - 1) < .01).toBeTruthy();
|
|
1087
|
+
gl2.useProgram(null);
|
|
1088
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fbo.fb);
|
|
1089
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, null, 0);
|
|
1090
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
1091
|
+
gl2.deleteTexture(fbo.colorTex);
|
|
1092
|
+
gl2.deleteFramebuffer(fbo.fb);
|
|
1093
|
+
gl2.deleteProgram(prog);
|
|
1094
|
+
});
|
|
1095
|
+
});
|
|
1096
|
+
await describe("WebGL2 MRT — writes to COLOR_ATTACHMENT0 and COLOR_ATTACHMENT1", async () => {
|
|
1097
|
+
beforeEach(async () => {
|
|
1098
|
+
glArea.make_current();
|
|
1099
|
+
});
|
|
1100
|
+
await it("MRT shader writes different colors to CA0 and CA1", async () => {
|
|
1101
|
+
const gl = gl2;
|
|
1102
|
+
const w = 4;
|
|
1103
|
+
const h = 4;
|
|
1104
|
+
const vs = `#version 300 es\nin vec2 position;\nvoid main(){gl_Position=vec4(position,0.,1.);}`;
|
|
1105
|
+
const fs = `#version 300 es\nprecision mediump float;\nlayout(location=0) out vec4 c0;\nlayout(location=1) out vec4 c1;\nvoid main(){c0=vec4(1.,0.,0.,1.);c1=vec4(0.,0.,1.,1.);}`;
|
|
1106
|
+
const prog = makeProgram(gl, vs, fs);
|
|
1107
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
1108
|
+
const fb = gl2.createFramebuffer();
|
|
1109
|
+
const tex0 = gl2.createTexture();
|
|
1110
|
+
const tex1 = gl2.createTexture();
|
|
1111
|
+
for (const [tex, attachment] of [[tex0, gl2.COLOR_ATTACHMENT0], [tex1, gl2.COLOR_ATTACHMENT0 + 1]]) {
|
|
1112
|
+
gl2.bindTexture(gl2.TEXTURE_2D, tex);
|
|
1113
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, w, h, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, null);
|
|
1114
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
|
|
1115
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
|
|
1116
|
+
gl2.bindTexture(gl2.TEXTURE_2D, null);
|
|
1117
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fb);
|
|
1118
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, attachment, gl2.TEXTURE_2D, tex, 0);
|
|
1119
|
+
}
|
|
1120
|
+
expect(gl2.checkFramebufferStatus(gl2.FRAMEBUFFER)).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
1121
|
+
gl2.viewport(0, 0, w, h);
|
|
1122
|
+
gl2.drawBuffers([gl2.COLOR_ATTACHMENT0, gl2.COLOR_ATTACHMENT0 + 1]);
|
|
1123
|
+
gl2.useProgram(prog);
|
|
1124
|
+
drawTriangle(gl);
|
|
1125
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1126
|
+
const fbRead0 = gl2.createFramebuffer();
|
|
1127
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fbRead0);
|
|
1128
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, tex0, 0);
|
|
1129
|
+
const p0 = new Uint8Array(4);
|
|
1130
|
+
gl2.readPixels(0, 0, 1, 1, gl2.RGBA, gl2.UNSIGNED_BYTE, p0);
|
|
1131
|
+
expect(p0[0]).toBe(255);
|
|
1132
|
+
expect(p0[1]).toBe(0);
|
|
1133
|
+
expect(p0[2]).toBe(0);
|
|
1134
|
+
const fbRead1 = gl2.createFramebuffer();
|
|
1135
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, fbRead1);
|
|
1136
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, tex1, 0);
|
|
1137
|
+
const p1 = new Uint8Array(4);
|
|
1138
|
+
gl2.readPixels(0, 0, 1, 1, gl2.RGBA, gl2.UNSIGNED_BYTE, p1);
|
|
1139
|
+
expect(p1[0]).toBe(0);
|
|
1140
|
+
expect(p1[1]).toBe(0);
|
|
1141
|
+
expect(p1[2]).toBe(255);
|
|
1142
|
+
gl2.useProgram(null);
|
|
1143
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
1144
|
+
gl2.deleteTexture(tex0);
|
|
1145
|
+
gl2.deleteTexture(tex1);
|
|
1146
|
+
gl2.deleteFramebuffer(fb);
|
|
1147
|
+
gl2.deleteFramebuffer(fbRead0);
|
|
1148
|
+
gl2.deleteFramebuffer(fbRead1);
|
|
1149
|
+
gl2.deleteProgram(prog);
|
|
1150
|
+
});
|
|
1151
|
+
});
|
|
1152
|
+
await describe("WebGL2 Excalibur-style VAO draw + READ/DRAW blitToScreen", async () => {
|
|
1153
|
+
beforeEach(async () => {
|
|
1154
|
+
glArea.make_current();
|
|
1155
|
+
});
|
|
1156
|
+
await it("VAO draw to source FBO survives clearBufferfv+blit pipeline", async () => {
|
|
1157
|
+
const W = 4;
|
|
1158
|
+
const H = 4;
|
|
1159
|
+
const gl = gl2;
|
|
1160
|
+
const srcFbo = gl2.createFramebuffer();
|
|
1161
|
+
const srcTex = gl2.createTexture();
|
|
1162
|
+
gl2.bindTexture(gl2.TEXTURE_2D, srcTex);
|
|
1163
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, W, H, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, null);
|
|
1164
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
|
|
1165
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
|
|
1166
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_S, gl2.CLAMP_TO_EDGE);
|
|
1167
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_T, gl2.CLAMP_TO_EDGE);
|
|
1168
|
+
gl2.bindTexture(gl2.TEXTURE_2D, null);
|
|
1169
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, srcFbo);
|
|
1170
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, srcTex, 0);
|
|
1171
|
+
expect(gl2.checkFramebufferStatus(gl2.FRAMEBUFFER)).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
1172
|
+
const dstFbo = gl2.createFramebuffer();
|
|
1173
|
+
const dstTex = gl2.createTexture();
|
|
1174
|
+
gl2.bindTexture(gl2.TEXTURE_2D, dstTex);
|
|
1175
|
+
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, W, H, 0, gl2.RGBA, gl2.UNSIGNED_BYTE, null);
|
|
1176
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
|
|
1177
|
+
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
|
|
1178
|
+
gl2.bindTexture(gl2.TEXTURE_2D, null);
|
|
1179
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, dstFbo);
|
|
1180
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, dstTex, 0);
|
|
1181
|
+
expect(gl2.checkFramebufferStatus(gl2.FRAMEBUFFER)).toBe(gl2.FRAMEBUFFER_COMPLETE);
|
|
1182
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
1183
|
+
const vs300 = `#version 300 es\nin vec2 a_pos;\nvoid main(){gl_Position=vec4(a_pos,0.,1.);}`;
|
|
1184
|
+
const fs300 = `#version 300 es\nprecision mediump float;\nout vec4 c;\nvoid main(){c=vec4(0.,1.,0.,1.);}`;
|
|
1185
|
+
const prog = makeProgram(gl, vs300, fs300);
|
|
1186
|
+
expect(gl2.getProgramParameter(prog, gl2.LINK_STATUS)).toBeTruthy();
|
|
1187
|
+
const vao = gl2.createVertexArray();
|
|
1188
|
+
gl2.bindVertexArray(vao);
|
|
1189
|
+
const vbo = gl2.createBuffer();
|
|
1190
|
+
gl2.bindBuffer(gl2.ARRAY_BUFFER, vbo);
|
|
1191
|
+
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array([
|
|
1192
|
+
-1,
|
|
1193
|
+
-1,
|
|
1194
|
+
3,
|
|
1195
|
+
-1,
|
|
1196
|
+
-1,
|
|
1197
|
+
3
|
|
1198
|
+
]), gl2.STATIC_DRAW);
|
|
1199
|
+
const aPos = gl2.getAttribLocation(prog, "a_pos");
|
|
1200
|
+
gl2.enableVertexAttribArray(aPos);
|
|
1201
|
+
gl2.vertexAttribPointer(aPos, 2, gl2.FLOAT, false, 0, 0);
|
|
1202
|
+
gl2.bindVertexArray(null);
|
|
1203
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, srcFbo);
|
|
1204
|
+
gl2.viewport(0, 0, W, H);
|
|
1205
|
+
gl2.clearColor(0, 0, 1, 1);
|
|
1206
|
+
gl2.clear(gl2.COLOR_BUFFER_BIT);
|
|
1207
|
+
gl2.useProgram(prog);
|
|
1208
|
+
gl2.bindVertexArray(vao);
|
|
1209
|
+
gl2.drawArrays(gl2.TRIANGLES, 0, 3);
|
|
1210
|
+
gl2.bindVertexArray(null);
|
|
1211
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1212
|
+
const READ_FRAMEBUFFER = 36008;
|
|
1213
|
+
const DRAW_FRAMEBUFFER = 36009;
|
|
1214
|
+
gl2.bindFramebuffer(READ_FRAMEBUFFER, srcFbo);
|
|
1215
|
+
gl2.bindFramebuffer(DRAW_FRAMEBUFFER, dstFbo);
|
|
1216
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1217
|
+
gl2.clearBufferfv(gl2.COLOR, 0, [
|
|
1218
|
+
0,
|
|
1219
|
+
0,
|
|
1220
|
+
1,
|
|
1221
|
+
1
|
|
1222
|
+
]);
|
|
1223
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1224
|
+
gl2.blitFramebuffer(0, 0, W, H, 0, 0, W, H, gl2.COLOR_BUFFER_BIT, gl2.LINEAR);
|
|
1225
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1226
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, dstFbo);
|
|
1227
|
+
const pixels = new Uint8Array(4);
|
|
1228
|
+
gl2.readPixels(0, 0, 1, 1, gl2.RGBA, gl2.UNSIGNED_BYTE, pixels);
|
|
1229
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1230
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, srcFbo);
|
|
1231
|
+
const srcPixels = new Uint8Array(4);
|
|
1232
|
+
gl2.readPixels(0, 0, 1, 1, gl2.RGBA, gl2.UNSIGNED_BYTE, srcPixels);
|
|
1233
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1234
|
+
gl2.bindVertexArray(null);
|
|
1235
|
+
gl2.deleteVertexArray(vao);
|
|
1236
|
+
gl2.deleteBuffer(vbo);
|
|
1237
|
+
gl2.deleteProgram(prog);
|
|
1238
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, srcFbo);
|
|
1239
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, null, 0);
|
|
1240
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, dstFbo);
|
|
1241
|
+
gl2.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, null, 0);
|
|
1242
|
+
gl2.bindFramebuffer(gl2.FRAMEBUFFER, null);
|
|
1243
|
+
gl2.deleteTexture(srcTex);
|
|
1244
|
+
gl2.deleteTexture(dstTex);
|
|
1245
|
+
gl2.deleteFramebuffer(srcFbo);
|
|
1246
|
+
gl2.deleteFramebuffer(dstFbo);
|
|
1247
|
+
expect(pixels[0]).toBe(0);
|
|
1248
|
+
expect(pixels[1]).toBe(255);
|
|
1249
|
+
expect(pixels[2]).toBe(0);
|
|
1250
|
+
expect(pixels[3]).toBe(255);
|
|
1251
|
+
expect(srcPixels[0]).toBe(0);
|
|
1252
|
+
expect(srcPixels[1]).toBe(255);
|
|
1253
|
+
expect(srcPixels[2]).toBe(0);
|
|
1254
|
+
expect(srcPixels[3]).toBe(255);
|
|
1255
|
+
});
|
|
1256
|
+
});
|
|
1257
|
+
await describe("WebGL2 bufferSubData with UNIFORM_BUFFER", async () => {
|
|
1258
|
+
beforeEach(async () => {
|
|
1259
|
+
glArea.make_current();
|
|
1260
|
+
});
|
|
1261
|
+
await it("bufferSubData with UNIFORM_BUFFER target returns NO_ERROR", async () => {
|
|
1262
|
+
const UNIFORM_BUFFER = 35345;
|
|
1263
|
+
const buf = gl2.createBuffer();
|
|
1264
|
+
gl2.bindBuffer(UNIFORM_BUFFER, buf);
|
|
1265
|
+
gl2.bufferData(UNIFORM_BUFFER, new Float32Array([
|
|
1266
|
+
1,
|
|
1267
|
+
0,
|
|
1268
|
+
0,
|
|
1269
|
+
1
|
|
1270
|
+
]), gl2.STATIC_DRAW);
|
|
1271
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1272
|
+
gl2.bufferSubData(UNIFORM_BUFFER, 0, new Float32Array([
|
|
1273
|
+
0,
|
|
1274
|
+
1,
|
|
1275
|
+
0,
|
|
1276
|
+
1
|
|
1277
|
+
]));
|
|
1278
|
+
expect(gl2.getError()).toBe(gl2.NO_ERROR);
|
|
1279
|
+
gl2.bindBuffer(UNIFORM_BUFFER, null);
|
|
1280
|
+
gl2.deleteBuffer(buf);
|
|
1281
|
+
});
|
|
1282
|
+
});
|
|
1283
|
+
win.destroy();
|
|
1284
|
+
});
|
|
1256
1285
|
};
|
|
1286
|
+
|
|
1287
|
+
//#endregion
|
|
1288
|
+
export { webgl2_spec_default as default };
|