@gjsify/webgl 0.1.1 → 0.1.3

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 (59) hide show
  1. package/lib/esm/canvas-webgl-widget.js +12 -0
  2. package/lib/esm/conformance/attribs.spec.js +296 -0
  3. package/lib/esm/conformance/buffers.spec.js +203 -0
  4. package/lib/esm/conformance/context.spec.js +302 -0
  5. package/lib/esm/conformance/programs.spec.js +468 -0
  6. package/lib/esm/conformance/rendering-basic.spec.js +136 -0
  7. package/lib/esm/conformance/rendering.spec.js +424 -0
  8. package/lib/esm/conformance/setup.js +36 -0
  9. package/lib/esm/conformance/state.spec.js +348 -0
  10. package/lib/esm/conformance/textures.spec.js +354 -0
  11. package/lib/esm/conformance/uniforms.spec.js +305 -0
  12. package/lib/esm/conformance-test.js +23 -0
  13. package/lib/esm/extensions/ext-color-buffer-float.js +13 -0
  14. package/lib/esm/extensions/ext-color-buffer-half-float.js +13 -0
  15. package/lib/esm/extensions/oes-texture-half-float.js +19 -0
  16. package/lib/esm/index.js +5 -0
  17. package/lib/esm/test-utils.js +65 -0
  18. package/lib/esm/test.js +2 -2
  19. package/lib/esm/webgl-buffer.js +1 -1
  20. package/lib/esm/webgl-context-base.js +3371 -0
  21. package/lib/esm/webgl-framebuffer.js +1 -1
  22. package/lib/esm/webgl-program.js +1 -1
  23. package/lib/esm/webgl-renderbuffer.js +1 -1
  24. package/lib/esm/webgl-rendering-context.js +95 -3253
  25. package/lib/esm/webgl-shader.js +2 -1
  26. package/lib/esm/webgl-texture.js +1 -1
  27. package/lib/esm/{index.spec.js → webgl1.spec.js} +2 -2
  28. package/lib/esm/webgl2-rendering-context.js +617 -27
  29. package/lib/esm/webgl2.spec.js +573 -1
  30. package/lib/types/conformance/setup.d.ts +14 -0
  31. package/lib/types/extensions/ext-blend-minmax.d.ts +2 -2
  32. package/lib/types/extensions/ext-color-buffer-float.d.ts +4 -0
  33. package/lib/types/extensions/ext-color-buffer-half-float.d.ts +4 -0
  34. package/lib/types/extensions/ext-texture-filter-anisotropic.d.ts +2 -2
  35. package/lib/types/extensions/oes-element-index-unit.d.ts +2 -2
  36. package/lib/types/extensions/oes-standard-derivatives.d.ts +2 -2
  37. package/lib/types/extensions/oes-texture-float-linear.d.ts +2 -2
  38. package/lib/types/extensions/oes-texture-float.d.ts +2 -2
  39. package/lib/types/extensions/oes-texture-half-float.d.ts +5 -0
  40. package/lib/types/extensions/stackgl-destroy-context.d.ts +3 -3
  41. package/lib/types/extensions/stackgl-resize-drawing-buffer.d.ts +3 -3
  42. package/lib/types/index.d.ts +1 -0
  43. package/lib/types/test-utils.d.ts +24 -0
  44. package/lib/types/types/extension.d.ts +2 -2
  45. package/lib/types/utils.d.ts +9 -10
  46. package/lib/types/webgl-buffer.d.ts +3 -3
  47. package/lib/types/webgl-context-base.d.ts +267 -0
  48. package/lib/types/webgl-framebuffer.d.ts +3 -3
  49. package/lib/types/webgl-program.d.ts +3 -3
  50. package/lib/types/webgl-renderbuffer.d.ts +3 -3
  51. package/lib/types/webgl-rendering-context.d.ts +5 -250
  52. package/lib/types/webgl-shader.d.ts +4 -3
  53. package/lib/types/webgl-texture-unit.d.ts +3 -3
  54. package/lib/types/webgl-texture.d.ts +3 -3
  55. package/lib/types/webgl-vertex-attribute.d.ts +5 -5
  56. package/lib/types/webgl2-rendering-context.d.ts +95 -6
  57. package/package.json +13 -11
  58. package/prebuilds/linux-x86_64/Gwebgl-0.1.typelib +0 -0
  59. package/prebuilds/linux-x86_64/libgwebgl.so +0 -0
