glre 0.34.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 +26 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +30 -25
- package/dist/index.js +26 -28
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +26 -28
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.ts +13 -11
- package/dist/native.js +26 -28
- package/dist/native.js.map +1 -1
- package/dist/react.cjs +26 -28
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +26 -28
- package/dist/react.js.map +1 -1
- package/dist/solid.cjs +26 -28
- package/dist/solid.cjs.map +1 -1
- package/dist/solid.d.ts +1 -1
- package/dist/solid.js +26 -28
- package/dist/solid.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +10 -2
- package/src/node/code.ts +6 -4
- package/src/node/index.ts +4 -3
- package/src/node/parse.ts +34 -31
- package/src/node/scope.ts +3 -2
- package/src/node/utils.ts +2 -2
- package/src/types.ts +12 -10
- package/src/utils/program.ts +10 -11
- package/src/webgl.ts +17 -8
- package/src/webgpu.ts +11 -7
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -45,9 +45,10 @@ const defaultVertex = () =>
|
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
export const createGL = (props?: Partial<GL>) => {
|
|
48
|
-
const gl = event
|
|
48
|
+
const gl = event({
|
|
49
49
|
isNative: false,
|
|
50
50
|
isWebGL: true,
|
|
51
|
+
isError: false,
|
|
51
52
|
isLoop: true,
|
|
52
53
|
isGL: true,
|
|
53
54
|
size: [0, 0],
|
|
@@ -55,6 +56,12 @@ export const createGL = (props?: Partial<GL>) => {
|
|
|
55
56
|
count: 6,
|
|
56
57
|
webgl: {},
|
|
57
58
|
webgpu: {},
|
|
59
|
+
loading: 0,
|
|
60
|
+
error() {
|
|
61
|
+
gl.isError = true
|
|
62
|
+
gl.isLoop = false
|
|
63
|
+
gl.clean()
|
|
64
|
+
},
|
|
58
65
|
}) as EventState<GL>
|
|
59
66
|
|
|
60
67
|
gl.queue = createQueue()
|
|
@@ -72,10 +79,12 @@ export const createGL = (props?: Partial<GL>) => {
|
|
|
72
79
|
if (gl.isWebGL) {
|
|
73
80
|
gl((await webgl(gl)) as GL)
|
|
74
81
|
} else gl((await webgpu(gl)) as GL)
|
|
82
|
+
if (gl.isError) return // stop if error
|
|
75
83
|
gl.resize()
|
|
76
84
|
gl.frame(() => {
|
|
77
85
|
gl.loop()
|
|
78
86
|
gl.queue.flush()
|
|
87
|
+
if (gl.loading) return true // wait for textures @TODO FIX
|
|
79
88
|
gl.render()
|
|
80
89
|
return gl.isLoop
|
|
81
90
|
})
|
|
@@ -86,7 +95,6 @@ export const createGL = (props?: Partial<GL>) => {
|
|
|
86
95
|
|
|
87
96
|
gl('clean', () => {
|
|
88
97
|
gl.frame.stop()
|
|
89
|
-
gl.frame.clean(gl.render)
|
|
90
98
|
if (gl.isNative) return
|
|
91
99
|
window.removeEventListener('resize', gl.resize)
|
|
92
100
|
gl.el.removeEventListener('mousemove', gl.mousemove)
|
package/src/node/code.ts
CHANGED
|
@@ -32,7 +32,7 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
32
32
|
if (is.bol(target)) return target ? 'true' : 'false'
|
|
33
33
|
if (!target) return ''
|
|
34
34
|
const { type, props } = target
|
|
35
|
-
const { id = '', children = [], fields, initialValues } = props
|
|
35
|
+
const { id = 'i', children = [], fields, initialValues } = props
|
|
36
36
|
const [x, y, z, w] = children
|
|
37
37
|
/**
|
|
38
38
|
* variables
|
|
@@ -49,8 +49,10 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
49
49
|
return `(${code(y, c)} ${getOperator(x)} ${code(z, c)})`
|
|
50
50
|
}
|
|
51
51
|
if (type === 'function') {
|
|
52
|
-
if (x === 'negate') return `(-${
|
|
52
|
+
if (x === 'negate') return `(-${code(y, c)})`
|
|
53
|
+
if (x === 'oneMinus') return `(1.0-${code(y, c)})`
|
|
53
54
|
if (x === 'texture') return parseTexture(c, y, z, w)
|
|
55
|
+
if (x === 'atan2' && c.isWebGL) return `atan(${code(y, c)}, ${code(z, c)})`
|
|
54
56
|
return `${x}(${parseArray(children.slice(1), c)})`
|
|
55
57
|
}
|
|
56
58
|
/**
|
|
@@ -61,8 +63,8 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
61
63
|
if (type === 'return') return `return ${code(x, c)};`
|
|
62
64
|
if (type === 'loop')
|
|
63
65
|
return c.isWebGL
|
|
64
|
-
? `for (int
|
|
65
|
-
: `for (var
|
|
66
|
+
? `for (int ${id} = 0; ${id} < ${code(x, c)}; ${id} += 1) {\n${code(y, c)}\n}`
|
|
67
|
+
: `for (var ${id}: i32 = 0; ${id} < ${code(x, c)}; ${id}++) {\n${code(y, c)}\n}`
|
|
66
68
|
if (type === 'if') return parseIf(c, x, y, children)
|
|
67
69
|
if (type === 'switch') return parseSwitch(c, x, children)
|
|
68
70
|
if (type === 'declare') return parseDeclare(c, x, y)
|
package/src/node/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { is } from '../utils/helpers'
|
|
|
2
2
|
import { code } from './code'
|
|
3
3
|
import { builtin, conversion as c, function_ as f, uniform as u } from './node'
|
|
4
4
|
import { hex2rgb, sortHeadersByDependencies } from './utils'
|
|
5
|
-
import type { Constants as C, NodeContext, X, Vec2, Float } from './types'
|
|
5
|
+
import type { Constants as C, NodeContext, X, Vec2, Float, NodeProxy } from './types'
|
|
6
6
|
export * from './code'
|
|
7
7
|
export * from './node'
|
|
8
8
|
export * from './scope'
|
|
@@ -56,7 +56,7 @@ export const vertex = (x: X, c: NodeContext) => {
|
|
|
56
56
|
}
|
|
57
57
|
ret.push('}')
|
|
58
58
|
const main = ret.filter(Boolean).join('\n').trim()
|
|
59
|
-
console.log(`↓↓↓generated↓↓↓\n${main}`)
|
|
59
|
+
// console.log(`↓↓↓generated↓↓↓\n${main}`)
|
|
60
60
|
return main
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -79,7 +79,7 @@ export const fragment = (x: X, c: NodeContext) => {
|
|
|
79
79
|
}
|
|
80
80
|
ret.push('}')
|
|
81
81
|
const main = ret.filter(Boolean).join('\n').trim()
|
|
82
|
-
console.log(`↓↓↓generated↓↓↓\n${main}`)
|
|
82
|
+
// console.log(`↓↓↓generated↓↓↓\n${main}`)
|
|
83
83
|
return main
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -219,3 +219,4 @@ export const difference = <T extends C>(x: X<T>, y: X) => f<T>('difference', x,
|
|
|
219
219
|
export const equals = (x: X, y: X) => f<'bool'>('equals', x, y)
|
|
220
220
|
export const faceforward = <T extends C>(N: X<T>, I: X, Nref: X) => f<T>('faceforward', N, I, Nref)
|
|
221
221
|
export const transformDirection = <T extends C>(dir: X<T>, matrix: X) => f<T>('transformDirection', dir, matrix)
|
|
222
|
+
export const mod = <T extends C>(x: NodeProxy<T>, y: X<T>) => x.sub(x.div(y).floor().mul(y))
|
package/src/node/parse.ts
CHANGED
|
@@ -58,37 +58,6 @@ export const parseDeclare = (c: NodeContext, x: X, y: X) => {
|
|
|
58
58
|
return `var ${varName}: ${wgslType} = ${code(x, c)};`
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
export const parseDefine = (c: NodeContext, props: NodeProps, returnType: Constants) => {
|
|
62
|
-
const { id, children = [], layout } = props
|
|
63
|
-
const [x, ...args] = children
|
|
64
|
-
const argParams: [name: string, type: string][] = []
|
|
65
|
-
const params: string[] = []
|
|
66
|
-
if (layout?.inputs)
|
|
67
|
-
for (const input of layout.inputs) {
|
|
68
|
-
argParams.push([input.name, input.type])
|
|
69
|
-
}
|
|
70
|
-
else
|
|
71
|
-
for (let i = 0; i < args.length; i++) {
|
|
72
|
-
argParams.push([`p${i}`, infer(args[i], c)])
|
|
73
|
-
}
|
|
74
|
-
const ret = []
|
|
75
|
-
if (c?.isWebGL) {
|
|
76
|
-
for (const [paramId, type] of argParams) {
|
|
77
|
-
addDependency(c, id!, type)
|
|
78
|
-
params.push(`${type} ${paramId}`)
|
|
79
|
-
}
|
|
80
|
-
addDependency(c, id!, returnType)
|
|
81
|
-
ret.push(`${returnType} ${id}(${params}) {`)
|
|
82
|
-
} else {
|
|
83
|
-
for (const [paramId, type] of argParams) params.push(`${paramId}: ${formatConversions(type, c)}`)
|
|
84
|
-
ret.push(`fn ${id}(${params}) -> ${formatConversions(returnType, c)} {`)
|
|
85
|
-
}
|
|
86
|
-
const scopeCode = code(x, c)
|
|
87
|
-
if (scopeCode) ret.push(scopeCode)
|
|
88
|
-
ret.push('}')
|
|
89
|
-
return ret.join('\n')
|
|
90
|
-
}
|
|
91
|
-
|
|
92
61
|
export const parseStructHead = (c: NodeContext, id: string, fields: Record<string, NodeProxy> = {}) => {
|
|
93
62
|
const lines: string[] = []
|
|
94
63
|
for (const key in fields) {
|
|
@@ -123,6 +92,40 @@ export const parseStruct = (
|
|
|
123
92
|
}
|
|
124
93
|
}
|
|
125
94
|
|
|
95
|
+
/**
|
|
96
|
+
* define
|
|
97
|
+
*/
|
|
98
|
+
export const parseDefine = (c: NodeContext, props: NodeProps, returnType: Constants) => {
|
|
99
|
+
const { id, children = [], layout } = props
|
|
100
|
+
const [x, ...args] = children
|
|
101
|
+
const argParams: [name: string, type: string][] = []
|
|
102
|
+
const params: string[] = []
|
|
103
|
+
if (layout?.inputs)
|
|
104
|
+
for (const input of layout.inputs) {
|
|
105
|
+
argParams.push([input.name, input.type])
|
|
106
|
+
}
|
|
107
|
+
else
|
|
108
|
+
for (let i = 0; i < args.length; i++) {
|
|
109
|
+
argParams.push([`p${i}`, infer(args[i], c)])
|
|
110
|
+
}
|
|
111
|
+
const ret = []
|
|
112
|
+
if (c?.isWebGL) {
|
|
113
|
+
for (const [paramId, type] of argParams) {
|
|
114
|
+
addDependency(c, id!, type)
|
|
115
|
+
params.push(`${type} ${paramId}`)
|
|
116
|
+
}
|
|
117
|
+
addDependency(c, id!, returnType)
|
|
118
|
+
ret.push(`${returnType} ${id}(${params}) {`)
|
|
119
|
+
} else {
|
|
120
|
+
for (const [paramId, type] of argParams) params.push(`${paramId}: ${formatConversions(type, c)}`)
|
|
121
|
+
ret.push(`fn ${id}(${params}) -> ${formatConversions(returnType, c)} {`)
|
|
122
|
+
}
|
|
123
|
+
const scopeCode = code(x, c)
|
|
124
|
+
if (scopeCode) ret.push(scopeCode)
|
|
125
|
+
ret.push('}')
|
|
126
|
+
return ret.join('\n')
|
|
127
|
+
}
|
|
128
|
+
|
|
126
129
|
/**
|
|
127
130
|
* headers
|
|
128
131
|
*/
|
package/src/node/scope.ts
CHANGED
|
@@ -82,8 +82,9 @@ export const If = (x: NodeProxy, fun: () => void) => {
|
|
|
82
82
|
|
|
83
83
|
export const Loop = (x: NodeProxy, fun: (params: { i: Int }) => void) => {
|
|
84
84
|
const y = node('scope')
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
const id = getId()
|
|
86
|
+
scoped(y, () => fun({ i: node<'int'>('variable', { id, inferFrom: [conversion('int', 0)] }) }))
|
|
87
|
+
const ret = node('loop', { id }, x, y)
|
|
87
88
|
addToScope(ret)
|
|
88
89
|
return ret
|
|
89
90
|
}
|
package/src/node/utils.ts
CHANGED
|
@@ -46,7 +46,7 @@ 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
51
|
export const formatConversions = <T extends Constants>(x: X<T>, c?: NodeContext) => {
|
|
52
52
|
if (!is.str(x)) return ''
|
|
@@ -79,7 +79,7 @@ export const getEventFun = (c: NodeContext, id: string, isAttribute = false, isT
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
export const safeEventCall = <T extends Constants>(x: X<T>, fun: (value: unknown) => void) => {
|
|
82
|
-
if (
|
|
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
|
@@ -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
|
|