@bigmistqke/view.gl 0.1.11 → 0.1.13

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/src/types.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import { DeepMerge, Prettify, ShallowMerge } from './type-utils'
2
2
 
3
+ /**********************************************************************************/
4
+ /* */
5
+ /* WebGL Constants */
6
+ /* */
7
+ /**********************************************************************************/
8
+
3
9
  export type GL = WebGLRenderingContext | WebGL2RenderingContext
4
10
 
5
11
  export type GLTarget = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
@@ -134,201 +140,70 @@ export interface KIND_TO_SIZE_MAP {
134
140
  /* */
135
141
  /**********************************************************************************/
136
142
 
137
- export type UniformFnName =
138
- | '1f'
139
- | '2f'
140
- | '3f'
141
- | '4f'
142
- | '1i'
143
- | '2i'
144
- | '3i'
145
- | '4i'
146
- | '1ui'
147
- | '2ui'
148
- | '3ui'
149
- | '4ui'
150
- | 'mat2'
151
- | 'mat3'
152
- | 'mat4'
153
- | 'mat2x3'
154
- | 'mat2x4'
155
- | 'mat3x2'
156
- | 'mat3x4'
157
- | 'mat4x2'
158
- | 'mat4x3'
159
- | 'sampler2D'
160
- | 'samplerCube'
161
- | 'sampler2DArray'
162
- | 'isampler2D'
163
- | 'isamplerCube'
164
- | 'isampler2DArray'
165
- | 'usampler2D'
166
- | 'usamplerCube'
167
- | 'usampler2DArray'
168
-
169
- export type UniformKind =
170
- | 'float'
171
- | 'vec2'
172
- | 'vec3'
173
- | 'vec4'
174
- | 'int'
175
- | 'ivec2'
176
- | 'ivec3'
177
- | 'ivec4'
178
- | 'bool'
179
- | 'bvec2'
180
- | 'bvec3'
181
- | 'bvec4'
182
- | 'mat2'
183
- | 'mat3'
184
- | 'mat4'
185
- | 'sampler2D'
186
- | 'samplerCube'
187
- // webgl2
188
- | 'uint'
189
- | 'uvec2'
190
- | 'uvec3'
191
- | 'uvec4'
192
- | 'mat2x3'
193
- | 'mat2x4'
194
- | 'mat3x2'
195
- | 'mat3x4'
196
- | 'mat4x2'
197
- | 'mat4x3'
198
- | 'sampler3D'
199
- | 'sampler2DArray'
200
- | 'sampler2DShadow'
201
- | 'samplerCubeShadow'
202
- | 'sampler2DArrayShadow'
203
- | 'isampler2D'
204
- | 'isampler3D'
205
- | 'isamplerCube'
206
- | 'isampler2DArray'
207
- | 'usampler2D'
208
- | 'usampler3D'
209
- | 'usamplerCube'
210
- | 'usampler2DArray'
211
-
212
- // prettier-ignore
213
- interface UniformKindMap {
143
+ export type UniformFnName = KIND_TO_UNIFORM_FN_NAME_MAP[keyof KIND_TO_UNIFORM_FN_NAME_MAP]
144
+
145
+ export type UniformKind = keyof KIND_TO_UNIFORM_FN_NAME_MAP
146
+
147
+ type MatrixArray<Size extends number> = [Float32Array] | number[]
148
+
149
+ export interface UniformKindMap {
214
150
  // Float scalars and vectors
215
- float: [number];
216
- vec2: [number, number];
217
- vec3: [number, number, number];
218
- vec4: [number, number, number, number];
151
+ float: [number]
152
+ vec2: [number, number]
153
+ vec3: [number, number, number]
154
+ vec4: [number, number, number, number]
219
155
 
220
156
  // Signed integer scalars and vectors
221
- int: [number];
222
- ivec2: [number, number];
223
- ivec3: [number, number, number];
224
- ivec4: [number, number, number, number];
157
+ int: [number]
158
+ ivec2: [number, number]
159
+ ivec3: [number, number, number]
160
+ ivec4: [number, number, number, number]
225
161
 
226
162
  // Booleans (set with uniform1i)
227
- bool: [number];
228
- bvec2: [number, number];
229
- bvec3: [number, number, number];
230
- bvec4: [number, number, number, number];
163
+ bool: [number]
164
+ bvec2: [number, number]
165
+ bvec3: [number, number, number]
166
+ bvec4: [number, number, number, number]
231
167
 
232
168
  // Unsigned integer scalars and vectors (WebGL2)
233
- uint: [number];
234
- uvec2: [number, number];
235
- uvec3: [number, number, number];
236
- uvec4: [number, number, number, number];
237
-
238
- // Matrices (float arrays or explicit numbers)
239
- mat2:
240
- | [Float32Array]
241
- | [
242
- number, number,
243
- number, number
244
- ];
245
-
246
- mat3:
247
- | [Float32Array]
248
- | [
249
- number, number, number,
250
- number, number, number,
251
- number, number, number
252
- ];
253
-
254
- mat4:
255
- | [Float32Array]
256
- | [
257
- number, number, number, number,
258
- number, number, number, number,
259
- number, number, number, number,
260
- number, number, number, number
261
- ];
169
+ uint: [number]
170
+ uvec2: [number, number]
171
+ uvec3: [number, number, number]
172
+ uvec4: [number, number, number, number]
173
+
174
+ // Matrices
175
+ mat2: MatrixArray<4>
176
+ mat3: MatrixArray<9>
177
+ mat4: MatrixArray<16>
262
178
 
263
179
  // WebGL2 extended matrix types
264
- mat2x3:
265
- | [Float32Array]
266
- | [
267
- number, number, number,
268
- number, number, number
269
- ];
270
-
271
- mat2x4:
272
- | [Float32Array]
273
- | [
274
- number, number, number, number,
275
- number, number, number, number
276
- ];
277
-
278
- mat3x2:
279
- | [Float32Array]
280
- | [
281
- number, number,
282
- number, number,
283
- number, number
284
- ];
285
-
286
- mat3x4:
287
- | [Float32Array]
288
- | [
289
- number, number, number, number,
290
- number, number, number, number,
291
- number, number, number, number
292
- ];
293
-
294
- mat4x2:
295
- | [Float32Array]
296
- | [
297
- number, number,
298
- number, number,
299
- number, number,
300
- number, number
301
- ];
302
-
303
- mat4x3:
304
- | [Float32Array]
305
- | [
306
- number, number, number,
307
- number, number, number,
308
- number, number, number,
309
- number, number, number
310
- ];
180
+ mat2x3: MatrixArray<6>
181
+ mat2x4: MatrixArray<8>
182
+ mat3x2: MatrixArray<6>
183
+ mat3x4: MatrixArray<12>
184
+ mat4x2: MatrixArray<8>
185
+ mat4x3: MatrixArray<12>
311
186
 
312
187
  // Samplers — always a single number (texture unit)
313
- sampler2D: [number];
314
- samplerCube: [number];
315
- sampler3D: [number]; // WebGL2
316
- sampler2DArray: [number]; // WebGL2
317
- sampler2DShadow: [number]; // WebGL2
318
- samplerCubeShadow: [number]; // WebGL2
319
- sampler2DArrayShadow: [number]; // WebGL2
188
+ sampler2D: [number]
189
+ samplerCube: [number]
190
+ sampler3D: [number] // WebGL2
191
+ sampler2DArray: [number] // WebGL2
192
+ sampler2DShadow: [number] // WebGL2
193
+ samplerCubeShadow: [number] // WebGL2
194
+ sampler2DArrayShadow: [number] // WebGL2
320
195
 
321
196
  // Integer samplers (WebGL2)
322
- isampler2D: [number];
323
- isampler3D: [number];
324
- isamplerCube: [number];
325
- isampler2DArray: [number];
197
+ isampler2D: [number]
198
+ isampler3D: [number]
199
+ isamplerCube: [number]
200
+ isampler2DArray: [number]
326
201
 
327
202
  // Unsigned integer samplers (WebGL2)
328
- usampler2D: [number];
329
- usampler3D: [number];
330
- usamplerCube: [number];
331
- usampler2DArray: [number];
203
+ usampler2D: [number]
204
+ usampler3D: [number]
205
+ usamplerCube: [number]
206
+ usampler2DArray: [number]
332
207
  }
333
208
 
334
209
  export interface UniformDefinition {
@@ -337,21 +212,31 @@ export interface UniformDefinition {
337
212
  }
338
213
 
339
214
  export type UniformSchema = Record<string | symbol, UniformDefinition>
340
- export type UniformSchemaPartial = Record<string | symbol, Partial<UniformDefinition>>
215
+
216
+ /** Methods for a single uniform element */
217
+ export type UniformElementMethods<TKind extends UniformKind> = {
218
+ set(...args: UniformKindMap[TKind]): void
219
+ }
220
+
221
+ /** Methods for array uniforms - supports both bulk set and indexed access */
222
+ export type UniformArrayMethods<TKind extends UniformKind, TSize extends number> = Array<
223
+ UniformElementMethods<TKind>
224
+ > & {
225
+ /** Bulk set all elements at once */
226
+ set(arg: Float32Array): void
227
+ }
341
228
 
342
229
  export type UniformMethods<TDefinition extends UniformDefinition> =
343
230
  TDefinition['size'] extends number
344
- ? {
345
- set(arg: Float32Array): void
346
- }
347
- : {
348
- set(...args: UniformKindMap[TDefinition['kind']]): void
349
- }
231
+ ? UniformArrayMethods<TDefinition['kind'], TDefinition['size']>
232
+ : UniformElementMethods<TDefinition['kind']>
350
233
 
351
234
  export type UniformView<T extends UniformSchema> = {
352
235
  [K in keyof T]: UniformMethods<T[K]>
353
236
  }
354
237
 
238
+ export type UniformValue = UniformKindMap[UniformKind]
239
+
355
240
  /**********************************************************************************/
356
241
  /* */
357
242
  /* Attributes */
@@ -507,7 +392,7 @@ export interface Framebuffer {
507
392
 
508
393
  /**********************************************************************************/
509
394
  /* */
510
- /* Texture View */
395
+ /* Textures */
511
396
  /* */
512
397
  /**********************************************************************************/
513
398
 
@@ -625,11 +510,14 @@ export interface ViewSchema {
625
510
  buffers?: BufferSchema
626
511
  }
627
512
 
513
+ type PartialSchema<T> =
514
+ T extends Record<string | symbol, infer V> ? Record<string | symbol, Partial<V>> : never
515
+
628
516
  export interface ViewSchemaPartial {
629
- uniforms?: Record<string | symbol, Partial<UniformDefinition>>
630
- attributes?: Record<string | symbol, Partial<AttributeDefinition>>
631
- interleavedAttributes?: Record<string | symbol, Partial<InterleavedAttributeDefinition>>
632
- buffers?: Record<string | symbol, Partial<BufferDefinition>>
517
+ uniforms?: PartialSchema<UniformSchema>
518
+ attributes?: PartialSchema<AttributeSchema>
519
+ interleavedAttributes?: PartialSchema<InterleavedAttributeSchema>
520
+ buffers?: PartialSchema<BufferSchema>
633
521
  }
634
522
 
635
523
  export type View<T extends ViewSchema = ViewSchema> = {
@@ -645,7 +533,7 @@ export type View<T extends ViewSchema = ViewSchema> = {
645
533
 
646
534
  /**********************************************************************************/
647
535
  /* */
648
- /* Tags */
536
+ /* GLSL System */
649
537
  /* */
650
538
  /**********************************************************************************/
651
539
 
@@ -654,6 +542,12 @@ export interface GLSLResult {
654
542
  schema: ViewSchema
655
543
  }
656
544
 
545
+ /**********************************************************************************/
546
+ /* */
547
+ /* GLSL Tokens */
548
+ /* */
549
+ /**********************************************************************************/
550
+
657
551
  type GLSLSlotItem =
658
552
  | GLSL
659
553
  | UniformToken
@@ -730,40 +624,89 @@ export type InterleaveToken<
730
624
  }
731
625
 
732
626
  export type GLSLToSchema<T extends GLSL> =
733
- FlattenSlots<T> extends infer TSlots
734
- ? TSlots extends Array<any>
735
- ? GLSLSlotsToSchema<TSlots>
627
+ T extends GLSL<infer TSlots>
628
+ ? FlattenSlots<TSlots> extends infer TFlatSlots extends Array<GLSLSlot>
629
+ ? GLSLSlotsToSchema<TFlatSlots>
736
630
  : never
737
631
  : never
738
632
 
739
633
  export type GLSLToView<T extends GLSL> = View<GLSLToSchema<T>>
740
634
 
635
+ type ExtractTokens<TSlots extends Array<GLSLSlot>, TTokenType> = TSlots[number] extends infer U
636
+ ? U extends TTokenType
637
+ ? U
638
+ : never
639
+ : never
640
+
741
641
  export type GLSLSlotsToSchema<TSlots extends Array<GLSLSlot>> = {
742
642
  uniforms: {
743
- [K in Extract<TSlots[number], UniformToken> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
643
+ [K in ExtractTokens<TSlots, UniformToken> as K['key']]: Omit<K, 'type'>
744
644
  }
745
645
  attributes: {
746
- [K in Extract<TSlots[number], AttributeToken> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
646
+ [K in ExtractTokens<TSlots, AttributeToken> as K['key']]: Omit<K, 'type'>
747
647
  }
748
648
  interleavedAttributes: {
749
- [K in Extract<TSlots[number], InterleaveToken> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
649
+ [K in ExtractTokens<TSlots, InterleaveToken> as K['key']]: Omit<K, 'type'>
750
650
  }
751
651
  }
752
652
 
753
- type FlattenSlots<T> =
754
- T extends GLSL<infer TSlots>
755
- ? _FlattenSlots<TSlots>
756
- : T extends Array<GLSLSlot>
757
- ? _FlattenSlots<T>
653
+ export type FlattenSlots<T, MaxDepth extends Depth = 10> =
654
+ T extends Array<GLSLSlot>
655
+ ? _FlattenSlots<T, [], MaxDepth>
656
+ : T extends GLSL<infer TSlots>
657
+ ? _FlattenSlots<TSlots, [], MaxDepth>
758
658
  : never
759
659
 
760
- type _FlattenSlots<T extends Array<GLSLSlot>> = T extends [infer First, ...infer Rest]
761
- ? First extends GLSL
762
- ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
763
- : First extends unknown[]
764
- ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
765
- : [First, ...FlattenSlots<Rest>]
766
- : []
660
+ type _FlattenSlots<
661
+ T extends Array<GLSLSlot>,
662
+ Acc extends Array<any> = [],
663
+ CurrentDepth extends Depth = 10,
664
+ > = CurrentDepth extends 0
665
+ ? [...Acc, ...T]
666
+ : T extends [infer First, ...infer Rest extends Array<GLSLSlot>]
667
+ ? First extends GLSL<infer TSlots>
668
+ ? _FlattenSlots<
669
+ Rest,
670
+ [...Acc, ..._FlattenSlots<TSlots, [], Dec<CurrentDepth>>],
671
+ Dec<CurrentDepth>
672
+ >
673
+ : First extends GLSLSlot[]
674
+ ? _FlattenSlots<
675
+ Rest,
676
+ [...Acc, ..._FlattenSlots<First, [], Dec<CurrentDepth>>],
677
+ Dec<CurrentDepth>
678
+ >
679
+ : _FlattenSlots<Rest, [...Acc, First], Dec<CurrentDepth>>
680
+ : [...Acc, ...T]
681
+
682
+ /**********************************************************************************/
683
+ /* */
684
+ /* Type Utilities */
685
+ /* */
686
+ /**********************************************************************************/
687
+
688
+ type Depth = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
689
+ type Dec<T extends number> = T extends 10
690
+ ? 9
691
+ : T extends 9
692
+ ? 8
693
+ : T extends 8
694
+ ? 7
695
+ : T extends 7
696
+ ? 6
697
+ : T extends 6
698
+ ? 5
699
+ : T extends 5
700
+ ? 4
701
+ : T extends 4
702
+ ? 3
703
+ : T extends 3
704
+ ? 2
705
+ : T extends 2
706
+ ? 1
707
+ : T extends 1
708
+ ? 0
709
+ : 0
767
710
 
768
711
  export type MergeGLSLSchema<
769
712
  TVertex extends ViewSchema,
@@ -8,11 +8,57 @@ import type {
8
8
  UniformKind,
9
9
  } from '../types'
10
10
 
11
+ export * as ObjectUtils from './object'
12
+
11
13
  export function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {
12
14
  if (value === undefined || value === null) throw new Error(message)
13
15
  return value
14
16
  }
15
17
 
18
+ function createGLShader(gl: GL, type: number, source: string): WebGLShader {
19
+ const shader = gl.createShader(type)
20
+ if (!shader) throw new Error('Failed to create shader')
21
+
22
+ gl.shaderSource(shader, source)
23
+ gl.compileShader(shader)
24
+
25
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
26
+ const info = gl.getShaderInfoLog(shader)
27
+ gl.deleteShader(shader)
28
+ throw new Error(
29
+ `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,
30
+ )
31
+ }
32
+
33
+ return shader
34
+ }
35
+
36
+ export function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {
37
+ const program = gl.createProgram()
38
+ if (!program) throw new Error('Failed to create WebGL program')
39
+
40
+ const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource)
41
+ const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource)
42
+
43
+ gl.attachShader(program, vertexShader)
44
+ gl.attachShader(program, fragmentShader)
45
+ gl.linkProgram(program)
46
+
47
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
48
+ const info = gl.getProgramInfoLog(program)
49
+ gl.deleteProgram(program)
50
+ gl.deleteShader(vertexShader)
51
+ gl.deleteShader(fragmentShader)
52
+ throw new Error(`Failed to link program: ${info}`)
53
+ }
54
+
55
+ // Clean up shaders after linking
56
+ gl.deleteShader(vertexShader)
57
+ gl.deleteShader(fragmentShader)
58
+
59
+ return program
60
+ }
61
+
16
62
  /**********************************************************************************/
17
63
  /* */
18
64
  /* Kind To Uniform Name */
package/tsup.config.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { defineConfig } from 'tsup'
2
2
 
3
3
  export default defineConfig({
4
- entry: ['src/index.ts', 'src/tag.ts', , 'src/gl.ts'],
4
+ entry: ['src/index.ts', 'src/tag.ts'],
5
5
  format: ['esm'],
6
- splitting: false,
6
+ splitting: true,
7
7
  sourcemap: true,
8
8
  minify: false,
9
9
  clean: true,
package/dist/gl.d.mts DELETED
@@ -1,8 +0,0 @@
1
- import { G as GL, R as RemoveSuffix } from './types-CHXzeNxF.mjs';
2
-
3
- declare function createShader(gl: GL, type: number, source: string): WebGLShader;
4
- declare function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram;
5
- declare function getInstancedArrays(gl: GL): RemoveSuffix<Pick<ANGLE_instanced_arrays, "drawArraysInstancedANGLE" | "drawElementsInstancedANGLE" | "vertexAttribDivisorANGLE">, "ANGLE"> | undefined;
6
- declare function getVertexArrayObject(gl: GL): RemoveSuffix<Pick<OES_vertex_array_object, "bindVertexArrayOES" | "createVertexArrayOES" | "deleteVertexArrayOES">, "OES"> | null;
7
-
8
- export { createProgram, createShader, getInstancedArrays, getVertexArrayObject };
package/dist/gl.mjs DELETED
@@ -1,71 +0,0 @@
1
- // src/gl.ts
2
- function createShader(gl, type, source) {
3
- const shader = gl.createShader(type);
4
- if (!shader) throw new Error("Failed to create shader");
5
- gl.shaderSource(shader, source);
6
- gl.compileShader(shader);
7
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
8
- const info = gl.getShaderInfoLog(shader);
9
- gl.deleteShader(shader);
10
- throw new Error(
11
- `Failed to compile ${type === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader: ${info}`
12
- );
13
- }
14
- return shader;
15
- }
16
- function createProgram(gl, vertexSource, fragmentSource) {
17
- const program = gl.createProgram();
18
- if (!program) throw new Error("Failed to create WebGL program");
19
- const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource);
20
- const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
21
- gl.attachShader(program, vertexShader);
22
- gl.attachShader(program, fragmentShader);
23
- gl.linkProgram(program);
24
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
25
- const info = gl.getProgramInfoLog(program);
26
- gl.deleteProgram(program);
27
- gl.deleteShader(vertexShader);
28
- gl.deleteShader(fragmentShader);
29
- throw new Error(`Failed to link program: ${info}`);
30
- }
31
- gl.deleteShader(vertexShader);
32
- gl.deleteShader(fragmentShader);
33
- return program;
34
- }
35
- var INSTANCED_ARRAYS_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
36
- function getInstancedArrays(gl) {
37
- if (gl instanceof WebGL2RenderingContext) return gl;
38
- const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl);
39
- if (cached) return cached;
40
- const ext = gl.getExtension("ANGLE_instanced_arrays");
41
- if (!ext) return void 0;
42
- const wrapper = {
43
- drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),
44
- drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),
45
- vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext)
46
- };
47
- INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper);
48
- return wrapper;
49
- }
50
- var VERTEX_ARRAY_OBJECT_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
51
- function getVertexArrayObject(gl) {
52
- if (gl instanceof WebGL2RenderingContext) return gl;
53
- const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl);
54
- if (cached) return cached;
55
- const ext = gl.getExtension("OES_vertex_array_object");
56
- if (!ext) return null;
57
- const wrapper = {
58
- bindVertexArray: ext.bindVertexArrayOES.bind(ext),
59
- createVertexArray: ext.createVertexArrayOES.bind(ext),
60
- deleteVertexArray: ext.deleteVertexArrayOES.bind(ext)
61
- };
62
- VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper);
63
- return wrapper;
64
- }
65
- export {
66
- createProgram,
67
- createShader,
68
- getInstancedArrays,
69
- getVertexArrayObject
70
- };
71
- //# sourceMappingURL=gl.mjs.map
package/dist/gl.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/gl.ts"],"sourcesContent":["import { RemoveSuffix } from './type-utils'\nimport { GL } from './types'\n\nexport function createShader(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 = createShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createShader(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\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"],"mappings":";AAGO,SAAS,aAAa,IAAQ,MAAc,QAA6B;AAC9E,QAAM,SAAS,GAAG,aAAa,IAAI;AACnC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,yBAAyB;AAEtD,KAAG,aAAa,QAAQ,MAAM;AAC9B,KAAG,cAAc,MAAM;AAEvB,MAAI,CAAC,GAAG,mBAAmB,QAAQ,GAAG,cAAc,GAAG;AACrD,UAAM,OAAO,GAAG,iBAAiB,MAAM;AACvC,OAAG,aAAa,MAAM;AACtB,UAAM,IAAI;AAAA,MACR,qBAAqB,SAAS,GAAG,gBAAgB,WAAW,UAAU,YAAY,IAAI;AAAA,IACxF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,IAAQ,cAAsB,gBAAsC;AAChG,QAAM,UAAU,GAAG,cAAc;AACjC,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC;AAE9D,QAAM,eAAe,aAAa,IAAI,GAAG,eAAe,YAAY;AACpE,QAAM,iBAAiB,aAAa,IAAI,GAAG,iBAAiB,cAAc;AAE1E,KAAG,aAAa,SAAS,YAAY;AACrC,KAAG,aAAa,SAAS,cAAc;AACvC,KAAG,YAAY,OAAO;AAEtB,MAAI,CAAC,GAAG,oBAAoB,SAAS,GAAG,WAAW,GAAG;AACpD,UAAM,OAAO,GAAG,kBAAkB,OAAO;AACzC,OAAG,cAAc,OAAO;AACxB,OAAG,aAAa,YAAY;AAC5B,OAAG,aAAa,cAAc;AAC9B,UAAM,IAAI,MAAM,2BAA2B,IAAI,EAAE;AAAA,EACnD;AAGA,KAAG,aAAa,YAAY;AAC5B,KAAG,aAAa,cAAc;AAE9B,SAAO;AACT;AAEA,IAAM,+BAA+B,oBAAI,QASvC;AACK,SAAS,mBAAmB,IAAQ;AACzC,MAAI,cAAc,uBAAwB,QAAO;AAEjD,QAAM,SAAS,6BAA6B,IAAI,EAAE;AAClD,MAAI,OAAQ,QAAO;AAEnB,QAAM,MAAM,GAAG,aAAa,wBAAwB;AACpD,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU;AAAA,IACd,qBAAqB,IAAI,yBAAyB,KAAK,GAAG;AAAA,IAC1D,uBAAuB,IAAI,2BAA2B,KAAK,GAAG;AAAA,IAC9D,qBAAqB,IAAI,yBAAyB,KAAK,GAAG;AAAA,EAC5D;AACA,+BAA6B,IAAI,IAAI,OAAO;AAE5C,SAAO;AACT;AAEA,IAAM,kCAAkC,oBAAI,QAS1C;AACK,SAAS,qBAAqB,IAAQ;AAC3C,MAAI,cAAc,uBAAwB,QAAO;AAEjD,QAAM,SAAS,gCAAgC,IAAI,EAAE;AACrD,MAAI,OAAQ,QAAO;AAEnB,QAAM,MAAM,GAAG,aAAa,yBAAyB;AACrD,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU;AAAA,IACd,iBAAiB,IAAI,mBAAmB,KAAK,GAAG;AAAA,IAChD,mBAAmB,IAAI,qBAAqB,KAAK,GAAG;AAAA,IACpD,mBAAmB,IAAI,qBAAqB,KAAK,GAAG;AAAA,EACtD;AACA,kCAAgC,IAAI,IAAI,OAAO;AAE/C,SAAO;AACT;","names":[]}