@@ -3,6 +3,7 @@ import GLib from "gi://GLib?version=2.0";
3
3
  import Gtk from "gi://Gtk?version=4.0";
4
4
  import { HTMLCanvasElement as OurHTMLCanvasElement } from "./html-canvas-element.js";
5
5
  import { attachEventControllers } from "@gjsify/event-bridge";
6
+ import { Event } from "@gjsify/dom-events";
6
7
  const CanvasWebGLWidget = GObject.registerClass(
7
8
  { GTypeName: "GjsifyCanvasWebGLWidget" },
8
9
  class CanvasWebGLWidget2 extends Gtk.GLArea {
@@ -26,6 +27,9 @@ const CanvasWebGLWidget = GObject.registerClass(
26
27
  this.disconnect(initId);
27
28
  this.make_current();
28
29
  this._canvas = new OurHTMLCanvasElement(this);
30
+ if (globalThis.document?.body) {
31
+ globalThis.document.body.appendChild(this._canvas);
32
+ }
29
33
  const gl = this._canvas.getContext("webgl");
30
34
  if (gl) {
31
35
  for (const cb of this._readyCallbacks) {
@@ -35,6 +39,14 @@ const CanvasWebGLWidget = GObject.registerClass(
35
39
  }
36
40
  return true;
37
41
  });
42
+ this.connect("resize", () => {
43
+ if (this._canvas) {
44
+ this._canvas.dispatchEvent(new Event("resize"));
45
+ }
46
+ if (this._frameCallback) {
47
+ this.requestAnimationFrame(this._frameCallback);
48
+ }
49
+ });
38
50
  this.connect("unrealize", () => {
39
51
  if (this._renderTag !== null) {
40
52
  this.disconnect(this._renderTag);
@@ -0,0 +1,296 @@
1
+ import { describe, it, expect, beforeEach, on } from "@gjsify/unit";
2
+ import { makeProgram, makeTestFBO, destroyTestFBO } from "../test-utils.js";
3
+ import { createGLSetup } from "./setup.js";
4
+ var attribs_spec_default = async () => {
5
+ await on("Display", async () => {
6
+ const setup = createGLSetup();
7
+ if (!setup) {
8
+ console.warn("WebGL context not available \u2014 skipping conformance/attribs tests");
9
+ return;
10
+ }
11
+ const { gl, glArea, win } = setup;
12
+ glArea.make_current();
13
+ await describe("conformance/attribs/gl-vertex-attrib: vertexAttrib round-trip", async () => {
14
+ beforeEach(async () => {
15
+ glArea.make_current();
16
+ });
17
+ await it("vertexAttrib1f stores value in slot 0 and defaults to [x,0,0,1]", async () => {
18
+ gl.vertexAttrib1f(0, 5);
19
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
20
+ expect(v instanceof Float32Array).toBeTruthy();
21
+ expect(v[0]).toBe(5);
22
+ expect(v[1]).toBe(0);
23
+ expect(v[2]).toBe(0);
24
+ expect(v[3]).toBe(1);
25
+ });
26
+ await it("vertexAttrib2f stores two values and defaults the rest to [_,_,0,1]", async () => {
27
+ gl.vertexAttrib2f(0, 6, 7);
28
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
29
+ expect(v[0]).toBe(6);
30
+ expect(v[1]).toBe(7);
31
+ expect(v[2]).toBe(0);
32
+ expect(v[3]).toBe(1);
33
+ });
34
+ await it("vertexAttrib3f stores three values and defaults last to 1", async () => {
35
+ gl.vertexAttrib3f(0, 7, 8, 9);
36
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
37
+ expect(v[0]).toBe(7);
38
+ expect(v[1]).toBe(8);
39
+ expect(v[2]).toBe(9);
40
+ expect(v[3]).toBe(1);
41
+ });
42
+ await it("vertexAttrib4f stores all four values", async () => {
43
+ gl.vertexAttrib4f(0, 6, 7, 8, 9);
44
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
45
+ expect(v[0]).toBe(6);
46
+ expect(v[1]).toBe(7);
47
+ expect(v[2]).toBe(8);
48
+ expect(v[3]).toBe(9);
49
+ });
50
+ await it("vertexAttrib1fv with array round-trips correctly", async () => {
51
+ gl.vertexAttrib1fv(0, [1]);
52
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
53
+ expect(v[0]).toBe(1);
54
+ expect(v[1]).toBe(0);
55
+ expect(v[2]).toBe(0);
56
+ expect(v[3]).toBe(1);
57
+ });
58
+ await it("vertexAttrib1fv with Float32Array round-trips correctly", async () => {
59
+ gl.vertexAttrib1fv(0, new Float32Array([-1]));
60
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
61
+ expect(v[0]).toBe(-1);
62
+ expect(v[3]).toBe(1);
63
+ });
64
+ await it("vertexAttrib2fv with array round-trips correctly", async () => {
65
+ gl.vertexAttrib2fv(0, [1, 2]);
66
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
67
+ expect(v[0]).toBe(1);
68
+ expect(v[1]).toBe(2);
69
+ expect(v[2]).toBe(0);
70
+ expect(v[3]).toBe(1);
71
+ });
72
+ await it("vertexAttrib3fv with Float32Array round-trips correctly", async () => {
73
+ gl.vertexAttrib3fv(0, new Float32Array([1, -2, 3]));
74
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
75
+ expect(v[0]).toBe(1);
76
+ expect(v[1]).toBe(-2);
77
+ expect(v[2]).toBe(3);
78
+ expect(v[3]).toBe(1);
79
+ });
80
+ await it("vertexAttrib4fv with Float32Array round-trips correctly", async () => {
81
+ gl.vertexAttrib4fv(0, new Float32Array([1, 2, -3, 4]));
82
+ const v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
83
+ expect(v[0]).toBe(1);
84
+ expect(v[1]).toBe(2);
85
+ expect(v[2]).toBe(-3);
86
+ expect(v[3]).toBe(4);
87
+ });
88
+ await it("setting attrib values generates no GL error", async () => {
89
+ const numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
90
+ for (let i = 0; i < numAttribs; i++) {
91
+ gl.vertexAttrib4f(i, i * 0.1, i * 0.2, i * 0.3, i * 0.4);
92
+ }
93
+ expect(gl.getError()).toBe(gl.NO_ERROR);
94
+ });
95
+ });
96
+ await describe("conformance/attribs/gl-vertex-attrib: out-of-range index", async () => {
97
+ beforeEach(async () => {
98
+ glArea.make_current();
99
+ });
100
+ await it("getVertexAttrib with out-of-range index generates INVALID_VALUE", async () => {
101
+ const numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
102
+ gl.getVertexAttrib(numAttribs, gl.CURRENT_VERTEX_ATTRIB);
103
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
104
+ });
105
+ await it("vertexAttrib1fv with out-of-range index generates INVALID_VALUE", async () => {
106
+ const numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
107
+ gl.vertexAttrib1fv(numAttribs, [1]);
108
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
109
+ });
110
+ await it("vertexAttrib4fv with out-of-range index generates INVALID_VALUE", async () => {
111
+ const numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
112
+ gl.vertexAttrib4fv(numAttribs, new Float32Array([1, 2, 3, 4]));
113
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
114
+ });
115
+ await it("vertexAttrib4f with out-of-range index generates INVALID_VALUE", async () => {
116
+ const numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
117
+ gl.vertexAttrib4f(numAttribs, 1, 2, 3, 4);
118
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
119
+ });
120
+ });
121
+ await describe("conformance/attribs/gl-enable-vertex-attrib", async () => {
122
+ beforeEach(async () => {
123
+ glArea.make_current();
124
+ });
125
+ await it("drawArrays with enabled attrib that has no buffer bound generates INVALID_OPERATION", async () => {
126
+ const vsSrc = `attribute vec4 vPosition; void main() { gl_Position = vPosition; }`;
127
+ const fsSrc = `void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }`;
128
+ const prog = makeProgram(gl, vsSrc, fsSrc);
129
+ gl.useProgram(prog);
130
+ const vertexObject = gl.createBuffer();
131
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
132
+ gl.bufferData(
133
+ gl.ARRAY_BUFFER,
134
+ new Float32Array([0, 0.5, 0, -0.5, -0.5, 0, 0.5, -0.5, 0]),
135
+ gl.STATIC_DRAW
136
+ );
137
+ gl.enableVertexAttribArray(0);
138
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
139
+ gl.enableVertexAttribArray(3);
140
+ expect(gl.getError()).toBe(gl.NO_ERROR);
141
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
142
+ expect(gl.getError()).toBe(gl.INVALID_OPERATION);
143
+ gl.disableVertexAttribArray(0);
144
+ gl.disableVertexAttribArray(3);
145
+ gl.deleteBuffer(vertexObject);
146
+ gl.deleteProgram(prog);
147
+ });
148
+ });
149
+ await describe("conformance/attribs/gl-bindAttribLocation-repeated", async () => {
150
+ beforeEach(async () => {
151
+ glArea.make_current();
152
+ });
153
+ await it("getAttribLocation returns the bound location after linkProgram", async () => {
154
+ const vsSrc = `attribute vec4 vPosition; void main() { gl_Position = vPosition; }`;
155
+ const fsSrc = `void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }`;
156
+ function setup2(attribIndex) {
157
+ const vs = gl.createShader(gl.VERTEX_SHADER);
158
+ gl.shaderSource(vs, vsSrc);
159
+ gl.compileShader(vs);
160
+ const fs = gl.createShader(gl.FRAGMENT_SHADER);
161
+ gl.shaderSource(fs, fsSrc);
162
+ gl.compileShader(fs);
163
+ const prog = gl.createProgram();
164
+ gl.attachShader(prog, vs);
165
+ gl.attachShader(prog, fs);
166
+ gl.bindAttribLocation(prog, attribIndex, "vPosition");
167
+ gl.linkProgram(prog);
168
+ expect(gl.getProgramParameter(prog, gl.LINK_STATUS)).toBeTruthy();
169
+ expect(gl.getAttribLocation(prog, "vPosition")).toBe(attribIndex);
170
+ gl.deleteShader(vs);
171
+ gl.deleteShader(fs);
172
+ return prog;
173
+ }
174
+ const p0 = setup2(0);
175
+ const p3 = setup2(3);
176
+ const p1 = setup2(1);
177
+ const p3b = setup2(3);
178
+ gl.deleteProgram(p0);
179
+ gl.deleteProgram(p3);
180
+ gl.deleteProgram(p1);
181
+ gl.deleteProgram(p3b);
182
+ });
183
+ });
184
+ await describe("conformance/attribs/attribute-weirdness", async () => {
185
+ beforeEach(async () => {
186
+ glArea.make_current();
187
+ });
188
+ const W = 2, H = 2;
189
+ const VDATA = new Int16Array([
190
+ 0,
191
+ 0,
192
+ 0,
193
+ 0,
194
+ 4,
195
+ 0,
196
+ 1,
197
+ 0,
198
+ 0,
199
+ 4,
200
+ 0,
201
+ 1,
202
+ 4,
203
+ 4,
204
+ 1,
205
+ 1
206
+ ]);
207
+ function renderAttribWeirdness(flipAttributes, flipLocations) {
208
+ const fbo = makeTestFBO(gl, W, H);
209
+ const attrs = [
210
+ "attribute vec2 a_pos;",
211
+ "attribute vec2 a_texture_pos;"
212
+ ];
213
+ if (flipAttributes) attrs.reverse();
214
+ const vsSrc = [
215
+ "precision mediump float;",
216
+ attrs[0],
217
+ attrs[1],
218
+ "varying vec2 v_pos0;",
219
+ "void main() {",
220
+ " v_pos0 = a_texture_pos;",
221
+ " gl_Position = vec4(a_pos - 1.0, 0.0, 1.0);",
222
+ "}"
223
+ ].join("\n");
224
+ const fsSrc = [
225
+ "precision mediump float;",
226
+ "varying vec2 v_pos0;",
227
+ "void main() {",
228
+ " gl_FragColor = vec4(v_pos0.x, 0.0, 0.0, 1.0);",
229
+ "}"
230
+ ].join("\n");
231
+ gl.clearColor(0, 0, 0, 0);
232
+ gl.clear(gl.COLOR_BUFFER_BIT);
233
+ const prog = makeProgram(gl, vsSrc, fsSrc);
234
+ gl.useProgram(prog);
235
+ const buf = gl.createBuffer();
236
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
237
+ gl.bufferData(gl.ARRAY_BUFFER, VDATA, gl.STATIC_DRAW);
238
+ let aPos = gl.getAttribLocation(prog, "a_pos");
239
+ let aTexPos = gl.getAttribLocation(prog, "a_texture_pos");
240
+ gl.enableVertexAttribArray(aPos);
241
+ gl.enableVertexAttribArray(aTexPos);
242
+ if (flipLocations) {
243
+ const tmp = aPos;
244
+ aPos = aTexPos;
245
+ aTexPos = tmp;
246
+ }
247
+ gl.vertexAttribPointer(aPos, 2, gl.SHORT, false, 8, 0);
248
+ gl.vertexAttribPointer(aTexPos, 2, gl.SHORT, false, 8, 4);
249
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
250
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
251
+ gl.deleteBuffer(buf);
252
+ const pixels = new Uint8Array(W * H * 4);
253
+ gl.readPixels(0, 0, W, H, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
254
+ destroyTestFBO(gl, fbo);
255
+ return pixels;
256
+ }
257
+ await it("normal order: all alpha values are 255 (quad covers canvas)", async () => {
258
+ const pixels = renderAttribWeirdness(false, false);
259
+ let ok = true;
260
+ for (let i = 3; i < W * H * 4; i += 4) {
261
+ if (pixels[i] !== 255) {
262
+ ok = false;
263
+ break;
264
+ }
265
+ }
266
+ expect(ok).toBe(true);
267
+ });
268
+ await it("flipped attribute declarations: all alpha values are still 255", async () => {
269
+ const pixels = renderAttribWeirdness(true, false);
270
+ let ok = true;
271
+ for (let i = 3; i < W * H * 4; i += 4) {
272
+ if (pixels[i] !== 255) {
273
+ ok = false;
274
+ break;
275
+ }
276
+ }
277
+ expect(ok).toBe(true);
278
+ });
279
+ await it("swapped location assignments: quad does not cover canvas (some alpha \u2260 255)", async () => {
280
+ const pixels = renderAttribWeirdness(false, true);
281
+ let hasNonAlpha = false;
282
+ for (let i = 3; i < W * H * 4; i += 4) {
283
+ if (pixels[i] !== 255) {
284
+ hasNonAlpha = true;
285
+ break;
286
+ }
287
+ }
288
+ expect(hasNonAlpha).toBe(true);
289
+ });
290
+ });
291
+ win.destroy();
292
+ });
293
+ };
294
+ export {
295
+ attribs_spec_default as default
296
+ };
@@ -0,0 +1,203 @@
1
+ import { describe, it, expect, beforeEach, on } from "@gjsify/unit";
2
+ import { makeProgram, makeTestFBO, destroyTestFBO, readPixel, pixelClose } from "../test-utils.js";
3
+ import { createGLSetup } from "./setup.js";
4
+ var buffers_spec_default = async () => {
5
+ await on("Display", async () => {
6
+ const setup = createGLSetup();
7
+ if (!setup) {
8
+ console.warn("WebGL context not available \u2014 skipping conformance/buffers tests");
9
+ return;
10
+ }
11
+ const { gl, glArea, win } = setup;
12
+ glArea.make_current();
13
+ await describe("conformance/buffers/buffer-bind-test", async () => {
14
+ beforeEach(async () => {
15
+ glArea.make_current();
16
+ });
17
+ await it("should be able to bind and unbind an ARRAY_BUFFER", async () => {
18
+ const buf = gl.createBuffer();
19
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
20
+ expect(gl.getError()).toBe(gl.NO_ERROR);
21
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
22
+ expect(gl.getError()).toBe(gl.NO_ERROR);
23
+ gl.deleteBuffer(buf);
24
+ });
25
+ await it("should be able to bind and unbind an ELEMENT_ARRAY_BUFFER", async () => {
26
+ const buf = gl.createBuffer();
27
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
28
+ expect(gl.getError()).toBe(gl.NO_ERROR);
29
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
30
+ expect(gl.getError()).toBe(gl.NO_ERROR);
31
+ gl.deleteBuffer(buf);
32
+ });
33
+ await it("binding ARRAY_BUFFER to ELEMENT_ARRAY_BUFFER target should generate INVALID_OPERATION", async () => {
34
+ const buf = gl.createBuffer();
35
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
36
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
37
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
38
+ expect(gl.getError()).toBe(gl.INVALID_OPERATION);
39
+ gl.deleteBuffer(buf);
40
+ });
41
+ await it("binding ELEMENT_ARRAY_BUFFER to ARRAY_BUFFER target should generate INVALID_OPERATION", async () => {
42
+ const buf = gl.createBuffer();
43
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
44
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
45
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
46
+ expect(gl.getError()).toBe(gl.INVALID_OPERATION);
47
+ gl.deleteBuffer(buf);
48
+ });
49
+ });
50
+ await describe("conformance/buffers/buffer-data-and-buffer-sub-data", async () => {
51
+ beforeEach(async () => {
52
+ glArea.make_current();
53
+ });
54
+ await it("bufferData with no buffer bound generates INVALID_OPERATION", async () => {
55
+ gl.bufferData(gl.ARRAY_BUFFER, 4, gl.STATIC_DRAW);
56
+ expect(gl.getError()).toBe(gl.INVALID_OPERATION);
57
+ });
58
+ await it("bufferData with negative size generates INVALID_VALUE", async () => {
59
+ const buf = gl.createBuffer();
60
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
61
+ gl.getError();
62
+ gl.bufferData(gl.ARRAY_BUFFER, -4, gl.STATIC_DRAW);
63
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
64
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
65
+ gl.deleteBuffer(buf);
66
+ });
67
+ await it("bufferData with null data generates INVALID_VALUE", async () => {
68
+ const buf = gl.createBuffer();
69
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
70
+ gl.getError();
71
+ gl.bufferData(gl.ARRAY_BUFFER, null, gl.STATIC_DRAW);
72
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
73
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
74
+ gl.deleteBuffer(buf);
75
+ });
76
+ await it("bufferData with size 0 succeeds and sets buffer size to 0", async () => {
77
+ const buf = gl.createBuffer();
78
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
79
+ gl.bufferData(gl.ARRAY_BUFFER, 0, gl.STATIC_DRAW);
80
+ expect(gl.getError()).toBe(gl.NO_ERROR);
81
+ expect(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE)).toBe(0);
82
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
83
+ gl.deleteBuffer(buf);
84
+ });
85
+ await it("bufferData with ArrayBuffer sets correct buffer size", async () => {
86
+ const buf = gl.createBuffer();
87
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
88
+ gl.bufferData(gl.ARRAY_BUFFER, new ArrayBuffer(4), gl.STATIC_DRAW);
89
+ expect(gl.getError()).toBe(gl.NO_ERROR);
90
+ expect(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE)).toBe(4);
91
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
92
+ gl.deleteBuffer(buf);
93
+ });
94
+ await it("bufferData with numeric size 4 sets buffer size to 4", async () => {
95
+ const buf = gl.createBuffer();
96
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
97
+ gl.bufferData(gl.ARRAY_BUFFER, 4, gl.STATIC_DRAW);
98
+ expect(gl.getError()).toBe(gl.NO_ERROR);
99
+ expect(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE)).toBe(4);
100
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
101
+ gl.deleteBuffer(buf);
102
+ });
103
+ await it("bufferSubData before bufferData generates INVALID_VALUE", async () => {
104
+ const buf = gl.createBuffer();
105
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
106
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new ArrayBuffer(1));
107
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
108
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
109
+ gl.deleteBuffer(buf);
110
+ });
111
+ await it("bufferSubData with negative offset generates INVALID_VALUE", async () => {
112
+ const buf = gl.createBuffer();
113
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
114
+ gl.bufferData(gl.ARRAY_BUFFER, 128, gl.STATIC_DRAW);
115
+ gl.getError();
116
+ gl.bufferSubData(gl.ARRAY_BUFFER, -10, new ArrayBuffer(64));
117
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
118
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
119
+ gl.deleteBuffer(buf);
120
+ });
121
+ await it("bufferSubData that overflows buffer generates INVALID_VALUE", async () => {
122
+ const buf = gl.createBuffer();
123
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
124
+ gl.bufferData(gl.ARRAY_BUFFER, 128, gl.STATIC_DRAW);
125
+ gl.getError();
126
+ gl.bufferSubData(gl.ARRAY_BUFFER, 65, new ArrayBuffer(64));
127
+ expect(gl.getError()).toBe(gl.INVALID_VALUE);
128
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
129
+ gl.deleteBuffer(buf);
130
+ });
131
+ await it("bufferSubData within bounds succeeds", async () => {
132
+ const buf = gl.createBuffer();
133
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
134
+ gl.bufferData(gl.ARRAY_BUFFER, 128, gl.STATIC_DRAW);
135
+ gl.getError();
136
+ gl.bufferSubData(gl.ARRAY_BUFFER, 10, new ArrayBuffer(64));
137
+ expect(gl.getError()).toBe(gl.NO_ERROR);
138
+ gl.bufferSubData(gl.ARRAY_BUFFER, 10, new Float32Array(0));
139
+ expect(gl.getError()).toBe(gl.NO_ERROR);
140
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
141
+ gl.deleteBuffer(buf);
142
+ });
143
+ await it("bufferSubData with non-ArrayBuffer throws TypeError", async () => {
144
+ const buf = gl.createBuffer();
145
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
146
+ gl.bufferData(gl.ARRAY_BUFFER, 128, gl.STATIC_DRAW);
147
+ gl.getError();
148
+ expect(() => gl.bufferSubData(gl.ARRAY_BUFFER, 0, 42)).toThrow();
149
+ expect(() => gl.bufferSubData(gl.ARRAY_BUFFER, 0, "5.5")).toThrow();
150
+ expect(() => gl.bufferSubData(gl.ARRAY_BUFFER, 10, null)).toThrow();
151
+ expect(gl.getError()).toBe(gl.NO_ERROR);
152
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
153
+ gl.deleteBuffer(buf);
154
+ });
155
+ });
156
+ await describe("conformance/buffers/element-array-buffer-delete-recreate", async () => {
157
+ beforeEach(async () => {
158
+ glArea.make_current();
159
+ });
160
+ await it("drawElements succeeds after deleting and recreating the element array buffer", async () => {
161
+ const vsSrc = `attribute vec2 position; void main() { gl_Position = vec4(position, 0.0, 1.0); }`;
162
+ const fsSrc = `precision mediump float; void main() { gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); }`;
163
+ const prog = makeProgram(gl, vsSrc, fsSrc);
164
+ gl.useProgram(prog);
165
+ const fbo = makeTestFBO(gl, 2, 2);
166
+ const vertexBuffer = gl.createBuffer();
167
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
168
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
169
+ -1,
170
+ -1,
171
+ 1,
172
+ -1,
173
+ -1,
174
+ 1,
175
+ 1,
176
+ 1
177
+ ]), gl.STATIC_DRAW);
178
+ gl.enableVertexAttribArray(0);
179
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
180
+ let indexBuffer = gl.createBuffer();
181
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
182
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 3]), gl.STATIC_DRAW);
183
+ gl.deleteBuffer(indexBuffer);
184
+ indexBuffer = gl.createBuffer();
185
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
186
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 3]), gl.STATIC_DRAW);
187
+ gl.clear(gl.COLOR_BUFFER_BIT);
188
+ gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_BYTE, 0);
189
+ expect(gl.getError()).toBe(gl.NO_ERROR);
190
+ const pixel = readPixel(gl, 1, 1);
191
+ expect(pixelClose(pixel, [0, 255, 0, 255])).toBeTruthy();
192
+ destroyTestFBO(gl, fbo);
193
+ gl.deleteBuffer(vertexBuffer);
194
+ gl.deleteBuffer(indexBuffer);
195
+ gl.deleteProgram(prog);
196
+ });
197
+ });
198
+ win.destroy();
199
+ });
200
+ };
201
+ export {
202
+ buffers_spec_default as default
203
+ };