@bigmistqke/view.gl 0.1.13 → 0.1.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.
@@ -1,516 +0,0 @@
1
- const INSTANCED_ARRAYS_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
2
- function getInstancedArrays(gl) {
3
- if (gl instanceof WebGL2RenderingContext) return gl;
4
- const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl);
5
- if (cached) return cached;
6
- const ext = gl.getExtension("ANGLE_instanced_arrays");
7
- if (!ext) return void 0;
8
- const wrapper = {
9
- drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),
10
- drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),
11
- vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext)
12
- };
13
- INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper);
14
- return wrapper;
15
- }
16
- const VERTEX_ARRAY_OBJECT_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
17
- function getVertexArrayObject(gl) {
18
- if (gl instanceof WebGL2RenderingContext) return gl;
19
- const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl);
20
- if (cached) return cached;
21
- const ext = gl.getExtension("OES_vertex_array_object");
22
- if (!ext) return null;
23
- const wrapper = {
24
- bindVertexArray: ext.bindVertexArrayOES.bind(ext),
25
- createVertexArray: ext.createVertexArrayOES.bind(ext),
26
- deleteVertexArray: ext.deleteVertexArrayOES.bind(ext)
27
- };
28
- VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper);
29
- return wrapper;
30
- }
31
-
32
- function forEach(value, callback) {
33
- let index = 0;
34
- for (const key in value) {
35
- callback(value[key], key, index);
36
- index++;
37
- }
38
- for (const key of Object.getOwnPropertySymbols(value)) {
39
- callback(value[key], key, index);
40
- index++;
41
- }
42
- }
43
- function map(value, callback) {
44
- const result = {};
45
- forEach(value, (value2, key, index) => {
46
- result[key] = callback(value2, key, index);
47
- });
48
- return result;
49
- }
50
-
51
- function assertedNotNullish(value, message) {
52
- if (value === void 0 || value === null) throw new Error(message);
53
- return value;
54
- }
55
- function createGLShader(gl, type, source) {
56
- const shader = gl.createShader(type);
57
- if (!shader) throw new Error("Failed to create shader");
58
- gl.shaderSource(shader, source);
59
- gl.compileShader(shader);
60
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
61
- const info = gl.getShaderInfoLog(shader);
62
- gl.deleteShader(shader);
63
- throw new Error(
64
- `Failed to compile ${type === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader: ${info}`
65
- );
66
- }
67
- return shader;
68
- }
69
- function createProgram(gl, vertexSource, fragmentSource) {
70
- const program = gl.createProgram();
71
- if (!program) throw new Error("Failed to create WebGL program");
72
- const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource);
73
- const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
74
- gl.attachShader(program, vertexShader);
75
- gl.attachShader(program, fragmentShader);
76
- gl.linkProgram(program);
77
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
78
- const info = gl.getProgramInfoLog(program);
79
- gl.deleteProgram(program);
80
- gl.deleteShader(vertexShader);
81
- gl.deleteShader(fragmentShader);
82
- throw new Error(`Failed to link program: ${info}`);
83
- }
84
- gl.deleteShader(vertexShader);
85
- gl.deleteShader(fragmentShader);
86
- return program;
87
- }
88
- const kindToUniformFnName = (kind) => {
89
- switch (kind[0]) {
90
- // mat
91
- case "m":
92
- return "Matrix" + kind.slice(3) + "fv";
93
- // sampler/booleans/integer
94
- case "s":
95
- case "b":
96
- case "i":
97
- return (kind.match(/\d/)?.[0] ?? "1") + "i";
98
- // unsigned integers
99
- case "u":
100
- return (kind[4] || "1") + "ui";
101
- // vec
102
- case "v":
103
- return kind[3] + "f";
104
- default:
105
- switch (kind) {
106
- case "float":
107
- return "1f";
108
- case "uint":
109
- return "1ui";
110
- default:
111
- return "1i";
112
- }
113
- }
114
- };
115
- const kindToSize = (kind) => {
116
- switch (kind[0]) {
117
- case "m":
118
- const [a, b] = kind.match(/\d+/g).map(Number);
119
- return a * (b ?? a);
120
- case "v":
121
- case "i":
122
- case "b":
123
- case "u":
124
- const match = kind.match(/\d/);
125
- return match ? +match[0] : 1;
126
- default:
127
- return 1;
128
- }
129
- };
130
- const isMatKind = (kind) => kind.includes("mat");
131
- const isSamplerKind = (kind) => kind.includes("sampler");
132
- function createTexture(gl, {
133
- target = "TEXTURE_2D",
134
- internalFormat = "RGBA",
135
- format = "RGBA",
136
- type = "UNSIGNED_BYTE",
137
- minFilter = "NEAREST",
138
- magFilter = "NEAREST",
139
- wrapS = "CLAMP_TO_EDGE",
140
- wrapT = "CLAMP_TO_EDGE",
141
- width,
142
- height
143
- }, data) {
144
- const texture = gl.createTexture();
145
- function getTextureConstant(name2) {
146
- if (!(name2 in gl)) {
147
- throw new Error(`Attempted to create webgl2-only texture (${name2}) in webgl1`);
148
- }
149
- return gl[name2];
150
- }
151
- gl.bindTexture(gl[target], texture);
152
- gl.texImage2D(
153
- gl[target],
154
- 0,
155
- getTextureConstant(internalFormat),
156
- width,
157
- height,
158
- 0,
159
- getTextureConstant(format),
160
- getTextureConstant(type),
161
- null
162
- );
163
- console.log(minFilter);
164
- gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter]);
165
- gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter]);
166
- gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS]);
167
- gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT]);
168
- return texture;
169
- }
170
- const FRAMEBUFFER_ATTACHMENT_MAP = {
171
- color: "COLOR_ATTACHMENT0",
172
- depth: "DEPTH_ATTACHMENT",
173
- stencil: "STENCIL_ATTACHMENT",
174
- depthStencil: "DEPTH_STENCIL_ATTACHMENT"
175
- };
176
- class FramebufferError extends Error {
177
- constructor(gl, status) {
178
- let errorMessage = `Framebuffer '${name}' not complete. Status: `;
179
- switch (status) {
180
- case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
181
- errorMessage += "FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
182
- break;
183
- case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
184
- errorMessage += "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
185
- break;
186
- case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
187
- errorMessage += "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
188
- break;
189
- case gl.FRAMEBUFFER_UNSUPPORTED:
190
- errorMessage += "FRAMEBUFFER_UNSUPPORTED";
191
- break;
192
- default:
193
- errorMessage += `Unknown (${status})`;
194
- }
195
- super(errorMessage);
196
- }
197
- }
198
- function createFramebuffer(gl, { attachment, texture, ...options }) {
199
- texture ??= createTexture(gl, options);
200
- const framebuffer = assertedNotNullish(
201
- gl.createFramebuffer(),
202
- `Failed to create framebuffer: ${name}`
203
- );
204
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
205
- gl.framebufferTexture2D(
206
- gl.FRAMEBUFFER,
207
- // Determine attachment point based on attachment kind
208
- gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],
209
- gl.TEXTURE_2D,
210
- texture,
211
- 0
212
- );
213
- const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
214
- if (status !== gl.FRAMEBUFFER_COMPLETE) {
215
- throw new FramebufferError(gl, status);
216
- }
217
- return {
218
- texture,
219
- framebuffer
220
- };
221
- }
222
- function createUpsertMap(constructor) {
223
- const map = new (constructor ?? Map)();
224
- return Object.assign(map, {
225
- getOrInsert(key, value) {
226
- let result = map.get(key);
227
- if (result) {
228
- return result;
229
- }
230
- result = value();
231
- map.set(key, result);
232
- return result;
233
- }
234
- });
235
- }
236
-
237
- let index = 0;
238
- const PREFIX = "VIEW_GL_ALIAS";
239
- const SYMBOL_MAP = createUpsertMap(WeakMap);
240
- function toID(key) {
241
- if (typeof key === "string") {
242
- return key;
243
- }
244
- if (typeof key === "symbol") {
245
- return SYMBOL_MAP.getOrInsert(key, () => `${PREFIX}_${index++}`);
246
- }
247
- return key.toString();
248
- }
249
- function view(gl, program, schema, options) {
250
- return {
251
- uniforms: !schema.uniforms ? void 0 : uniformView(gl, program, schema.uniforms),
252
- attributes: !schema.attributes ? void 0 : attributeView(gl, program, schema.attributes, options),
253
- interleavedAttributes: !schema.interleavedAttributes ? void 0 : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),
254
- buffers: !schema.buffers ? void 0 : bufferView(gl, schema.buffers)
255
- };
256
- }
257
- function uniformView(gl, program, schema) {
258
- return map(schema, ({ kind, size }, key) => {
259
- const name = toID(key);
260
- const location = gl.getUniformLocation(program, name);
261
- if (isSamplerKind(kind)) {
262
- return {
263
- set(arg) {
264
- gl.uniform1i(location, arg);
265
- }
266
- };
267
- }
268
- const fnName = `uniform${kindToUniformFnName(kind)}${size ? "v" : ""}`;
269
- const fn = gl[fnName].bind(gl);
270
- if (isMatKind(kind)) {
271
- return {
272
- set(...args) {
273
- fn(location, false, args[0]);
274
- }
275
- };
276
- }
277
- return {
278
- set(...args) {
279
- fn(location, ...args);
280
- }
281
- };
282
- });
283
- }
284
- function handleAttribute(gl, location, size, stride, offset, type, instanced) {
285
- gl.enableVertexAttribArray(location);
286
- gl.vertexAttribPointer(location, size, gl[type], false, stride, offset);
287
- if (instanced) {
288
- assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1);
289
- }
290
- }
291
- function attributeView(gl, program, schema, { signal } = {}) {
292
- const attributes = map(
293
- schema,
294
- ({ kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) }, key) => {
295
- const name = toID(key);
296
- const location = gl.getAttribLocation(program, name);
297
- if (location < 0) {
298
- throw new Error(`Attribute '${name}' not found`);
299
- }
300
- const size = kindToSize(kind);
301
- const type = kind.startsWith("i") ? "INT" : "FLOAT";
302
- return {
303
- buffer,
304
- bind() {
305
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
306
- handleAttribute(gl, location, size, 0, 0, type, instanced);
307
- },
308
- dispose() {
309
- gl.deleteBuffer(buffer);
310
- },
311
- set(data, usage = "STATIC_DRAW") {
312
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
313
- gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage]);
314
- return this;
315
- }
316
- };
317
- }
318
- );
319
- signal?.addEventListener("abort", function dispose() {
320
- forEach(attributes, (value) => value.dispose());
321
- });
322
- return attributes;
323
- }
324
- function interleavedAttributeView(gl, program, schema, { signal } = {}) {
325
- const interleavedAttributes = map(schema, ({ layout, instanced }) => {
326
- let index2 = 0;
327
- const handles = layout.map((layout2) => {
328
- const name = toID(layout2.key);
329
- const location = gl.getAttribLocation(program, name);
330
- if (location < 0) {
331
- throw new Error(`Attribute '${name}' not found`);
332
- }
333
- const size = kindToSize(layout2.kind);
334
- const offset = index2;
335
- const type = layout2.kind.startsWith("i") ? "INT" : "FLOAT";
336
- index2 += size * 4;
337
- return () => handleAttribute(gl, location, size, stride, offset, type, instanced);
338
- });
339
- const stride = index2;
340
- const buffer = assertedNotNullish(gl.createBuffer());
341
- let vao = void 0;
342
- const feature = getVertexArrayObject(gl);
343
- if (feature) {
344
- const vertexArray = feature.createVertexArray();
345
- feature.bindVertexArray(vertexArray);
346
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
347
- for (const handle of handles) {
348
- handle();
349
- }
350
- feature.bindVertexArray(null);
351
- vao = {
352
- unbind() {
353
- feature.bindVertexArray(null);
354
- },
355
- bind() {
356
- feature.bindVertexArray(vertexArray);
357
- },
358
- dispose() {
359
- feature.deleteVertexArray(vertexArray);
360
- }
361
- };
362
- }
363
- return {
364
- bind() {
365
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
366
- if (vao) {
367
- vao.bind();
368
- } else {
369
- for (const handle of handles) {
370
- handle();
371
- }
372
- }
373
- },
374
- unbind() {
375
- if (vao) {
376
- vao.unbind();
377
- }
378
- },
379
- dispose() {
380
- gl.deleteBuffer(buffer);
381
- if (vao) {
382
- vao.dispose();
383
- }
384
- },
385
- set(value, usage = "STATIC_DRAW") {
386
- if (vao) {
387
- vao.bind();
388
- } else {
389
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
390
- }
391
- gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage]);
392
- if (vao) {
393
- vao.unbind();
394
- }
395
- }
396
- };
397
- });
398
- signal?.addEventListener("abort", function dispose() {
399
- forEach(interleavedAttributes, (value) => value.dispose());
400
- });
401
- return interleavedAttributes;
402
- }
403
- function bufferView(gl, schema, { signal } = {}) {
404
- const buffers = map(schema, ({ target = "ARRAY_BUFFER", usage = "STATIC_DRAW" }) => {
405
- const buffer = assertedNotNullish(gl.createBuffer());
406
- return {
407
- bind() {
408
- gl.bindBuffer(gl[target], buffer);
409
- },
410
- dispose() {
411
- gl.deleteBuffer(buffer);
412
- },
413
- set(data) {
414
- gl.bindBuffer(gl[target], buffer);
415
- gl.bufferData(gl[target], data, gl[usage]);
416
- }
417
- };
418
- });
419
- signal?.addEventListener("abort", function dispose() {
420
- forEach(buffers, (value) => value.dispose());
421
- });
422
- return buffers;
423
- }
424
-
425
- const uniform = new Proxy(
426
- {},
427
- {
428
- get(target, property) {
429
- if (typeof property === "symbol") return target[property];
430
- return (key, options) => ({
431
- type: "uniform",
432
- key,
433
- kind: property,
434
- ...options
435
- });
436
- }
437
- }
438
- );
439
- const attribute = new Proxy(
440
- {},
441
- {
442
- get(target, property) {
443
- if (typeof property === "symbol") return target[property];
444
- return (key, options) => ({
445
- type: "attribute",
446
- key,
447
- kind: property,
448
- ...options
449
- });
450
- }
451
- }
452
- );
453
- function interleave(key, layout, { instanced, buffer } = {}) {
454
- return {
455
- type: "interleavedAttribute",
456
- key,
457
- // remove instanced- and type-property
458
- layout: layout.map(({ key: key2, kind }) => ({
459
- key: key2,
460
- kind
461
- })),
462
- instanced: !!instanced,
463
- buffer
464
- };
465
- }
466
- function glsl([initial, ...rest], ...holes) {
467
- const v300 = initial?.startsWith("#version 300 es");
468
- const template = rest.reduce((out, templatePart, index) => {
469
- const hole = holes[index];
470
- const holePart = typeof hole === "string" || typeof hole === "number" || typeof hole === "symbol" ? toID(hole) : hole.type === "interleavedAttribute" ? hole.layout.reduce(
471
- (a, v) => v300 ? `${a}in ${v.kind} ${toID(v.key)};
472
- ` : `${a}attribute ${v.kind} ${toID(v.key)};
473
- `,
474
- ""
475
- ) : typeof hole === "object" && hole.type === "uniform" && "size" in hole ? `${hole.type} ${hole.kind} ${toID(hole.key)}[${hole.size}];` : `${hole.type === "attribute" && v300 ? "in" : hole.type} ${hole.kind} ${toID(hole.key)};`;
476
- return out + holePart + templatePart;
477
- }, initial || "");
478
- return holes.reduce(
479
- (resources, resource) => {
480
- if (typeof resource === "string" || typeof resource === "number" || typeof resource === "symbol") {
481
- return resources;
482
- }
483
- const { key: name, type, ...rest2 } = resource;
484
- resources[`${type}s`][name] = rest2;
485
- return resources;
486
- },
487
- {
488
- template,
489
- uniforms: {},
490
- attributes: {},
491
- interleavedAttributes: {}
492
- }
493
- );
494
- }
495
- function compile(gl, vertex, fragment) {
496
- const program = createProgram(gl, vertex.template, fragment.template);
497
- return {
498
- program,
499
- schema: {
500
- uniforms: {
501
- ...vertex.uniforms,
502
- ...fragment.uniforms
503
- },
504
- attributes: {
505
- ...vertex.attributes,
506
- ...fragment.attributes
507
- },
508
- interleavedAttributes: {
509
- ...vertex.interleavedAttributes,
510
- ...fragment.interleavedAttributes
511
- }
512
- }
513
- };
514
- }
515
-
516
- export { attribute as a, createFramebuffer as b, compile as c, uniformView as d, attributeView as e, glsl as g, interleave as i, uniform as u, view as v };