@bigmistqke/view.gl 0.1.4 → 0.1.6
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/.prettierignore +1 -0
- package/README.md +72 -109
- package/dev/src/examples/glsl-composition.ts +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/tag.d.mts +1 -1
- package/dist/tag.mjs +13 -4
- package/dist/tag.mjs.map +1 -1
- package/dist/{types-CGTxl3Eq.d.mts → types-COnZSrXA.d.mts} +165 -2
- package/package.json +1 -1
- package/src/index.ts +6 -1
- package/src/tag.ts +50 -4
- package/src/types.ts +3 -8
- package/test/tag.test.ts +269 -0
package/.prettierignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
README.md
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
- [🚀 Basic Usage](#-basic-usage-1)
|
|
21
21
|
- [📝 glsl](#-glsl)
|
|
22
22
|
- [🧩 GLSL Fragment](#-glsl-fragment)
|
|
23
|
-
- [🔒 Symbol
|
|
23
|
+
- [🔒 Symbol Variables](#-symbol-variables)
|
|
24
24
|
- [WebGL Version Support](#webgl-version-support)
|
|
25
25
|
- [⚙️ Resource Tags](#️-resource-tags)
|
|
26
26
|
- [🎯 uniform[kind](name, options?)](#-uniformkindname-options)
|
|
@@ -52,8 +52,6 @@ The view system provides type-safe WebGL resource management for uniforms, attri
|
|
|
52
52
|
### 🚀 Basic Usage
|
|
53
53
|
|
|
54
54
|
```typescript
|
|
55
|
-
import { view } from '@bigmistqke/view.gl'
|
|
56
|
-
|
|
57
55
|
const { uniforms, attributes } = view(gl, program, {
|
|
58
56
|
uniforms: {
|
|
59
57
|
time: { kind: 'float' },
|
|
@@ -158,14 +156,6 @@ uniforms.lights.set(lightData) // Takes Float32Array for array uniforms
|
|
|
158
156
|
**UniformSchema:**
|
|
159
157
|
A mapping of uniform names to their configuration. Each uniform has a GLSL type and optional array size.
|
|
160
158
|
|
|
161
|
-
```typescript
|
|
162
|
-
{
|
|
163
|
-
time: { kind: 'float' },
|
|
164
|
-
transform: { kind: 'mat4' },
|
|
165
|
-
lights: { kind: 'vec3', size: 8 }, // Array uniform
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
159
|
- `kind`: GLSL type (see [Uniform Types](#-uniform-types) for full list and WebGL compatibility)
|
|
170
160
|
- `size`: Array size (optional) - converts uniform to array type
|
|
171
161
|
|
|
@@ -194,7 +184,7 @@ type UniformKind =
|
|
|
194
184
|
|
|
195
185
|
interface UniformOptions {
|
|
196
186
|
kind: UniformKind
|
|
197
|
-
size?: number
|
|
187
|
+
size?: number // Creates array uniform with Float32Array setter
|
|
198
188
|
}
|
|
199
189
|
|
|
200
190
|
type UniformSchema = Record<string | symbol, UniformOptions>
|
|
@@ -221,13 +211,6 @@ gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 100)
|
|
|
221
211
|
**AttributeSchema:**
|
|
222
212
|
A mapping of attribute names to their configuration. Each attribute has a GLSL type, optional instancing, and optional custom buffer.
|
|
223
213
|
|
|
224
|
-
```typescript
|
|
225
|
-
{
|
|
226
|
-
position: { kind: 'vec3' },
|
|
227
|
-
instanceOffset: { kind: 'vec2', instanced: true },
|
|
228
|
-
}
|
|
229
|
-
```
|
|
230
|
-
|
|
231
214
|
- `kind`: GLSL type (see [Attribute Types](#-attribute-types) for full list and WebGL compatibility)
|
|
232
215
|
- `instanced`: Boolean - enables instanced rendering
|
|
233
216
|
- `buffer`: Custom WebGLBuffer (optional)
|
|
@@ -251,8 +234,8 @@ type AttributeKind =
|
|
|
251
234
|
|
|
252
235
|
interface AttributeOptions {
|
|
253
236
|
kind: AttributeKind
|
|
254
|
-
instanced?: boolean
|
|
255
|
-
buffer?: WebGLBuffer
|
|
237
|
+
instanced?: boolean // Enables vertexAttribDivisor
|
|
238
|
+
buffer?: WebGLBuffer // Custom buffer, auto-created if not provided
|
|
256
239
|
}
|
|
257
240
|
|
|
258
241
|
type AttributeSchema = Record<string | symbol, AttributeOptions>
|
|
@@ -281,19 +264,7 @@ interleavedAttributes.vertexData.set(interleavedVertexData).bind()
|
|
|
281
264
|
**InterleavedAttributeSchema:**
|
|
282
265
|
A mapping of interleaved buffer names to their layout configuration. Each layout defines multiple attributes packed into a single buffer.
|
|
283
266
|
|
|
284
|
-
|
|
285
|
-
{
|
|
286
|
-
vertexData: {
|
|
287
|
-
layout: [
|
|
288
|
-
{ key: 'position', kind: 'vec3' },
|
|
289
|
-
{ key: 'normal', kind: 'vec3' },
|
|
290
|
-
{ key: 'uv', kind: 'vec2' },
|
|
291
|
-
],
|
|
292
|
-
},
|
|
293
|
-
}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
- `layout`: Array of attribute definitions with `key` and `kind` (see [Attribute Types](#-attribute-types) for WebGL compatibility)
|
|
267
|
+
- `layout`: Array of attribute definitions with `key` and `kind` (see [Attribute Types](#-attribute-types))
|
|
297
268
|
- `instanced`: Boolean - applies to all attributes in layout
|
|
298
269
|
|
|
299
270
|
<details>
|
|
@@ -305,8 +276,8 @@ interface InterleavedAttributeOptions {
|
|
|
305
276
|
key: string | symbol
|
|
306
277
|
kind: AttributeKind
|
|
307
278
|
}>
|
|
308
|
-
instanced?: boolean
|
|
309
|
-
buffer?: WebGLBuffer
|
|
279
|
+
instanced?: boolean // Applies vertexAttribDivisor to all attributes
|
|
280
|
+
buffer?: WebGLBuffer // Custom buffer for interleaved data
|
|
310
281
|
}
|
|
311
282
|
|
|
312
283
|
type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeOptions>
|
|
@@ -331,13 +302,6 @@ buffers.data.set(dynamicData).bind()
|
|
|
331
302
|
**BufferSchema:**
|
|
332
303
|
A mapping of buffer names to their configuration. Each buffer has a target type and optional usage pattern.
|
|
333
304
|
|
|
334
|
-
```typescript
|
|
335
|
-
{
|
|
336
|
-
indices: { target: 'ELEMENT_ARRAY_BUFFER' },
|
|
337
|
-
data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
305
|
- `target`: Buffer target (`'ARRAY_BUFFER'`, `'ELEMENT_ARRAY_BUFFER'`)
|
|
342
306
|
- `usage`: Usage pattern (`'STATIC_DRAW'`, `'DYNAMIC_DRAW'`, `'STREAM_DRAW'`)
|
|
343
307
|
|
|
@@ -361,25 +325,21 @@ Type-safe GLSL template literals with automatic schema extraction.
|
|
|
361
325
|
|
|
362
326
|
- **Embedded Resources**: Define uniforms, attributes, and interleaved layouts directly in GLSL
|
|
363
327
|
- **Type Inference**: Automatically infers schema types and creates type-safe view
|
|
364
|
-
- **
|
|
328
|
+
- **Unique Variables**: Prevent naming collisions using symbols for unique shader variables
|
|
365
329
|
- **GLSL Composition**: Compose reusable GLSL fragments with automatic dependency resolution
|
|
366
330
|
|
|
367
331
|
### 🚀 Basic Usage
|
|
368
332
|
|
|
369
333
|
```typescript
|
|
370
|
-
import { glsl, uniform, attribute, compile } from '@bigmistqke/view.gl/tag'
|
|
371
|
-
|
|
372
334
|
const vertexShader = glsl`
|
|
373
335
|
${attribute.vec3('position')}
|
|
374
|
-
${attribute.vec2('uv')}
|
|
375
|
-
${uniform.mat4('projection')}
|
|
376
336
|
${uniform.mat4('model')}
|
|
377
337
|
|
|
378
338
|
varying vec2 vUv;
|
|
379
339
|
|
|
380
340
|
void main() {
|
|
381
341
|
vUv = uv;
|
|
382
|
-
gl_Position =
|
|
342
|
+
gl_Position = model * vec4(position, 1.0);
|
|
383
343
|
}
|
|
384
344
|
`
|
|
385
345
|
|
|
@@ -401,15 +361,23 @@ const { program, schema } = compile(gl, vertexShader, fragmentShader)
|
|
|
401
361
|
Template literal processor that handles GLSL code and embedded resources. Supports interpolation of:
|
|
402
362
|
|
|
403
363
|
- **[Resource tags](#️-resource-tags)**: `uniform.*()`, `attribute.*()`, `interleave()`
|
|
404
|
-
- **[
|
|
405
|
-
- **[
|
|
364
|
+
- **[GLSL fragments](#-glsl-fragment)**: Reusable shader code snippets
|
|
365
|
+
- **[Symbol Variables](#-symbol-variables)**: Unique variable names to prevent collisions
|
|
366
|
+
- **Strings**: Interpolated as-is into the shader code
|
|
367
|
+
- **Arrays**: Arrays of any supported interpolation types
|
|
406
368
|
|
|
407
369
|
```typescript
|
|
408
|
-
|
|
370
|
+
const precision = 'precision mediump float;'
|
|
371
|
+
const functionName = Symbol('function')
|
|
409
372
|
|
|
410
373
|
const shader = glsl`
|
|
374
|
+
${precision} // String interpolated as-is
|
|
411
375
|
${uniform.vec2('resolution')}
|
|
412
|
-
${attribute.vec3('position')}
|
|
376
|
+
${[attribute.vec3('position'), attribute.vec2('uv')]} // Array interpolation
|
|
377
|
+
|
|
378
|
+
vec3 ${functionName}(vec2 uv) { // Symbol interpolated to unique identifier
|
|
379
|
+
return vec3(uv, 0.5);
|
|
380
|
+
}
|
|
413
381
|
|
|
414
382
|
void main() {
|
|
415
383
|
gl_Position = vec4(position, 1.0);
|
|
@@ -430,18 +398,19 @@ const lighting = glsl`
|
|
|
430
398
|
`
|
|
431
399
|
|
|
432
400
|
const vertexShader = glsl`
|
|
433
|
-
${attribute.vec3('
|
|
401
|
+
${attribute.vec3('direction')}
|
|
434
402
|
${attribute.vec3('normal')}
|
|
435
|
-
${lighting}
|
|
403
|
+
${lighting} // Include the lighting fragment
|
|
404
|
+
|
|
405
|
+
varying vec3 vLighting;
|
|
436
406
|
|
|
437
407
|
void main() {
|
|
438
|
-
|
|
439
|
-
// Use the composed function
|
|
408
|
+
vLighting = calculateLighting(normal, direction);
|
|
440
409
|
}
|
|
441
410
|
`
|
|
442
411
|
```
|
|
443
412
|
|
|
444
|
-
#### 🔒 Symbol
|
|
413
|
+
#### 🔒 Symbol Variables
|
|
445
414
|
|
|
446
415
|
Use JavaScript symbols to prevent naming collisions:
|
|
447
416
|
|
|
@@ -462,7 +431,7 @@ void main(){
|
|
|
462
431
|
`
|
|
463
432
|
```
|
|
464
433
|
|
|
465
|
-
Symbols are converted to unique identifiers
|
|
434
|
+
Symbols are converted to unique identifiers during the compilation of the shader.
|
|
466
435
|
|
|
467
436
|
#### WebGL Version Support
|
|
468
437
|
|
|
@@ -471,7 +440,7 @@ The glsl-function supports both WebGL1 and WebGL2 syntax, automatically using th
|
|
|
471
440
|
```typescript
|
|
472
441
|
// WebGL1 (default)
|
|
473
442
|
const shader = glsl`
|
|
474
|
-
${attribute.vec3('position')}
|
|
443
|
+
${attribute.vec3('position')} // → attribute vec3 position;
|
|
475
444
|
varying vec2 vUv;
|
|
476
445
|
`
|
|
477
446
|
```
|
|
@@ -481,7 +450,7 @@ If the shader starts with `#version 300 es`, resource tags generate WebGL2 synta
|
|
|
481
450
|
```typescript
|
|
482
451
|
// WebGL2
|
|
483
452
|
const shader = glsl`#version 300 es
|
|
484
|
-
${attribute.vec3('position')}
|
|
453
|
+
${attribute.vec3('position')} // → in vec3 position;
|
|
485
454
|
out vec2 vUv;
|
|
486
455
|
`
|
|
487
456
|
```
|
|
@@ -492,48 +461,43 @@ Functions for defining WebGL resources directly in GLSL templates. These tags ge
|
|
|
492
461
|
|
|
493
462
|
#### 🎯 uniform[kind](name, options?)
|
|
494
463
|
|
|
495
|
-
Define uniform variables in GLSL templates
|
|
464
|
+
Define uniform variables in GLSL templates (see [Uniform Types](#-uniform-types)).
|
|
496
465
|
|
|
497
466
|
```typescript
|
|
498
|
-
|
|
467
|
+
const uniqueTime = Symbol('time')
|
|
499
468
|
|
|
500
469
|
const shader = glsl`
|
|
501
|
-
${uniform.float('time')}
|
|
502
|
-
${uniform.
|
|
470
|
+
${uniform.float('time')} // String key
|
|
471
|
+
${uniform.float(uniqueTime)} // Symbol key
|
|
472
|
+
${uniform.vec3('lights', { size: 8 })} // Array uniform: vec3[8]
|
|
503
473
|
|
|
504
474
|
void main() {
|
|
505
|
-
|
|
475
|
+
float wave = sin(time * 2.0 + ${uniqueTime});
|
|
476
|
+
vec3 totalLight = vec3(0.0);
|
|
477
|
+
for(int i = 0; i < 8; i++) {
|
|
478
|
+
totalLight += lights[i] * wave;
|
|
479
|
+
}
|
|
480
|
+
gl_FragColor = vec4(totalLight, 1.0);
|
|
506
481
|
}
|
|
507
482
|
`
|
|
508
483
|
```
|
|
509
484
|
|
|
510
|
-
**
|
|
485
|
+
**Parameters**:
|
|
511
486
|
|
|
512
|
-
- `
|
|
487
|
+
- `name`: Uniform name (string or symbol for unique variables)
|
|
488
|
+
- `options`: Optional configuration object
|
|
489
|
+
- `size`: Array size (creates array uniform with Float32Array setter)
|
|
513
490
|
|
|
514
491
|
#### 📝 attribute[kind](name, options?)
|
|
515
492
|
|
|
516
|
-
Define vertex attributes in GLSL templates (see [Attribute Types](#-attribute-types)
|
|
517
|
-
|
|
518
|
-
**Regular rendering:**
|
|
493
|
+
Define vertex attributes in GLSL templates (see [Attribute Types](#-attribute-types)).
|
|
519
494
|
|
|
520
495
|
```typescript
|
|
521
|
-
|
|
496
|
+
const uniquePosition = Symbol('position')
|
|
522
497
|
|
|
523
498
|
const vertexShader = glsl`
|
|
524
|
-
${attribute.vec3('position')}
|
|
525
|
-
|
|
526
|
-
void main() {
|
|
527
|
-
gl_Position = vec4(position, 1.0);
|
|
528
|
-
}
|
|
529
|
-
`
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
**Instanced rendering:**
|
|
533
|
-
|
|
534
|
-
```typescript
|
|
535
|
-
const vertexShader = glsl`
|
|
536
|
-
${attribute.vec3('position')}
|
|
499
|
+
${attribute.vec3('position')} // String key
|
|
500
|
+
${attribute.vec3(uniquePosition)} // Symbol key
|
|
537
501
|
${attribute.vec2('offset', { instanced: true })}
|
|
538
502
|
|
|
539
503
|
void main() {
|
|
@@ -542,23 +506,32 @@ const vertexShader = glsl`
|
|
|
542
506
|
`
|
|
543
507
|
```
|
|
544
508
|
|
|
545
|
-
**
|
|
509
|
+
**Parameters**:
|
|
546
510
|
|
|
547
|
-
- `
|
|
548
|
-
- `
|
|
511
|
+
- `name`: Attribute name (string or symbol for unique variables)
|
|
512
|
+
- `options`: Optional configuration object
|
|
513
|
+
- `instanced`: Boolean - enables instanced rendering with `vertexAttribDivisor`
|
|
514
|
+
- `buffer`: Custom WebGLBuffer (optional)
|
|
549
515
|
|
|
550
516
|
#### 🔗 interleave(name, layout, options?)
|
|
551
517
|
|
|
552
518
|
Define interleaved attribute layouts for efficient vertex data.
|
|
553
519
|
|
|
554
520
|
```typescript
|
|
555
|
-
|
|
521
|
+
const uniqueVertexData = Symbol('vertexData')
|
|
522
|
+
const uniquePosition = Symbol('position')
|
|
556
523
|
|
|
557
524
|
const vertexShader = glsl`
|
|
558
525
|
${interleave('vertexData', [
|
|
526
|
+
// String key
|
|
559
527
|
{ key: 'position', kind: 'vec3' },
|
|
560
528
|
{ key: 'uv', kind: 'vec2' },
|
|
561
529
|
])}
|
|
530
|
+
${interleave(uniqueVertexData, [
|
|
531
|
+
// Symbol key
|
|
532
|
+
{ key: uniquePosition, kind: 'vec3' }, // Symbol keys in layout
|
|
533
|
+
{ key: 'uv', kind: 'vec2' },
|
|
534
|
+
])}
|
|
562
535
|
|
|
563
536
|
void main() {
|
|
564
537
|
gl_Position = vec4(position + vec3(uv, 0.0), 1.0);
|
|
@@ -566,22 +539,20 @@ const vertexShader = glsl`
|
|
|
566
539
|
`
|
|
567
540
|
```
|
|
568
541
|
|
|
569
|
-
**
|
|
542
|
+
**Parameters**:
|
|
570
543
|
|
|
571
|
-
- `
|
|
572
|
-
- `
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
- `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes
|
|
544
|
+
- `name`: Buffer name (string or symbol for unique variables)
|
|
545
|
+
- `layout`: Array of attribute definitions
|
|
546
|
+
- `key`: Attribute name (string or symbol for unique variables)
|
|
547
|
+
- `kind`: GLSL type (see [Attribute Types](#-attribute-types))
|
|
548
|
+
- `options`: Optional configuration object
|
|
549
|
+
- `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes
|
|
577
550
|
|
|
578
551
|
### ⚙️ compile(gl, vertex, fragment, overrideSchema?)
|
|
579
552
|
|
|
580
553
|
Compiles shaders and extracts schema from embedded resources. Returns both the compiled program and a ready-to-use view.
|
|
581
554
|
|
|
582
555
|
```typescript
|
|
583
|
-
import { compile } from '@bigmistqke/view.gl/tag'
|
|
584
|
-
|
|
585
556
|
const { program, schema, view } = compile(gl, vertexShader, fragmentShader)
|
|
586
557
|
|
|
587
558
|
// Use the view directly
|
|
@@ -589,8 +560,8 @@ view.uniforms.time.set(performance.now())
|
|
|
589
560
|
view.attributes.position.set(vertexData).bind()
|
|
590
561
|
|
|
591
562
|
// Or access the extracted schema
|
|
592
|
-
console.log(schema.uniforms)
|
|
593
|
-
console.log(schema.attributes)
|
|
563
|
+
console.log(schema.uniforms) // { time: { kind: 'float' }, ... }
|
|
564
|
+
console.log(schema.attributes) // { position: { kind: 'vec3' }, ... }
|
|
594
565
|
```
|
|
595
566
|
|
|
596
567
|
**Override Schema:**
|
|
@@ -623,11 +594,9 @@ view.buffers.indices.set(indexData).bind()
|
|
|
623
594
|
<details>
|
|
624
595
|
<summary>Usage with vanilla view.gl</summary>
|
|
625
596
|
|
|
626
|
-
When manually constructing GLSL strings, use `toID()` to convert symbols to valid identifiers:
|
|
597
|
+
When manually constructing GLSL strings, use `toID()` to convert symbols to valid, unique identifiers:
|
|
627
598
|
|
|
628
599
|
```typescript
|
|
629
|
-
import { createProgram, view, toID } from 'view.gl'
|
|
630
|
-
|
|
631
600
|
const u_time = Symbol('time')
|
|
632
601
|
const a_position = Symbol('position')
|
|
633
602
|
|
|
@@ -669,8 +638,6 @@ uniforms[u_time].set(performance.now())
|
|
|
669
638
|
Creates and links a WebGL program from vertex and fragment shader sources.
|
|
670
639
|
|
|
671
640
|
```typescript
|
|
672
|
-
import { createProgram } from '@bigmistqke/view.gl/utils'
|
|
673
|
-
|
|
674
641
|
const program = createProgram(gl, vertexShaderSource, fragmentShaderSource)
|
|
675
642
|
```
|
|
676
643
|
|
|
@@ -679,8 +646,6 @@ const program = createProgram(gl, vertexShaderSource, fragmentShaderSource)
|
|
|
679
646
|
Creates a WebGL texture with specified parameters.
|
|
680
647
|
|
|
681
648
|
```typescript
|
|
682
|
-
import { createTexture } from '@bigmistqke/view.gl/utils'
|
|
683
|
-
|
|
684
649
|
const texture = createTexture(
|
|
685
650
|
gl,
|
|
686
651
|
{
|
|
@@ -705,8 +670,6 @@ Automatically validates WebGL2-only formats and provides fallbacks for WebGL1.
|
|
|
705
670
|
Creates a framebuffer with attached texture for render-to-texture operations.
|
|
706
671
|
|
|
707
672
|
```typescript
|
|
708
|
-
import { createFramebuffer } from '@bigmistqke/view.gl/utils'
|
|
709
|
-
|
|
710
673
|
const { framebuffer, texture } = createFramebuffer(gl, {
|
|
711
674
|
width: 512,
|
|
712
675
|
height: 512,
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { V as ViewSchema, G as GL, a as ViewOptions, b as View, U as UniformSchema, c as UniformView, A as AttributeSchema, d as AttributeView, I as InterleavedAttributeSchema, e as InterleavedAttributeView, B as BufferSchema, f as BufferView } from './types-
|
|
1
|
+
import { V as ViewSchema, G as GL, a as ViewOptions, b as View, U as UniformSchema, c as UniformView, A as AttributeSchema, d as AttributeView, I as InterleavedAttributeSchema, e as InterleavedAttributeView, B as BufferSchema, f as BufferView } from './types-COnZSrXA.mjs';
|
|
2
|
+
export { n as AttributeKind, p as AttributeMethods, o as AttributeOptions, m as AttributeShortHand, $ as AttributeTag, a0 as AttributeTagFn, u as BufferMethods, t as BufferOptions, D as DeepMerge, L as Format, v as Framebuffer, F as FramebufferOptions, W as GLSLResult, X as GLSLSlot, Y as GLSLTag, a1 as InterleaveTag, q as InterleavedAttributeLayout, s as InterleavedAttributeMethods, r as InterleavedAttributeOptions, J as InternalFormat, g as KIND_TO_SIZE_MAP, K as KIND_TO_UNIFORM_FN_NAME_MAP, M as Merge, N as PixelType, P as Prettify, R as RemoveSuffix, S as ShallowMerge, O as TexImage2DOptions, y as TextureMethods, T as TextureOptions, C as TextureParameterName, E as TextureParameterValue, H as TextureParameters, x as TextureSchema, w as TextureTarget, z as TextureView, h as UniformFnName, i as UniformKind, l as UniformMethods, j as UniformOptions, k as UniformSchemaPartial, Z as UniformTag, _ as UniformTagFn, Q as ViewSchemaPartial } from './types-COnZSrXA.mjs';
|
|
2
3
|
|
|
3
4
|
declare function toID(key: string | number | symbol): any;
|
|
4
5
|
/**********************************************************************************/
|
|
@@ -15,4 +16,4 @@ declare function interleavedAttributeView<T extends InterleavedAttributeSchema>(
|
|
|
15
16
|
/**********************************************************************************/
|
|
16
17
|
declare function bufferView<T extends BufferSchema>(gl: GL, schema: T, { signal }?: ViewOptions): BufferView<T>;
|
|
17
18
|
|
|
18
|
-
export { attributeView, bufferView, interleavedAttributeView, toID, uniformView, view };
|
|
19
|
+
export { AttributeSchema, AttributeView, BufferSchema, BufferView, GL, InterleavedAttributeSchema, InterleavedAttributeView, UniformSchema, UniformView, View, ViewOptions, ViewSchema, attributeView, bufferView, interleavedAttributeView, toID, uniformView, view };
|
package/dist/index.mjs
CHANGED
|
@@ -128,7 +128,8 @@ function createUpsertMap(constructor) {
|
|
|
128
128
|
// src/index.ts
|
|
129
129
|
var index = 0;
|
|
130
130
|
var PREFIX = "VIEW_GL_ALIAS";
|
|
131
|
-
var
|
|
131
|
+
var IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf("firefox") >= 0;
|
|
132
|
+
var SYMBOL_MAP = createUpsertMap(IS_FIREFOX ? Map : WeakMap);
|
|
132
133
|
function toID(key) {
|
|
133
134
|
if (typeof key === "string") {
|
|
134
135
|
return key;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/features.ts","../src/utils/object.ts","../src/utils/index.ts","../src/index.ts"],"sourcesContent":["import type { GL, RemoveSuffix } from './types'\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n","export function forEach<T extends Record<string, any>>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => void,\n) {\n let index = 0\n for (const key in value) {\n callback(value[key], key, index)\n index++\n }\n for (const key of Object.getOwnPropertySymbols(value)) {\n callback(value[key as keyof T], key as keyof T, index)\n index++\n }\n}\n\nexport function map<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n const result = {} as { [TKey in keyof T]: TReturn }\n\n forEach(value, (value, key, index) => {\n result[key] = callback(value, key, index)\n })\n\n return result\n}\n","import type {\n AttributeKind,\n FramebufferOptions,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureOptions,\n UniformKind,\n} from '../types'\n\nexport * as ObjectUtils from './object'\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\nfunction createGLShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return ('Matrix' + kind.slice(3) + 'fv') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return ((kind.match(/\\d/)?.[0] ?? '1') + 'i') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // unsigned integers\n case 'u':\n return ((kind[4] || '1') + 'ui') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // vec\n case 'v':\n return (kind[3] + 'f') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n switch (kind) {\n case 'float':\n return '1f' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n case 'uint':\n return '1ui' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n return '1i' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number) as [number, number?]\n return (a * (b ?? a)) as KIND_TO_SIZE_MAP[T]\n case 'v':\n case 'i':\n case 'b':\n case 'u':\n const match = kind.match(/\\d/) as [string] | undefined\n return (match ? +match[0] : 1) as KIND_TO_SIZE_MAP[T]\n default:\n return 1 as KIND_TO_SIZE_MAP[T]\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureOptions,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name as keyof typeof gl] as any\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(gl: GL, { attachment, texture, ...options }: FramebufferOptions) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Create Upsert */\n/* */\n/**********************************************************************************/\n\ntype UpsertMapKind<T, U> = Map<T, U> | (T extends WeakKey ? WeakMap<T, U> : never)\n\nexport function createUpsertMap<T extends UpsertMapKind<any, any> = Map<any, any>>(\n constructor?: new () => T,\n) {\n const map = new (constructor ?? Map)() as T\n return Object.assign(map, {\n getOrInsert(\n key: T extends UpsertMapKind<infer U, any> ? U : never,\n value: T extends UpsertMapKind<any, infer U> ? () => U : never,\n ) {\n let result = map.get(key)\n if (result) {\n return result\n }\n result = value()\n map.set(key, result)\n return result\n },\n })\n}\n","import { getInstancedArrays, getVertexArrayObject } from './features'\nimport type {\n AttributeMethods,\n AttributeSchema,\n AttributeView,\n BufferSchema,\n BufferView,\n GL,\n UniformView as InferUniformView,\n InterleavedAttributeMethods,\n InterleavedAttributeSchema,\n InterleavedAttributeView,\n UniformSchema,\n View,\n ViewOptions,\n ViewSchema,\n} from './types'\nimport {\n assertedNotNullish,\n createUpsertMap,\n isMatKind,\n isSamplerKind,\n kindToSize,\n kindToUniformFnName,\n ObjectUtils,\n} from './utils'\n\n/**********************************************************************************/\n/* */\n/* To ID */\n/* */\n/**********************************************************************************/\n\nlet index = 0\nconst PREFIX = 'VIEW_GL_ALIAS'\n\nconst SYMBOL_MAP = createUpsertMap(WeakMap<symbol, string>)\n\nexport function toID(key: string | number | symbol) {\n if (typeof key === 'string') {\n return key\n }\n if (typeof key === 'symbol') {\n return SYMBOL_MAP.getOrInsert(key, () => `${PREFIX}_${index++}`)\n }\n return key.toString()\n}\n\n/**********************************************************************************/\n/* */\n/* View */\n/* */\n/**********************************************************************************/\n\nexport function view<TSchema extends ViewSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: TSchema,\n options?: ViewOptions,\n): View<TSchema> {\n return {\n uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),\n attributes: !schema.attributes\n ? undefined\n : attributeView(gl, program, schema.attributes, options),\n interleavedAttributes: !schema.interleavedAttributes\n ? undefined\n : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),\n buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),\n } as View<TSchema>\n}\n\n/**********************************************************************************/\n/* */\n/* Uniform View */\n/* */\n/**********************************************************************************/\n\nexport function uniformView<T extends UniformSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n): InferUniformView<T> {\n return ObjectUtils.map(schema, ({ kind, size }, key) => {\n const name = toID(key)\n\n const location = gl.getUniformLocation(program, name)\n\n if (isSamplerKind(kind)) {\n return {\n set(arg: number) {\n gl.uniform1i(location, arg)\n },\n }\n }\n\n const fnName = `uniform${kindToUniformFnName(kind)}${size ? 'v' : ''}`\n\n // @ts-ignore FIX WEBGL/WEBGL2 TYPES\n const fn = gl[fnName].bind(gl)\n\n if (isMatKind(kind)) {\n return {\n set(...args: any[]) {\n fn(location, false, args[0])\n },\n }\n }\n\n return {\n set(...args: any[]) {\n fn(location, ...args)\n },\n }\n })\n}\n\n/**********************************************************************************/\n/* */\n/* Attribute View */\n/* */\n/**********************************************************************************/\n\n// Shared attribute helper functions\n// between attributeView and interleavedAttributeView\nfunction handleAttribute(\n gl: GL,\n location: number,\n size: number,\n stride: number,\n offset: number,\n type: 'FLOAT' | 'INT',\n instanced?: boolean,\n) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl[type], false, stride, offset)\n\n if (instanced) {\n // Get instanced-arrays-feature: extension if webgl, gl if webgl2\n assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1)\n }\n}\n\nexport function attributeView<T extends AttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): AttributeView<T> {\n const attributes = ObjectUtils.map(\n schema,\n (\n { kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) },\n key,\n ): AttributeMethods => {\n const name = toID(key)\n\n const location = gl.getAttribLocation(program, name)\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(kind)\n const type = kind.startsWith('i') ? 'INT' : 'FLOAT'\n\n return {\n buffer,\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n handleAttribute(gl, location, size, 0, 0, type, instanced)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data, usage = 'STATIC_DRAW') {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage])\n return this\n },\n }\n },\n )\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(attributes, value => value.dispose())\n })\n\n return attributes\n}\n\n/**********************************************************************************/\n/* */\n/* Interleaved Attribute View */\n/* */\n/**********************************************************************************/\n\nexport function interleavedAttributeView<T extends InterleavedAttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): InterleavedAttributeView<T> {\n // Initialize interleaved attributes\n const interleavedAttributes = ObjectUtils.map(schema, ({ layout, instanced }) => {\n // Increment number to keep track of offset\n let index = 0\n\n // Calculate layout information\n const handles = layout.map(layout => {\n const name = toID(layout.key)\n\n const location = gl.getAttribLocation(program, name)\n\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(layout.kind)\n const offset = index\n const type = layout.kind.startsWith('i') ? 'INT' : 'FLOAT'\n index += size * 4\n\n return () => handleAttribute(gl, location, size, stride, offset, type, instanced)\n })\n\n // Set stride to final index\n const stride = index\n\n // Create a buffer\n const buffer = assertedNotNullish(gl.createBuffer())\n\n // Create VAO to cache attribute state\n let vao: { unbind(): void; bind(): void; dispose(): void } | undefined = undefined\n\n // Get VAO-feature: extension if webgl1, gl if webgl2\n const feature = getVertexArrayObject(gl)\n if (feature) {\n const vertexArray = feature.createVertexArray()\n feature.bindVertexArray(vertexArray)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n for (const handle of handles) {\n handle()\n }\n feature.bindVertexArray(null)\n vao = {\n unbind() {\n feature.bindVertexArray(null)\n },\n bind() {\n feature.bindVertexArray(vertexArray)\n },\n dispose() {\n feature.deleteVertexArray(vertexArray)\n },\n }\n }\n\n return {\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n if (vao) {\n vao.bind()\n } else {\n // Fallback: manual attribute setup\n for (const handle of handles) {\n handle()\n }\n }\n },\n unbind() {\n if (vao) {\n vao.unbind()\n }\n },\n dispose() {\n gl.deleteBuffer(buffer)\n if (vao) {\n vao.dispose()\n }\n },\n set(value, usage = 'STATIC_DRAW') {\n if (vao) {\n vao.bind()\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n }\n gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage])\n if (vao) {\n vao.unbind()\n }\n },\n } satisfies InterleavedAttributeMethods\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(interleavedAttributes, value => value.dispose())\n })\n\n return interleavedAttributes\n}\n\n/**********************************************************************************/\n/* */\n/* Buffer View */\n/* */\n/**********************************************************************************/\n\nexport function bufferView<T extends BufferSchema>(\n gl: GL,\n schema: T,\n { signal }: ViewOptions = {},\n): BufferView<T> {\n // Initialize buffers\n const buffers = ObjectUtils.map(schema, ({ target = 'ARRAY_BUFFER', usage = 'STATIC_DRAW' }) => {\n const buffer = assertedNotNullish(gl.createBuffer())\n return {\n bind() {\n gl.bindBuffer(gl[target], buffer)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data: Float32Array) {\n gl.bindBuffer(gl[target], buffer)\n gl.bufferData(gl[target], data, gl[usage])\n },\n }\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(buffers, value => value.dispose())\n })\n\n return buffers\n}\n"],"mappings":"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","names":["index","value","map","name","index","layout"]}
|
|
1
|
+
{"version":3,"sources":["../src/features.ts","../src/utils/object.ts","../src/utils/index.ts","../src/index.ts"],"sourcesContent":["import type { GL, RemoveSuffix } from './types'\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n","export function forEach<T extends Record<string, any>>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => void,\n) {\n let index = 0\n for (const key in value) {\n callback(value[key], key, index)\n index++\n }\n for (const key of Object.getOwnPropertySymbols(value)) {\n callback(value[key as keyof T], key as keyof T, index)\n index++\n }\n}\n\nexport function map<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n const result = {} as { [TKey in keyof T]: TReturn }\n\n forEach(value, (value, key, index) => {\n result[key] = callback(value, key, index)\n })\n\n return result\n}\n","import type {\n AttributeKind,\n FramebufferOptions,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureOptions,\n UniformKind,\n} from '../types'\n\nexport * as ObjectUtils from './object'\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\nfunction createGLShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return ('Matrix' + kind.slice(3) + 'fv') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return ((kind.match(/\\d/)?.[0] ?? '1') + 'i') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // unsigned integers\n case 'u':\n return ((kind[4] || '1') + 'ui') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // vec\n case 'v':\n return (kind[3] + 'f') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n switch (kind) {\n case 'float':\n return '1f' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n case 'uint':\n return '1ui' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n return '1i' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number) as [number, number?]\n return (a * (b ?? a)) as KIND_TO_SIZE_MAP[T]\n case 'v':\n case 'i':\n case 'b':\n case 'u':\n const match = kind.match(/\\d/) as [string] | undefined\n return (match ? +match[0] : 1) as KIND_TO_SIZE_MAP[T]\n default:\n return 1 as KIND_TO_SIZE_MAP[T]\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureOptions,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name as keyof typeof gl] as any\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(gl: GL, { attachment, texture, ...options }: FramebufferOptions) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Create Upsert */\n/* */\n/**********************************************************************************/\n\ntype UpsertMapKind<T, U> = Map<T, U> | (T extends WeakKey ? WeakMap<T, U> : never)\n\nexport function createUpsertMap<T extends UpsertMapKind<any, any> = Map<any, any>>(\n constructor?: new () => T,\n) {\n const map = new (constructor ?? Map)() as T\n return Object.assign(map, {\n getOrInsert(\n key: T extends UpsertMapKind<infer U, any> ? U : never,\n value: T extends UpsertMapKind<any, infer U> ? () => U : never,\n ) {\n let result = map.get(key)\n if (result) {\n return result\n }\n result = value()\n map.set(key, result)\n return result\n },\n })\n}\n","import { getInstancedArrays, getVertexArrayObject } from './features'\nimport type {\n AttributeMethods,\n AttributeSchema,\n AttributeView,\n BufferSchema,\n BufferView,\n GL,\n UniformView as InferUniformView,\n InterleavedAttributeMethods,\n InterleavedAttributeSchema,\n InterleavedAttributeView,\n UniformSchema,\n View,\n ViewOptions,\n ViewSchema,\n} from './types'\nimport {\n assertedNotNullish,\n createUpsertMap,\n isMatKind,\n isSamplerKind,\n kindToSize,\n kindToUniformFnName,\n ObjectUtils,\n} from './utils'\nexport * from './types'\n\n/**********************************************************************************/\n/* */\n/* To ID */\n/* */\n/**********************************************************************************/\n\nlet index = 0\nconst PREFIX = 'VIEW_GL_ALIAS'\nconst IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf('firefox') >= 0\n\n// NOTE: using symbol as key for WeakMap is currently broken in firefox\n// see https://bugzilla.mozilla.org/show_bug.cgi?id=1710433\n// fallback to Map will currently cause a memory leak.\nconst SYMBOL_MAP = createUpsertMap(IS_FIREFOX ? Map<symbol, string> : WeakMap<symbol, string>)\n\nexport function toID(key: string | number | symbol) {\n if (typeof key === 'string') {\n return key\n }\n if (typeof key === 'symbol') {\n return SYMBOL_MAP.getOrInsert(key, () => `${PREFIX}_${index++}`)\n }\n return key.toString()\n}\n\n/**********************************************************************************/\n/* */\n/* View */\n/* */\n/**********************************************************************************/\n\nexport function view<TSchema extends ViewSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: TSchema,\n options?: ViewOptions,\n): View<TSchema> {\n return {\n uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),\n attributes: !schema.attributes\n ? undefined\n : attributeView(gl, program, schema.attributes, options),\n interleavedAttributes: !schema.interleavedAttributes\n ? undefined\n : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),\n buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),\n } as View<TSchema>\n}\n\n/**********************************************************************************/\n/* */\n/* Uniform View */\n/* */\n/**********************************************************************************/\n\nexport function uniformView<T extends UniformSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n): InferUniformView<T> {\n return ObjectUtils.map(schema, ({ kind, size }, key) => {\n const name = toID(key)\n\n const location = gl.getUniformLocation(program, name)\n\n if (isSamplerKind(kind)) {\n return {\n set(arg: number) {\n gl.uniform1i(location, arg)\n },\n }\n }\n\n const fnName = `uniform${kindToUniformFnName(kind)}${size ? 'v' : ''}`\n\n // @ts-ignore FIX WEBGL/WEBGL2 TYPES\n const fn = gl[fnName].bind(gl)\n\n if (isMatKind(kind)) {\n return {\n set(...args: any[]) {\n fn(location, false, args[0])\n },\n }\n }\n\n return {\n set(...args: any[]) {\n fn(location, ...args)\n },\n }\n })\n}\n\n/**********************************************************************************/\n/* */\n/* Attribute View */\n/* */\n/**********************************************************************************/\n\n// Shared attribute helper functions\n// between attributeView and interleavedAttributeView\nfunction handleAttribute(\n gl: GL,\n location: number,\n size: number,\n stride: number,\n offset: number,\n type: 'FLOAT' | 'INT',\n instanced?: boolean,\n) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl[type], false, stride, offset)\n\n if (instanced) {\n // Get instanced-arrays-feature: extension if webgl, gl if webgl2\n assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1)\n }\n}\n\nexport function attributeView<T extends AttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): AttributeView<T> {\n const attributes = ObjectUtils.map(\n schema,\n (\n { kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) },\n key,\n ): AttributeMethods => {\n const name = toID(key)\n\n const location = gl.getAttribLocation(program, name)\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(kind)\n const type = kind.startsWith('i') ? 'INT' : 'FLOAT'\n\n return {\n buffer,\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n handleAttribute(gl, location, size, 0, 0, type, instanced)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data, usage = 'STATIC_DRAW') {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage])\n return this\n },\n }\n },\n )\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(attributes, value => value.dispose())\n })\n\n return attributes\n}\n\n/**********************************************************************************/\n/* */\n/* Interleaved Attribute View */\n/* */\n/**********************************************************************************/\n\nexport function interleavedAttributeView<T extends InterleavedAttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): InterleavedAttributeView<T> {\n // Initialize interleaved attributes\n const interleavedAttributes = ObjectUtils.map(schema, ({ layout, instanced }) => {\n // Increment number to keep track of offset\n let index = 0\n\n // Calculate layout information\n const handles = layout.map(layout => {\n const name = toID(layout.key)\n\n const location = gl.getAttribLocation(program, name)\n\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(layout.kind)\n const offset = index\n const type = layout.kind.startsWith('i') ? 'INT' : 'FLOAT'\n index += size * 4\n\n return () => handleAttribute(gl, location, size, stride, offset, type, instanced)\n })\n\n // Set stride to final index\n const stride = index\n\n // Create a buffer\n const buffer = assertedNotNullish(gl.createBuffer())\n\n // Create VAO to cache attribute state\n let vao: { unbind(): void; bind(): void; dispose(): void } | undefined = undefined\n\n // Get VAO-feature: extension if webgl1, gl if webgl2\n const feature = getVertexArrayObject(gl)\n if (feature) {\n const vertexArray = feature.createVertexArray()\n feature.bindVertexArray(vertexArray)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n for (const handle of handles) {\n handle()\n }\n feature.bindVertexArray(null)\n vao = {\n unbind() {\n feature.bindVertexArray(null)\n },\n bind() {\n feature.bindVertexArray(vertexArray)\n },\n dispose() {\n feature.deleteVertexArray(vertexArray)\n },\n }\n }\n\n return {\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n if (vao) {\n vao.bind()\n } else {\n // Fallback: manual attribute setup\n for (const handle of handles) {\n handle()\n }\n }\n },\n unbind() {\n if (vao) {\n vao.unbind()\n }\n },\n dispose() {\n gl.deleteBuffer(buffer)\n if (vao) {\n vao.dispose()\n }\n },\n set(value, usage = 'STATIC_DRAW') {\n if (vao) {\n vao.bind()\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n }\n gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage])\n if (vao) {\n vao.unbind()\n }\n },\n } satisfies InterleavedAttributeMethods\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(interleavedAttributes, value => value.dispose())\n })\n\n return interleavedAttributes\n}\n\n/**********************************************************************************/\n/* */\n/* Buffer View */\n/* */\n/**********************************************************************************/\n\nexport function bufferView<T extends BufferSchema>(\n gl: GL,\n schema: T,\n { signal }: ViewOptions = {},\n): BufferView<T> {\n // Initialize buffers\n const buffers = ObjectUtils.map(schema, ({ target = 'ARRAY_BUFFER', usage = 'STATIC_DRAW' }) => {\n const buffer = assertedNotNullish(gl.createBuffer())\n return {\n bind() {\n gl.bindBuffer(gl[target], buffer)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data: Float32Array) {\n gl.bindBuffer(gl[target], buffer)\n gl.bufferData(gl[target], data, gl[usage])\n },\n }\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(buffers, value => value.dispose())\n })\n\n return buffers\n}\n"],"mappings":"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","names":["index","value","map","name","index","layout"]}
|
package/dist/tag.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { X as GLSLSlot, Y as GLSLTag, _ as UniformTagFn, a0 as AttributeTagFn, $ as AttributeTag, n as AttributeKind, o as AttributeOptions, a1 as InterleaveTag, Q as ViewSchemaPartial, V as ViewSchema, D as DeepMerge, S as ShallowMerge, Z as UniformTag, P as Prettify, b as View } from './types-COnZSrXA.mjs';
|
|
2
2
|
|
|
3
3
|
declare function glsl<TSlot extends GLSLSlot, TSlots extends TSlot[]>(template: TemplateStringsArray, ...slots: [...TSlots]): GLSLTag<TSlots>;
|
|
4
4
|
declare const uniform: {
|
package/dist/tag.mjs
CHANGED
|
@@ -161,7 +161,8 @@ function createUpsertMap(constructor) {
|
|
|
161
161
|
// src/index.ts
|
|
162
162
|
var index = 0;
|
|
163
163
|
var PREFIX = "VIEW_GL_ALIAS";
|
|
164
|
-
var
|
|
164
|
+
var IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf("firefox") >= 0;
|
|
165
|
+
var SYMBOL_MAP = createUpsertMap(IS_FIREFOX ? Map : WeakMap);
|
|
165
166
|
function toID(key) {
|
|
166
167
|
if (typeof key === "string") {
|
|
167
168
|
return key;
|
|
@@ -439,9 +440,13 @@ function glslTagToSchema(tag) {
|
|
|
439
440
|
attributes: {},
|
|
440
441
|
interleavedAttributes: {}
|
|
441
442
|
};
|
|
442
|
-
|
|
443
|
+
function handleSlot(slot) {
|
|
444
|
+
if (Array.isArray(slot)) {
|
|
445
|
+
slot.forEach(handleSlot);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
443
448
|
if (typeof slot !== "object") {
|
|
444
|
-
|
|
449
|
+
return;
|
|
445
450
|
}
|
|
446
451
|
if (slot.type === "glsl") {
|
|
447
452
|
const { uniforms, attributes, interleavedAttributes } = glslTagToSchema(slot);
|
|
@@ -457,11 +462,12 @@ function glslTagToSchema(tag) {
|
|
|
457
462
|
...result.interleavedAttributes,
|
|
458
463
|
...interleavedAttributes
|
|
459
464
|
};
|
|
460
|
-
|
|
465
|
+
return;
|
|
461
466
|
}
|
|
462
467
|
const { key: name2, type, ...rest } = slot;
|
|
463
468
|
result[`${type}s`][name2] = rest;
|
|
464
469
|
}
|
|
470
|
+
tag.slots.forEach(handleSlot);
|
|
465
471
|
return result;
|
|
466
472
|
}
|
|
467
473
|
function glslTagToString({ template: [initial, ...rest], slots }) {
|
|
@@ -476,6 +482,9 @@ function glslSlotToString(slot, v300) {
|
|
|
476
482
|
if (typeof slot !== "object") {
|
|
477
483
|
return toID(slot);
|
|
478
484
|
}
|
|
485
|
+
if (Array.isArray(slot)) {
|
|
486
|
+
return slot.map((slot2) => glslSlotToString(slot2, v300)).join("");
|
|
487
|
+
}
|
|
479
488
|
if (slot.type === "glsl") {
|
|
480
489
|
return glslTagToString(slot);
|
|
481
490
|
}
|