glre 0.28.0 → 0.30.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/node/node.ts CHANGED
@@ -1,51 +1,52 @@
1
1
  import { code } from './code'
2
- import { assign, toVar, toConst } from './scope'
3
- import { getId, isConversion, isFunction, isOperator, isSwizzle } from './utils'
2
+ import { assign, toVar } from './scope'
3
+ import { conversionToConstant, isConversion, isFunction, isOperator, isSwizzle } from './utils'
4
4
  import type { Functions, NodeProps, NodeProxy, NodeTypes, Operators, Swizzles, X } from './types'
5
5
 
6
- const toPrimitive = (x: X) => {
7
- return (hint: string) => {
8
- if (hint === 'string') return code(x)
9
- }
6
+ const toPrimitive = (x: X, hint: string) => {
7
+ if (hint === 'string') return code(x)
10
8
  }
11
9
 
12
10
  export const node = (type: NodeTypes, props?: NodeProps | null, ...args: X[]) => {
13
11
  if (!props) props = {}
14
12
  if (args.length) props.children = args
15
- const x = new Proxy(() => {}, {
16
- get(_, key) {
17
- if (key === 'type') return type
18
- if (key === 'props') return props
19
- if (key === 'toVar') return toVar(x)
20
- if (key === 'toConst') return toConst(x)
21
- if (key === 'assign') return assign(x)
22
- if (key === 'isProxy') return true
23
- if (key === 'toString') return code.bind(null, x)
24
- if (key === Symbol.toPrimitive) return toPrimitive(x)
25
- if (isSwizzle(key)) return s(key, x)
26
- if (isOperator(key)) return (...y: X[]) => o(key, x, ...y)
27
- if (isFunction(key)) return (...y: X[]) => f(key, x, ...y)
28
- if (isConversion(key)) return n(key, x)
29
- },
30
- set(_, key, value) {
31
- if (isSwizzle(key)) {
32
- s(key, x).assign(value)
33
- return true
34
- }
35
- return false
36
- },
37
- }) as unknown as NodeProxy
13
+ const get = (_: unknown, key: string | Symbol) => {
14
+ if (key === 'type') return type
15
+ if (key === 'props') return props
16
+ if (key === 'toVar') return toVar.bind(null, x)
17
+ if (key === 'assign') return assign.bind(null, x)
18
+ if (key === 'isProxy') return true
19
+ if (key === 'toString') return code.bind(null, x)
20
+ if (key === Symbol.toPrimitive) return toPrimitive.bind(null, x)
21
+ if (isSwizzle(key)) return swizzle(key, x)
22
+ if (isOperator(key)) return (...y: X[]) => operator(key, x, ...y)
23
+ if (isFunction(key)) return (...y: X[]) => function_(key, x, ...y)
24
+ if (isConversion(key)) return () => conversion(conversionToConstant(key), x)
25
+ }
26
+ const set = (_: unknown, key: string, y: X) => {
27
+ if (isSwizzle(key)) {
28
+ swizzle(key, x).assign(y)
29
+ return true
30
+ }
31
+ return false
32
+ }
33
+ const x = new Proxy({}, { get, set }) as unknown as NodeProxy
38
34
  return x
39
35
  }
40
36
 
41
- // Node shorthands
42
- export const v = (...args: X[]) => node('variable', { id: getId() }, ...args)
43
- export const s = (key: Swizzles, arg: X) => node('swizzle', null, key, arg)
44
- export const n = (key: string, ...args: X[]) => node('conversions', null, key, ...args)
45
- export const o = (key: Operators, ...args: X[]) => node('operator', null, key, ...args)
46
- export const f = (key: Functions, ...args: X[]) => node('math_fun', null, key, ...args)
37
+ // headers
38
+ export const attribute = (x: X, id?: string) => node('varying', { id }, x)
39
+ export const uniform = (x: X, id?: string) => node('uniform', { id }, x)
40
+ export const varying = (x: X, id?: string) => node('varying', { id }, x)
41
+ export const constant = (x: X, id?: string) => node('constant', { id }, x)
42
+ export const variable = (id: string) => node('variable', { id })
43
+ export const builtin = (id: string) => node('builtin', { id })
47
44
 
48
- // uniform and attribute
49
- export const u = (id: string, value?: number | number[] | boolean) => node('uniform', { id, value })
45
+ // Node shorthands
46
+ export const swizzle = (key: Swizzles, arg: X) => node('swizzle', null, key, arg)
47
+ export const operator = (key: Operators, ...args: X[]) => node('operator', null, key, ...args)
48
+ export const function_ = (key: Functions, ...args: X[]) => node('function', null, key, ...args)
49
+ export const conversion = (key: string, ...args: X[]) => node('conversion', null, key, ...args)
50
50
 
51
+ // x ? y : z
51
52
  export const select = (x: X, y: X, z: X) => node('ternary', null, x, y, z)
package/src/node/scope.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { infer } from './infer'
2
- import { node } from './node'
1
+ import { int } from '.'
2
+ import { conversion, node } from './node'
3
3
  import { getId } from './utils'
4
- import type { NodeProxy, X } from './types'
4
+ import type { FnLayout, NodeProps, NodeProxy, X } from './types'
5
5
 
6
6
  let _scope: NodeProxy | null = null
7
7
 
8
- const scoped = (x: NodeProxy | null, callback = () => {}) => {
8
+ const scoped = (x: NodeProxy | null, fun = () => {}) => {
9
9
  const prev = _scope
10
10
  _scope = x
11
- callback()
11
+ fun()
12
12
  _scope = prev
13
13
  }
14
14
 
@@ -18,104 +18,94 @@ const addToScope = (x: NodeProxy) => {
18
18
  _scope.props.children.push(x)
19
19
  }
20
20
 
21
- export const If = (condition: X, callback: () => void) => {
22
- const scope = node('scope')
23
- scoped(scope, callback)
24
- const ifNode = node('if', null, condition, scope)
21
+ export const toVar = (x: X, id?: string) => {
22
+ if (!id) id = getId()
23
+ const y = node('variable', { id, inferFrom: x })
24
+ const z = node('declare', null, x, y)
25
+ addToScope(z)
26
+ return y
27
+ }
28
+
29
+ export const assign = (x: X, y: X) => {
30
+ const z = node('assign', null, x, y)
31
+ addToScope(z)
32
+ return x
33
+ }
34
+
35
+ export const If = (x: X, fun: () => void) => {
36
+ const y = node('scope')
37
+ scoped(y, fun)
38
+ const ifNode = node('if', null, x, y)
25
39
  addToScope(ifNode)
26
- const createChain = () => ({
27
- ElseIf: (newCondition: X, elseIfCallback: () => void) => {
28
- const elseIfScope = node('scope')
29
- scoped(elseIfScope, elseIfCallback)
30
- ifNode.props.children!.push(newCondition, elseIfScope)
31
- return createChain()
40
+ const ret = () => ({
41
+ ElseIf: (_x: X, _fun: () => void) => {
42
+ const _y = node('scope')
43
+ scoped(_y, _fun)
44
+ ifNode.props.children!.push(_x, _y)
45
+ return ret()
32
46
  },
33
- Else: (elseCallback: () => void) => {
34
- const elseScope = node('scope')
35
- scoped(elseScope, elseCallback)
36
- ifNode.props.children!.push(elseScope)
47
+ Else: (_fun: () => void) => {
48
+ const _x = node('scope')
49
+ scoped(_x, _fun)
50
+ ifNode.props.children!.push(_x)
37
51
  },
38
52
  })
39
- return createChain()
53
+ return ret()
40
54
  }
41
55
 
42
- export const Loop = (x: X, callback?: (params: { i: NodeProxy }) => void) => {
56
+ export const Loop = (x: X, fun: (params: { i: NodeProxy }) => void) => {
43
57
  const y = node('scope')
44
- scoped(y, () => callback?.({ i: node('variable', { id: 'i' }) }))
58
+ scoped(y, () => fun({ i: node('variable', { id: 'i', inferFrom: int(0) }) }))
45
59
  const ret = node('loop', null, x, y)
46
60
  addToScope(ret)
47
61
  return ret
48
62
  }
49
63
 
50
- export const Switch = (value: X) => {
51
- const switchNode = node('switch', null, value)
64
+ export const Switch = (x: X) => {
65
+ const switchNode = node('switch', null, x)
52
66
  addToScope(switchNode)
53
- const createChain = () => ({
67
+ const ret = () => ({
54
68
  Case: (...values: X[]) => {
55
- return (callback: () => void) => {
56
- const caseScope = node('scope')
57
- scoped(caseScope, callback)
58
- const caseNode = node('case', null, ...values, caseScope)
59
- switchNode.props.children!.push(caseNode)
60
- return createChain()
69
+ return (fun: () => void) => {
70
+ const y = node('scope')
71
+ scoped(y, fun)
72
+ for (const _x of values) switchNode.props.children!.push(_x, y)
73
+ return ret()
61
74
  }
62
75
  },
63
- Default: (callback: () => void) => {
64
- const defaultScope = node('scope')
65
- scoped(defaultScope, callback)
66
- const defaultNode = node('default', null, defaultScope)
67
- switchNode.props.children!.push(defaultNode)
76
+ Default: (fun: () => void) => {
77
+ const scope = node('scope')
78
+ scoped(scope, fun)
79
+ switchNode.props.children!.push(scope)
68
80
  },
69
81
  })
70
82
 
71
- return createChain()
83
+ return ret()
72
84
  }
73
85
 
74
- export const Fn = (callback: (args: NodeProxy[]) => NodeProxy) => {
75
- const id = getId()
76
- return (...args: NodeProxy[]) => {
86
+ export const Fn = (fun: (paramVars: NodeProxy[]) => NodeProxy) => {
87
+ let layout: FnLayout
88
+ const ret = (...args: X[]) => {
89
+ const id = layout?.name || getId()
77
90
  const x = node('scope')
78
91
  let y: NodeProxy | undefined
79
92
  const paramVars: NodeProxy[] = []
80
- for (let i = 0; i < args.length; i++) {
81
- const paramId = `p${i}`
82
- const paramVar = node('variable', { id: paramId })
83
- paramVars.push(paramVar)
84
- }
85
- scoped(x, () => (y = callback(paramVars)))
86
- const returnType = y ? infer(y) : 'void'
87
- const paramInfo = args.map((arg, i) => ({ name: `p${i}`, type: infer(arg) }))
88
- const def = node('fn_def', { id, returnType, paramInfo, args }, x, y)
89
- return node('fn_run', { id, returnType }, def, ...paramVars)
93
+ const paramDefs: NodeProps[] = []
94
+ if (layout?.inputs)
95
+ for (const input of layout.inputs) {
96
+ paramDefs.push({ id: input.name, inferFrom: conversion(input.type) })
97
+ }
98
+ else
99
+ for (let i = 0; i < args.length; i++) {
100
+ paramDefs.push({ id: `p${i}`, inferFrom: args[i] })
101
+ }
102
+ for (const props of paramDefs) paramVars.push(node('variable', props))
103
+ scoped(x, () => (y = fun(paramVars)))
104
+ return node('define', { id, layout }, x, y, ...args)
90
105
  }
91
- }
92
-
93
- export const toVar = (x: X) => (id?: string) => {
94
- if (!id) id = getId()
95
- const y = node('variable', { id })
96
- const z = node('declare', null, y, x)
97
- addToScope(z)
98
- return y
99
- }
100
-
101
- export const toConst = (x: X) => (id?: string) => {
102
- if (!id) id = getId()
103
- const y = node('constant', { id })
104
- const z = node('declare', null, y, x)
105
- addToScope(z)
106
- return y
107
- }
108
-
109
- export const assign = (x: X) => (y: X) => {
110
- const assignNode = node('assign', null, x, y)
111
- addToScope(assignNode)
112
- return x
113
- }
114
-
115
- export const varying = (value: X, name?: string) => {
116
- if (!name) name = getId()
117
- const varyingVar = node('varying', { id: name })
118
- const declaration = node('declare', null, varyingVar, value)
119
- addToScope(declaration)
120
- return varyingVar
106
+ ret.setLayout = (newLayout: FnLayout) => {
107
+ layout = newLayout
108
+ return ret
109
+ }
110
+ return ret
121
111
  }
package/src/node/types.ts CHANGED
@@ -8,21 +8,30 @@ export type Functions = (typeof FUNCTIONS)[number]
8
8
 
9
9
  export type Operators = (typeof OPERATOR_KEYS)[number]
10
10
 
11
+ export interface FnLayout {
12
+ name: string
13
+ type: Constants | 'auto'
14
+ inputs?: Array<{
15
+ name: string
16
+ type: Constants
17
+ }>
18
+ }
19
+
11
20
  export interface NodeProps {
12
21
  id?: string
13
22
  args?: X[]
14
23
  type?: string
15
24
  children?: X[]
16
- returnType?: Constants
17
- value?: number | number[] | boolean
18
- paramInfo?: Array<{ name: string; type: string }>
25
+ inferFrom?: X
26
+ layout?: FnLayout
19
27
  }
20
28
 
21
29
  export interface NodeConfig {
22
30
  isWebGL?: boolean
23
- uniforms?: Set<string>
24
- functions?: Set<string>
25
- onUniform?: (name: string, value: any) => void
31
+ binding?: number
32
+ infers?: WeakMap<NodeProxy, Constants>
33
+ headers?: Map<string, string>
34
+ onMount?: (name: string) => void
26
35
  }
27
36
 
28
37
  type _Swizzles<T extends string> = T | `${T}${T}` | `${T}${T}${T}` | `${T}${T}${T}${T}`
@@ -34,30 +43,29 @@ export type Swizzles =
34
43
  | _Swizzles<'s' | 't'>
35
44
 
36
45
  export type NodeTypes =
46
+ // headers
47
+ | 'attribute'
37
48
  | 'uniform'
49
+ | 'varying'
50
+ | 'constant'
51
+ // variables
38
52
  | 'variable'
39
53
  | 'swizzle'
54
+ | 'ternary'
55
+ | 'builtin'
56
+ | 'conversion'
40
57
  | 'operator'
41
- | 'conversions'
42
- | 'math_fun'
43
- | 'declare'
58
+ | 'function'
59
+ // scopes
60
+ | 'scope'
44
61
  | 'assign'
45
- | 'fn_def'
46
- | 'fn_run'
47
- | 'if'
48
62
  | 'loop'
49
- | 'scope'
63
+ | 'define'
64
+ | 'if'
50
65
  | 'switch'
51
- | 'case'
52
- | 'default'
53
- | 'ternary'
54
- | 'attribute'
55
- | 'varying'
56
- | 'builtin'
57
- | 'constant'
58
- | 'vertex_stage'
66
+ | 'declare'
59
67
 
60
- export interface NodeProxy extends Record<Swizzles | Conversions, NodeProxy> {
68
+ export interface NodeProxy extends Record<Swizzles, NodeProxy> {
61
69
  // Operators
62
70
  add(n: X): NodeProxy
63
71
  sub(n: X): NodeProxy
@@ -77,7 +85,6 @@ export interface NodeProxy extends Record<Swizzles | Conversions, NodeProxy> {
77
85
  // Variable manipulation
78
86
  assign(n: X): NodeProxy
79
87
  toVar(name?: string): NodeProxy
80
- toConst(name?: string): NodeProxy
81
88
 
82
89
  // Math function methods
83
90
  abs(): NodeProxy
@@ -126,10 +133,30 @@ export interface NodeProxy extends Record<Swizzles | Conversions, NodeProxy> {
126
133
  fwidth(): NodeProxy
127
134
 
128
135
  // System properties
136
+ toBool(): NodeProxy
137
+ toUint(): NodeProxy
138
+ toInt(): NodeProxy
139
+ toFloat(): NodeProxy
140
+ toBvec2(): NodeProxy
141
+ toIvec2(): NodeProxy
142
+ toUvec2(): NodeProxy
143
+ toVec2(): NodeProxy
144
+ toBvec3(): NodeProxy
145
+ toIvec3(): NodeProxy
146
+ toUvec3(): NodeProxy
147
+ toVec3(): NodeProxy
148
+ toBvec4(): NodeProxy
149
+ toIvec4(): NodeProxy
150
+ toUvec4(): NodeProxy
151
+ toVec4(): NodeProxy
152
+ toColor(): NodeProxy
153
+ toMat2(): NodeProxy
154
+ toMat3(): NodeProxy
155
+ toMat4(): NodeProxy
129
156
  toString(c?: NodeConfig): string
130
157
  type: NodeTypes
131
158
  props: NodeProps
132
159
  isProxy: true
133
160
  }
134
161
 
135
- export type X = NodeProxy | number | string | boolean | null | undefined
162
+ export type X = NodeProxy | number | string | boolean | undefined
package/src/node/utils.ts CHANGED
@@ -1,7 +1,26 @@
1
1
  import { is } from '../utils/helpers'
2
2
  import { code } from './code'
3
- import { CONVERSIONS, FUNCTIONS, OPERATOR_KEYS, OPERATORS, TYPE_MAPPING } from './const'
4
- import type { Conversions, Functions, NodeConfig, NodeProxy, Operators, Swizzles, X } from './types'
3
+ import { infer } from './infer'
4
+ import {
5
+ CONSTANTS,
6
+ CONVERSIONS,
7
+ FUNCTIONS,
8
+ OPERATOR_KEYS,
9
+ OPERATORS,
10
+ TYPE_MAPPING,
11
+ WGSL_TO_GLSL_BUILTIN,
12
+ } from './const'
13
+ import type {
14
+ Constants,
15
+ Conversions,
16
+ Functions,
17
+ NodeConfig,
18
+ NodeProps,
19
+ NodeProxy,
20
+ Operators,
21
+ Swizzles,
22
+ X,
23
+ } from './types'
5
24
 
6
25
  export const isSwizzle = (key: unknown): key is Swizzles => {
7
26
  return is.str(key) && /^[xyzwrgbastpq]{1,4}$/.test(key)
@@ -21,12 +40,10 @@ export const isConversion = (key: unknown): key is Conversions => {
21
40
 
22
41
  export const isNodeProxy = (x: unknown): x is NodeProxy => {
23
42
  if (!x) return false
24
- if (!is.fun(x)) return false // @ts-ignore
43
+ if (typeof x !== 'object') return false // @ts-ignore
25
44
  return x.isProxy
26
45
  }
27
46
 
28
- let count = 0
29
-
30
47
  export const hex2rgb = (hex: number) => {
31
48
  const r = ((hex >> 16) & 0xff) / 255
32
49
  const g = ((hex >> 8) & 0xff) / 255
@@ -34,6 +51,8 @@ export const hex2rgb = (hex: number) => {
34
51
  return [r, g, b]
35
52
  }
36
53
 
54
+ let count = 0
55
+
37
56
  export const getId = () => `i${count++}`
38
57
 
39
58
  export const joins = (children: X[], c: NodeConfig) => {
@@ -53,43 +72,89 @@ export const getOperator = (op: X) => {
53
72
  return OPERATORS[op as keyof typeof OPERATORS] || op
54
73
  }
55
74
 
75
+ export const getBluiltin = (id: string) => {
76
+ return WGSL_TO_GLSL_BUILTIN[id as keyof typeof WGSL_TO_GLSL_BUILTIN]
77
+ }
78
+
79
+ export const conversionToConstant = (conversionKey: string): Constants => {
80
+ const index = CONVERSIONS.indexOf(conversionKey as Conversions)
81
+ return index !== -1 ? CONSTANTS[index] : 'float'
82
+ }
83
+
56
84
  const generateHead = (c: NodeConfig) => {
57
- const uniforms = Array.from(c.uniforms!)
58
- .map((uniform, i) => {
59
- if (c.isWebGL) return `uniform ${uniform};`
60
- else return `@group(0) @binding(${i}) var<uniform> ${uniform};`
61
- })
85
+ return Array.from(c.headers!)
86
+ .map(([, v]) => v)
62
87
  .join('\n')
63
- const functions = Array.from(c.functions!).join('\n')
64
- return `${uniforms}\n${functions}`
65
88
  }
66
89
 
67
- const generateFragmentMain = (body: string, head: string, isWebGL = true) => {
68
- if (isWebGL)
69
- return `
90
+ export const generateDefine = (props: NodeProps, c: NodeConfig) => {
91
+ const { id, children = [], layout } = props
92
+ const [x, y, ...args] = children
93
+ const returnType = layout?.type && layout?.type !== 'auto' ? layout?.type : y ? infer(y, c) : 'void'
94
+ const argParams: [name: string, type: string][] = []
95
+ const params: string[] = []
96
+ if (layout?.inputs)
97
+ for (const input of layout.inputs) {
98
+ argParams.push([input.name, input.type])
99
+ }
100
+ else
101
+ for (let i = 0; i < args.length; i++) {
102
+ argParams.push([`p${i}`, infer(args[i], c)])
103
+ }
104
+ let ret = ''
105
+ if (c?.isWebGL) {
106
+ for (const [id, type] of argParams) params.push(`${type} ${id}`)
107
+ ret += `${returnType} ${id}(${params}) {\n`
108
+ } else {
109
+ for (const [id, type] of argParams) params.push(`${id}: ${formatConversions(type, c)}`)
110
+ ret += `fn ${id}(${params}) -> ${formatConversions(returnType, c)} {\n`
111
+ }
112
+ const scopeCode = code(x, c)
113
+ if (scopeCode) ret += scopeCode + '\n'
114
+ if (y) ret += `return ${code(y, c)};`
115
+ ret += '\n}'
116
+ return ret
117
+ }
118
+
119
+ const GLSL_FRAGMENT_HEAD = `
70
120
  #version 300 es
71
121
  precision mediump float;
72
122
  out vec4 fragColor;
73
- ${head}
74
- void main() {
75
- fragColor = ${body};
76
- }`.trim()
77
- return `
78
- ${head}
123
+ `.trim()
124
+
125
+ const WGSL_FRAGMENT_HEAD = `
79
126
  @fragment
80
127
  fn main(@builtin(position) position: vec4f) -> @location(0) vec4f {
81
- return ${body};
82
- }`.trim()
128
+ `.trim()
129
+
130
+ const generateFragmentMain = (body: string, head: string, isWebGL = true) => {
131
+ let ret = ''
132
+ if (isWebGL) ret += GLSL_FRAGMENT_HEAD
133
+ if (head) ret += '\n' + head + '\n'
134
+ if (isWebGL) ret += `void main() {\n fragColor = ${body};`
135
+ else {
136
+ ret += WGSL_FRAGMENT_HEAD + '\n'
137
+ ret += ` return ${body};`
138
+ }
139
+ ret += '\n}'
140
+ return ret
141
+ }
142
+
143
+ const generateVertexMain = (_body: string, _head: string, isWebGL = true) => {
144
+ if (isWebGL) return ``
145
+ return ``
83
146
  }
84
147
 
85
- export const fragment = (x: X, c: NodeConfig) => {
148
+ export const fragment = (x: X, c: NodeConfig = {}) => {
86
149
  const body = code(x, c)
87
150
  const head = generateHead(c)
88
- return generateFragmentMain(body, head, c.isWebGL)
151
+ const main = generateFragmentMain(body, head, c.isWebGL)
152
+ console.log(`// ↓↓↓ generated ↓↓↓\n\n${main}\n\n`)
153
+ return main
89
154
  }
90
155
 
91
156
  export const vertex = (x: X, c: NodeConfig) => {
92
157
  const body = code(x, c)
93
158
  const head = generateHead(c)
94
- return generateFragmentMain(body, head, c.isWebGL)
159
+ return generateVertexMain(body, head, c.isWebGL)
95
160
  }
package/src/types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { EventState } from 'reev'
2
2
  import type { Fun, Queue, Frame } from 'refr'
3
- import type { X } from './node'
3
+ import type { NodeProxy } from './node'
4
4
  export type { Fun, Queue, Frame }
5
5
  export type GPUContext = any // GPUCanvasContext https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext
6
6
  export type GPUDevice = any //
@@ -52,12 +52,12 @@ export type GL = EventState<{
52
52
  mouse: [number, number]
53
53
  count: number
54
54
  el: HTMLCanvasElement
55
- vs: string | X
56
- fs: string | X
57
- vert: string | X
58
- frag: string | X
59
- vertex: string | X
60
- fragment: string | X
55
+ vs: string | NodeProxy
56
+ fs: string | NodeProxy
57
+ vert: string | NodeProxy
58
+ frag: string | NodeProxy
59
+ vertex: string | NodeProxy
60
+ fragment: string | NodeProxy
61
61
 
62
62
  /**
63
63
  * core state
@@ -1,5 +1,5 @@
1
- import { fragment, vertex, X } from '../node'
2
- import { is } from './helpers'
1
+ import { fragment, isNodeProxy, vertex } from '../node'
2
+ import type { NodeProxy } from '../node'
3
3
  import type { GPUContext, GPUDevice, GPUPipeline } from '../types'
4
4
 
5
5
  const defaultVertexWGSL = `
@@ -34,11 +34,11 @@ export const createPipeline = (
34
34
  format: string,
35
35
  bufferLayouts: any[],
36
36
  bindGroupLayouts: any[],
37
- vs: string | X = defaultVertexWGSL,
38
- fs: string | X = defaultFragmentWGSL
37
+ vs: string | NodeProxy = defaultVertexWGSL,
38
+ fs: string | NodeProxy = defaultFragmentWGSL
39
39
  ) => {
40
- if (!is.str(fs)) fs = fragment(fs, { isWebGL: false })
41
- if (!is.str(vs)) vs = vertex(vs, { isWebGL: false })
40
+ if (isNodeProxy(vs)) vs = vertex(vs, { isWebGL: false })
41
+ if (isNodeProxy(fs)) fs = fragment(fs, { isWebGL: false })
42
42
  const layout = device.createPipelineLayout({ bindGroupLayouts })
43
43
  return device.createRenderPipeline({
44
44
  vertex: {
@@ -1,5 +1,5 @@
1
- import { fragment, vertex, X } from '../node'
2
- import { is } from './helpers'
1
+ import { fragment, isNodeProxy, vertex } from '../node'
2
+ import type { NodeProxy } from '../node'
3
3
 
4
4
  export const defaultVertexGLSL = /* cpp */ `
5
5
  #version 300 es
@@ -33,12 +33,12 @@ const createShader = (c: WebGLRenderingContext, source: string, type: number) =>
33
33
 
34
34
  export const createProgram = (
35
35
  c: WebGLRenderingContext,
36
- vs: string | X = defaultVertexGLSL,
37
- fs: string | X = defaultFragmentGLSL,
36
+ vs: string | NodeProxy = defaultVertexGLSL,
37
+ fs: string | NodeProxy = defaultFragmentGLSL,
38
38
  onError = () => {}
39
39
  ) => {
40
- if (!is.str(fs)) fs = fragment(fs, { isWebGL: true })
41
- if (!is.str(vs)) vs = vertex(fs, { isWebGL: true })
40
+ if (isNodeProxy(fs)) fs = fragment(fs, { isWebGL: true })
41
+ if (isNodeProxy(vs)) vs = vertex(fs, { isWebGL: true })
42
42
  const pg = c.createProgram()
43
43
  const _vs = createShader(c, vs, c.VERTEX_SHADER)
44
44
  const _fs = createShader(c, fs, c.FRAGMENT_SHADER)
package/src/webgl.ts CHANGED
@@ -6,13 +6,12 @@ import type { GL, WebGLState } from './types'
6
6
  export const webgl = async (gl: Partial<GL>) => {
7
7
  const c = gl.el!.getContext('webgl2')!
8
8
  const pg = createProgram(c, gl.vs, gl.fs, () => void (gl.isLoop = false))!
9
- const state = { context: c, program: pg } as WebGLState
10
9
  c.useProgram(pg)
11
-
12
10
  let _activeUnit = 0
13
11
  const uniforms = cached((key) => c.getUniformLocation(pg, key))
14
12
  const attribs = cached((key) => c.getAttribLocation(pg, key))
15
13
  const units = cached(() => _activeUnit++)
14
+ const state = { context: c, program: pg } as WebGLState
16
15
 
17
16
  const clean = () => c.deleteProgram(pg)
18
17