@bigmistqke/view.gl 0.1.5 → 0.1.7

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/tag.ts CHANGED
@@ -1,20 +1,18 @@
1
1
  import { toID, view } from '.'
2
+ import type { Prettify } from './type-utils'
2
3
  import type {
4
+ AttributeDefinition,
3
5
  AttributeKind,
4
- AttributeOptions,
5
6
  AttributeTag,
6
7
  AttributeTagFn as AttributeTagMethod,
7
- DeepMerge,
8
+ CompileResult,
8
9
  GLSLSlot,
9
10
  GLSLTag,
11
+ GLSLTagToSchema,
10
12
  InterleaveTag,
11
- Prettify,
12
- ShallowMerge,
13
+ UniformDefinition,
13
14
  UniformKind,
14
- UniformOptions,
15
- UniformTag,
16
15
  UniformTagFn as UniformTagMethod,
17
- View,
18
16
  ViewSchema,
19
17
  ViewSchemaPartial,
20
18
  } from './types'
@@ -35,7 +33,7 @@ export const uniform = new Proxy(
35
33
  get(target, property) {
36
34
  // @ts-expect-error
37
35
  if (typeof property === 'symbol') return target[property]
38
- return (key: string, options?: Omit<UniformOptions, 'kind'>) => ({
36
+ return (key: string, options?: Omit<UniformDefinition, 'kind'>) => ({
39
37
  type: 'uniform',
40
38
  key,
41
39
  kind: property,
@@ -53,7 +51,7 @@ export const attribute = new Proxy(
53
51
  get(target, property) {
54
52
  // @ts-expect-error
55
53
  if (typeof property === 'symbol') return target[property]
56
- return (key: string, options?: Omit<AttributeOptions, 'kind'>) => ({
54
+ return (key: string, options?: Omit<AttributeDefinition, 'kind'>) => ({
57
55
  type: 'attribute',
58
56
  key,
59
57
  kind: property,
@@ -66,7 +64,7 @@ export const attribute = new Proxy(
66
64
  export function interleave<
67
65
  const TKey extends string | symbol,
68
66
  const TLayout extends Array<AttributeTag<string | symbol, AttributeKind, undefined>>,
69
- const TOptions extends Omit<AttributeOptions, 'kind'>,
67
+ const TOptions extends Omit<AttributeDefinition, 'kind'>,
70
68
  >(key: TKey, layout: TLayout, instanced: TOptions): InterleaveTag<TKey, TLayout, TOptions>
71
69
  export function interleave<
72
70
  const TKey extends string | symbol,
@@ -75,7 +73,7 @@ export function interleave<
75
73
  export function interleave<
76
74
  const TKey extends string | symbol,
77
75
  const TLayout extends Array<AttributeTag<string | symbol, AttributeKind, undefined>>,
78
- const TOptions extends Omit<AttributeOptions, 'kind'>,
76
+ const TOptions extends Omit<AttributeDefinition, 'kind'>,
79
77
  >(key: TKey, layout: TLayout, { instanced, buffer }: Partial<TOptions> = {}) {
80
78
  return {
81
79
  type: 'interleavedAttribute',
@@ -96,83 +94,13 @@ export function interleave<
96
94
  /* */
97
95
  /**********************************************************************************/
98
96
 
99
- type glslTagToSchema<TTag extends GLSLTag> =
100
- FlattenSlots<TTag> extends infer TSlots
101
- ? TSlots extends Array<any>
102
- ? GLSLSlotsToSchema<TSlots>
103
- : never
104
- : never
105
-
106
- type GLSLSlotsToSchema<TSlots extends Array<GLSLSlot>> = {
107
- uniforms: {
108
- [K in Extract<TSlots[number], UniformTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
109
- }
110
- attributes: {
111
- [K in Extract<TSlots[number], AttributeTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
112
- }
113
- interleavedAttributes: {
114
- [K in Extract<TSlots[number], InterleaveTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
115
- }
116
- }
117
-
118
- type FlattenSlots<T> =
119
- T extends GLSLTag<infer TSlots>
120
- ? _FlattenSlots<TSlots>
121
- : T extends Array<GLSLSlot>
122
- ? _FlattenSlots<T>
123
- : never
124
-
125
- type _FlattenSlots<T extends Array<GLSLSlot>> = T extends [infer First, ...infer Rest]
126
- ? First extends GLSLTag
127
- ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
128
- : First extends unknown[]
129
- ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
130
- : [First, ...FlattenSlots<Rest>]
131
- : []
132
-
133
- type MergeGLSLSchema<
134
- TVertex extends ViewSchema,
135
- TFragment extends ViewSchema,
136
- TOverrides extends ViewSchemaPartial,
137
- > = {
138
- uniforms: DeepMerge<
139
- [ShallowMerge<[TVertex['uniforms'], TFragment['uniforms']]>, TOverrides['uniforms']]
140
- >
141
- attributes: DeepMerge<
142
- [ShallowMerge<[TVertex['attributes'], TFragment['attributes']]>, TOverrides['attributes']]
143
- >
144
- interleavedAttributes: DeepMerge<
145
- [
146
- ShallowMerge<[TVertex['interleavedAttributes'], TFragment['interleavedAttributes']]>,
147
- TOverrides['interleavedAttributes'],
148
- ]
149
- >
150
- }
151
-
152
- type CompileResult<
153
- TVertex extends GLSLTag,
154
- TFragment extends GLSLTag,
155
- TOverrides extends ViewSchemaPartial,
156
- > =
157
- MergeGLSLSchema<
158
- glslTagToSchema<TVertex>,
159
- glslTagToSchema<TFragment>,
160
- TOverrides
161
- > extends infer TSchema extends ViewSchema
162
- ? {
163
- program: WebGLProgram
164
- schema: TSchema
165
- view: View<TSchema>
166
- }
167
- : never
168
-
169
97
  export function compile<
170
98
  TVertex extends GLSLTag,
171
99
  TFragment extends GLSLTag,
172
100
  TOverride extends ViewSchemaPartial,
173
101
  >(gl: WebGLRenderingContext, vertex: TVertex, fragment: TFragment, overrideSchema?: TOverride) {
174
- const _vertex = resolveGLSLTag(vertex)
175
- const _fragment = resolveGLSLTag(fragment)
102
+ const _vertex = resolveGLSLTag(vertex) as { template: string; schema: ViewSchema }
103
+ const _fragment = resolveGLSLTag(fragment) as { template: string; schema: ViewSchema }
176
104
 
177
105
  const schema = {
178
106
  uniforms: {
@@ -194,9 +122,7 @@ export function compile<
194
122
  const overrideSchemaKind = overrideSchema[kind]
195
123
 
196
124
  for (const key in overrideSchemaKind) {
197
- // @ts-expect-error
198
125
  schemaKind[key] = {
199
- // @ts-expect-error
200
126
  ...schemaKind[key],
201
127
  ...overrideSchemaKind[key],
202
128
  }
@@ -209,17 +135,17 @@ export function compile<
209
135
  program,
210
136
  schema,
211
137
  view: view(gl, program, schema),
212
- } as CompileResult<TVertex, TFragment, TOverride>
138
+ } as Prettify<CompileResult<TVertex, TFragment, TOverride>>
213
139
  }
214
140
 
215
141
  function resolveGLSLTag<TTag extends GLSLTag>(tag: TTag) {
216
142
  return {
217
- template: glslTagToString(tag),
218
- schema: glslTagToSchema(tag),
143
+ template: compile.toString(tag),
144
+ schema: compile.toSchema(tag),
219
145
  }
220
146
  }
221
147
 
222
- function glslTagToSchema<TTag extends GLSLTag>(tag: TTag) {
148
+ compile.toSchema = function <TTag extends GLSLTag>(tag: TTag) {
223
149
  const result = {
224
150
  uniforms: {},
225
151
  attributes: {},
@@ -237,7 +163,7 @@ function glslTagToSchema<TTag extends GLSLTag>(tag: TTag) {
237
163
  }
238
164
 
239
165
  if (slot.type === 'glsl') {
240
- const { uniforms, attributes, interleavedAttributes } = glslTagToSchema(slot)
166
+ const { uniforms, attributes, interleavedAttributes } = compile.toSchema(slot)
241
167
 
242
168
  result.uniforms = {
243
169
  ...result.uniforms,
@@ -263,45 +189,10 @@ function glslTagToSchema<TTag extends GLSLTag>(tag: TTag) {
263
189
 
264
190
  tag.slots.forEach(handleSlot)
265
191
 
266
- return result
192
+ return result as unknown as Prettify<GLSLTagToSchema<TTag>>
267
193
  }
268
194
 
269
- // function glslSlotToSchema(slot: GLSLSlot){
270
- // if(Array.isArray(slot)){
271
-
272
- // return
273
- // }
274
-
275
- // if (typeof slot !== 'object') {
276
- // return
277
- // }
278
-
279
- // if (slot.type === 'glsl') {
280
- // return glslTagToSchema(slot)
281
-
282
- // // result.uniforms = {
283
- // // ...result.uniforms,
284
- // // ...uniforms,
285
- // // }
286
- // // result.attributes = {
287
- // // ...result.attributes,
288
- // // ...attributes,
289
- // // }
290
- // // result.interleavedAttributes = {
291
- // // ...result.interleavedAttributes,
292
- // // ...interleavedAttributes,
293
- // // }
294
-
295
- // // continue
296
- // }
297
-
298
- // const { key: name, type, ...rest } = slot
299
-
300
- // // @ts-expect-error
301
- // result[`${type}s`][name] = rest
302
- // }
303
-
304
- function glslTagToString<TTag extends GLSLTag>({ template: [initial, ...rest], slots }: TTag) {
195
+ compile.toString = function <TTag extends GLSLTag>({ template: [initial, ...rest], slots }: TTag) {
305
196
  const v300 = !!initial?.startsWith('#version 300 es')
306
197
 
307
198
  let template = initial ?? ''
@@ -323,7 +214,7 @@ function glslSlotToString(slot: GLSLSlot, v300: boolean): string {
323
214
  }
324
215
 
325
216
  if (slot.type === 'glsl') {
326
- return glslTagToString(slot)
217
+ return compile.toString(slot)
327
218
  }
328
219
 
329
220
  if (slot.type === 'interleavedAttribute') {
@@ -0,0 +1,43 @@
1
+ export type Prettify<T> = {
2
+ [K in keyof T]: T[K]
3
+ } & {}
4
+
5
+ export type RemoveSuffix<T, S extends string> = {
6
+ [K in keyof T as K extends `${infer Prefix}${S}` ? Prefix : K]: T[K]
7
+ }
8
+
9
+ export type DeepMerge<A extends readonly [...any]> = A extends [infer L, ...infer R]
10
+ ? DeepMergeTwo<L, DeepMerge<R>>
11
+ : unknown
12
+
13
+ type DeepMergeTwo<TBase, TOverride> = {
14
+ [K in keyof TBase | keyof TOverride]: K extends keyof TOverride
15
+ ? K extends keyof TBase
16
+ ? ShallowMerge<[TBase[K], TOverride[K]]>
17
+ : TOverride[K]
18
+ : K extends keyof TBase
19
+ ? TBase[K]
20
+ : never
21
+ }
22
+
23
+ // see https://stackoverflow.com/a/49683575
24
+ export type ShallowMerge<A extends readonly [...any]> = A extends [infer L, ...infer R]
25
+ ? ShallowMergeTwo<L, ShallowMerge<R>>
26
+ : unknown
27
+
28
+ type OptionalPropertyNames<T> = {
29
+ [K in keyof T]-?: {} extends { [P in K]: T[K] } ? K : never
30
+ }[keyof T]
31
+
32
+ type SpreadProperties<L, R, K extends keyof L & keyof R> = {
33
+ [P in K]: L[P] | Exclude<R[P], undefined>
34
+ }
35
+
36
+ type Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
37
+
38
+ type ShallowMergeTwo<L, R> = Id<
39
+ Pick<L, Exclude<keyof L, keyof R>> &
40
+ Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>> &
41
+ Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>> &
42
+ SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>
43
+ >
package/src/types.ts CHANGED
@@ -1,72 +1,14 @@
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
- }
1
+ import { DeepMerge, Prettify, ShallowMerge } from './type-utils'
18
2
 
19
3
  export type GL = WebGLRenderingContext | WebGL2RenderingContext
20
4
 
21
- export type DeepMerge<A extends readonly [...any]> = A extends [infer L, ...infer R]
22
- ? DeepMergeTwo<L, DeepMerge<R>>
23
- : unknown
24
-
25
- type DeepMergeTwo<TBase, TOverride> = {
26
- [K in keyof TBase | keyof TOverride]: K extends keyof TOverride
27
- ? K extends keyof TBase
28
- ? ShallowMerge<[TBase[K], TOverride[K]]>
29
- : TOverride[K]
30
- : K extends keyof TBase
31
- ? TBase[K]
32
- : never
33
- }
34
-
35
- // see https://stackoverflow.com/a/49683575
36
- export type ShallowMerge<A extends readonly [...any]> = A extends [infer L, ...infer R]
37
- ? ShallowMergeTwo<L, ShallowMerge<R>>
38
- : unknown
39
-
40
- type OptionalPropertyNames<T> = {
41
- [K in keyof T]-?: {} extends { [P in K]: T[K] } ? K : never
42
- }[keyof T]
43
-
44
- type SpreadProperties<L, R, K extends keyof L & keyof R> = {
45
- [P in K]: L[P] | Exclude<R[P], undefined>
46
- }
47
-
48
- type Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
49
-
50
- type ShallowMergeTwo<L, R> = Id<
51
- Pick<L, Exclude<keyof L, keyof R>> &
52
- Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>> &
53
- Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>> &
54
- SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>
55
- >
56
-
57
- /**********************************************************************************/
58
- /* */
59
- /* Constants */
60
- /* */
61
- /**********************************************************************************/
62
-
63
- type GLTarget = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
64
- type GLUsage = 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW'
65
- type GLTextureTarget = 'TEXTURE_2D' | 'TEXTURE_CUBE_MAP'
66
- type GLTextureFormat = 'RGBA' | 'RGB' | 'RGBA32F' | 'RGB32F' | 'RGBA16F' | 'RGB16F'
67
- type GLTextureType = 'UNSIGNED_BYTE' | 'FLOAT' | 'HALF_FLOAT'
68
- type GLTextureFilter = 'NEAREST' | 'LINEAR'
69
- type GLTextureWrap = 'CLAMP_TO_EDGE' | 'REPEAT' | 'MIRRORED_REPEAT'
5
+ export type GLTarget = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
6
+ export type GLUsage = 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW'
7
+ export type GLTextureTarget = 'TEXTURE_2D' | 'TEXTURE_CUBE_MAP'
8
+ export type GLTextureFormat = 'RGBA' | 'RGB' | 'RGBA32F' | 'RGB32F' | 'RGBA16F' | 'RGB16F'
9
+ export type GLTextureType = 'UNSIGNED_BYTE' | 'FLOAT' | 'HALF_FLOAT'
10
+ export type GLTextureFilter = 'NEAREST' | 'LINEAR'
11
+ export type GLTextureWrap = 'CLAMP_TO_EDGE' | 'REPEAT' | 'MIRRORED_REPEAT'
70
12
 
71
13
  export interface KIND_TO_UNIFORM_FN_NAME_MAP {
72
14
  // Floats (WebGL1 + WebGL2)
@@ -389,21 +331,22 @@ interface UniformKindMap {
389
331
  usampler2DArray: [number];
390
332
  }
391
333
 
392
- export interface UniformOptions {
334
+ export interface UniformDefinition {
393
335
  kind: UniformKind
394
336
  size?: number
395
337
  }
396
338
 
397
- export type UniformSchema = Record<string | symbol, UniformOptions>
398
- export type UniformSchemaPartial = Record<string | symbol, Partial<UniformOptions>>
339
+ export type UniformSchema = Record<string | symbol, UniformDefinition>
340
+ export type UniformSchemaPartial = Record<string | symbol, Partial<UniformDefinition>>
399
341
 
400
- export type UniformMethods<TOptions extends UniformOptions> = TOptions['size'] extends number
401
- ? {
402
- set(arg: Float32Array): void
403
- }
404
- : {
405
- set(...args: UniformKindMap[TOptions['kind']]): void
406
- }
342
+ export type UniformMethods<TDefinition extends UniformDefinition> =
343
+ TDefinition['size'] extends number
344
+ ? {
345
+ set(arg: Float32Array): void
346
+ }
347
+ : {
348
+ set(...args: UniformKindMap[TDefinition['kind']]): void
349
+ }
407
350
 
408
351
  export type UniformView<T extends UniformSchema> = {
409
352
  [K in keyof T]: UniformMethods<T[K]>
@@ -457,13 +400,13 @@ export type AttributeKind =
457
400
  | 'uvec3'
458
401
  | 'uvec4'
459
402
 
460
- export interface AttributeOptions {
403
+ export interface AttributeDefinition {
461
404
  kind: AttributeKind
462
405
  instanced?: boolean
463
406
  buffer?: WebGLBuffer
464
407
  }
465
408
 
466
- export type AttributeSchema = Record<string | symbol, AttributeOptions>
409
+ export type AttributeSchema = Record<string | symbol, AttributeDefinition>
467
410
 
468
411
  export interface AttributeMethods<T = AttributeKind> {
469
412
  buffer: WebGLBuffer
@@ -487,12 +430,12 @@ export interface InterleavedAttributeLayout {
487
430
  kind: AttributeKind
488
431
  }
489
432
 
490
- export interface InterleavedAttributeOptions {
433
+ export interface InterleavedAttributeDefinition {
491
434
  layout: InterleavedAttributeLayout[]
492
435
  instanced?: boolean
493
436
  }
494
437
 
495
- export type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeOptions>
438
+ export type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeDefinition>
496
439
 
497
440
  export interface InterleavedAttributeMethods<
498
441
  T extends InterleavedAttributeLayout[] = InterleavedAttributeLayout[],
@@ -513,12 +456,12 @@ export type InterleavedAttributeView<T extends InterleavedAttributeSchema> = {
513
456
  /* */
514
457
  /**********************************************************************************/
515
458
 
516
- export interface BufferOptions {
459
+ export interface BufferDefinition {
517
460
  target?: GLTarget
518
461
  usage?: GLUsage
519
462
  }
520
463
 
521
- export type BufferSchema = Record<string | symbol, BufferOptions>
464
+ export type BufferSchema = Record<string | symbol, BufferDefinition>
522
465
 
523
466
  export interface BufferMethods {
524
467
  set(data: Float32Array | Uint16Array | Uint32Array): void
@@ -536,12 +479,12 @@ export type BufferView<T extends BufferSchema> = {
536
479
  /* */
537
480
  /**********************************************************************************/
538
481
 
539
- export interface FramebufferOptions extends Omit<TextureOptions, 'data'> {
482
+ export interface FramebufferDefinition extends Omit<TextureDefinition, 'data'> {
540
483
  attachment: 'color' | 'depth' | 'stencil' | 'depthStencil'
541
484
  texture?: WebGLTexture
542
485
  }
543
486
 
544
- export interface TextureOptions {
487
+ export interface TextureDefinition {
545
488
  target?: GLTextureTarget
546
489
  width: number
547
490
  height: number
@@ -574,7 +517,7 @@ export type TextureTarget =
574
517
  | 'TEXTURE_3D' // WebGL2 only
575
518
  | 'TEXTURE_2D_ARRAY' // WebGL2 only
576
519
 
577
- export type TextureSchema = Record<string | symbol, TextureOptions>
520
+ export type TextureSchema = Record<string | symbol, TextureDefinition>
578
521
 
579
522
  export interface TextureMethods {
580
523
  texture: WebGLTexture
@@ -683,10 +626,10 @@ export interface ViewSchema {
683
626
  }
684
627
 
685
628
  export interface ViewSchemaPartial {
686
- uniforms?: Record<string | symbol, Partial<UniformOptions>>
687
- attributes?: Record<string | symbol, Partial<AttributeOptions>>
688
- interleavedAttributes?: Record<string | symbol, Partial<InterleavedAttributeOptions>>
689
- buffers?: Record<string | symbol, Partial<BufferOptions>>
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>>
690
633
  }
691
634
 
692
635
  export type View<T extends ViewSchema = ViewSchema> = {
@@ -722,8 +665,8 @@ export interface GLSLTag<TSlots extends GLSLSlot[] = GLSLSlot[]> {
722
665
  export type UniformTag<
723
666
  TKey extends string | symbol = string | symbol,
724
667
  TKind extends UniformKind = UniformKind,
725
- TOptions extends Partial<UniformOptions> = UniformOptions,
726
- > = TOptions extends { size: infer TSize }
668
+ TDefinition extends Partial<UniformDefinition> = UniformDefinition,
669
+ > = TDefinition extends { size: infer TSize }
727
670
  ? {
728
671
  type: 'uniform'
729
672
  kind: TKind
@@ -737,10 +680,10 @@ export type UniformTag<
737
680
  }
738
681
 
739
682
  export interface UniformTagFn<TKind extends UniformKind> {
740
- <const TKey extends string | symbol, const TOptions extends Omit<UniformOptions, 'kind'>>(
683
+ <const TKey extends string | symbol, const TDefinition extends Omit<UniformDefinition, 'kind'>>(
741
684
  key: TKey,
742
- TOptions: TOptions,
743
- ): Prettify<UniformTag<TKey, TKind, TOptions>>
685
+ TDefinition: TDefinition,
686
+ ): Prettify<UniformTag<TKey, TKind, TDefinition>>
744
687
  <const TName extends string | symbol>(key: TName): Prettify<UniformTag<TName, TKind>>
745
688
  }
746
689
 
@@ -756,10 +699,10 @@ export interface AttributeTag<
756
699
  }
757
700
 
758
701
  export interface AttributeTagFn<TKey extends AttributeKind> {
759
- <TName extends string | symbol, TOptions extends Omit<AttributeOptions, 'kind'>>(
702
+ <TName extends string | symbol, TDefinition extends Omit<AttributeDefinition, 'kind'>>(
760
703
  key: TName,
761
- options: TOptions,
762
- ): Prettify<AttributeTag<TName, TKey, TOptions['instanced']>>
704
+ options: TDefinition,
705
+ ): Prettify<AttributeTag<TName, TKey, TDefinition['instanced']>>
763
706
  <TName extends string | symbol>(key: TName): Prettify<AttributeTag<TName, TKey, undefined>>
764
707
  }
765
708
 
@@ -768,11 +711,81 @@ export type InterleaveTag<
768
711
  TLayout extends Array<AttributeTag<string | symbol, AttributeKind, undefined>> = Array<
769
712
  AttributeTag<string | symbol, AttributeKind, undefined>
770
713
  >,
771
- TOptions extends Omit<AttributeOptions, 'kind'> = Omit<AttributeOptions, 'kind'>,
772
- > = TOptions & {
714
+ TDefinition extends Omit<AttributeDefinition, 'kind'> = Omit<AttributeDefinition, 'kind'>,
715
+ > = TDefinition & {
773
716
  key: TKey
774
717
  type: 'interleavedAttribute'
775
718
  layout: {
776
719
  [TKey in keyof TLayout]: Prettify<Pick<TLayout[TKey], 'kind' | 'key'>>
777
720
  }
778
721
  }
722
+
723
+ export type GLSLTagToSchema<TTag extends GLSLTag> =
724
+ FlattenSlots<TTag> extends infer TSlots
725
+ ? TSlots extends Array<any>
726
+ ? GLSLSlotsToSchema<TSlots>
727
+ : never
728
+ : never
729
+
730
+ export type GLSLSlotsToSchema<TSlots extends Array<GLSLSlot>> = {
731
+ uniforms: {
732
+ [K in Extract<TSlots[number], UniformTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
733
+ }
734
+ attributes: {
735
+ [K in Extract<TSlots[number], AttributeTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
736
+ }
737
+ interleavedAttributes: {
738
+ [K in Extract<TSlots[number], InterleaveTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
739
+ }
740
+ }
741
+
742
+ type FlattenSlots<T> =
743
+ T extends GLSLTag<infer TSlots>
744
+ ? _FlattenSlots<TSlots>
745
+ : T extends Array<GLSLSlot>
746
+ ? _FlattenSlots<T>
747
+ : never
748
+
749
+ type _FlattenSlots<T extends Array<GLSLSlot>> = T extends [infer First, ...infer Rest]
750
+ ? First extends GLSLTag
751
+ ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
752
+ : First extends unknown[]
753
+ ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
754
+ : [First, ...FlattenSlots<Rest>]
755
+ : []
756
+
757
+ export type MergeGLSLSchema<
758
+ TVertex extends ViewSchema,
759
+ TFragment extends ViewSchema,
760
+ TOverrides extends ViewSchemaPartial = {},
761
+ > = {
762
+ uniforms: DeepMerge<
763
+ [ShallowMerge<[TVertex['uniforms'], TFragment['uniforms']]>, TOverrides['uniforms']]
764
+ >
765
+ attributes: DeepMerge<
766
+ [ShallowMerge<[TVertex['attributes'], TFragment['attributes']]>, TOverrides['attributes']]
767
+ >
768
+ interleavedAttributes: DeepMerge<
769
+ [
770
+ ShallowMerge<[TVertex['interleavedAttributes'], TFragment['interleavedAttributes']]>,
771
+ TOverrides['interleavedAttributes'],
772
+ ]
773
+ >
774
+ }
775
+
776
+ export type CompileResult<
777
+ TVertex extends GLSLTag,
778
+ TFragment extends GLSLTag,
779
+ TOverrides extends ViewSchemaPartial,
780
+ > =
781
+ MergeGLSLSchema<
782
+ GLSLTagToSchema<TVertex>,
783
+ GLSLTagToSchema<TFragment>,
784
+ TOverrides
785
+ > extends infer TSchema extends ViewSchema
786
+ ? {
787
+ program: WebGLProgram
788
+ schema: TSchema
789
+ view: View<TSchema>
790
+ }
791
+ : never
@@ -1,10 +1,10 @@
1
1
  import type {
2
2
  AttributeKind,
3
- FramebufferOptions,
3
+ FramebufferDefinition,
4
4
  GL,
5
5
  KIND_TO_SIZE_MAP,
6
6
  KIND_TO_UNIFORM_FN_NAME_MAP,
7
- TextureOptions,
7
+ TextureDefinition,
8
8
  UniformKind,
9
9
  } from '../types'
10
10
 
@@ -158,7 +158,7 @@ export function createTexture(
158
158
  wrapT = 'CLAMP_TO_EDGE',
159
159
  width,
160
160
  height,
161
- }: TextureOptions,
161
+ }: TextureDefinition,
162
162
  data?: ArrayBufferView | null,
163
163
  ): WebGLTexture {
164
164
  const texture = gl.createTexture()
@@ -229,7 +229,10 @@ class FramebufferError extends Error {
229
229
  }
230
230
  }
231
231
 
232
- export function createFramebuffer(gl: GL, { attachment, texture, ...options }: FramebufferOptions) {
232
+ export function createFramebuffer(
233
+ gl: GL,
234
+ { attachment, texture, ...options }: FramebufferDefinition,
235
+ ) {
233
236
  // Create texture for the framebuffer
234
237
  texture ??= createTexture(gl, options)
235
238