@bigmistqke/view.gl 0.1.8 → 0.1.10
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 -8
- package/README.md +30 -0
- package/dev/src/examples/bezier.ts +3 -2
- package/dev/src/examples/game-of-life.ts +13 -30
- package/dev/src/examples/glsl-composition.ts +3 -3
- package/dev/src/examples/grid.ts +20 -14
- package/dev/src/examples/pix-sim.ts +29 -22
- package/dev/src/examples/ray-casting.ts +455 -0
- package/dev/src/examples/sdf.ts +98 -0
- package/dev/src/examples/symbol.ts +2 -2
- package/dev/src/index.ts +12 -11
- package/dev/src/utils.ts +18 -4
- package/dist/gl.d.mts +6 -0
- package/dist/gl.mjs +39 -0
- package/dist/gl.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +27 -38
- package/dist/index.mjs.map +1 -1
- package/dist/tag.d.mts +21 -4
- package/dist/tag.mjs +140 -110
- package/dist/tag.mjs.map +1 -1
- package/dist/{types-Bp9VAVe3.d.mts → types-DaV9McmR.d.mts} +18 -14
- package/package.json +10 -4
- package/src/gl.ts +45 -0
- package/src/index.ts +1 -1
- package/src/tag.ts +112 -44
- package/src/types.ts +36 -22
- package/src/utils/index.ts +0 -46
- package/test/tag.test.ts +462 -0
- package/tsup.config.ts +1 -1
- package/dev/dist/404.html +0 -19
- package/dev/dist/assets/bezier-DuLTb2d1.js +0 -294
- package/dev/dist/assets/game_of_life-D7qHdFcv.js +0 -202
- package/dev/dist/assets/grid-Ie22U_9K.js +0 -173
- package/dev/dist/assets/index-0qrXMlfv.js +0 -109
- package/dev/dist/assets/index-C2N3u8wj.css +0 -12
- package/dev/dist/assets/main-BZ1N6pp6.js +0 -32
- package/dev/dist/assets/overview-DAxtMIw5.js +0 -78
- package/dev/dist/assets/pix_sim-DIhzM_vu.js +0 -501
- package/dev/dist/assets/symbol-BouRL-Ni.js +0 -65
- package/dev/dist/assets/tag-C_bg62fD.js +0 -516
- package/dev/dist/assets/tetris-IMnkSi9p.js +0 -344
- package/dev/dist/assets/utils-CvCgsM08.js +0 -50
- package/dev/dist/index.html +0 -51
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigmistqke/view.gl",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "👀 Utilities for managing WebGL resources.",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
"./tag": {
|
|
11
11
|
"import": "./dist/tag.mjs",
|
|
12
12
|
"types": "./dist/tag.d.mts"
|
|
13
|
+
},
|
|
14
|
+
"./gl": {
|
|
15
|
+
"import": "./dist/gl.mjs",
|
|
16
|
+
"types": "./dist/gl.d.mts"
|
|
13
17
|
}
|
|
14
18
|
},
|
|
15
19
|
"keywords": [
|
|
@@ -26,7 +30,8 @@
|
|
|
26
30
|
"typescript": "^5.8.3",
|
|
27
31
|
"vite": "^7.0.2",
|
|
28
32
|
"vite-tsconfig-paths": "^5.1.4",
|
|
29
|
-
"vitest": "^3.2.4"
|
|
33
|
+
"vitest": "^3.2.4",
|
|
34
|
+
"bumpp": "^10.3.2"
|
|
30
35
|
},
|
|
31
36
|
"scripts": {
|
|
32
37
|
"build": "tsup",
|
|
@@ -35,10 +40,11 @@
|
|
|
35
40
|
"dev:watch": "concurrently \"pnpm dev:preview\" \"vite dev:build --watch\"",
|
|
36
41
|
"dev": "vite serve dev",
|
|
37
42
|
"format": "prettier -w \"src/**/*.{js,ts,json,css,tsx,jsx}\" \"dev/**/*.{js,ts,json,css,tsx,jsx}\"",
|
|
38
|
-
"prepublish": "pnpm build",
|
|
43
|
+
"prepublish": "pnpm test && pnpm build",
|
|
39
44
|
"test": "vitest --run",
|
|
40
45
|
"test:coverage": "vitest run --coverage",
|
|
41
46
|
"test:ui": "vitest --ui",
|
|
42
|
-
"lint:types": "tsc --noEmit"
|
|
47
|
+
"lint:types": "tsc --noEmit",
|
|
48
|
+
"bump": "bumpp"
|
|
43
49
|
}
|
|
44
50
|
}
|
package/src/gl.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { GL } from "./types"
|
|
2
|
+
|
|
3
|
+
export function createShader(gl: GL, type: number, source: string): WebGLShader {
|
|
4
|
+
const shader = gl.createShader(type)
|
|
5
|
+
if (!shader) throw new Error('Failed to create shader')
|
|
6
|
+
|
|
7
|
+
gl.shaderSource(shader, source)
|
|
8
|
+
gl.compileShader(shader)
|
|
9
|
+
|
|
10
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
11
|
+
const info = gl.getShaderInfoLog(shader)
|
|
12
|
+
gl.deleteShader(shader)
|
|
13
|
+
throw new Error(
|
|
14
|
+
`Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return shader
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {
|
|
22
|
+
const program = gl.createProgram()
|
|
23
|
+
if (!program) throw new Error('Failed to create WebGL program')
|
|
24
|
+
|
|
25
|
+
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource)
|
|
26
|
+
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)
|
|
27
|
+
|
|
28
|
+
gl.attachShader(program, vertexShader)
|
|
29
|
+
gl.attachShader(program, fragmentShader)
|
|
30
|
+
gl.linkProgram(program)
|
|
31
|
+
|
|
32
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
33
|
+
const info = gl.getProgramInfoLog(program)
|
|
34
|
+
gl.deleteProgram(program)
|
|
35
|
+
gl.deleteShader(vertexShader)
|
|
36
|
+
gl.deleteShader(fragmentShader)
|
|
37
|
+
throw new Error(`Failed to link program: ${info}`)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Clean up shaders after linking
|
|
41
|
+
gl.deleteShader(vertexShader)
|
|
42
|
+
gl.deleteShader(fragmentShader)
|
|
43
|
+
|
|
44
|
+
return program
|
|
45
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -22,9 +22,9 @@ import {
|
|
|
22
22
|
isSamplerKind,
|
|
23
23
|
kindToSize,
|
|
24
24
|
kindToUniformFnName,
|
|
25
|
-
ObjectUtils,
|
|
26
25
|
} from './utils'
|
|
27
26
|
export * from './types'
|
|
27
|
+
import * as ObjectUtils from "./utils/object"
|
|
28
28
|
|
|
29
29
|
/**********************************************************************************/
|
|
30
30
|
/* */
|
package/src/tag.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { toID, view } from '.'
|
|
2
|
+
import { createProgram } from './gl'
|
|
2
3
|
import type { Prettify } from './type-utils'
|
|
3
4
|
import type {
|
|
4
5
|
AttributeDefinition,
|
|
@@ -6,6 +7,7 @@ import type {
|
|
|
6
7
|
AttributeTokenFn as AttributeTagMethod,
|
|
7
8
|
AttributeToken,
|
|
8
9
|
CompileResult,
|
|
10
|
+
GL,
|
|
9
11
|
GLSL,
|
|
10
12
|
GLSLSlot,
|
|
11
13
|
GLSLToSchema,
|
|
@@ -16,7 +18,7 @@ import type {
|
|
|
16
18
|
ViewSchema,
|
|
17
19
|
ViewSchemaPartial,
|
|
18
20
|
} from './types'
|
|
19
|
-
import {
|
|
21
|
+
import { createUpsertMap } from './utils'
|
|
20
22
|
|
|
21
23
|
export function glsl<TSlot extends GLSLSlot, TSlots extends TSlot[]>(
|
|
22
24
|
template: TemplateStringsArray,
|
|
@@ -94,13 +96,23 @@ export function interleave<
|
|
|
94
96
|
/* */
|
|
95
97
|
/**********************************************************************************/
|
|
96
98
|
|
|
99
|
+
export interface CompileOptions<TSchema extends ViewSchemaPartial> {
|
|
100
|
+
schema?: TSchema
|
|
101
|
+
webgl2?: boolean
|
|
102
|
+
}
|
|
103
|
+
|
|
97
104
|
export function compile<
|
|
98
105
|
TVertex extends GLSL,
|
|
99
106
|
TFragment extends GLSL,
|
|
100
|
-
|
|
101
|
-
>(
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
TSchema extends ViewSchemaPartial,
|
|
108
|
+
>(
|
|
109
|
+
gl: WebGLRenderingContext,
|
|
110
|
+
vertex: TVertex,
|
|
111
|
+
fragment: TFragment,
|
|
112
|
+
options?: CompileOptions<TSchema> | undefined,
|
|
113
|
+
) {
|
|
114
|
+
const _vertex = resolveGLSLTag(vertex, options) as { template: string; schema: ViewSchema }
|
|
115
|
+
const _fragment = resolveGLSLTag(fragment, options) as { template: string; schema: ViewSchema }
|
|
104
116
|
|
|
105
117
|
const schema = {
|
|
106
118
|
uniforms: {
|
|
@@ -117,32 +129,40 @@ export function compile<
|
|
|
117
129
|
},
|
|
118
130
|
}
|
|
119
131
|
|
|
120
|
-
|
|
132
|
+
// Deep merge options.schema with generated schema
|
|
133
|
+
for (const kind in options?.schema) {
|
|
121
134
|
const schemaKind = schema[kind as keyof typeof schema]
|
|
122
|
-
const
|
|
135
|
+
const configSchemaKind = options?.schema[kind]
|
|
123
136
|
|
|
124
|
-
for (const key in
|
|
137
|
+
for (const key in configSchemaKind) {
|
|
125
138
|
schemaKind[key] = {
|
|
126
139
|
...schemaKind[key],
|
|
127
|
-
...
|
|
140
|
+
...configSchemaKind[key],
|
|
128
141
|
}
|
|
129
142
|
}
|
|
130
143
|
}
|
|
131
144
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
try {
|
|
146
|
+
const program = createProgram(gl, _vertex.template, _fragment.template)
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
program,
|
|
150
|
+
schema,
|
|
151
|
+
view: view(gl, program, schema),
|
|
152
|
+
vertex: _vertex.template,
|
|
153
|
+
fragment: _fragment.template,
|
|
154
|
+
} as unknown as Prettify<CompileResult<TVertex, TFragment, TSchema>>
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error('Error while creating WebGLProgram - vertex\n\n', _vertex.template)
|
|
157
|
+
console.error('Error while creating WebGLProgram - fragment\n\n', _fragment.template)
|
|
158
|
+
|
|
159
|
+
throw error
|
|
160
|
+
}
|
|
141
161
|
}
|
|
142
162
|
|
|
143
|
-
function resolveGLSLTag<TTag extends GLSL>(tag: TTag) {
|
|
163
|
+
function resolveGLSLTag<TTag extends GLSL>(tag: TTag, options?: { webgl2?: boolean }) {
|
|
144
164
|
return {
|
|
145
|
-
template: compile.toString(tag),
|
|
165
|
+
template: compile.toString(tag, options),
|
|
146
166
|
schema: compile.toSchema(tag),
|
|
147
167
|
}
|
|
148
168
|
}
|
|
@@ -154,13 +174,13 @@ compile.toSchema = function <TTag extends GLSL>(tag: TTag) {
|
|
|
154
174
|
interleavedAttributes: {},
|
|
155
175
|
}
|
|
156
176
|
|
|
157
|
-
function handleSlot(slot: GLSLSlot) {
|
|
158
|
-
if (
|
|
159
|
-
slot.forEach(handleSlot)
|
|
177
|
+
tag.slots.forEach(function handleSlot(slot: GLSLSlot) {
|
|
178
|
+
if (typeof slot !== 'object') {
|
|
160
179
|
return
|
|
161
180
|
}
|
|
162
181
|
|
|
163
|
-
if (
|
|
182
|
+
if (Array.isArray(slot)) {
|
|
183
|
+
slot.forEach(handleSlot)
|
|
164
184
|
return
|
|
165
185
|
}
|
|
166
186
|
|
|
@@ -187,49 +207,97 @@ compile.toSchema = function <TTag extends GLSL>(tag: TTag) {
|
|
|
187
207
|
|
|
188
208
|
// @ts-expect-error
|
|
189
209
|
result[`${type}s`][name] = rest
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
tag.slots.forEach(handleSlot)
|
|
210
|
+
})
|
|
193
211
|
|
|
194
212
|
return result as unknown as Prettify<GLSLToSchema<TTag>>
|
|
195
213
|
}
|
|
196
214
|
|
|
197
|
-
compile.toString = function <TTag extends GLSL>(
|
|
198
|
-
|
|
215
|
+
compile.toString = function <TTag extends GLSL>(
|
|
216
|
+
{ template: [initial, ...rest], slots }: TTag,
|
|
217
|
+
config?: { webgl2?: boolean },
|
|
218
|
+
) {
|
|
219
|
+
const v300 = config?.webgl2 ?? !!initial?.startsWith('#version 300 es')
|
|
199
220
|
|
|
200
221
|
let template = initial ?? ''
|
|
201
222
|
|
|
202
223
|
for (let i = 0; i < rest.length; i++) {
|
|
203
|
-
template += `${
|
|
224
|
+
template += `${resolveGlslSlotToString(slots[i]!, v300)}${rest[i]}`
|
|
204
225
|
}
|
|
205
226
|
|
|
206
227
|
return template
|
|
207
228
|
}
|
|
208
229
|
|
|
209
|
-
function
|
|
230
|
+
function resolveGlslSlotToString(slot: GLSLSlot, v300: boolean): string {
|
|
210
231
|
if (typeof slot !== 'object') {
|
|
211
232
|
return toID(slot)
|
|
212
233
|
}
|
|
213
234
|
|
|
214
235
|
if (Array.isArray(slot)) {
|
|
215
|
-
return slot.map(slot =>
|
|
236
|
+
return slot.map(slot => resolveGlslSlotToString(slot, v300)).join('')
|
|
216
237
|
}
|
|
217
238
|
|
|
218
|
-
|
|
219
|
-
|
|
239
|
+
switch (slot.type) {
|
|
240
|
+
case 'glsl':
|
|
241
|
+
return compile.toString(slot)
|
|
242
|
+
case 'interleavedAttribute':
|
|
243
|
+
return slot.layout.reduce(
|
|
244
|
+
(a, v) =>
|
|
245
|
+
v300 ? `${a}in ${v.kind} ${toID(v.key)};\n` : `${a}attribute ${v.kind} ${toID(v.key)};\n`,
|
|
246
|
+
'',
|
|
247
|
+
)
|
|
248
|
+
case 'uniform':
|
|
249
|
+
if ('size' in slot) {
|
|
250
|
+
return `${slot.type} ${slot.kind} ${toID(slot.key)}[${slot.size}];`
|
|
251
|
+
}
|
|
252
|
+
return `${slot.type} ${slot.kind} ${toID(slot.key)};`
|
|
220
253
|
}
|
|
221
254
|
|
|
222
|
-
if (slot.type === '
|
|
223
|
-
return slot.
|
|
224
|
-
(a, v) =>
|
|
225
|
-
v300 ? `${a}in ${v.kind} ${toID(v.key)};\n` : `${a}attribute ${v.kind} ${toID(v.key)};\n`,
|
|
226
|
-
'',
|
|
227
|
-
)
|
|
255
|
+
if (slot.type === 'attribute') {
|
|
256
|
+
return `${v300 ? 'in' : slot.type} ${slot.kind} ${toID(slot.key)};`
|
|
228
257
|
}
|
|
229
258
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
259
|
+
throw new Error(`Unexpected slot: ${JSON.stringify(slot)}`)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const QUAD_FLOAT_ARRAY = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1])
|
|
263
|
+
const QUAD_BUFFER_MAP = createUpsertMap(WeakMap<GL, WebGLBuffer>)
|
|
264
|
+
|
|
265
|
+
compile.toQuad = function <TFragment extends GLSL, TSchema extends ViewSchemaPartial>(
|
|
266
|
+
gl: GL,
|
|
267
|
+
fragment: TFragment,
|
|
268
|
+
options?: CompileOptions<TSchema>,
|
|
269
|
+
) {
|
|
270
|
+
const buffer = QUAD_BUFFER_MAP.getOrInsert(gl, gl.createBuffer.bind(gl))
|
|
271
|
+
|
|
272
|
+
const webgl2 = options?.webgl2 ?? fragment.template[0]?.startsWith('#version 300 es')
|
|
273
|
+
|
|
274
|
+
const vertex = webgl2
|
|
275
|
+
? glsl`#version 300 es
|
|
276
|
+
precision mediump float;
|
|
277
|
+
|
|
278
|
+
${attribute.vec2('a_quad', { buffer })}
|
|
279
|
+
|
|
280
|
+
out vec2 v_uv;
|
|
281
|
+
|
|
282
|
+
void main() {
|
|
283
|
+
v_uv = a_quad;
|
|
284
|
+
gl_Position = vec4(v_uv, 0.0, 1.0);
|
|
285
|
+
}`
|
|
286
|
+
: glsl`precision mediump float;
|
|
287
|
+
|
|
288
|
+
${attribute.vec2('a_quad', { buffer })}
|
|
289
|
+
|
|
290
|
+
varying vec2 v_uv;
|
|
291
|
+
|
|
292
|
+
void main() {
|
|
293
|
+
v_uv = a_quad;
|
|
294
|
+
gl_Position = vec4(v_uv, 0.0, 1.0);
|
|
295
|
+
}`
|
|
296
|
+
|
|
297
|
+
const result = compile(gl, vertex, fragment, options)
|
|
298
|
+
|
|
299
|
+
// @ts-expect-error
|
|
300
|
+
result.view.attributes.a_quad.set(QUAD_FLOAT_ARRAY)
|
|
233
301
|
|
|
234
|
-
return
|
|
302
|
+
return result
|
|
235
303
|
}
|
package/src/types.ts
CHANGED
|
@@ -416,7 +416,7 @@ export interface AttributeMethods<T = AttributeKind> {
|
|
|
416
416
|
}
|
|
417
417
|
|
|
418
418
|
export type AttributeView<T extends AttributeSchema> = {
|
|
419
|
-
[K in keyof T]: AttributeMethods<T[K]['kind']
|
|
419
|
+
[K in keyof T]: Prettify<AttributeMethods<T[K]['kind']>>
|
|
420
420
|
}
|
|
421
421
|
|
|
422
422
|
/**********************************************************************************/
|
|
@@ -635,12 +635,12 @@ export interface ViewSchemaPartial {
|
|
|
635
635
|
export type View<T extends ViewSchema = ViewSchema> = {
|
|
636
636
|
attributes: T['attributes'] extends AttributeSchema
|
|
637
637
|
? Prettify<AttributeView<T['attributes']>>
|
|
638
|
-
:
|
|
638
|
+
: {}
|
|
639
639
|
interleavedAttributes: T['interleavedAttributes'] extends InterleavedAttributeSchema
|
|
640
640
|
? Prettify<InterleavedAttributeView<T['interleavedAttributes']>>
|
|
641
|
-
:
|
|
642
|
-
buffers: T['buffers'] extends BufferSchema ? Prettify<BufferView<T['buffers']>> :
|
|
643
|
-
uniforms: T['uniforms'] extends UniformSchema ? Prettify<UniformView<T['uniforms']>> :
|
|
641
|
+
: {}
|
|
642
|
+
buffers: T['buffers'] extends BufferSchema ? Prettify<BufferView<T['buffers']>> : {}
|
|
643
|
+
uniforms: T['uniforms'] extends UniformSchema ? Prettify<UniformView<T['uniforms']>> : {}
|
|
644
644
|
}
|
|
645
645
|
|
|
646
646
|
/**********************************************************************************/
|
|
@@ -703,7 +703,7 @@ export interface AttributeToken<
|
|
|
703
703
|
> {
|
|
704
704
|
type: 'attribute'
|
|
705
705
|
kind: TKind
|
|
706
|
-
instanced: TInstanced
|
|
706
|
+
instanced: TInstanced extends boolean ? boolean : false
|
|
707
707
|
key: TKey
|
|
708
708
|
}
|
|
709
709
|
|
|
@@ -768,26 +768,40 @@ type _FlattenSlots<T extends Array<GLSLSlot>> = T extends [infer First, ...infer
|
|
|
768
768
|
export type MergeGLSLSchema<
|
|
769
769
|
TVertex extends ViewSchema,
|
|
770
770
|
TFragment extends ViewSchema,
|
|
771
|
-
TOverrides extends ViewSchemaPartial = {},
|
|
772
|
-
> =
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
771
|
+
TOverrides extends ViewSchemaPartial | undefined = {},
|
|
772
|
+
> = TOverrides extends ViewSchemaPartial
|
|
773
|
+
? {
|
|
774
|
+
uniforms: Prettify<
|
|
775
|
+
DeepMerge<
|
|
776
|
+
[ShallowMerge<[TVertex['uniforms'], TFragment['uniforms']]>, TOverrides['uniforms']]
|
|
777
|
+
>
|
|
778
|
+
>
|
|
779
|
+
attributes: Prettify<
|
|
780
|
+
DeepMerge<
|
|
781
|
+
[ShallowMerge<[TVertex['attributes'], TFragment['attributes']]>, TOverrides['attributes']]
|
|
782
|
+
>
|
|
783
|
+
>
|
|
784
|
+
interleavedAttributes: Prettify<
|
|
785
|
+
DeepMerge<
|
|
786
|
+
[
|
|
787
|
+
ShallowMerge<[TVertex['interleavedAttributes'], TFragment['interleavedAttributes']]>,
|
|
788
|
+
TOverrides['interleavedAttributes'],
|
|
789
|
+
]
|
|
790
|
+
>
|
|
791
|
+
>
|
|
792
|
+
}
|
|
793
|
+
: {
|
|
794
|
+
uniforms: Prettify<ShallowMerge<[TVertex['uniforms'], TFragment['uniforms']]>>
|
|
795
|
+
attributes: Prettify<ShallowMerge<[TVertex['attributes'], TFragment['attributes']]>>
|
|
796
|
+
interleavedAttributes: Prettify<
|
|
797
|
+
ShallowMerge<[TVertex['interleavedAttributes'], TFragment['interleavedAttributes']]>
|
|
798
|
+
>
|
|
799
|
+
}
|
|
786
800
|
|
|
787
801
|
export type CompileResult<
|
|
788
802
|
TVertex extends GLSL,
|
|
789
803
|
TFragment extends GLSL,
|
|
790
|
-
TOverrideSchema extends ViewSchemaPartial,
|
|
804
|
+
TOverrideSchema extends ViewSchemaPartial | undefined,
|
|
791
805
|
> =
|
|
792
806
|
MergeGLSLSchema<
|
|
793
807
|
GLSLToSchema<TVertex>,
|
package/src/utils/index.ts
CHANGED
|
@@ -8,57 +8,11 @@ import type {
|
|
|
8
8
|
UniformKind,
|
|
9
9
|
} from '../types'
|
|
10
10
|
|
|
11
|
-
export * as ObjectUtils from './object'
|
|
12
|
-
|
|
13
11
|
export function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {
|
|
14
12
|
if (value === undefined || value === null) throw new Error(message)
|
|
15
13
|
return value
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
function createGLShader(gl: GL, type: number, source: string): WebGLShader {
|
|
19
|
-
const shader = gl.createShader(type)
|
|
20
|
-
if (!shader) throw new Error('Failed to create shader')
|
|
21
|
-
|
|
22
|
-
gl.shaderSource(shader, source)
|
|
23
|
-
gl.compileShader(shader)
|
|
24
|
-
|
|
25
|
-
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
26
|
-
const info = gl.getShaderInfoLog(shader)
|
|
27
|
-
gl.deleteShader(shader)
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return shader
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {
|
|
37
|
-
const program = gl.createProgram()
|
|
38
|
-
if (!program) throw new Error('Failed to create WebGL program')
|
|
39
|
-
|
|
40
|
-
const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource)
|
|
41
|
-
const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource)
|
|
42
|
-
|
|
43
|
-
gl.attachShader(program, vertexShader)
|
|
44
|
-
gl.attachShader(program, fragmentShader)
|
|
45
|
-
gl.linkProgram(program)
|
|
46
|
-
|
|
47
|
-
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
48
|
-
const info = gl.getProgramInfoLog(program)
|
|
49
|
-
gl.deleteProgram(program)
|
|
50
|
-
gl.deleteShader(vertexShader)
|
|
51
|
-
gl.deleteShader(fragmentShader)
|
|
52
|
-
throw new Error(`Failed to link program: ${info}`)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Clean up shaders after linking
|
|
56
|
-
gl.deleteShader(vertexShader)
|
|
57
|
-
gl.deleteShader(fragmentShader)
|
|
58
|
-
|
|
59
|
-
return program
|
|
60
|
-
}
|
|
61
|
-
|
|
62
16
|
/**********************************************************************************/
|
|
63
17
|
/* */
|
|
64
18
|
/* Kind To Uniform Name */
|