glre 0.33.0 → 0.35.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/README.md +96 -98
- package/dist/index.cjs +29 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1813 -248
- package/dist/index.js +29 -31
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +29 -31
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.ts +15 -13
- package/dist/native.js +29 -31
- package/dist/native.js.map +1 -1
- package/dist/react.cjs +29 -31
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +29 -31
- package/dist/react.js.map +1 -1
- package/dist/solid.cjs +29 -31
- package/dist/solid.cjs.map +1 -1
- package/dist/solid.d.ts +1 -1
- package/dist/solid.js +29 -31
- package/dist/solid.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +10 -2
- package/src/node/code.ts +13 -9
- package/src/node/const.ts +57 -30
- package/src/node/index.ts +111 -98
- package/src/node/infer.ts +47 -64
- package/src/node/node.ts +19 -17
- package/src/node/parse.ts +38 -33
- package/src/node/scope.ts +25 -20
- package/src/node/types.ts +222 -98
- package/src/node/utils.ts +6 -6
- package/src/types.ts +13 -11
- package/src/utils/program.ts +10 -11
- package/src/webgl.ts +17 -8
- package/src/webgpu.ts +11 -7
package/src/node/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GL } from '../types'
|
|
2
|
+
|
|
2
3
|
import { CONSTANTS, CONVERSIONS, FUNCTIONS, OPERATOR_KEYS } from './const'
|
|
3
4
|
|
|
4
5
|
export type Constants = (typeof CONSTANTS)[number] | 'void'
|
|
@@ -47,17 +48,17 @@ export type NodeTypes =
|
|
|
47
48
|
| 'declare'
|
|
48
49
|
| 'return'
|
|
49
50
|
|
|
50
|
-
export interface NodeProps {
|
|
51
|
+
export interface NodeProps<T extends Record<string, NodeProxy> = {}> {
|
|
51
52
|
id?: string
|
|
52
|
-
args?:
|
|
53
|
+
args?: any[]
|
|
53
54
|
type?: string
|
|
54
|
-
children?:
|
|
55
|
-
inferFrom?:
|
|
55
|
+
children?: any[]
|
|
56
|
+
inferFrom?: any[]
|
|
56
57
|
layout?: FnLayout
|
|
57
58
|
parent?: NodeProxy
|
|
58
59
|
// for struct
|
|
59
|
-
fields?:
|
|
60
|
-
initialValues?:
|
|
60
|
+
fields?: T
|
|
61
|
+
initialValues?: T
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
export interface NodeContext {
|
|
@@ -78,7 +79,48 @@ export interface NodeContext {
|
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
|
-
*
|
|
82
|
+
* infer
|
|
83
|
+
*/
|
|
84
|
+
// Unified logic with infer.ts inferOperator function
|
|
85
|
+
// prettier-ignore
|
|
86
|
+
type InferOperator<L extends Constants, R extends Constants> =
|
|
87
|
+
L extends R ? L :
|
|
88
|
+
// broadcast
|
|
89
|
+
L extends 'float' | 'int' ? R :
|
|
90
|
+
R extends 'float' | 'int' ? L :
|
|
91
|
+
// mat * vec → vec
|
|
92
|
+
L extends 'mat4' ? R extends 'vec4' ? R /* default */ : L :
|
|
93
|
+
L extends 'mat3' ? R extends 'vec3' ? R /* default */ : L :
|
|
94
|
+
L extends 'mat2' ? R extends 'vec2' ? R /* default */ : L :
|
|
95
|
+
// vec * mat → vec
|
|
96
|
+
L extends 'vec4' ? R extends 'mat4' ? L /* default */ : L :
|
|
97
|
+
L extends 'vec3' ? R extends 'mat3' ? L /* default */ : L :
|
|
98
|
+
L extends 'vec2' ? R extends 'mat2' ? L /* default */ : L : L
|
|
99
|
+
|
|
100
|
+
type _StringLength<S extends string> = S extends `${infer _}${infer Rest}`
|
|
101
|
+
? Rest extends ''
|
|
102
|
+
? 1
|
|
103
|
+
: Rest extends `${infer _}${infer Rest2}`
|
|
104
|
+
? Rest2 extends ''
|
|
105
|
+
? 2
|
|
106
|
+
: Rest2 extends `${infer _}${infer Rest3}`
|
|
107
|
+
? Rest3 extends ''
|
|
108
|
+
? 3
|
|
109
|
+
: 4
|
|
110
|
+
: never
|
|
111
|
+
: never
|
|
112
|
+
: 0
|
|
113
|
+
|
|
114
|
+
type InferSwizzleType<S extends string> = _StringLength<S> extends 4
|
|
115
|
+
? 'vec4'
|
|
116
|
+
: _StringLength<S> extends 3
|
|
117
|
+
? 'vec3'
|
|
118
|
+
: _StringLength<S> extends 2
|
|
119
|
+
? 'vec2'
|
|
120
|
+
: 'float'
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Swizzles
|
|
82
124
|
*/
|
|
83
125
|
type _Swizzles<T extends string> = T | `${T}${T}` | `${T}${T}${T}` | `${T}${T}${T}${T}`
|
|
84
126
|
|
|
@@ -101,14 +143,10 @@ type NodeProxyMethods =
|
|
|
101
143
|
| 'toVar'
|
|
102
144
|
| 'toString'
|
|
103
145
|
|
|
104
|
-
export
|
|
105
|
-
[K in string as K extends NodeProxyMethods ? never : K]: X
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface BaseNodeProxy extends Record<Swizzles, NodeProxy> {
|
|
146
|
+
export interface BaseNodeProxy<T extends Constants> {
|
|
109
147
|
// System properties
|
|
110
|
-
assign(
|
|
111
|
-
toVar(name?: string): NodeProxy
|
|
148
|
+
assign(x: any): NodeProxy<T>
|
|
149
|
+
toVar(name?: string): NodeProxy<T>
|
|
112
150
|
toString(c?: NodeContext): string
|
|
113
151
|
type: NodeTypes
|
|
114
152
|
props: NodeProps
|
|
@@ -116,90 +154,176 @@ export interface BaseNodeProxy extends Record<Swizzles, NodeProxy> {
|
|
|
116
154
|
listeners: Set<(value: any) => void>
|
|
117
155
|
|
|
118
156
|
// Operators methods
|
|
119
|
-
add(
|
|
120
|
-
sub(
|
|
121
|
-
mul(
|
|
122
|
-
div(
|
|
123
|
-
mod(
|
|
124
|
-
equal(
|
|
125
|
-
notEqual(
|
|
126
|
-
lessThan(
|
|
127
|
-
lessThanEqual(
|
|
128
|
-
greaterThan(
|
|
129
|
-
greaterThanEqual(
|
|
130
|
-
and(
|
|
131
|
-
or(
|
|
132
|
-
not():
|
|
133
|
-
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
157
|
+
add<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
158
|
+
sub<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
159
|
+
mul<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
160
|
+
div<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
161
|
+
mod<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
162
|
+
equal<U extends Constants>(x: X<U>): Bool
|
|
163
|
+
notEqual<U extends Constants>(x: X<U>): Bool
|
|
164
|
+
lessThan<U extends Constants>(x: X<U>): Bool
|
|
165
|
+
lessThanEqual<U extends Constants>(x: X<U>): Bool
|
|
166
|
+
greaterThan<U extends Constants>(x: X<U>): Bool
|
|
167
|
+
greaterThanEqual<U extends Constants>(x: X<U>): Bool
|
|
168
|
+
and(x: X<'bool'>): Bool
|
|
169
|
+
or(x: X<'bool'>): Bool
|
|
170
|
+
not(): Bool
|
|
171
|
+
|
|
172
|
+
// Bitwise operators
|
|
173
|
+
bitAnd(x: X<T>): NodeProxy<T>
|
|
174
|
+
bitOr(x: X<T>): NodeProxy<T>
|
|
175
|
+
bitXor(x: X<T>): NodeProxy<T>
|
|
176
|
+
bitNot(): NodeProxy<T>
|
|
177
|
+
shiftLeft<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
178
|
+
shiftRight<U extends Constants>(x: X<U>): NodeProxy<InferOperator<T, U>>
|
|
179
|
+
|
|
180
|
+
// Conversion methods
|
|
181
|
+
toBool(): Bool
|
|
182
|
+
toUint(): UInt
|
|
183
|
+
toInt(): Int
|
|
184
|
+
toFloat(): Float
|
|
185
|
+
toBvec2(): BVec2
|
|
186
|
+
toIvec2(): IVec2
|
|
187
|
+
toUvec2(): UVec2
|
|
188
|
+
toVec2(): Vec2
|
|
189
|
+
toBvec3(): BVec3
|
|
190
|
+
toIvec3(): IVec3
|
|
191
|
+
toUvec3(): UVec3
|
|
192
|
+
toVec3(): Vec3
|
|
193
|
+
toBvec4(): BVec4
|
|
194
|
+
toIvec4(): IVec4
|
|
195
|
+
toUvec4(): UVec4
|
|
196
|
+
toVec4(): Vec4
|
|
197
|
+
toColor(): Color
|
|
198
|
+
toMat2(): Mat2
|
|
199
|
+
toMat3(): Mat3
|
|
200
|
+
toMat4(): Mat4
|
|
201
|
+
|
|
202
|
+
// Mathematical function methods (preserve type functions)
|
|
203
|
+
abs(): NodeProxy<T>
|
|
204
|
+
sign(): NodeProxy<T>
|
|
205
|
+
floor(): NodeProxy<T>
|
|
206
|
+
ceil(): NodeProxy<T>
|
|
207
|
+
round(): NodeProxy<T>
|
|
208
|
+
fract(): NodeProxy<T>
|
|
209
|
+
trunc(): NodeProxy<T>
|
|
210
|
+
sin(): NodeProxy<T>
|
|
211
|
+
cos(): NodeProxy<T>
|
|
212
|
+
tan(): NodeProxy<T>
|
|
213
|
+
asin(): NodeProxy<T>
|
|
214
|
+
acos(): NodeProxy<T>
|
|
215
|
+
atan(): NodeProxy<T>
|
|
216
|
+
exp(): NodeProxy<T>
|
|
217
|
+
exp2(): NodeProxy<T>
|
|
218
|
+
log(): NodeProxy<T>
|
|
219
|
+
log2(): NodeProxy<T>
|
|
220
|
+
sqrt(): NodeProxy<T>
|
|
221
|
+
inverseSqrt(): NodeProxy<T>
|
|
222
|
+
normalize(): NodeProxy<T>
|
|
223
|
+
oneMinus(): NodeProxy<T>
|
|
224
|
+
saturate(): NodeProxy<T>
|
|
225
|
+
negate(): NodeProxy<T>
|
|
226
|
+
reciprocal(): NodeProxy<T>
|
|
227
|
+
dFdx(): NodeProxy<T>
|
|
228
|
+
dFdy(): NodeProxy<T>
|
|
229
|
+
fwidth(): NodeProxy<T>
|
|
230
|
+
|
|
231
|
+
// Scalar return functions
|
|
232
|
+
length(): Float
|
|
233
|
+
lengthSq(): Float
|
|
234
|
+
determinant(): Float
|
|
235
|
+
luminance(): Float
|
|
236
|
+
|
|
237
|
+
// Bool return functions
|
|
238
|
+
all(): Bool
|
|
239
|
+
any(): Bool
|
|
240
|
+
|
|
241
|
+
// Specific return type functions
|
|
242
|
+
cross<U extends Constants>(y: X<U>): Vec3
|
|
243
|
+
|
|
244
|
+
// Two argument functions with variable return types
|
|
245
|
+
atan2<U extends Constants>(x: X<U>): NodeProxy<T>
|
|
246
|
+
pow<U extends Constants>(y: X<U>): NodeProxy<T>
|
|
247
|
+
distance<U extends Constants>(y: X<U>): Float
|
|
248
|
+
dot<U extends Constants>(y: X<U>): Float
|
|
249
|
+
reflect<U extends Constants>(N: X<U>): NodeProxy<T>
|
|
250
|
+
refract<U extends Constants>(N: X<U>, eta: any): NodeProxy<T>
|
|
251
|
+
|
|
252
|
+
// Multi-argument functions that return highest priority type
|
|
253
|
+
min<U extends Constants>(y: X<U>): NodeProxy<InferOperator<T, U>>
|
|
254
|
+
max<U extends Constants>(y: X<U>): NodeProxy<InferOperator<T, U>>
|
|
255
|
+
mix<U extends Constants, V>(y: X<U>, a: V): NodeProxy<InferOperator<T, U>>
|
|
256
|
+
clamp<U extends Constants, V>(mix: X<U>, max: V): NodeProxy<InferOperator<T, U>>
|
|
257
|
+
step<U extends Constants>(edge: X<U>): NodeProxy<InferOperator<T, U>>
|
|
258
|
+
smoothstep<U extends Constants, V>(edge0: X<U>, edge1: V): NodeProxy<InferOperator<T, U>>
|
|
259
|
+
|
|
260
|
+
// Power functions
|
|
261
|
+
pow2(): NodeProxy<T>
|
|
262
|
+
pow3(): NodeProxy<T>
|
|
263
|
+
pow4(): NodeProxy<T>
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
type ReadNodeProxy = {
|
|
267
|
+
[K in string as K extends NodeProxyMethods ? never : K]: any
|
|
268
|
+
} & {
|
|
269
|
+
[K in Swizzles]: NodeProxy<InferSwizzleType<K>>
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Internal NodeProxy implementation (renamed from original)
|
|
273
|
+
type NodeProxyImpl<T extends Constants = string> = BaseNodeProxy<T> & ReadNodeProxy
|
|
274
|
+
|
|
275
|
+
export type Bool = NodeProxyImpl<'bool'>
|
|
276
|
+
export type UInt = NodeProxyImpl<'uint'>
|
|
277
|
+
export type Int = NodeProxyImpl<'int'>
|
|
278
|
+
export type Float = NodeProxyImpl<'float'>
|
|
279
|
+
export type BVec2 = NodeProxyImpl<'bvec2'>
|
|
280
|
+
export type IVec2 = NodeProxyImpl<'ivec2'>
|
|
281
|
+
export type UVec2 = NodeProxyImpl<'uvec2'>
|
|
282
|
+
export type Vec2 = NodeProxyImpl<'vec2'>
|
|
283
|
+
export type BVec3 = NodeProxyImpl<'bvec3'>
|
|
284
|
+
export type IVec3 = NodeProxyImpl<'ivec3'>
|
|
285
|
+
export type UVec3 = NodeProxyImpl<'uvec3'>
|
|
286
|
+
export type Vec3 = NodeProxyImpl<'vec3'>
|
|
287
|
+
export type BVec4 = NodeProxyImpl<'bvec4'>
|
|
288
|
+
export type IVec4 = NodeProxyImpl<'ivec4'>
|
|
289
|
+
export type UVec4 = NodeProxyImpl<'uvec4'>
|
|
290
|
+
export type Vec4 = NodeProxyImpl<'vec4'>
|
|
291
|
+
export type Color = NodeProxyImpl<'color'>
|
|
292
|
+
export type Mat2 = NodeProxyImpl<'mat2'>
|
|
293
|
+
export type Mat3 = NodeProxyImpl<'mat3'>
|
|
294
|
+
export type Mat4 = NodeProxyImpl<'mat4'>
|
|
295
|
+
export type Texture = NodeProxyImpl<'texture'>
|
|
296
|
+
export type Sampler2D = NodeProxyImpl<'sampler2D'>
|
|
297
|
+
export type Struct = NodeProxyImpl<'struct'>
|
|
298
|
+
|
|
299
|
+
export interface ConstantsToType {
|
|
300
|
+
bool: Bool
|
|
301
|
+
uint: UInt
|
|
302
|
+
int: Int
|
|
303
|
+
float: Float
|
|
304
|
+
bvec2: BVec2
|
|
305
|
+
ivec2: IVec2
|
|
306
|
+
uvec2: UVec2
|
|
307
|
+
vec2: Vec2
|
|
308
|
+
bvec3: BVec3
|
|
309
|
+
ivec3: IVec3
|
|
310
|
+
uvec3: UVec3
|
|
311
|
+
vec3: Vec3
|
|
312
|
+
bvec4: BVec4
|
|
313
|
+
ivec4: IVec4
|
|
314
|
+
uvec4: UVec4
|
|
315
|
+
vec4: Vec4
|
|
316
|
+
color: Color
|
|
317
|
+
mat2: Mat2
|
|
318
|
+
mat3: Mat3
|
|
319
|
+
mat4: Mat4
|
|
320
|
+
texture: Texture
|
|
321
|
+
sampler2D: Sampler2D
|
|
322
|
+
struct: Struct
|
|
201
323
|
}
|
|
202
324
|
|
|
203
|
-
export type NodeProxy =
|
|
325
|
+
export type NodeProxy<T extends Constants = string> = T extends keyof ConstantsToType
|
|
326
|
+
? ConstantsToType[T]
|
|
327
|
+
: NodeProxyImpl<T>
|
|
204
328
|
|
|
205
|
-
export type X
|
|
329
|
+
export type X<T extends Constants = string> = number | string | boolean | undefined | NodeProxy<T> | X[]
|
package/src/node/utils.ts
CHANGED
|
@@ -26,7 +26,7 @@ export const isConversion = (key: unknown): key is Conversions => {
|
|
|
26
26
|
return CONVERSIONS.includes(key as Conversions)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export const isNodeProxy = (x: unknown): x is NodeProxy => {
|
|
29
|
+
export const isNodeProxy = <T extends Constants>(x: unknown): x is NodeProxy<T> => {
|
|
30
30
|
if (!x) return false
|
|
31
31
|
if (typeof x !== 'object') return false // @ts-ignore
|
|
32
32
|
return x.isProxy
|
|
@@ -46,15 +46,15 @@ export const hex2rgb = (hex: number) => {
|
|
|
46
46
|
|
|
47
47
|
let count = 0
|
|
48
48
|
|
|
49
|
-
export const getId = () => `
|
|
49
|
+
export const getId = () => `x${count++}`
|
|
50
50
|
|
|
51
|
-
export const formatConversions = (x: X
|
|
51
|
+
export const formatConversions = <T extends Constants>(x: X<T>, c?: NodeContext) => {
|
|
52
52
|
if (!is.str(x)) return ''
|
|
53
53
|
if (c?.isWebGL) return x
|
|
54
54
|
return TYPE_MAPPING[x as keyof typeof TYPE_MAPPING] || x // for struct type
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
export const getOperator = (op: X) => {
|
|
57
|
+
export const getOperator = (op: X<string>) => {
|
|
58
58
|
return OPERATORS[op as keyof typeof OPERATORS] || op
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -78,8 +78,8 @@ export const getEventFun = (c: NodeContext, id: string, isAttribute = false, isT
|
|
|
78
78
|
return (value: any) => c.gl?._uniform?.(id, value)
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
export const safeEventCall = (x: X
|
|
82
|
-
if (
|
|
81
|
+
export const safeEventCall = <T extends Constants>(x: X<T>, fun: (value: unknown) => void) => {
|
|
82
|
+
if (is.und(x)) return
|
|
83
83
|
if (!isNodeProxy(x)) return fun(x) // for uniform(1)
|
|
84
84
|
if (x.type !== 'conversion') return
|
|
85
85
|
const value = x.props.children?.slice(1).filter(Boolean)
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EventState, Nested } from 'reev'
|
|
2
2
|
import type { Fun, Queue, Frame } from 'refr'
|
|
3
|
-
import type { NodeProxy } from './node'
|
|
3
|
+
import type { NodeProxy, Vec4 } from './node'
|
|
4
4
|
export type { Fun, Queue, Frame }
|
|
5
5
|
export type PrecisionMode = 'highp' | 'mediump' | 'lowp'
|
|
6
6
|
export type GLClearMode = 'COLOR_BUFFER_BIT' | 'DEPTH_BUFFER_BIT' | 'STENCIL_BUFFER_BIT'
|
|
@@ -59,20 +59,22 @@ export type GL = EventState<{
|
|
|
59
59
|
*/
|
|
60
60
|
isNative: boolean
|
|
61
61
|
isWebGL: boolean
|
|
62
|
+
isError: boolean
|
|
62
63
|
isLoop: boolean
|
|
63
64
|
isGL: true
|
|
64
|
-
width
|
|
65
|
-
height
|
|
65
|
+
width?: number
|
|
66
|
+
height?: number
|
|
66
67
|
size: [number, number]
|
|
67
68
|
mouse: [number, number]
|
|
68
69
|
count: number
|
|
70
|
+
loading: number
|
|
69
71
|
el: HTMLCanvasElement
|
|
70
|
-
vs
|
|
71
|
-
fs
|
|
72
|
-
vert
|
|
73
|
-
frag
|
|
74
|
-
vertex
|
|
75
|
-
fragment
|
|
72
|
+
vs?: string | Vec4
|
|
73
|
+
fs?: string | Vec4
|
|
74
|
+
vert?: string | Vec4
|
|
75
|
+
frag?: string | Vec4
|
|
76
|
+
vertex?: string | Vec4
|
|
77
|
+
fragment?: string | Vec4
|
|
76
78
|
|
|
77
79
|
/**
|
|
78
80
|
* core state
|
|
@@ -86,13 +88,13 @@ export type GL = EventState<{
|
|
|
86
88
|
* events
|
|
87
89
|
*/
|
|
88
90
|
ref?: any
|
|
89
|
-
init(): void
|
|
90
|
-
loop(): void
|
|
91
91
|
mount(): void
|
|
92
92
|
clean(): void
|
|
93
|
+
error(e?: string): void
|
|
93
94
|
render(): void
|
|
94
95
|
resize(e?: Event): void
|
|
95
96
|
mousemove(e: Event): void
|
|
97
|
+
loop(): void
|
|
96
98
|
|
|
97
99
|
/**
|
|
98
100
|
* setter
|
package/src/utils/program.ts
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
const createShader = (c: WebGLRenderingContext, source: string, type: number) => {
|
|
1
|
+
const createShader = (c: WebGLRenderingContext, source: string, type: number, onError = console.warn) => {
|
|
2
2
|
const shader = c.createShader(type)
|
|
3
|
-
if (!shader)
|
|
3
|
+
if (!shader) return onError('Failed to create shader')
|
|
4
4
|
c.shaderSource(shader, source.trim())
|
|
5
5
|
c.compileShader(shader)
|
|
6
6
|
if (c.getShaderParameter(shader, c.COMPILE_STATUS)) return shader
|
|
7
7
|
const error = c.getShaderInfoLog(shader)
|
|
8
8
|
c.deleteShader(shader)
|
|
9
|
-
|
|
9
|
+
onError(`Could not compile shader: ${error}`)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export const createProgram = (c: WebGLRenderingContext, vert: string, frag: string, onError =
|
|
12
|
+
export const createProgram = (c: WebGLRenderingContext, vert: string, frag: string, onError = console.warn) => {
|
|
13
13
|
const pg = c.createProgram()
|
|
14
|
-
const fs = createShader(c, frag, c.FRAGMENT_SHADER)
|
|
15
|
-
const vs = createShader(c, vert, c.VERTEX_SHADER)
|
|
16
|
-
if (!fs || !vs) return
|
|
17
|
-
c.attachShader(pg, vs)
|
|
18
|
-
c.attachShader(pg, fs)
|
|
14
|
+
const fs = createShader(c, frag, c.FRAGMENT_SHADER, onError)
|
|
15
|
+
const vs = createShader(c, vert, c.VERTEX_SHADER, onError)
|
|
16
|
+
if (!fs || !vs) return
|
|
17
|
+
c.attachShader(pg, vs!)
|
|
18
|
+
c.attachShader(pg, fs!)
|
|
19
19
|
c.linkProgram(pg)
|
|
20
20
|
if (c.getProgramParameter(pg, c.LINK_STATUS)) return pg
|
|
21
21
|
const error = c.getProgramInfoLog(pg)
|
|
22
22
|
c.deleteProgram(pg)
|
|
23
|
-
onError()
|
|
24
|
-
console.warn(`Could not link program: ${error}`)
|
|
23
|
+
onError(`Could not link program: ${error}`)
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export const createVbo = (c: WebGLRenderingContext, data: number[]) => {
|
package/src/webgl.ts
CHANGED
|
@@ -4,24 +4,29 @@ import { is } from './utils/helpers'
|
|
|
4
4
|
import { createAttrib, createIbo, createProgram, createTexture, createVbo, getStride } from './utils/program'
|
|
5
5
|
import type { GL, WebGLState } from './types'
|
|
6
6
|
|
|
7
|
-
export const webgl = async (gl:
|
|
7
|
+
export const webgl = async (gl: GL) => {
|
|
8
8
|
const c = gl.el!.getContext('webgl2')!
|
|
9
9
|
const config = { isWebGL: true, gl }
|
|
10
10
|
const fs = fragment(gl.fs, config)
|
|
11
11
|
const vs = vertex(gl.vs, config)
|
|
12
|
-
const pg = createProgram(c, vs, fs,
|
|
12
|
+
const pg = createProgram(c, vs, fs, gl.error)!
|
|
13
13
|
c.useProgram(pg)
|
|
14
14
|
|
|
15
|
-
let
|
|
15
|
+
let activeUnit = 0
|
|
16
16
|
const uniforms = cached((key) => c.getUniformLocation(pg, key))
|
|
17
17
|
const attribs = cached((key) => c.getAttribLocation(pg, key))
|
|
18
|
-
const units = cached(() =>
|
|
18
|
+
const units = cached(() => activeUnit++)
|
|
19
19
|
|
|
20
|
-
const clean = () =>
|
|
20
|
+
const clean = () => {
|
|
21
|
+
c.deleteProgram(pg)
|
|
22
|
+
c.getExtension('WEBGL_lose_context')?.loseContext()
|
|
23
|
+
gl.el.width = 1
|
|
24
|
+
gl.el.height = 1
|
|
25
|
+
}
|
|
21
26
|
|
|
22
27
|
const render = () => {
|
|
23
28
|
c.clear(c.COLOR_BUFFER_BIT)
|
|
24
|
-
c.viewport(0, 0, ...gl.size
|
|
29
|
+
c.viewport(0, 0, ...gl.size)
|
|
25
30
|
c.drawArrays(c.TRIANGLES, 0, 3)
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -29,7 +34,7 @@ export const webgl = async (gl: Partial<GL>) => {
|
|
|
29
34
|
const loc = attribs(key, true)
|
|
30
35
|
const vbo = createVbo(c, value)
|
|
31
36
|
const ibo = createIbo(c, iboValue)
|
|
32
|
-
const str = getStride(gl.count
|
|
37
|
+
const str = getStride(gl.count, value, iboValue)
|
|
33
38
|
createAttrib(c, str, loc, vbo, ibo)
|
|
34
39
|
}
|
|
35
40
|
|
|
@@ -43,14 +48,18 @@ export const webgl = async (gl: Partial<GL>) => {
|
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
const _texture = (key: string, src: string) => {
|
|
51
|
+
gl.loading++
|
|
46
52
|
const image = new Image()
|
|
47
53
|
Object.assign(image, { src, crossOrigin: 'anonymous' })
|
|
48
54
|
image.decode().then(() => {
|
|
49
55
|
const loc = uniforms(key)
|
|
50
56
|
const unit = units(key)
|
|
51
57
|
createTexture(c, image, loc, unit)
|
|
58
|
+
gl.loading--
|
|
52
59
|
})
|
|
53
60
|
}
|
|
54
61
|
|
|
55
|
-
|
|
62
|
+
const webgl: WebGLState = { context: c, program: pg }
|
|
63
|
+
|
|
64
|
+
return { webgl, render, clean, _attribute, _uniform, _texture }
|
|
56
65
|
}
|
package/src/webgpu.ts
CHANGED
|
@@ -15,14 +15,14 @@ import {
|
|
|
15
15
|
import type { GL, WebGPUState } from './types'
|
|
16
16
|
import { fragment, vertex } from './node'
|
|
17
17
|
|
|
18
|
-
export const webgpu = async (gl:
|
|
18
|
+
export const webgpu = async (gl: GL) => {
|
|
19
19
|
const context = gl.el!.getContext('webgpu') as GPUCanvasContext
|
|
20
20
|
const { device, format } = await createDevice(context)
|
|
21
|
+
device.onuncapturederror = (e) => gl.error(e.error.message)
|
|
21
22
|
const bindings = createBindings()
|
|
22
23
|
let frag: string
|
|
23
24
|
let vert: string
|
|
24
25
|
let flush = (_pass: GPURenderPassEncoder) => {}
|
|
25
|
-
let imageLoading = 0
|
|
26
26
|
let needsUpdate = true
|
|
27
27
|
let depthTexture: GPUTexture
|
|
28
28
|
|
|
@@ -42,7 +42,7 @@ export const webgpu = async (gl: Partial<GL>) => {
|
|
|
42
42
|
|
|
43
43
|
const attribs = cached((_key, value: number[]) => {
|
|
44
44
|
needsUpdate = true
|
|
45
|
-
const stride = value.length / gl.count
|
|
45
|
+
const stride = value.length / gl.count
|
|
46
46
|
const { location } = bindings.attrib()
|
|
47
47
|
const { array, buffer } = createAttribBuffer(device, value)
|
|
48
48
|
return { array, buffer, location, stride }
|
|
@@ -60,7 +60,7 @@ export const webgpu = async (gl: Partial<GL>) => {
|
|
|
60
60
|
pass.setPipeline(pipeline)
|
|
61
61
|
bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
|
|
62
62
|
vertexBuffers.forEach((v, i) => pass.setVertexBuffer(i, v))
|
|
63
|
-
pass.draw(gl.count
|
|
63
|
+
pass.draw(gl.count, 1, 0, 0)
|
|
64
64
|
pass.end()
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -71,7 +71,7 @@ export const webgpu = async (gl: Partial<GL>) => {
|
|
|
71
71
|
frag = fragment(gl.fs, config)
|
|
72
72
|
vert = vertex(gl.vs, config)
|
|
73
73
|
}
|
|
74
|
-
if (
|
|
74
|
+
if (gl.loading) return // MEMO: loading after build node
|
|
75
75
|
if (needsUpdate) update()
|
|
76
76
|
needsUpdate = false
|
|
77
77
|
const encoder = device.createCommandEncoder()
|
|
@@ -86,7 +86,11 @@ export const webgpu = async (gl: Partial<GL>) => {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
const clean = () => {
|
|
89
|
+
device.destroy()
|
|
89
90
|
depthTexture?.destroy()
|
|
91
|
+
for (const { texture } of textures.map.values()) texture.destroy()
|
|
92
|
+
for (const { buffer } of uniforms.map.values()) buffer.destroy()
|
|
93
|
+
for (const { buffer } of attribs.map.values()) buffer.destroy()
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
const _attribute = (key = '', value: number[]) => {
|
|
@@ -103,13 +107,13 @@ export const webgpu = async (gl: Partial<GL>) => {
|
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
const _texture = (key: string, src: string) => {
|
|
106
|
-
|
|
110
|
+
gl.loading++
|
|
107
111
|
const source = Object.assign(new Image(), { src, crossOrigin: 'anonymous' })
|
|
108
112
|
source.decode().then(() => {
|
|
109
113
|
const { width, height } = source
|
|
110
114
|
const { texture } = textures(key, width, height)
|
|
111
115
|
device.queue.copyExternalImageToTexture({ source }, { texture }, { width, height })
|
|
112
|
-
|
|
116
|
+
gl.loading--
|
|
113
117
|
})
|
|
114
118
|
}
|
|
115
119
|
|