@bigmistqke/view.gl 0.1.0

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 ADDED
@@ -0,0 +1,718 @@
1
+ export type Merge<A, B> = {
2
+ [K in keyof A | keyof B]: K extends keyof A
3
+ ? K extends keyof B
4
+ ? A[K] | B[K]
5
+ : A[K]
6
+ : K extends keyof B
7
+ ? B[K]
8
+ : never
9
+ }
10
+
11
+ export type Prettify<T> = {
12
+ [K in keyof T]: T[K]
13
+ } & {}
14
+
15
+ export type RemoveSuffix<T, S extends string> = {
16
+ [K in keyof T as K extends `${infer Prefix}${S}` ? Prefix : K]: T[K]
17
+ }
18
+
19
+ export type GL = WebGLRenderingContext | WebGL2RenderingContext
20
+
21
+ /**********************************************************************************/
22
+ /* */
23
+ /* Constants */
24
+ /* */
25
+ /**********************************************************************************/
26
+
27
+ type GLTarget = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
28
+ type GLUsage = 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW'
29
+ type GLTextureTarget = 'TEXTURE_2D' | 'TEXTURE_CUBE_MAP'
30
+ type GLTextureFormat = 'RGBA' | 'RGB' | 'RGBA32F' | 'RGB32F' | 'RGBA16F' | 'RGB16F'
31
+ type GLTextureType = 'UNSIGNED_BYTE' | 'FLOAT' | 'HALF_FLOAT'
32
+ type GLTextureFilter = 'NEAREST' | 'LINEAR'
33
+ type GLTextureWrap = 'CLAMP_TO_EDGE' | 'REPEAT' | 'MIRRORED_REPEAT'
34
+
35
+ export interface KIND_TO_UNIFORM_FN_NAME_MAP {
36
+ // Floats (WebGL1 + WebGL2)
37
+ float: '1f'
38
+ vec2: '2f'
39
+ vec3: '3f'
40
+ vec4: '4f'
41
+
42
+ // Signed Integers (WebGL1 + WebGL2)
43
+ int: '1i'
44
+ ivec2: '2i'
45
+ ivec3: '3i'
46
+ ivec4: '4i'
47
+
48
+ // Matrices (WebGL1 + WebGL2)
49
+ mat2: 'Matrix2fv'
50
+ mat3: 'Matrix3fv'
51
+ mat4: 'Matrix4fv'
52
+
53
+ // Unsigned Integers (WebGL2 only)
54
+ uint: '1ui'
55
+ uvec2: '2ui'
56
+ uvec3: '3ui'
57
+ uvec4: '4ui'
58
+
59
+ // WebGL2 extended matrix types
60
+ mat2x3: 'Matrix2x3fv'
61
+ mat2x4: 'Matrix2x4fv'
62
+ mat3x2: 'Matrix3x2fv'
63
+ mat3x4: 'Matrix3x4fv'
64
+ mat4x2: 'Matrix4x2fv'
65
+ mat4x3: 'Matrix4x3fv'
66
+
67
+ // Booleans — GLSL booleans are set with uniform1i
68
+ bool: '1i'
69
+ bvec2: '2i'
70
+ bvec3: '3i'
71
+ bvec4: '4i'
72
+
73
+ // Samplers — all use 1i to bind texture unit indices
74
+ sampler2D: '1i'
75
+ samplerCube: '1i'
76
+ sampler2DArray: '1i'
77
+ sampler3D: '1i' // WebGL2
78
+ sampler2DShadow: '1i' // WebGL2
79
+ samplerCubeShadow: '1i' // WebGL2
80
+ sampler2DArrayShadow: '1i' // WebGL2
81
+
82
+ // Integer samplers (WebGL2)
83
+ isampler2D: '1i'
84
+ isampler3D: '1i'
85
+ isamplerCube: '1i'
86
+ isampler2DArray: '1i'
87
+
88
+ // Unsigned integer samplers (WebGL2)
89
+ usampler2D: '1i'
90
+ usampler3D: '1i'
91
+ usamplerCube: '1i'
92
+ usampler2DArray: '1i'
93
+ }
94
+
95
+ export interface KIND_TO_SIZE_MAP {
96
+ // Floats
97
+ float: 1
98
+ vec2: 2
99
+ vec3: 3
100
+ vec4: 4
101
+
102
+ // Signed integers
103
+ int: 1
104
+ ivec2: 2
105
+ ivec3: 3
106
+ ivec4: 4
107
+
108
+ // Booleans (set as ints)
109
+ bool: 1
110
+ bvec2: 2
111
+ bvec3: 3
112
+ bvec4: 4
113
+
114
+ // Unsigned integers (WebGL2)
115
+ uint: 1
116
+ uvec2: 2
117
+ uvec3: 3
118
+ uvec4: 4
119
+
120
+ // Matrices
121
+ mat2: 4
122
+ mat3: 9
123
+ mat4: 16
124
+ mat2x3: 6
125
+ mat2x4: 8
126
+ mat3x2: 6
127
+ mat3x4: 12
128
+ mat4x2: 8
129
+ mat4x3: 12
130
+
131
+ // Samplers (texture unit indices)
132
+ sampler2D: 1
133
+ samplerCube: 1
134
+ sampler3D: 1
135
+ sampler2DArray: 1
136
+ sampler2DShadow: 1
137
+ samplerCubeShadow: 1
138
+ sampler2DArrayShadow: 1
139
+
140
+ // Integer samplers (WebGL2)
141
+ isampler2D: 1
142
+ isampler3D: 1
143
+ isamplerCube: 1
144
+ isampler2DArray: 1
145
+
146
+ // Unsigned integer samplers (WebGL2)
147
+ usampler2D: 1
148
+ usampler3D: 1
149
+ usamplerCube: 1
150
+ usampler2DArray: 1
151
+ }
152
+
153
+ /**********************************************************************************/
154
+ /* */
155
+ /* Uniform */
156
+ /* */
157
+ /**********************************************************************************/
158
+
159
+ export type UniformFnName =
160
+ | '1f'
161
+ | '2f'
162
+ | '3f'
163
+ | '4f'
164
+ | '1i'
165
+ | '2i'
166
+ | '3i'
167
+ | '4i'
168
+ | '1ui'
169
+ | '2ui'
170
+ | '3ui'
171
+ | '4ui'
172
+ | 'mat2'
173
+ | 'mat3'
174
+ | 'mat4'
175
+ | 'mat2x3'
176
+ | 'mat2x4'
177
+ | 'mat3x2'
178
+ | 'mat3x4'
179
+ | 'mat4x2'
180
+ | 'mat4x3'
181
+ | 'sampler2D'
182
+ | 'samplerCube'
183
+ | 'sampler2DArray'
184
+ | 'isampler2D'
185
+ | 'isamplerCube'
186
+ | 'isampler2DArray'
187
+ | 'usampler2D'
188
+ | 'usamplerCube'
189
+ | 'usampler2DArray'
190
+
191
+ export type UniformKind =
192
+ | 'float'
193
+ | 'vec2'
194
+ | 'vec3'
195
+ | 'vec4'
196
+ | 'int'
197
+ | 'ivec2'
198
+ | 'ivec3'
199
+ | 'ivec4'
200
+ | 'bool'
201
+ | 'bvec2'
202
+ | 'bvec3'
203
+ | 'bvec4'
204
+ | 'mat2'
205
+ | 'mat3'
206
+ | 'mat4'
207
+ | 'sampler2D'
208
+ | 'samplerCube'
209
+ // webgl2
210
+ | 'uint'
211
+ | 'uvec2'
212
+ | 'uvec3'
213
+ | 'uvec4'
214
+ | 'mat2x3'
215
+ | 'mat2x4'
216
+ | 'mat3x2'
217
+ | 'mat3x4'
218
+ | 'mat4x2'
219
+ | 'mat4x3'
220
+ | 'sampler3D'
221
+ | 'sampler2DArray'
222
+ | 'sampler2DShadow'
223
+ | 'samplerCubeShadow'
224
+ | 'sampler2DArrayShadow'
225
+ | 'isampler2D'
226
+ | 'isampler3D'
227
+ | 'isamplerCube'
228
+ | 'isampler2DArray'
229
+ | 'usampler2D'
230
+ | 'usampler3D'
231
+ | 'usamplerCube'
232
+ | 'usampler2DArray'
233
+
234
+ // prettier-ignore
235
+ interface UniformKindMap {
236
+ // Float scalars and vectors
237
+ float: [number];
238
+ vec2: [number, number];
239
+ vec3: [number, number, number];
240
+ vec4: [number, number, number, number];
241
+
242
+ // Signed integer scalars and vectors
243
+ int: [number];
244
+ ivec2: [number, number];
245
+ ivec3: [number, number, number];
246
+ ivec4: [number, number, number, number];
247
+
248
+ // Booleans (set with uniform1i)
249
+ bool: [number];
250
+ bvec2: [number, number];
251
+ bvec3: [number, number, number];
252
+ bvec4: [number, number, number, number];
253
+
254
+ // Unsigned integer scalars and vectors (WebGL2)
255
+ uint: [number];
256
+ uvec2: [number, number];
257
+ uvec3: [number, number, number];
258
+ uvec4: [number, number, number, number];
259
+
260
+ // Matrices (float arrays or explicit numbers)
261
+ mat2:
262
+ | [Float32Array]
263
+ | [
264
+ number, number,
265
+ number, number
266
+ ];
267
+
268
+ mat3:
269
+ | [Float32Array]
270
+ | [
271
+ number, number, number,
272
+ number, number, number,
273
+ number, number, number
274
+ ];
275
+
276
+ mat4:
277
+ | [Float32Array]
278
+ | [
279
+ number, number, number, number,
280
+ number, number, number, number,
281
+ number, number, number, number,
282
+ number, number, number, number
283
+ ];
284
+
285
+ // WebGL2 extended matrix types
286
+ mat2x3:
287
+ | [Float32Array]
288
+ | [
289
+ number, number, number,
290
+ number, number, number
291
+ ];
292
+
293
+ mat2x4:
294
+ | [Float32Array]
295
+ | [
296
+ number, number, number, number,
297
+ number, number, number, number
298
+ ];
299
+
300
+ mat3x2:
301
+ | [Float32Array]
302
+ | [
303
+ number, number,
304
+ number, number,
305
+ number, number
306
+ ];
307
+
308
+ mat3x4:
309
+ | [Float32Array]
310
+ | [
311
+ number, number, number, number,
312
+ number, number, number, number,
313
+ number, number, number, number
314
+ ];
315
+
316
+ mat4x2:
317
+ | [Float32Array]
318
+ | [
319
+ number, number,
320
+ number, number,
321
+ number, number,
322
+ number, number
323
+ ];
324
+
325
+ mat4x3:
326
+ | [Float32Array]
327
+ | [
328
+ number, number, number,
329
+ number, number, number,
330
+ number, number, number,
331
+ number, number, number
332
+ ];
333
+
334
+ // Samplers — always a single number (texture unit)
335
+ sampler2D: [number];
336
+ samplerCube: [number];
337
+ sampler3D: [number]; // WebGL2
338
+ sampler2DArray: [number]; // WebGL2
339
+ sampler2DShadow: [number]; // WebGL2
340
+ samplerCubeShadow: [number]; // WebGL2
341
+ sampler2DArrayShadow: [number]; // WebGL2
342
+
343
+ // Integer samplers (WebGL2)
344
+ isampler2D: [number];
345
+ isampler3D: [number];
346
+ isamplerCube: [number];
347
+ isampler2DArray: [number];
348
+
349
+ // Unsigned integer samplers (WebGL2)
350
+ usampler2D: [number];
351
+ usampler3D: [number];
352
+ usamplerCube: [number];
353
+ usampler2DArray: [number];
354
+ }
355
+
356
+ export interface UniformOptions {
357
+ kind: UniformKind
358
+ size?: number
359
+ }
360
+
361
+ export type UniformSchema = Record<string, UniformOptions>
362
+
363
+ export type UniformMethods<TOptions extends UniformOptions> = TOptions['size'] extends number
364
+ ? {
365
+ set(arg: Float32Array): void
366
+ }
367
+ : {
368
+ set(...args: UniformKindMap[TOptions['kind']]): void
369
+ }
370
+
371
+ export type UniformView<T extends UniformSchema> = {
372
+ [K in keyof T]: UniformMethods<T[K]>
373
+ }
374
+
375
+ /**********************************************************************************/
376
+ /* */
377
+ /* Attributes */
378
+ /* */
379
+ /**********************************************************************************/
380
+
381
+ export type AttributeShortHand =
382
+ | '1f'
383
+ | '2f'
384
+ | '3f'
385
+ | '4f'
386
+ | '1i'
387
+ | '2i'
388
+ | '3i'
389
+ | '4i'
390
+ | '1ui'
391
+ | '2ui'
392
+ | '3ui'
393
+ | '4ui'
394
+
395
+ export type AttributeKind =
396
+ // webgl1
397
+ | 'float'
398
+ | 'vec2'
399
+ | 'vec3'
400
+ | 'vec4'
401
+ | 'mat2'
402
+ | 'mat3'
403
+ | 'mat4'
404
+
405
+ // webgl2
406
+ | 'mat2x3'
407
+ | 'mat2x4'
408
+ | 'mat3x2'
409
+ | 'mat3x4'
410
+ | 'mat4x2'
411
+ | 'mat4x3'
412
+
413
+ // (via vertexAttribIPointer)
414
+ | 'int'
415
+ | 'ivec2'
416
+ | 'ivec3'
417
+ | 'ivec4'
418
+ | 'uint'
419
+ | 'uvec2'
420
+ | 'uvec3'
421
+ | 'uvec4'
422
+
423
+ export interface AttributeOptions {
424
+ kind: AttributeKind
425
+ instanced?: boolean
426
+ buffer?: WebGLBuffer
427
+ }
428
+
429
+ export type AttributeSchema = Record<string, AttributeOptions>
430
+
431
+ export interface AttributeMethods<T = AttributeKind> {
432
+ buffer: WebGLBuffer
433
+ bind(): void
434
+ set(data: Float32Array, usage?: GLUsage): { bind(): void }
435
+ dispose(): void
436
+ }
437
+
438
+ export type AttributeView<T extends AttributeSchema> = {
439
+ [K in keyof T]: AttributeMethods<T[K]['kind']>
440
+ }
441
+
442
+ /**********************************************************************************/
443
+ /* */
444
+ /* Interleaved Attributes */
445
+ /* */
446
+ /**********************************************************************************/
447
+
448
+ export interface InterleavedAttributeLayout {
449
+ name: string
450
+ kind: AttributeKind
451
+ }
452
+
453
+ export interface InterleavedAttributeOptions {
454
+ layout: InterleavedAttributeLayout[]
455
+ instanced?: boolean
456
+ }
457
+
458
+ export type InterleavedAttributeSchema = Record<string, InterleavedAttributeOptions>
459
+
460
+ export interface InterleavedAttributeMethods<
461
+ T extends InterleavedAttributeLayout[] = InterleavedAttributeLayout[],
462
+ > {
463
+ bind(): void
464
+ unbind(): void
465
+ set(data: Float32Array, usage?: GLUsage): void
466
+ dispose(): void
467
+ }
468
+
469
+ export type InterleavedAttributeView<T extends InterleavedAttributeSchema> = {
470
+ [K in keyof T]: InterleavedAttributeMethods<T[K]['layout']>
471
+ }
472
+
473
+ /**********************************************************************************/
474
+ /* */
475
+ /* Buffers */
476
+ /* */
477
+ /**********************************************************************************/
478
+
479
+ export interface BufferOptions {
480
+ target?: GLTarget
481
+ usage?: GLUsage
482
+ }
483
+
484
+ export type BufferSchema = Record<string, BufferOptions>
485
+
486
+ export interface BufferMethods {
487
+ set(data: Float32Array | Uint16Array | Uint32Array): void
488
+ bind(): void
489
+ dispose(): void
490
+ }
491
+
492
+ export type BufferView<T extends BufferSchema> = {
493
+ [K in keyof T]: BufferMethods
494
+ }
495
+
496
+ /**********************************************************************************/
497
+ /* */
498
+ /* Framebuffer */
499
+ /* */
500
+ /**********************************************************************************/
501
+
502
+ export interface FramebufferOptions extends Omit<TextureOptions, 'data'> {
503
+ attachment: 'color' | 'depth' | 'stencil' | 'depthStencil'
504
+ texture?: WebGLTexture
505
+ }
506
+
507
+ export interface TextureOptions {
508
+ target?: GLTextureTarget
509
+ width: number
510
+ height: number
511
+ level?: number
512
+ border?: number
513
+ internalFormat?: GLTextureFormat
514
+ format?: GLTextureFormat
515
+ type?: GLTextureType
516
+ minFilter?: GLTextureFilter
517
+ magFilter?: GLTextureFilter
518
+ wrapS?: GLTextureWrap
519
+ wrapT?: GLTextureWrap
520
+ data?: ArrayBufferView | null
521
+ }
522
+
523
+ export interface Framebuffer {
524
+ texture: WebGLTexture
525
+ framebuffer: WebGLFramebuffer
526
+ }
527
+
528
+ /**********************************************************************************/
529
+ /* */
530
+ /* Texture View */
531
+ /* */
532
+ /**********************************************************************************/
533
+
534
+ export type TextureTarget =
535
+ | 'TEXTURE_2D'
536
+ | 'TEXTURE_CUBE_MAP'
537
+ | 'TEXTURE_3D' // WebGL2 only
538
+ | 'TEXTURE_2D_ARRAY' // WebGL2 only
539
+
540
+ export type TextureSchema = Record<string, TextureOptions>
541
+
542
+ export interface TextureMethods {
543
+ texture: WebGLTexture
544
+ dispose(): void
545
+ bind(unit?: number): void
546
+ set(data: ImageBufferSource | null, options?: Partial<TexImage2DOptions>): void
547
+ parameters(params: Record<number, number>): void
548
+ }
549
+
550
+ export type TextureView<T extends TextureSchema> = {
551
+ [K in keyof T]: TextureMethods
552
+ }
553
+
554
+ export type TextureParameterName =
555
+ | 'TEXTURE_MIN_FILTER'
556
+ | 'TEXTURE_MAG_FILTER'
557
+ | 'TEXTURE_WRAP_S'
558
+ | 'TEXTURE_WRAP_T'
559
+ | 'TEXTURE_WRAP_R' // For WebGL2 (3D textures)
560
+
561
+ export type TextureParameterValue =
562
+ // Filters
563
+ | 'NEAREST'
564
+ | 'LINEAR'
565
+ | 'NEAREST_MIPMAP_NEAREST'
566
+ | 'LINEAR_MIPMAP_NEAREST'
567
+ | 'NEAREST_MIPMAP_LINEAR'
568
+ | 'LINEAR_MIPMAP_LINEAR'
569
+
570
+ // Wrap modes
571
+ | 'CLAMP_TO_EDGE'
572
+ | 'REPEAT'
573
+ | 'MIRRORED_REPEAT'
574
+
575
+ // The texture parameters record type
576
+ export type TextureParameters = Partial<Record<TextureParameterName, TextureParameterValue>>
577
+
578
+ // Internal formats (commonly used)
579
+ export type InternalFormat =
580
+ | 'ALPHA'
581
+ | 'RGB'
582
+ | 'RGBA'
583
+ | 'LUMINANCE'
584
+ | 'LUMINANCE_ALPHA'
585
+ | 'DEPTH_COMPONENT'
586
+ | 'DEPTH_STENCIL'
587
+ // WebGL2 adds many more, e.g.
588
+ | 'R8'
589
+ | 'RG8'
590
+ | 'RGB8'
591
+ | 'RGBA8'
592
+ | 'DEPTH_COMPONENT16'
593
+ | 'DEPTH_COMPONENT24'
594
+ | 'DEPTH24_STENCIL8'
595
+
596
+ // Formats (same as internalFormat in WebGL1)
597
+ export type Format =
598
+ | 'ALPHA'
599
+ | 'RGB'
600
+ | 'RGBA'
601
+ | 'LUMINANCE'
602
+ | 'LUMINANCE_ALPHA'
603
+ | 'DEPTH_COMPONENT'
604
+ | 'DEPTH_STENCIL'
605
+
606
+ // Data types
607
+ export type PixelType =
608
+ | 'UNSIGNED_BYTE'
609
+ | 'UNSIGNED_SHORT_5_6_5'
610
+ | 'UNSIGNED_SHORT_4_4_4_4'
611
+ | 'UNSIGNED_SHORT_5_5_5_1'
612
+ | 'FLOAT' // WebGL extension or WebGL2
613
+ | 'HALF_FLOAT' // WebGL2 or extension
614
+ | 'UNSIGNED_INT_24_8' // WebGL2
615
+ | 'UNSIGNED_INT'
616
+ | 'BYTE'
617
+ | 'SHORT'
618
+ | 'INT'
619
+
620
+ // Options for the set() method
621
+ export type TexImage2DOptions = {
622
+ level: number
623
+ internalFormat: InternalFormat
624
+ width: number
625
+ height: number
626
+ border: number
627
+ format: Format
628
+ type: PixelType
629
+ }
630
+
631
+ /**********************************************************************************/
632
+ /* */
633
+ /* View */
634
+ /* */
635
+ /**********************************************************************************/
636
+
637
+ export interface ViewOptions {
638
+ signal?: AbortSignal
639
+ }
640
+
641
+ export interface ViewSchema {
642
+ uniforms?: UniformSchema
643
+ attributes?: AttributeSchema
644
+ interleavedAttributes?: InterleavedAttributeSchema
645
+ buffers?: BufferSchema
646
+ }
647
+
648
+ export type View<T extends ViewSchema = ViewSchema> = {
649
+ attributes: T['attributes'] extends AttributeSchema ? AttributeView<T['attributes']> : undefined
650
+ interleavedAttributes: T['interleavedAttributes'] extends InterleavedAttributeSchema
651
+ ? InterleavedAttributeView<T['interleavedAttributes']>
652
+ : undefined
653
+ buffers: T['buffers'] extends BufferSchema ? BufferView<T['buffers']> : undefined
654
+ uniforms: T['uniforms'] extends UniformSchema ? UniformView<T['uniforms']> : never
655
+ }
656
+
657
+ /**********************************************************************************/
658
+ /* */
659
+ /* Tags */
660
+ /* */
661
+ /**********************************************************************************/
662
+
663
+ export interface GLSL {
664
+ template: string
665
+ uniforms: Record<string, UniformOptions>
666
+ attributes: Record<string, AttributeOptions>
667
+ interleavedAttributes: Record<string, InterleavedAttributeOptions>
668
+ }
669
+
670
+ export type UniformTag<
671
+ TName extends string = string,
672
+ TKind extends UniformKind = UniformKind,
673
+ TOptions extends Partial<UniformOptions> = UniformOptions,
674
+ > = TOptions extends { size: infer TSize }
675
+ ? {
676
+ type: 'uniform'
677
+ kind: TKind
678
+ name: TName
679
+ size: TSize
680
+ }
681
+ : {
682
+ type: 'uniform'
683
+ kind: TKind
684
+ name: TName
685
+ }
686
+
687
+ export interface AttributeTag<
688
+ TName extends string = string,
689
+ TKind extends AttributeKind = AttributeKind,
690
+ TInstanced extends boolean | undefined = boolean | undefined,
691
+ > {
692
+ type: 'attribute'
693
+ kind: TKind
694
+ instanced: TInstanced
695
+ name: TName
696
+ }
697
+
698
+ export interface AttributeTagFn<TKey extends AttributeKind> {
699
+ <TName extends string, TOptions extends Omit<AttributeOptions, 'kind'>>(
700
+ name: TName,
701
+ options: TOptions,
702
+ ): Prettify<AttributeTag<TName, TKey, TOptions['instanced']>>
703
+ <TName extends string>(name: TName): Prettify<AttributeTag<TName, TKey, undefined>>
704
+ }
705
+
706
+ export type InterleaveTag<
707
+ TName extends string = string,
708
+ TLayout extends Array<AttributeTag<string, AttributeKind, undefined>> = Array<
709
+ AttributeTag<string, AttributeKind, undefined>
710
+ >,
711
+ TOptions extends Omit<AttributeOptions, 'kind'> = Omit<AttributeOptions, 'kind'>,
712
+ > = TOptions & {
713
+ name: TName
714
+ type: 'interleavedAttribute'
715
+ layout: {
716
+ [TKey in keyof TLayout]: Prettify<Pick<TLayout[TKey], 'kind' | 'name'>>
717
+ }
718
+ }