@bigmistqke/view.gl 0.1.3 → 0.1.5
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/.claude/settings.local.json +4 -1
- package/.prettierignore +1 -0
- package/README.md +429 -213
- package/dev/src/examples/bezier.ts +3 -9
- package/dev/src/examples/{game_of_life.ts → game-of-life.ts} +2 -9
- package/dev/src/examples/glsl-composition.ts +131 -0
- package/dev/src/examples/grid.ts +4 -3
- package/dev/src/examples/overview.ts +7 -6
- package/dev/src/examples/{pix_sim.ts → pix-sim.ts} +3 -14
- package/dev/src/examples/symbol.ts +4 -3
- package/dev/src/index.ts +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/tag.d.mts +39 -21
- package/dist/tag.mjs +395 -47
- package/dist/tag.mjs.map +1 -1
- package/dist/{types-DoFAJoh-.d.mts → types-DIIqZ8e6.d.mts} +34 -11
- package/package.json +3 -2
- package/src/index.ts +4 -4
- package/src/tag.ts +251 -110
- package/src/types.ts +65 -5
- package/src/utils/index.ts +9 -9
- package/test/tag.test.ts +800 -82
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
type Merge<A, B> = {
|
|
2
|
-
[K in keyof A | keyof B]: K extends keyof A ? K extends keyof B ? A[K] | B[K] : A[K] : K extends keyof B ? B[K] : never;
|
|
3
|
-
};
|
|
4
1
|
type Prettify<T> = {
|
|
5
2
|
[K in keyof T]: T[K];
|
|
6
3
|
} & {};
|
|
7
4
|
type GL = WebGLRenderingContext | WebGL2RenderingContext;
|
|
5
|
+
type DeepMerge<A extends readonly [...any]> = A extends [infer L, ...infer R] ? DeepMergeTwo<L, DeepMerge<R>> : unknown;
|
|
6
|
+
type DeepMergeTwo<TBase, TOverride> = {
|
|
7
|
+
[K in keyof TBase | keyof TOverride]: K extends keyof TOverride ? K extends keyof TBase ? ShallowMerge<[TBase[K], TOverride[K]]> : TOverride[K] : K extends keyof TBase ? TBase[K] : never;
|
|
8
|
+
};
|
|
9
|
+
type ShallowMerge<A extends readonly [...any]> = A extends [infer L, ...infer R] ? ShallowMergeTwo<L, ShallowMerge<R>> : unknown;
|
|
10
|
+
type OptionalPropertyNames<T> = {
|
|
11
|
+
[K in keyof T]-?: {} extends {
|
|
12
|
+
[P in K]: T[K];
|
|
13
|
+
} ? K : never;
|
|
14
|
+
}[keyof T];
|
|
15
|
+
type SpreadProperties<L, R, K extends keyof L & keyof R> = {
|
|
16
|
+
[P in K]: L[P] | Exclude<R[P], undefined>;
|
|
17
|
+
};
|
|
18
|
+
type Id<T> = T extends infer U ? {
|
|
19
|
+
[K in keyof U]: U[K];
|
|
20
|
+
} : never;
|
|
21
|
+
type ShallowMergeTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>> & Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>> & SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>>;
|
|
8
22
|
/**********************************************************************************/
|
|
9
23
|
/**********************************************************************************/
|
|
10
24
|
type GLTarget = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER';
|
|
@@ -219,19 +233,24 @@ interface ViewSchema {
|
|
|
219
233
|
interleavedAttributes?: InterleavedAttributeSchema;
|
|
220
234
|
buffers?: BufferSchema;
|
|
221
235
|
}
|
|
236
|
+
interface ViewSchemaPartial {
|
|
237
|
+
uniforms?: Record<string | symbol, Partial<UniformOptions>>;
|
|
238
|
+
attributes?: Record<string | symbol, Partial<AttributeOptions>>;
|
|
239
|
+
interleavedAttributes?: Record<string | symbol, Partial<InterleavedAttributeOptions>>;
|
|
240
|
+
buffers?: Record<string | symbol, Partial<BufferOptions>>;
|
|
241
|
+
}
|
|
222
242
|
type View<T extends ViewSchema = ViewSchema> = {
|
|
223
243
|
attributes: T['attributes'] extends AttributeSchema ? AttributeView<T['attributes']> : undefined;
|
|
224
244
|
interleavedAttributes: T['interleavedAttributes'] extends InterleavedAttributeSchema ? InterleavedAttributeView<T['interleavedAttributes']> : undefined;
|
|
225
245
|
buffers: T['buffers'] extends BufferSchema ? BufferView<T['buffers']> : undefined;
|
|
226
246
|
uniforms: T['uniforms'] extends UniformSchema ? UniformView<T['uniforms']> : never;
|
|
227
247
|
};
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
interface
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
interleavedAttributes: Record<string | symbol, InterleavedAttributeOptions>;
|
|
248
|
+
type GLSLSlotItem = GLSLTag | UniformTag | AttributeTag | InterleaveTag | string | number | symbol;
|
|
249
|
+
type GLSLSlot = GLSLSlotItem | Array<GLSLSlotItem>;
|
|
250
|
+
interface GLSLTag<TSlots extends GLSLSlot[] = GLSLSlot[]> {
|
|
251
|
+
type: 'glsl';
|
|
252
|
+
template: TemplateStringsArray;
|
|
253
|
+
slots: TSlots;
|
|
235
254
|
}
|
|
236
255
|
type UniformTag<TKey extends string | symbol = string | symbol, TKind extends UniformKind = UniformKind, TOptions extends Partial<UniformOptions> = UniformOptions> = TOptions extends {
|
|
237
256
|
size: infer TSize;
|
|
@@ -245,6 +264,10 @@ type UniformTag<TKey extends string | symbol = string | symbol, TKind extends Un
|
|
|
245
264
|
kind: TKind;
|
|
246
265
|
key: TKey;
|
|
247
266
|
};
|
|
267
|
+
interface UniformTagFn<TKind extends UniformKind> {
|
|
268
|
+
<const TKey extends string | symbol, const TOptions extends Omit<UniformOptions, 'kind'>>(key: TKey, TOptions: TOptions): Prettify<UniformTag<TKey, TKind, TOptions>>;
|
|
269
|
+
<const TName extends string | symbol>(key: TName): Prettify<UniformTag<TName, TKind>>;
|
|
270
|
+
}
|
|
248
271
|
interface AttributeTag<TKey extends string | symbol = string | symbol, TKind extends AttributeKind = AttributeKind, TInstanced extends boolean | undefined = boolean | undefined> {
|
|
249
272
|
type: 'attribute';
|
|
250
273
|
kind: TKind;
|
|
@@ -263,4 +286,4 @@ type InterleaveTag<TKey extends string | symbol = string | symbol, TLayout exten
|
|
|
263
286
|
};
|
|
264
287
|
};
|
|
265
288
|
|
|
266
|
-
export type { AttributeSchema as A, BufferSchema as B, GL as G, InterleavedAttributeSchema as I,
|
|
289
|
+
export type { AttributeSchema as A, BufferSchema as B, DeepMerge as D, GL as G, InterleavedAttributeSchema as I, Prettify as P, ShallowMerge as S, UniformSchema as U, ViewSchema as V, ViewOptions as a, View as b, UniformView as c, AttributeView as d, InterleavedAttributeView as e, BufferView as f, GLSLSlot as g, GLSLTag as h, UniformTagFn as i, AttributeTagFn as j, AttributeTag as k, AttributeKind as l, AttributeOptions as m, InterleaveTag as n, ViewSchemaPartial as o, UniformTag as p };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigmistqke/view.gl",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "🪟 Utilities for managing WebGL resources.",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"prepublish": "pnpm build",
|
|
39
39
|
"test": "vitest --run",
|
|
40
40
|
"test:coverage": "vitest run --coverage",
|
|
41
|
-
"test:ui": "vitest --ui"
|
|
41
|
+
"test:ui": "vitest --ui",
|
|
42
|
+
"lint:types": "tsc --noEmit"
|
|
42
43
|
}
|
|
43
44
|
}
|
package/src/index.ts
CHANGED
|
@@ -52,12 +52,12 @@ export function toID(key: string | number | symbol) {
|
|
|
52
52
|
/* */
|
|
53
53
|
/**********************************************************************************/
|
|
54
54
|
|
|
55
|
-
export function view<
|
|
55
|
+
export function view<TSchema extends ViewSchema>(
|
|
56
56
|
gl: GL,
|
|
57
57
|
program: WebGLProgram,
|
|
58
|
-
schema:
|
|
58
|
+
schema: TSchema,
|
|
59
59
|
options?: ViewOptions,
|
|
60
|
-
): View<
|
|
60
|
+
): View<TSchema> {
|
|
61
61
|
return {
|
|
62
62
|
uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),
|
|
63
63
|
attributes: !schema.attributes
|
|
@@ -67,7 +67,7 @@ export function view<T extends ViewSchema>(
|
|
|
67
67
|
? undefined
|
|
68
68
|
: interleavedAttributeView(gl, program, schema.interleavedAttributes, options),
|
|
69
69
|
buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),
|
|
70
|
-
} as View<
|
|
70
|
+
} as View<TSchema>
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**********************************************************************************/
|
package/src/tag.ts
CHANGED
|
@@ -1,36 +1,35 @@
|
|
|
1
|
-
import { toID } from '.'
|
|
1
|
+
import { toID, view } from '.'
|
|
2
2
|
import type {
|
|
3
3
|
AttributeKind,
|
|
4
4
|
AttributeOptions,
|
|
5
5
|
AttributeTag,
|
|
6
|
-
AttributeTagFn,
|
|
7
|
-
|
|
6
|
+
AttributeTagFn as AttributeTagMethod,
|
|
7
|
+
DeepMerge,
|
|
8
|
+
GLSLSlot,
|
|
9
|
+
GLSLTag,
|
|
8
10
|
InterleaveTag,
|
|
9
|
-
Merge,
|
|
10
11
|
Prettify,
|
|
12
|
+
ShallowMerge,
|
|
11
13
|
UniformKind,
|
|
12
14
|
UniformOptions,
|
|
13
15
|
UniformTag,
|
|
16
|
+
UniformTagFn as UniformTagMethod,
|
|
17
|
+
View,
|
|
18
|
+
ViewSchema,
|
|
19
|
+
ViewSchemaPartial,
|
|
14
20
|
} from './types'
|
|
15
21
|
import { createProgram } from './utils'
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
interface UniformTagFn<TKind extends UniformKind> {
|
|
24
|
-
<const TKey extends string | symbol, const TOptions extends Omit<UniformOptions, 'kind'>>(
|
|
25
|
-
key: TKey,
|
|
26
|
-
TOptions: TOptions,
|
|
27
|
-
): Prettify<UniformTag<TKey, TKind, TOptions>>
|
|
28
|
-
<const TName extends string | symbol>(key: TName): Prettify<UniformTag<TName, TKind>>
|
|
23
|
+
export function glsl<TSlot extends GLSLSlot, TSlots extends TSlot[]>(
|
|
24
|
+
template: TemplateStringsArray,
|
|
25
|
+
...slots: [...TSlots]
|
|
26
|
+
): GLSLTag<TSlots> {
|
|
27
|
+
return { template, slots, type: 'glsl' }
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
export const uniform = new Proxy(
|
|
32
31
|
{} as {
|
|
33
|
-
[TKey in UniformKind]:
|
|
32
|
+
[TKey in UniformKind]: UniformTagMethod<TKey>
|
|
34
33
|
},
|
|
35
34
|
{
|
|
36
35
|
get(target, property) {
|
|
@@ -48,7 +47,7 @@ export const uniform = new Proxy(
|
|
|
48
47
|
|
|
49
48
|
export const attribute = new Proxy(
|
|
50
49
|
{} as {
|
|
51
|
-
[TKey in AttributeKind]:
|
|
50
|
+
[TKey in AttributeKind]: AttributeTagMethod<TKey>
|
|
52
51
|
},
|
|
53
52
|
{
|
|
54
53
|
get(target, property) {
|
|
@@ -93,109 +92,251 @@ export function interleave<
|
|
|
93
92
|
|
|
94
93
|
/**********************************************************************************/
|
|
95
94
|
/* */
|
|
96
|
-
/*
|
|
95
|
+
/* Compile */
|
|
97
96
|
/* */
|
|
98
97
|
/**********************************************************************************/
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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>
|
|
135
166
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
: never
|
|
168
|
+
|
|
169
|
+
export function compile<
|
|
170
|
+
TVertex extends GLSLTag,
|
|
171
|
+
TFragment extends GLSLTag,
|
|
172
|
+
TOverride extends ViewSchemaPartial,
|
|
173
|
+
>(gl: WebGLRenderingContext, vertex: TVertex, fragment: TFragment, overrideSchema?: TOverride) {
|
|
174
|
+
const _vertex = resolveGLSLTag(vertex)
|
|
175
|
+
const _fragment = resolveGLSLTag(fragment)
|
|
176
|
+
|
|
177
|
+
const schema = {
|
|
178
|
+
uniforms: {
|
|
179
|
+
..._vertex.schema.uniforms,
|
|
180
|
+
..._fragment.schema.uniforms,
|
|
141
181
|
},
|
|
142
|
-
{
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
attributes: {},
|
|
146
|
-
interleavedAttributes: {},
|
|
147
|
-
} as {
|
|
148
|
-
template: string
|
|
149
|
-
uniforms: {
|
|
150
|
-
[K in Extract<Holes[number], UniformTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
|
|
151
|
-
}
|
|
152
|
-
attributes: {
|
|
153
|
-
[K in Extract<Holes[number], AttributeTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
|
|
154
|
-
}
|
|
155
|
-
interleavedAttributes: {
|
|
156
|
-
[K in Extract<Holes[number], InterleaveTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
|
|
157
|
-
}
|
|
182
|
+
attributes: {
|
|
183
|
+
..._vertex.schema.attributes,
|
|
184
|
+
..._fragment.schema.attributes,
|
|
158
185
|
},
|
|
159
|
-
|
|
160
|
-
|
|
186
|
+
interleavedAttributes: {
|
|
187
|
+
..._vertex.schema.interleavedAttributes,
|
|
188
|
+
..._fragment.schema.interleavedAttributes,
|
|
189
|
+
},
|
|
190
|
+
}
|
|
161
191
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
/* */
|
|
166
|
-
/**********************************************************************************/
|
|
192
|
+
for (const kind in overrideSchema) {
|
|
193
|
+
const schemaKind = schema[kind as keyof typeof schema]
|
|
194
|
+
const overrideSchemaKind = overrideSchema[kind]
|
|
167
195
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
196
|
+
for (const key in overrideSchemaKind) {
|
|
197
|
+
// @ts-expect-error
|
|
198
|
+
schemaKind[key] = {
|
|
199
|
+
// @ts-expect-error
|
|
200
|
+
...schemaKind[key],
|
|
201
|
+
...overrideSchemaKind[key],
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const program = createProgram(gl, _vertex.template, _fragment.template)
|
|
174
207
|
|
|
175
208
|
return {
|
|
176
209
|
program,
|
|
177
|
-
schema
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
210
|
+
schema,
|
|
211
|
+
view: view(gl, program, schema),
|
|
212
|
+
} as CompileResult<TVertex, TFragment, TOverride>
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function resolveGLSLTag<TTag extends GLSLTag>(tag: TTag) {
|
|
216
|
+
return {
|
|
217
|
+
template: glslTagToString(tag),
|
|
218
|
+
schema: glslTagToSchema(tag),
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function glslTagToSchema<TTag extends GLSLTag>(tag: TTag) {
|
|
223
|
+
const result = {
|
|
224
|
+
uniforms: {},
|
|
225
|
+
attributes: {},
|
|
226
|
+
interleavedAttributes: {},
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function handleSlot(slot: GLSLSlot) {
|
|
230
|
+
if (Array.isArray(slot)) {
|
|
231
|
+
slot.forEach(handleSlot)
|
|
232
|
+
return
|
|
199
233
|
}
|
|
234
|
+
|
|
235
|
+
if (typeof slot !== 'object') {
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (slot.type === 'glsl') {
|
|
240
|
+
const { uniforms, attributes, interleavedAttributes } = glslTagToSchema(slot)
|
|
241
|
+
|
|
242
|
+
result.uniforms = {
|
|
243
|
+
...result.uniforms,
|
|
244
|
+
...uniforms,
|
|
245
|
+
}
|
|
246
|
+
result.attributes = {
|
|
247
|
+
...result.attributes,
|
|
248
|
+
...attributes,
|
|
249
|
+
}
|
|
250
|
+
result.interleavedAttributes = {
|
|
251
|
+
...result.interleavedAttributes,
|
|
252
|
+
...interleavedAttributes,
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const { key: name, type, ...rest } = slot
|
|
259
|
+
|
|
260
|
+
// @ts-expect-error
|
|
261
|
+
result[`${type}s`][name] = rest
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
tag.slots.forEach(handleSlot)
|
|
265
|
+
|
|
266
|
+
return result
|
|
267
|
+
}
|
|
268
|
+
|
|
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) {
|
|
305
|
+
const v300 = !!initial?.startsWith('#version 300 es')
|
|
306
|
+
|
|
307
|
+
let template = initial ?? ''
|
|
308
|
+
|
|
309
|
+
for (let i = 0; i < rest.length; i++) {
|
|
310
|
+
template += `${glslSlotToString(slots[i]!, v300)}${rest[i]}`
|
|
200
311
|
}
|
|
312
|
+
|
|
313
|
+
return template
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function glslSlotToString(slot: GLSLSlot, v300: boolean): string {
|
|
317
|
+
if (typeof slot !== 'object') {
|
|
318
|
+
return toID(slot)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (Array.isArray(slot)) {
|
|
322
|
+
return slot.map(slot => glslSlotToString(slot, v300)).join('')
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (slot.type === 'glsl') {
|
|
326
|
+
return glslTagToString(slot)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (slot.type === 'interleavedAttribute') {
|
|
330
|
+
return slot.layout.reduce(
|
|
331
|
+
(a, v) =>
|
|
332
|
+
v300 ? `${a}in ${v.kind} ${toID(v.key)};\n` : `${a}attribute ${v.kind} ${toID(v.key)};\n`,
|
|
333
|
+
'',
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (slot.type === 'uniform' && 'size' in slot) {
|
|
338
|
+
return `${slot.type} ${slot.kind} ${toID(slot.key)}[${slot.size}];`
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return `${slot.type === 'attribute' && v300 ? 'in' : slot.type} ${slot.kind} ${toID(slot.key)};`
|
|
201
342
|
}
|
package/src/types.ts
CHANGED
|
@@ -18,6 +18,42 @@ export type RemoveSuffix<T, S extends string> = {
|
|
|
18
18
|
|
|
19
19
|
export type GL = WebGLRenderingContext | WebGL2RenderingContext
|
|
20
20
|
|
|
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
|
+
|
|
21
57
|
/**********************************************************************************/
|
|
22
58
|
/* */
|
|
23
59
|
/* Constants */
|
|
@@ -359,6 +395,7 @@ export interface UniformOptions {
|
|
|
359
395
|
}
|
|
360
396
|
|
|
361
397
|
export type UniformSchema = Record<string | symbol, UniformOptions>
|
|
398
|
+
export type UniformSchemaPartial = Record<string | symbol, Partial<UniformOptions>>
|
|
362
399
|
|
|
363
400
|
export type UniformMethods<TOptions extends UniformOptions> = TOptions['size'] extends number
|
|
364
401
|
? {
|
|
@@ -645,6 +682,13 @@ export interface ViewSchema {
|
|
|
645
682
|
buffers?: BufferSchema
|
|
646
683
|
}
|
|
647
684
|
|
|
685
|
+
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>>
|
|
690
|
+
}
|
|
691
|
+
|
|
648
692
|
export type View<T extends ViewSchema = ViewSchema> = {
|
|
649
693
|
attributes: T['attributes'] extends AttributeSchema ? AttributeView<T['attributes']> : undefined
|
|
650
694
|
interleavedAttributes: T['interleavedAttributes'] extends InterleavedAttributeSchema
|
|
@@ -660,11 +704,19 @@ export type View<T extends ViewSchema = ViewSchema> = {
|
|
|
660
704
|
/* */
|
|
661
705
|
/**********************************************************************************/
|
|
662
706
|
|
|
663
|
-
export interface
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
707
|
+
export interface GLSLResult {
|
|
708
|
+
program: WebGLProgram
|
|
709
|
+
schema: ViewSchema
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
type GLSLSlotItem = GLSLTag | UniformTag | AttributeTag | InterleaveTag | string | number | symbol
|
|
713
|
+
|
|
714
|
+
export type GLSLSlot = GLSLSlotItem | Array<GLSLSlotItem>
|
|
715
|
+
|
|
716
|
+
export interface GLSLTag<TSlots extends GLSLSlot[] = GLSLSlot[]> {
|
|
717
|
+
type: 'glsl'
|
|
718
|
+
template: TemplateStringsArray
|
|
719
|
+
slots: TSlots
|
|
668
720
|
}
|
|
669
721
|
|
|
670
722
|
export type UniformTag<
|
|
@@ -684,6 +736,14 @@ export type UniformTag<
|
|
|
684
736
|
key: TKey
|
|
685
737
|
}
|
|
686
738
|
|
|
739
|
+
export interface UniformTagFn<TKind extends UniformKind> {
|
|
740
|
+
<const TKey extends string | symbol, const TOptions extends Omit<UniformOptions, 'kind'>>(
|
|
741
|
+
key: TKey,
|
|
742
|
+
TOptions: TOptions,
|
|
743
|
+
): Prettify<UniformTag<TKey, TKind, TOptions>>
|
|
744
|
+
<const TName extends string | symbol>(key: TName): Prettify<UniformTag<TName, TKind>>
|
|
745
|
+
}
|
|
746
|
+
|
|
687
747
|
export interface AttributeTag<
|
|
688
748
|
TKey extends string | symbol = string | symbol,
|
|
689
749
|
TKind extends AttributeKind = AttributeKind,
|