@bigmistqke/view.gl 0.1.0 → 0.1.1
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/dist/index.d.mts +17 -0
- package/dist/index.mjs +270 -0
- package/dist/index.mjs.map +1 -0
- package/dist/tag.d.mts +97 -0
- package/dist/tag.mjs +133 -0
- package/dist/tag.mjs.map +1 -0
- package/dist/types-DxpS9Bae.d.mts +266 -0
- package/package.json +8 -7
- package/src/tag.ts +1 -1
- package/.claude/settings.local.json +0 -8
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { V as ViewSchema, G as GL, a as ViewOptions, b as View, U as UniformSchema, c as UniformView, A as AttributeSchema, d as AttributeView, I as InterleavedAttributeSchema, e as InterleavedAttributeView, B as BufferSchema, f as BufferView } from './types-DxpS9Bae.mjs';
|
|
2
|
+
|
|
3
|
+
/**********************************************************************************/
|
|
4
|
+
/**********************************************************************************/
|
|
5
|
+
declare function view<T extends ViewSchema>(gl: GL, program: WebGLProgram, schema: T, options?: ViewOptions): View<T>;
|
|
6
|
+
/**********************************************************************************/
|
|
7
|
+
/**********************************************************************************/
|
|
8
|
+
declare function uniformView<T extends UniformSchema>(gl: GL, program: WebGLProgram, schema: T): UniformView<T>;
|
|
9
|
+
declare function attributeView<T extends AttributeSchema>(gl: GL, program: WebGLProgram, schema: T, { signal }?: ViewOptions): AttributeView<T>;
|
|
10
|
+
/**********************************************************************************/
|
|
11
|
+
/**********************************************************************************/
|
|
12
|
+
declare function interleavedAttributeView<T extends InterleavedAttributeSchema>(gl: GL, program: WebGLProgram, schema: T, { signal }?: ViewOptions): InterleavedAttributeView<T>;
|
|
13
|
+
/**********************************************************************************/
|
|
14
|
+
/**********************************************************************************/
|
|
15
|
+
declare function bufferView<T extends BufferSchema>(gl: GL, schema: T, { signal }?: ViewOptions): BufferView<T>;
|
|
16
|
+
|
|
17
|
+
export { attributeView, bufferView, interleavedAttributeView, uniformView, view };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// src/features.ts
|
|
2
|
+
var INSTANCED_ARRAYS_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function getInstancedArrays(gl) {
|
|
4
|
+
if (gl instanceof WebGL2RenderingContext) return gl;
|
|
5
|
+
const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl);
|
|
6
|
+
if (cached) return cached;
|
|
7
|
+
const ext = gl.getExtension("ANGLE_instanced_arrays");
|
|
8
|
+
if (!ext) return void 0;
|
|
9
|
+
const wrapper = {
|
|
10
|
+
drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),
|
|
11
|
+
drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),
|
|
12
|
+
vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext)
|
|
13
|
+
};
|
|
14
|
+
INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper);
|
|
15
|
+
return wrapper;
|
|
16
|
+
}
|
|
17
|
+
var VERTEX_ARRAY_OBJECT_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
|
|
18
|
+
function getVertexArrayObject(gl) {
|
|
19
|
+
if (gl instanceof WebGL2RenderingContext) return gl;
|
|
20
|
+
const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl);
|
|
21
|
+
if (cached) return cached;
|
|
22
|
+
const ext = gl.getExtension("OES_vertex_array_object");
|
|
23
|
+
if (!ext) return null;
|
|
24
|
+
const wrapper = {
|
|
25
|
+
bindVertexArray: ext.bindVertexArrayOES.bind(ext),
|
|
26
|
+
createVertexArray: ext.createVertexArrayOES.bind(ext),
|
|
27
|
+
deleteVertexArray: ext.deleteVertexArrayOES.bind(ext)
|
|
28
|
+
};
|
|
29
|
+
VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper);
|
|
30
|
+
return wrapper;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/utils.ts
|
|
34
|
+
function mapObject(value, callback) {
|
|
35
|
+
return Object.fromEntries(
|
|
36
|
+
Object.entries(value).map(([key, value2], index) => [key, callback(value2, key, index)])
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
function assertedNotNullish(value, message) {
|
|
40
|
+
if (value === void 0 || value === null) throw new Error(message);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
var kindToUniformFnName = (kind) => {
|
|
44
|
+
switch (kind[0]) {
|
|
45
|
+
// mat
|
|
46
|
+
case "m":
|
|
47
|
+
return "Matrix" + kind.slice(3) + "fv";
|
|
48
|
+
// sampler/booleans/integer
|
|
49
|
+
case "s":
|
|
50
|
+
case "b":
|
|
51
|
+
case "i":
|
|
52
|
+
return (kind.match(/\d/)?.[0] ?? "1") + "i";
|
|
53
|
+
// unsigned integers
|
|
54
|
+
case "u":
|
|
55
|
+
return (kind[4] || "1") + "ui";
|
|
56
|
+
// vec
|
|
57
|
+
case "v":
|
|
58
|
+
return kind[3] + "f";
|
|
59
|
+
default:
|
|
60
|
+
switch (kind) {
|
|
61
|
+
case "float":
|
|
62
|
+
return "1f";
|
|
63
|
+
case "uint":
|
|
64
|
+
return "1ui";
|
|
65
|
+
default:
|
|
66
|
+
return "1i";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var kindToSize = (kind) => {
|
|
71
|
+
switch (kind[0]) {
|
|
72
|
+
case "m":
|
|
73
|
+
const [a, b] = kind.match(/\d+/g).map(Number);
|
|
74
|
+
return a * (b || a);
|
|
75
|
+
case "v":
|
|
76
|
+
return +kind.match(/\d/)[0];
|
|
77
|
+
default:
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var isMatKind = (kind) => kind.includes("mat");
|
|
82
|
+
var isSamplerKind = (kind) => kind.includes("sampler");
|
|
83
|
+
|
|
84
|
+
// src/index.ts
|
|
85
|
+
function view(gl, program, schema, options) {
|
|
86
|
+
return {
|
|
87
|
+
uniforms: !schema.uniforms ? void 0 : uniformView(gl, program, schema.uniforms),
|
|
88
|
+
attributes: !schema.attributes ? void 0 : attributeView(gl, program, schema.attributes, options),
|
|
89
|
+
interleavedAttributes: !schema.interleavedAttributes ? void 0 : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),
|
|
90
|
+
buffers: !schema.buffers ? void 0 : bufferView(gl, schema.buffers)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function uniformView(gl, program, schema) {
|
|
94
|
+
return mapObject(schema, ({ kind, size }, name2) => {
|
|
95
|
+
const location = gl.getUniformLocation(program, name2);
|
|
96
|
+
if (isSamplerKind(kind)) {
|
|
97
|
+
return {
|
|
98
|
+
set(arg) {
|
|
99
|
+
gl.uniform1i(location, arg);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const fnName = `uniform${kindToUniformFnName(kind)}${size ? "v" : ""}`;
|
|
104
|
+
const fn = gl[fnName].bind(gl);
|
|
105
|
+
if (isMatKind(kind)) {
|
|
106
|
+
return {
|
|
107
|
+
set(...args) {
|
|
108
|
+
fn(location, false, args[0]);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
set(...args) {
|
|
114
|
+
fn(location, ...args);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function handleAttribute(gl, location, size, stride, offset, type, instanced) {
|
|
120
|
+
gl.enableVertexAttribArray(location);
|
|
121
|
+
gl.vertexAttribPointer(location, size, gl[type], false, stride, offset);
|
|
122
|
+
if (instanced) {
|
|
123
|
+
assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function attributeView(gl, program, schema, { signal } = {}) {
|
|
127
|
+
const attributes = mapObject(
|
|
128
|
+
schema,
|
|
129
|
+
({ kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) }, name2) => {
|
|
130
|
+
const location = gl.getAttribLocation(program, name2);
|
|
131
|
+
if (location < 0) {
|
|
132
|
+
throw new Error(`Attribute '${name2}' not found`);
|
|
133
|
+
}
|
|
134
|
+
const size = kindToSize(kind);
|
|
135
|
+
const type = kind.startsWith("i") ? "INT" : "FLOAT";
|
|
136
|
+
return {
|
|
137
|
+
buffer,
|
|
138
|
+
bind() {
|
|
139
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
140
|
+
handleAttribute(gl, location, size, 0, 0, type, instanced);
|
|
141
|
+
},
|
|
142
|
+
dispose() {
|
|
143
|
+
gl.deleteBuffer(buffer);
|
|
144
|
+
},
|
|
145
|
+
set(data, usage = "STATIC_DRAW") {
|
|
146
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
147
|
+
gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage]);
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
signal?.addEventListener("abort", function dispose() {
|
|
154
|
+
for (const name2 in attributes) {
|
|
155
|
+
attributes[name2].dispose();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return attributes;
|
|
159
|
+
}
|
|
160
|
+
function interleavedAttributeView(gl, program, schema, { signal } = {}) {
|
|
161
|
+
const interleavedAttributes = mapObject(schema, ({ layout, instanced }) => {
|
|
162
|
+
let index = 0;
|
|
163
|
+
const handles = layout.map((layout2) => {
|
|
164
|
+
const location = gl.getAttribLocation(program, layout2.name);
|
|
165
|
+
if (location < 0) {
|
|
166
|
+
throw new Error(`Attribute '${layout2.name}' not found`);
|
|
167
|
+
}
|
|
168
|
+
const size = kindToSize(layout2.kind);
|
|
169
|
+
const offset = index;
|
|
170
|
+
const type = layout2.kind.startsWith("i") ? "INT" : "FLOAT";
|
|
171
|
+
index += size * 4;
|
|
172
|
+
return () => handleAttribute(gl, location, size, stride, offset, type, instanced);
|
|
173
|
+
});
|
|
174
|
+
const stride = index;
|
|
175
|
+
const buffer = assertedNotNullish(gl.createBuffer());
|
|
176
|
+
let vao = void 0;
|
|
177
|
+
const feature = getVertexArrayObject(gl);
|
|
178
|
+
if (feature) {
|
|
179
|
+
const vertexArray = feature.createVertexArray();
|
|
180
|
+
feature.bindVertexArray(vertexArray);
|
|
181
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
182
|
+
for (const handle of handles) {
|
|
183
|
+
handle();
|
|
184
|
+
}
|
|
185
|
+
feature.bindVertexArray(null);
|
|
186
|
+
vao = {
|
|
187
|
+
unbind() {
|
|
188
|
+
feature.bindVertexArray(null);
|
|
189
|
+
},
|
|
190
|
+
bind() {
|
|
191
|
+
feature.bindVertexArray(vertexArray);
|
|
192
|
+
},
|
|
193
|
+
dispose() {
|
|
194
|
+
feature.deleteVertexArray(vertexArray);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
bind() {
|
|
200
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
201
|
+
if (vao) {
|
|
202
|
+
vao.bind();
|
|
203
|
+
} else {
|
|
204
|
+
for (const handle of handles) {
|
|
205
|
+
handle();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
unbind() {
|
|
210
|
+
if (vao) {
|
|
211
|
+
vao.unbind();
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
dispose() {
|
|
215
|
+
gl.deleteBuffer(buffer);
|
|
216
|
+
if (vao) {
|
|
217
|
+
vao.dispose();
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
set(value, usage = "STATIC_DRAW") {
|
|
221
|
+
if (vao) {
|
|
222
|
+
vao.bind();
|
|
223
|
+
} else {
|
|
224
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
225
|
+
}
|
|
226
|
+
gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage]);
|
|
227
|
+
if (vao) {
|
|
228
|
+
vao.unbind();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
});
|
|
233
|
+
signal?.addEventListener("abort", function dispose() {
|
|
234
|
+
for (const name2 in interleavedAttributes) {
|
|
235
|
+
interleavedAttributes[name2].dispose();
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
return interleavedAttributes;
|
|
239
|
+
}
|
|
240
|
+
function bufferView(gl, schema, { signal } = {}) {
|
|
241
|
+
const buffers = mapObject(schema, ({ target = "ARRAY_BUFFER", usage = "STATIC_DRAW" }) => {
|
|
242
|
+
const buffer = assertedNotNullish(gl.createBuffer());
|
|
243
|
+
return {
|
|
244
|
+
bind() {
|
|
245
|
+
gl.bindBuffer(gl[target], buffer);
|
|
246
|
+
},
|
|
247
|
+
dispose() {
|
|
248
|
+
gl.deleteBuffer(buffer);
|
|
249
|
+
},
|
|
250
|
+
set(data) {
|
|
251
|
+
gl.bindBuffer(gl[target], buffer);
|
|
252
|
+
gl.bufferData(gl[target], data, gl[usage]);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
signal?.addEventListener("abort", function dispose() {
|
|
257
|
+
for (const name2 in buffers) {
|
|
258
|
+
buffers[name2].dispose();
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
return buffers;
|
|
262
|
+
}
|
|
263
|
+
export {
|
|
264
|
+
attributeView,
|
|
265
|
+
bufferView,
|
|
266
|
+
interleavedAttributeView,
|
|
267
|
+
uniformView,
|
|
268
|
+
view
|
|
269
|
+
};
|
|
270
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import type { GL, RemoveSuffix } from './types'\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n","import type {\n AttributeKind,\n FramebufferOptions,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureOptions,\n UniformKind,\n} from './types'\n\nexport function mapObject<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: Extract<keyof T, string>, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n return Object.fromEntries(\n Object.entries(value).map(([key, value], index) => [key, callback(value, key, index)]),\n )\n}\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\nfunction createGLShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return 'Matrix' + kind.slice(3) + 'fv'\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return (kind.match(/\\d/)?.[0] ?? '1') + 'i'\n // unsigned integers\n case 'u':\n return (kind[4] || '1') + 'ui'\n // vec\n case 'v':\n return kind[3] + 'f'\n default:\n switch (kind) {\n case 'float':\n return '1f'\n case 'uint':\n return '1ui'\n default:\n return '1i'\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number)\n return a * (b || a)\n case 'v':\n return +kind.match(/\\d/)![0]\n default:\n return 1\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureOptions,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name]\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(gl: GL, { attachment, texture, ...options }: FramebufferOptions) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n","import { getInstancedArrays, getVertexArrayObject } from './features'\nimport type {\n AttributeMethods,\n AttributeSchema,\n AttributeView,\n BufferSchema,\n BufferView,\n GL,\n UniformView as InferUniformView,\n InterleavedAttributeMethods,\n InterleavedAttributeSchema,\n InterleavedAttributeView,\n UniformSchema,\n View,\n ViewOptions,\n ViewSchema,\n} from './types'\nimport {\n assertedNotNullish,\n isMatKind,\n isSamplerKind,\n kindToSize,\n kindToUniformFnName,\n mapObject,\n} from './utils'\n\n/**********************************************************************************/\n/* */\n/* View */\n/* */\n/**********************************************************************************/\n\nexport function view<T extends ViewSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n options?: ViewOptions,\n): View<T> {\n return {\n uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),\n attributes: !schema.attributes\n ? undefined\n : attributeView(gl, program, schema.attributes, options),\n interleavedAttributes: !schema.interleavedAttributes\n ? undefined\n : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),\n buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),\n } as View<T>\n}\n\n/**********************************************************************************/\n/* */\n/* Uniform View */\n/* */\n/**********************************************************************************/\n\nexport function uniformView<T extends UniformSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n): InferUniformView<T> {\n return mapObject(schema, ({ kind, size }, name) => {\n const location = gl.getUniformLocation(program, name)\n\n if (isSamplerKind(kind)) {\n return {\n set(arg: number) {\n gl.uniform1i(location, arg)\n },\n }\n }\n\n const fnName = `uniform${kindToUniformFnName(kind)}${size ? 'v' : ''}`\n\n // @ts-ignore FIX WEBGL/WEBGL2 TYPES\n const fn = gl[fnName].bind(gl)\n\n if (isMatKind(kind)) {\n return {\n set(...args: any[]) {\n fn(location, false, args[0])\n },\n }\n }\n\n return {\n set(...args: any[]) {\n fn(location, ...args)\n },\n }\n })\n}\n\n/**********************************************************************************/\n/* */\n/* Attribute View */\n/* */\n/**********************************************************************************/\n\n// Shared attribute helper functions\n// between attributeView and interleavedAttributeView\nfunction handleAttribute(\n gl: GL,\n location: number,\n size: number,\n stride: number,\n offset: number,\n type: 'FLOAT' | 'INT',\n instanced?: boolean,\n) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl[type], false, stride, offset)\n\n if (instanced) {\n // Get instanced-arrays-feature: extension if webgl, gl if webgl2\n assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1)\n }\n}\n\nexport function attributeView<T extends AttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): AttributeView<T> {\n const attributes = mapObject(\n schema,\n (\n { kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) },\n name,\n ): AttributeMethods => {\n const location = gl.getAttribLocation(program, name)\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(kind)\n const type = kind.startsWith('i') ? 'INT' : 'FLOAT'\n\n return {\n buffer,\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n handleAttribute(gl, location, size, 0, 0, type, instanced)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data, usage = 'STATIC_DRAW') {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage])\n return this\n },\n }\n },\n )\n\n signal?.addEventListener('abort', function dispose() {\n for (const name in attributes) {\n attributes[name].dispose()\n }\n })\n\n return attributes\n}\n\n/**********************************************************************************/\n/* */\n/* Interleaved Attribute View */\n/* */\n/**********************************************************************************/\n\nexport function interleavedAttributeView<T extends InterleavedAttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): InterleavedAttributeView<T> {\n // Initialize interleaved attributes\n const interleavedAttributes = mapObject(schema, ({ layout, instanced }) => {\n // Increment number to keep track of offset\n let index = 0\n\n // Calculate layout information\n const handles = layout.map(layout => {\n const location = gl.getAttribLocation(program, layout.name)\n\n if (location < 0) {\n throw new Error(`Attribute '${layout.name}' not found`)\n }\n\n const size = kindToSize(layout.kind)\n const offset = index\n const type = layout.kind.startsWith('i') ? 'INT' : 'FLOAT'\n index += size * 4\n\n return () => handleAttribute(gl, location, size, stride, offset, type, instanced)\n })\n\n // Set stride to final index\n const stride = index\n\n // Create a buffer\n const buffer = assertedNotNullish(gl.createBuffer())\n\n // Create VAO to cache attribute state\n let vao: { unbind(): void; bind(): void; dispose(): void } | undefined = undefined\n\n // Get VAO-feature: extension if webgl1, gl if webgl2\n const feature = getVertexArrayObject(gl)\n if (feature) {\n const vertexArray = feature.createVertexArray()\n feature.bindVertexArray(vertexArray)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n for (const handle of handles) {\n handle()\n }\n feature.bindVertexArray(null)\n vao = {\n unbind() {\n feature.bindVertexArray(null)\n },\n bind() {\n feature.bindVertexArray(vertexArray)\n },\n dispose() {\n feature.deleteVertexArray(vertexArray)\n },\n }\n }\n\n return {\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n if (vao) {\n vao.bind()\n } else {\n // Fallback: manual attribute setup\n for (const handle of handles) {\n handle()\n }\n }\n },\n unbind() {\n if (vao) {\n vao.unbind()\n }\n },\n dispose() {\n gl.deleteBuffer(buffer)\n if (vao) {\n vao.dispose()\n }\n },\n set(value, usage = 'STATIC_DRAW') {\n if (vao) {\n vao.bind()\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n }\n gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage])\n if (vao) {\n vao.unbind()\n }\n },\n } satisfies InterleavedAttributeMethods\n })\n\n signal?.addEventListener('abort', function dispose() {\n for (const name in interleavedAttributes) {\n interleavedAttributes[name].dispose()\n }\n })\n\n return interleavedAttributes\n}\n\n/**********************************************************************************/\n/* */\n/* Buffer View */\n/* */\n/**********************************************************************************/\n\nexport function bufferView<T extends BufferSchema>(\n gl: GL,\n schema: T,\n { signal }: ViewOptions = {},\n): BufferView<T> {\n // Initialize buffers\n const buffers = mapObject(schema, ({ target = 'ARRAY_BUFFER', usage = 'STATIC_DRAW' }) => {\n const buffer = assertedNotNullish(gl.createBuffer())\n return {\n bind() {\n gl.bindBuffer(gl[target], buffer)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data: Float32Array) {\n gl.bindBuffer(gl[target], buffer)\n gl.bufferData(gl[target], data, gl[usage])\n },\n }\n })\n\n signal?.addEventListener('abort', function dispose() {\n for (const name in buffers) {\n buffers[name].dispose()\n }\n })\n\n return buffers\n}\n"],"mappings":";AAEA,IAAM,+BAA+B,oBAAI,QASvC;AACK,SAAS,mBAAmB,IAAQ;AACzC,MAAI,cAAc,uBAAwB,QAAO;AAEjD,QAAM,SAAS,6BAA6B,IAAI,EAAE;AAClD,MAAI,OAAQ,QAAO;AAEnB,QAAM,MAAM,GAAG,aAAa,wBAAwB;AACpD,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU;AAAA,IACd,qBAAqB,IAAI,yBAAyB,KAAK,GAAG;AAAA,IAC1D,uBAAuB,IAAI,2BAA2B,KAAK,GAAG;AAAA,IAC9D,qBAAqB,IAAI,yBAAyB,KAAK,GAAG;AAAA,EAC5D;AACA,+BAA6B,IAAI,IAAI,OAAO;AAE5C,SAAO;AACT;AAEA,IAAM,kCAAkC,oBAAI,QAS1C;AACK,SAAS,qBAAqB,IAAQ;AAC3C,MAAI,cAAc,uBAAwB,QAAO;AAEjD,QAAM,SAAS,gCAAgC,IAAI,EAAE;AACrD,MAAI,OAAQ,QAAO;AAEnB,QAAM,MAAM,GAAG,aAAa,yBAAyB;AACrD,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU;AAAA,IACd,iBAAiB,IAAI,mBAAmB,KAAK,GAAG;AAAA,IAChD,mBAAmB,IAAI,qBAAqB,KAAK,GAAG;AAAA,IACpD,mBAAmB,IAAI,qBAAqB,KAAK,GAAG;AAAA,EACtD;AACA,kCAAgC,IAAI,IAAI,OAAO;AAE/C,SAAO;AACT;;;AChDO,SAAS,UACd,OACA,UACgC;AAChC,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAKA,MAAK,GAAG,UAAU,CAAC,KAAK,SAASA,QAAO,KAAK,KAAK,CAAC,CAAC;AAAA,EACvF;AACF;AAEO,SAAS,mBAAsB,OAAU,SAAkC;AAChF,MAAI,UAAU,UAAa,UAAU,KAAM,OAAM,IAAI,MAAM,OAAO;AAClE,SAAO;AACT;AAoDO,IAAM,sBAAsB,CACjC,SACmC;AACnC,UAAQ,KAAK,CAAC,GAAG;AAAA;AAAA,IAEf,KAAK;AACH,aAAO,WAAW,KAAK,MAAM,CAAC,IAAI;AAAA;AAAA,IAEpC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,OAAO;AAAA;AAAA,IAE1C,KAAK;AACH,cAAQ,KAAK,CAAC,KAAK,OAAO;AAAA;AAAA,IAE5B,KAAK;AACH,aAAO,KAAK,CAAC,IAAI;AAAA,IACnB;AACE,cAAQ,MAAM;AAAA,QACZ,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACX;AAAA,EACJ;AACF;AAQO,IAAM,aAAa,CAAwB,SAAiC;AACjF,UAAQ,KAAK,CAAC,GAAG;AAAA,IACf,KAAK;AACH,YAAM,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,MAAM,EAAG,IAAI,MAAM;AAC7C,aAAO,KAAK,KAAK;AAAA,IACnB,KAAK;AACH,aAAO,CAAC,KAAK,MAAM,IAAI,EAAG,CAAC;AAAA,IAC7B;AACE,aAAO;AAAA,EACX;AACF;AAQO,IAAM,YAAY,CAKvB,SAC2C,KAAK,SAAS,KAAK;AAEzD,IAAM,gBAAgB,CAC3B,SACyD,KAAK,SAAS,SAAS;;;AC1G3E,SAAS,KACd,IACA,SACA,QACA,SACS;AACT,SAAO;AAAA,IACL,UAAU,CAAC,OAAO,WAAW,SAAY,YAAY,IAAI,SAAS,OAAO,QAAQ;AAAA,IACjF,YAAY,CAAC,OAAO,aAChB,SACA,cAAc,IAAI,SAAS,OAAO,YAAY,OAAO;AAAA,IACzD,uBAAuB,CAAC,OAAO,wBAC3B,SACA,yBAAyB,IAAI,SAAS,OAAO,uBAAuB,OAAO;AAAA,IAC/E,SAAS,CAAC,OAAO,UAAU,SAAY,WAAW,IAAI,OAAO,OAAO;AAAA,EACtE;AACF;AAQO,SAAS,YACd,IACA,SACA,QACqB;AACrB,SAAO,UAAU,QAAQ,CAAC,EAAE,MAAM,KAAK,GAAGC,UAAS;AACjD,UAAM,WAAW,GAAG,mBAAmB,SAASA,KAAI;AAEpD,QAAI,cAAc,IAAI,GAAG;AACvB,aAAO;AAAA,QACL,IAAI,KAAa;AACf,aAAG,UAAU,UAAU,GAAG;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,UAAU,oBAAoB,IAAI,CAAC,GAAG,OAAO,MAAM,EAAE;AAGpE,UAAM,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE;AAE7B,QAAI,UAAU,IAAI,GAAG;AACnB,aAAO;AAAA,QACL,OAAO,MAAa;AAClB,aAAG,UAAU,OAAO,KAAK,CAAC,CAAC;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,MAAa;AAClB,WAAG,UAAU,GAAG,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAUA,SAAS,gBACP,IACA,UACA,MACA,QACA,QACA,MACA,WACA;AACA,KAAG,wBAAwB,QAAQ;AACnC,KAAG,oBAAoB,UAAU,MAAM,GAAG,IAAI,GAAG,OAAO,QAAQ,MAAM;AAEtE,MAAI,WAAW;AAEb,uBAAmB,mBAAmB,EAAE,CAAC,EAAE,oBAAoB,UAAU,CAAC;AAAA,EAC5E;AACF;AAEO,SAAS,cACd,IACA,SACA,QACA,EAAE,OAAO,IAAiB,CAAC,GACT;AAClB,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,CACE,EAAE,MAAM,WAAW,SAAS,mBAAmB,GAAG,aAAa,CAAC,EAAE,GAClEA,UACqB;AACrB,YAAM,WAAW,GAAG,kBAAkB,SAASA,KAAI;AACnD,UAAI,WAAW,GAAG;AAChB,cAAM,IAAI,MAAM,cAAcA,KAAI,aAAa;AAAA,MACjD;AAEA,YAAM,OAAO,WAAW,IAAI;AAC5B,YAAM,OAAO,KAAK,WAAW,GAAG,IAAI,QAAQ;AAE5C,aAAO;AAAA,QACL;AAAA,QACA,OAAO;AACL,aAAG,WAAW,GAAG,cAAc,MAAM;AACrC,0BAAgB,IAAI,UAAU,MAAM,GAAG,GAAG,MAAM,SAAS;AAAA,QAC3D;AAAA,QACA,UAAU;AACR,aAAG,aAAa,MAAM;AAAA,QACxB;AAAA,QACA,IAAI,MAAM,QAAQ,eAAe;AAC/B,aAAG,WAAW,GAAG,cAAc,MAAM;AACrC,aAAG,WAAW,GAAG,cAAc,MAAM,GAAG,KAAK,CAAC;AAC9C,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,iBAAiB,SAAS,SAAS,UAAU;AACnD,eAAWA,SAAQ,YAAY;AAC7B,iBAAWA,KAAI,EAAE,QAAQ;AAAA,IAC3B;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAQO,SAAS,yBACd,IACA,SACA,QACA,EAAE,OAAO,IAAiB,CAAC,GACE;AAE7B,QAAM,wBAAwB,UAAU,QAAQ,CAAC,EAAE,QAAQ,UAAU,MAAM;AAEzE,QAAI,QAAQ;AAGZ,UAAM,UAAU,OAAO,IAAI,CAAAC,YAAU;AACnC,YAAM,WAAW,GAAG,kBAAkB,SAASA,QAAO,IAAI;AAE1D,UAAI,WAAW,GAAG;AAChB,cAAM,IAAI,MAAM,cAAcA,QAAO,IAAI,aAAa;AAAA,MACxD;AAEA,YAAM,OAAO,WAAWA,QAAO,IAAI;AACnC,YAAM,SAAS;AACf,YAAM,OAAOA,QAAO,KAAK,WAAW,GAAG,IAAI,QAAQ;AACnD,eAAS,OAAO;AAEhB,aAAO,MAAM,gBAAgB,IAAI,UAAU,MAAM,QAAQ,QAAQ,MAAM,SAAS;AAAA,IAClF,CAAC;AAGD,UAAM,SAAS;AAGf,UAAM,SAAS,mBAAmB,GAAG,aAAa,CAAC;AAGnD,QAAI,MAAqE;AAGzE,UAAM,UAAU,qBAAqB,EAAE;AACvC,QAAI,SAAS;AACX,YAAM,cAAc,QAAQ,kBAAkB;AAC9C,cAAQ,gBAAgB,WAAW;AACnC,SAAG,WAAW,GAAG,cAAc,MAAM;AACrC,iBAAW,UAAU,SAAS;AAC5B,eAAO;AAAA,MACT;AACA,cAAQ,gBAAgB,IAAI;AAC5B,YAAM;AAAA,QACJ,SAAS;AACP,kBAAQ,gBAAgB,IAAI;AAAA,QAC9B;AAAA,QACA,OAAO;AACL,kBAAQ,gBAAgB,WAAW;AAAA,QACrC;AAAA,QACA,UAAU;AACR,kBAAQ,kBAAkB,WAAW;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO;AACL,WAAG,WAAW,GAAG,cAAc,MAAM;AACrC,YAAI,KAAK;AACP,cAAI,KAAK;AAAA,QACX,OAAO;AAEL,qBAAW,UAAU,SAAS;AAC5B,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,MACA,SAAS;AACP,YAAI,KAAK;AACP,cAAI,OAAO;AAAA,QACb;AAAA,MACF;AAAA,MACA,UAAU;AACR,WAAG,aAAa,MAAM;AACtB,YAAI,KAAK;AACP,cAAI,QAAQ;AAAA,QACd;AAAA,MACF;AAAA,MACA,IAAI,OAAO,QAAQ,eAAe;AAChC,YAAI,KAAK;AACP,cAAI,KAAK;AAAA,QACX,OAAO;AACL,aAAG,WAAW,GAAG,cAAc,MAAM;AAAA,QACvC;AACA,WAAG,WAAW,GAAG,cAAc,OAAO,GAAG,KAAK,CAAC;AAC/C,YAAI,KAAK;AACP,cAAI,OAAO;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,iBAAiB,SAAS,SAAS,UAAU;AACnD,eAAWD,SAAQ,uBAAuB;AACxC,4BAAsBA,KAAI,EAAE,QAAQ;AAAA,IACtC;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAQO,SAAS,WACd,IACA,QACA,EAAE,OAAO,IAAiB,CAAC,GACZ;AAEf,QAAM,UAAU,UAAU,QAAQ,CAAC,EAAE,SAAS,gBAAgB,QAAQ,cAAc,MAAM;AACxF,UAAM,SAAS,mBAAmB,GAAG,aAAa,CAAC;AACnD,WAAO;AAAA,MACL,OAAO;AACL,WAAG,WAAW,GAAG,MAAM,GAAG,MAAM;AAAA,MAClC;AAAA,MACA,UAAU;AACR,WAAG,aAAa,MAAM;AAAA,MACxB;AAAA,MACA,IAAI,MAAoB;AACtB,WAAG,WAAW,GAAG,MAAM,GAAG,MAAM;AAChC,WAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,iBAAiB,SAAS,SAAS,UAAU;AACnD,eAAWA,SAAQ,SAAS;AAC1B,cAAQA,KAAI,EAAE,QAAQ;AAAA,IACxB;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":["value","name","layout"]}
|
package/dist/tag.d.mts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { g as UniformKind, h as UniformOptions, P as Prettify, i as UniformTag, j as AttributeTagFn, k as AttributeTag, l as AttributeKind, m as AttributeOptions, n as InterleaveTag, o as GLSL, M as Merge } from './types-DxpS9Bae.mjs';
|
|
2
|
+
|
|
3
|
+
/**********************************************************************************/
|
|
4
|
+
/**********************************************************************************/
|
|
5
|
+
interface UniformTagFn<TKind extends UniformKind> {
|
|
6
|
+
<const TName extends string, const TOptions extends Omit<UniformOptions, 'kind'>>(name: TName, TOptions: TOptions): Prettify<UniformTag<TName, TKind, TOptions>>;
|
|
7
|
+
<const TName extends string>(name: TName): Prettify<UniformTag<TName, TKind>>;
|
|
8
|
+
}
|
|
9
|
+
declare const uniform: {
|
|
10
|
+
float: UniformTagFn<"float">;
|
|
11
|
+
vec2: UniformTagFn<"vec2">;
|
|
12
|
+
vec3: UniformTagFn<"vec3">;
|
|
13
|
+
vec4: UniformTagFn<"vec4">;
|
|
14
|
+
int: UniformTagFn<"int">;
|
|
15
|
+
ivec2: UniformTagFn<"ivec2">;
|
|
16
|
+
ivec3: UniformTagFn<"ivec3">;
|
|
17
|
+
ivec4: UniformTagFn<"ivec4">;
|
|
18
|
+
bool: UniformTagFn<"bool">;
|
|
19
|
+
bvec2: UniformTagFn<"bvec2">;
|
|
20
|
+
bvec3: UniformTagFn<"bvec3">;
|
|
21
|
+
bvec4: UniformTagFn<"bvec4">;
|
|
22
|
+
mat2: UniformTagFn<"mat2">;
|
|
23
|
+
mat3: UniformTagFn<"mat3">;
|
|
24
|
+
mat4: UniformTagFn<"mat4">;
|
|
25
|
+
sampler2D: UniformTagFn<"sampler2D">;
|
|
26
|
+
samplerCube: UniformTagFn<"samplerCube">;
|
|
27
|
+
uint: UniformTagFn<"uint">;
|
|
28
|
+
uvec2: UniformTagFn<"uvec2">;
|
|
29
|
+
uvec3: UniformTagFn<"uvec3">;
|
|
30
|
+
uvec4: UniformTagFn<"uvec4">;
|
|
31
|
+
mat2x3: UniformTagFn<"mat2x3">;
|
|
32
|
+
mat2x4: UniformTagFn<"mat2x4">;
|
|
33
|
+
mat3x2: UniformTagFn<"mat3x2">;
|
|
34
|
+
mat3x4: UniformTagFn<"mat3x4">;
|
|
35
|
+
mat4x2: UniformTagFn<"mat4x2">;
|
|
36
|
+
mat4x3: UniformTagFn<"mat4x3">;
|
|
37
|
+
sampler3D: UniformTagFn<"sampler3D">;
|
|
38
|
+
sampler2DArray: UniformTagFn<"sampler2DArray">;
|
|
39
|
+
sampler2DShadow: UniformTagFn<"sampler2DShadow">;
|
|
40
|
+
samplerCubeShadow: UniformTagFn<"samplerCubeShadow">;
|
|
41
|
+
sampler2DArrayShadow: UniformTagFn<"sampler2DArrayShadow">;
|
|
42
|
+
isampler2D: UniformTagFn<"isampler2D">;
|
|
43
|
+
isampler3D: UniformTagFn<"isampler3D">;
|
|
44
|
+
isamplerCube: UniformTagFn<"isamplerCube">;
|
|
45
|
+
isampler2DArray: UniformTagFn<"isampler2DArray">;
|
|
46
|
+
usampler2D: UniformTagFn<"usampler2D">;
|
|
47
|
+
usampler3D: UniformTagFn<"usampler3D">;
|
|
48
|
+
usamplerCube: UniformTagFn<"usamplerCube">;
|
|
49
|
+
usampler2DArray: UniformTagFn<"usampler2DArray">;
|
|
50
|
+
};
|
|
51
|
+
declare const attribute: {
|
|
52
|
+
float: AttributeTagFn<"float">;
|
|
53
|
+
vec2: AttributeTagFn<"vec2">;
|
|
54
|
+
vec3: AttributeTagFn<"vec3">;
|
|
55
|
+
vec4: AttributeTagFn<"vec4">;
|
|
56
|
+
int: AttributeTagFn<"int">;
|
|
57
|
+
ivec2: AttributeTagFn<"ivec2">;
|
|
58
|
+
ivec3: AttributeTagFn<"ivec3">;
|
|
59
|
+
ivec4: AttributeTagFn<"ivec4">;
|
|
60
|
+
mat2: AttributeTagFn<"mat2">;
|
|
61
|
+
mat3: AttributeTagFn<"mat3">;
|
|
62
|
+
mat4: AttributeTagFn<"mat4">;
|
|
63
|
+
uint: AttributeTagFn<"uint">;
|
|
64
|
+
uvec2: AttributeTagFn<"uvec2">;
|
|
65
|
+
uvec3: AttributeTagFn<"uvec3">;
|
|
66
|
+
uvec4: AttributeTagFn<"uvec4">;
|
|
67
|
+
mat2x3: AttributeTagFn<"mat2x3">;
|
|
68
|
+
mat2x4: AttributeTagFn<"mat2x4">;
|
|
69
|
+
mat3x2: AttributeTagFn<"mat3x2">;
|
|
70
|
+
mat3x4: AttributeTagFn<"mat3x4">;
|
|
71
|
+
mat4x2: AttributeTagFn<"mat4x2">;
|
|
72
|
+
mat4x3: AttributeTagFn<"mat4x3">;
|
|
73
|
+
};
|
|
74
|
+
declare function interleave<const TName extends string, const TLayout extends Array<AttributeTag<string, AttributeKind, undefined>>, const TOptions extends Omit<AttributeOptions, 'kind'>>(name: TName, layout: TLayout, instanced: TOptions): InterleaveTag<TName, TLayout, TOptions>;
|
|
75
|
+
declare function interleave<const TName extends string, const TLayout extends Array<AttributeTag<string, AttributeKind, undefined>>>(name: TName, layout: TLayout): InterleaveTag<TName, TLayout, {
|
|
76
|
+
instanced: false;
|
|
77
|
+
}>;
|
|
78
|
+
/**********************************************************************************/
|
|
79
|
+
/**********************************************************************************/
|
|
80
|
+
declare function glsl<Elem extends string, Template extends ReadonlyArray<Elem>, Hole extends UniformTag | AttributeTag | InterleaveTag | string | number, Holes extends Hole[]>([initial, ...rest]: Template, ...holes: [...Holes]): {
|
|
81
|
+
template: string;
|
|
82
|
+
uniforms: { [K in Extract<Holes[number], UniformTag> as K["name"]]: Prettify<Omit<K, "name" | "type">>; };
|
|
83
|
+
attributes: { [K in Extract<Holes[number], AttributeTag> as K["name"]]: Prettify<Omit<K, "name" | "type">>; };
|
|
84
|
+
interleavedAttributes: { [K in Extract<Holes[number], InterleaveTag> as K["name"]]: Prettify<Omit<K, "name" | "type">>; };
|
|
85
|
+
};
|
|
86
|
+
/**********************************************************************************/
|
|
87
|
+
/**********************************************************************************/
|
|
88
|
+
declare function compile<TVertex extends GLSL, TFragment extends GLSL>(gl: WebGLRenderingContext, vertex: TVertex, fragment: TFragment): {
|
|
89
|
+
program: WebGLProgram;
|
|
90
|
+
schema: {
|
|
91
|
+
uniforms: Prettify<Merge<TVertex["uniforms"], TFragment["uniforms"]>>;
|
|
92
|
+
attributes: Prettify<Merge<TVertex["attributes"], TFragment["attributes"]>>;
|
|
93
|
+
interleavedAttributes: Prettify<Merge<TVertex["interleavedAttributes"], TFragment["interleavedAttributes"]>>;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export { attribute, compile, glsl, interleave, uniform };
|
package/dist/tag.mjs
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// src/utils.ts
|
|
2
|
+
function createGLShader(gl, type, source) {
|
|
3
|
+
const shader = gl.createShader(type);
|
|
4
|
+
if (!shader) throw new Error("Failed to create shader");
|
|
5
|
+
gl.shaderSource(shader, source);
|
|
6
|
+
gl.compileShader(shader);
|
|
7
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
8
|
+
const info = gl.getShaderInfoLog(shader);
|
|
9
|
+
gl.deleteShader(shader);
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Failed to compile ${type === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader: ${info}`
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return shader;
|
|
15
|
+
}
|
|
16
|
+
function createProgram(gl, vertexSource, fragmentSource) {
|
|
17
|
+
const program = gl.createProgram();
|
|
18
|
+
if (!program) throw new Error("Failed to create WebGL program");
|
|
19
|
+
const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource);
|
|
20
|
+
const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
|
|
21
|
+
gl.attachShader(program, vertexShader);
|
|
22
|
+
gl.attachShader(program, fragmentShader);
|
|
23
|
+
gl.linkProgram(program);
|
|
24
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
25
|
+
const info = gl.getProgramInfoLog(program);
|
|
26
|
+
gl.deleteProgram(program);
|
|
27
|
+
gl.deleteShader(vertexShader);
|
|
28
|
+
gl.deleteShader(fragmentShader);
|
|
29
|
+
throw new Error(`Failed to link program: ${info}`);
|
|
30
|
+
}
|
|
31
|
+
gl.deleteShader(vertexShader);
|
|
32
|
+
gl.deleteShader(fragmentShader);
|
|
33
|
+
return program;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/tag.ts
|
|
37
|
+
var uniform = new Proxy(
|
|
38
|
+
{},
|
|
39
|
+
{
|
|
40
|
+
get(target, property) {
|
|
41
|
+
if (typeof property === "symbol") return target[property];
|
|
42
|
+
return (name2, options) => ({
|
|
43
|
+
type: "uniform",
|
|
44
|
+
name: name2,
|
|
45
|
+
kind: property,
|
|
46
|
+
...options
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
var attribute = new Proxy(
|
|
52
|
+
{},
|
|
53
|
+
{
|
|
54
|
+
get(target, property) {
|
|
55
|
+
if (typeof property === "symbol") return target[property];
|
|
56
|
+
return (name2, options) => ({
|
|
57
|
+
type: "attribute",
|
|
58
|
+
name: name2,
|
|
59
|
+
kind: property,
|
|
60
|
+
...options
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
function interleave(name2, layout, { instanced, buffer } = {}) {
|
|
66
|
+
return {
|
|
67
|
+
type: "interleavedAttribute",
|
|
68
|
+
name: name2,
|
|
69
|
+
// remove instanced- and type-property
|
|
70
|
+
layout: layout.map(({ name: name3, kind }) => ({
|
|
71
|
+
name: name3,
|
|
72
|
+
kind
|
|
73
|
+
})),
|
|
74
|
+
instanced: !!instanced,
|
|
75
|
+
buffer
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function glsl([initial, ...rest], ...holes) {
|
|
79
|
+
const v300 = initial?.startsWith("#version 300 es");
|
|
80
|
+
const template = rest.reduce((out, templatePart, index) => {
|
|
81
|
+
const hole = holes[index];
|
|
82
|
+
const holePart = typeof hole === "string" || typeof hole === "number" ? hole : hole.type === "interleavedAttribute" ? hole.layout.reduce(
|
|
83
|
+
(a, v) => v300 ? `${a}in ${v.kind} ${v.name};
|
|
84
|
+
` : `${a}attribute ${v.kind} ${v.name};
|
|
85
|
+
`,
|
|
86
|
+
""
|
|
87
|
+
) : typeof hole === "object" && hole.type === "uniform" && "size" in hole ? `${hole.type} ${hole.kind} ${hole.name}[${hole.size}];` : `${hole.type === "attribute" && v300 ? "in" : hole.type} ${hole.kind} ${hole.name};`;
|
|
88
|
+
return out + holePart + templatePart;
|
|
89
|
+
}, initial || "");
|
|
90
|
+
return holes.reduce(
|
|
91
|
+
(resources, resource) => {
|
|
92
|
+
if (typeof resource === "string" || typeof resource === "number") {
|
|
93
|
+
return resources;
|
|
94
|
+
}
|
|
95
|
+
resources[`${resource.type}s`][resource.name] = resource;
|
|
96
|
+
return resources;
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
template,
|
|
100
|
+
uniforms: {},
|
|
101
|
+
attributes: {},
|
|
102
|
+
interleavedAttributes: {}
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
function compile(gl, vertex, fragment) {
|
|
107
|
+
const program = createProgram(gl, vertex.template, fragment.template);
|
|
108
|
+
return {
|
|
109
|
+
program,
|
|
110
|
+
schema: {
|
|
111
|
+
uniforms: {
|
|
112
|
+
...vertex.uniforms,
|
|
113
|
+
...fragment.uniforms
|
|
114
|
+
},
|
|
115
|
+
attributes: {
|
|
116
|
+
...vertex.attributes,
|
|
117
|
+
...fragment.attributes
|
|
118
|
+
},
|
|
119
|
+
interleavedAttributes: {
|
|
120
|
+
...vertex.interleavedAttributes,
|
|
121
|
+
...fragment.interleavedAttributes
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export {
|
|
127
|
+
attribute,
|
|
128
|
+
compile,
|
|
129
|
+
glsl,
|
|
130
|
+
interleave,
|
|
131
|
+
uniform
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=tag.mjs.map
|
package/dist/tag.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/tag.ts"],"sourcesContent":["import type {\n AttributeKind,\n FramebufferOptions,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureOptions,\n UniformKind,\n} from './types'\n\nexport function mapObject<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: Extract<keyof T, string>, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n return Object.fromEntries(\n Object.entries(value).map(([key, value], index) => [key, callback(value, key, index)]),\n )\n}\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\nfunction createGLShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createGLShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createGLShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return 'Matrix' + kind.slice(3) + 'fv'\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return (kind.match(/\\d/)?.[0] ?? '1') + 'i'\n // unsigned integers\n case 'u':\n return (kind[4] || '1') + 'ui'\n // vec\n case 'v':\n return kind[3] + 'f'\n default:\n switch (kind) {\n case 'float':\n return '1f'\n case 'uint':\n return '1ui'\n default:\n return '1i'\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number)\n return a * (b || a)\n case 'v':\n return +kind.match(/\\d/)![0]\n default:\n return 1\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureOptions,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name]\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(gl: GL, { attachment, texture, ...options }: FramebufferOptions) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n","import type {\n AttributeKind,\n AttributeOptions,\n AttributeTag,\n AttributeTagFn,\n GLSL,\n InterleaveTag,\n Merge,\n Prettify,\n UniformKind,\n UniformOptions,\n UniformTag,\n} from './types'\nimport { createProgram } from './utils'\n\n/**********************************************************************************/\n/* */\n/* Tag Utilities */\n/* */\n/**********************************************************************************/\n\ninterface UniformTagFn<TKind extends UniformKind> {\n <const TName extends string, const TOptions extends Omit<UniformOptions, 'kind'>>(\n name: TName,\n TOptions: TOptions,\n ): Prettify<UniformTag<TName, TKind, TOptions>>\n <const TName extends string>(name: TName): Prettify<UniformTag<TName, TKind>>\n}\n\nexport const uniform = new Proxy(\n {} as {\n [TKey in UniformKind]: UniformTagFn<TKey>\n },\n {\n get(target, property) {\n // @ts-expect-error\n if (typeof property === 'symbol') return target[property]\n return (name: string, options?: Omit<UniformOptions, 'kind'>) => ({\n type: 'uniform',\n name,\n kind: property,\n ...options,\n })\n },\n },\n)\n\nexport const attribute = new Proxy(\n {} as {\n [TKey in AttributeKind]: AttributeTagFn<TKey>\n },\n {\n get(target, property) {\n // @ts-expect-error\n if (typeof property === 'symbol') return target[property]\n return (name: string, options?: Omit<AttributeOptions, 'kind'>) => ({\n type: 'attribute',\n name,\n kind: property,\n ...options,\n })\n },\n },\n)\n\nexport function interleave<\n const TName extends string,\n const TLayout extends Array<AttributeTag<string, AttributeKind, undefined>>,\n const TOptions extends Omit<AttributeOptions, 'kind'>,\n>(name: TName, layout: TLayout, instanced: TOptions): InterleaveTag<TName, TLayout, TOptions>\nexport function interleave<\n const TName extends string,\n const TLayout extends Array<AttributeTag<string, AttributeKind, undefined>>,\n>(name: TName, layout: TLayout): InterleaveTag<TName, TLayout, { instanced: false }>\nexport function interleave<\n const TName extends string,\n const TLayout extends Array<AttributeTag<string, AttributeKind, undefined>>,\n const TOptions extends Omit<AttributeOptions, 'kind'>,\n>(name: TName, layout: TLayout, { instanced, buffer }: Partial<TOptions> = {}) {\n return {\n type: 'interleavedAttribute',\n name,\n // remove instanced- and type-property\n layout: layout.map(({ name, kind }) => ({\n name,\n kind,\n })),\n instanced: !!instanced,\n buffer,\n } as InterleaveTag<TName, TLayout, TOptions>\n}\n\n/**********************************************************************************/\n/* */\n/* GLSL */\n/* */\n/**********************************************************************************/\n\nexport function glsl<\n Elem extends string,\n Template extends ReadonlyArray<Elem>,\n Hole extends UniformTag | AttributeTag | InterleaveTag | string | number,\n Holes extends Hole[],\n>([initial, ...rest]: Template, ...holes: [...Holes]) {\n const v300 = initial?.startsWith('#version 300 es')\n const template = rest.reduce((out, templatePart, index) => {\n const hole = holes[index]\n const holePart =\n typeof hole === 'string' || typeof hole === 'number'\n ? hole\n : hole.type === 'interleavedAttribute'\n ? hole.layout.reduce(\n (a, v) =>\n v300 ? `${a}in ${v.kind} ${v.name};\\n` : `${a}attribute ${v.kind} ${v.name};\\n`,\n '',\n )\n : typeof hole === 'object' && hole.type === 'uniform' && 'size' in hole\n ? `${hole.type} ${hole.kind} ${hole.name}[${hole.size}];`\n : `${hole.type === 'attribute' && v300 ? 'in' : hole.type} ${hole.kind} ${hole.name};`\n return out + holePart + templatePart\n }, initial || '')\n\n return holes.reduce(\n (resources, resource) => {\n if (typeof resource === 'string' || typeof resource === 'number') {\n return resources\n }\n // @ts-expect-error\n resources[`${resource.type}s`][resource.name] = resource\n return resources\n },\n {\n template,\n uniforms: {},\n attributes: {},\n interleavedAttributes: {},\n } as {\n template: string\n uniforms: {\n [K in Extract<Holes[number], UniformTag> as K['name']]: Prettify<Omit<K, 'name' | 'type'>>\n }\n attributes: {\n [K in Extract<Holes[number], AttributeTag> as K['name']]: Prettify<Omit<K, 'name' | 'type'>>\n }\n interleavedAttributes: {\n [K in Extract<Holes[number], InterleaveTag> as K['name']]: Prettify<\n Omit<K, 'name' | 'type'>\n >\n }\n },\n )\n}\n\n/**********************************************************************************/\n/* */\n/* Compile */\n/* */\n/**********************************************************************************/\n\nexport function compile<TVertex extends GLSL, TFragment extends GLSL>(\n gl: WebGLRenderingContext,\n vertex: TVertex,\n fragment: TFragment,\n) {\n const program = createProgram(gl, vertex.template, fragment.template)\n\n return {\n program,\n schema: {\n uniforms: {\n ...vertex.uniforms,\n ...fragment.uniforms,\n },\n attributes: {\n ...vertex.attributes,\n ...fragment.attributes,\n },\n interleavedAttributes: {\n ...vertex.interleavedAttributes,\n ...fragment.interleavedAttributes,\n },\n },\n } as {\n program: WebGLProgram\n schema: {\n uniforms: Prettify<Merge<TVertex['uniforms'], TFragment['uniforms']>>\n attributes: Prettify<Merge<TVertex['attributes'], TFragment['attributes']>>\n interleavedAttributes: Prettify<\n Merge<TVertex['interleavedAttributes'], TFragment['interleavedAttributes']>\n >\n }\n }\n}\n"],"mappings":"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","names":["name"]}
|
|
@@ -0,0 +1,266 @@
|
|
|
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
|
+
type Prettify<T> = {
|
|
5
|
+
[K in keyof T]: T[K];
|
|
6
|
+
} & {};
|
|
7
|
+
type GL = WebGLRenderingContext | WebGL2RenderingContext;
|
|
8
|
+
/**********************************************************************************/
|
|
9
|
+
/**********************************************************************************/
|
|
10
|
+
type GLTarget = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER';
|
|
11
|
+
type GLUsage = 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW';
|
|
12
|
+
type UniformKind = 'float' | 'vec2' | 'vec3' | 'vec4' | 'int' | 'ivec2' | 'ivec3' | 'ivec4' | 'bool' | 'bvec2' | 'bvec3' | 'bvec4' | 'mat2' | 'mat3' | 'mat4' | 'sampler2D' | 'samplerCube' | 'uint' | 'uvec2' | 'uvec3' | 'uvec4' | 'mat2x3' | 'mat2x4' | 'mat3x2' | 'mat3x4' | 'mat4x2' | 'mat4x3' | 'sampler3D' | 'sampler2DArray' | 'sampler2DShadow' | 'samplerCubeShadow' | 'sampler2DArrayShadow' | 'isampler2D' | 'isampler3D' | 'isamplerCube' | 'isampler2DArray' | 'usampler2D' | 'usampler3D' | 'usamplerCube' | 'usampler2DArray';
|
|
13
|
+
interface UniformKindMap {
|
|
14
|
+
float: [number];
|
|
15
|
+
vec2: [number, number];
|
|
16
|
+
vec3: [number, number, number];
|
|
17
|
+
vec4: [number, number, number, number];
|
|
18
|
+
int: [number];
|
|
19
|
+
ivec2: [number, number];
|
|
20
|
+
ivec3: [number, number, number];
|
|
21
|
+
ivec4: [number, number, number, number];
|
|
22
|
+
bool: [number];
|
|
23
|
+
bvec2: [number, number];
|
|
24
|
+
bvec3: [number, number, number];
|
|
25
|
+
bvec4: [number, number, number, number];
|
|
26
|
+
uint: [number];
|
|
27
|
+
uvec2: [number, number];
|
|
28
|
+
uvec3: [number, number, number];
|
|
29
|
+
uvec4: [number, number, number, number];
|
|
30
|
+
mat2: [Float32Array] | [
|
|
31
|
+
number,
|
|
32
|
+
number,
|
|
33
|
+
number,
|
|
34
|
+
number
|
|
35
|
+
];
|
|
36
|
+
mat3: [Float32Array] | [
|
|
37
|
+
number,
|
|
38
|
+
number,
|
|
39
|
+
number,
|
|
40
|
+
number,
|
|
41
|
+
number,
|
|
42
|
+
number,
|
|
43
|
+
number,
|
|
44
|
+
number,
|
|
45
|
+
number
|
|
46
|
+
];
|
|
47
|
+
mat4: [Float32Array] | [
|
|
48
|
+
number,
|
|
49
|
+
number,
|
|
50
|
+
number,
|
|
51
|
+
number,
|
|
52
|
+
number,
|
|
53
|
+
number,
|
|
54
|
+
number,
|
|
55
|
+
number,
|
|
56
|
+
number,
|
|
57
|
+
number,
|
|
58
|
+
number,
|
|
59
|
+
number,
|
|
60
|
+
number,
|
|
61
|
+
number,
|
|
62
|
+
number,
|
|
63
|
+
number
|
|
64
|
+
];
|
|
65
|
+
mat2x3: [Float32Array] | [
|
|
66
|
+
number,
|
|
67
|
+
number,
|
|
68
|
+
number,
|
|
69
|
+
number,
|
|
70
|
+
number,
|
|
71
|
+
number
|
|
72
|
+
];
|
|
73
|
+
mat2x4: [Float32Array] | [
|
|
74
|
+
number,
|
|
75
|
+
number,
|
|
76
|
+
number,
|
|
77
|
+
number,
|
|
78
|
+
number,
|
|
79
|
+
number,
|
|
80
|
+
number,
|
|
81
|
+
number
|
|
82
|
+
];
|
|
83
|
+
mat3x2: [Float32Array] | [
|
|
84
|
+
number,
|
|
85
|
+
number,
|
|
86
|
+
number,
|
|
87
|
+
number,
|
|
88
|
+
number,
|
|
89
|
+
number
|
|
90
|
+
];
|
|
91
|
+
mat3x4: [Float32Array] | [
|
|
92
|
+
number,
|
|
93
|
+
number,
|
|
94
|
+
number,
|
|
95
|
+
number,
|
|
96
|
+
number,
|
|
97
|
+
number,
|
|
98
|
+
number,
|
|
99
|
+
number,
|
|
100
|
+
number,
|
|
101
|
+
number,
|
|
102
|
+
number,
|
|
103
|
+
number
|
|
104
|
+
];
|
|
105
|
+
mat4x2: [Float32Array] | [
|
|
106
|
+
number,
|
|
107
|
+
number,
|
|
108
|
+
number,
|
|
109
|
+
number,
|
|
110
|
+
number,
|
|
111
|
+
number,
|
|
112
|
+
number,
|
|
113
|
+
number
|
|
114
|
+
];
|
|
115
|
+
mat4x3: [Float32Array] | [
|
|
116
|
+
number,
|
|
117
|
+
number,
|
|
118
|
+
number,
|
|
119
|
+
number,
|
|
120
|
+
number,
|
|
121
|
+
number,
|
|
122
|
+
number,
|
|
123
|
+
number,
|
|
124
|
+
number,
|
|
125
|
+
number,
|
|
126
|
+
number,
|
|
127
|
+
number
|
|
128
|
+
];
|
|
129
|
+
sampler2D: [number];
|
|
130
|
+
samplerCube: [number];
|
|
131
|
+
sampler3D: [number];
|
|
132
|
+
sampler2DArray: [number];
|
|
133
|
+
sampler2DShadow: [number];
|
|
134
|
+
samplerCubeShadow: [number];
|
|
135
|
+
sampler2DArrayShadow: [number];
|
|
136
|
+
isampler2D: [number];
|
|
137
|
+
isampler3D: [number];
|
|
138
|
+
isamplerCube: [number];
|
|
139
|
+
isampler2DArray: [number];
|
|
140
|
+
usampler2D: [number];
|
|
141
|
+
usampler3D: [number];
|
|
142
|
+
usamplerCube: [number];
|
|
143
|
+
usampler2DArray: [number];
|
|
144
|
+
}
|
|
145
|
+
interface UniformOptions {
|
|
146
|
+
kind: UniformKind;
|
|
147
|
+
size?: number;
|
|
148
|
+
}
|
|
149
|
+
type UniformSchema = Record<string, UniformOptions>;
|
|
150
|
+
type UniformMethods<TOptions extends UniformOptions> = TOptions['size'] extends number ? {
|
|
151
|
+
set(arg: Float32Array): void;
|
|
152
|
+
} : {
|
|
153
|
+
set(...args: UniformKindMap[TOptions['kind']]): void;
|
|
154
|
+
};
|
|
155
|
+
type UniformView<T extends UniformSchema> = {
|
|
156
|
+
[K in keyof T]: UniformMethods<T[K]>;
|
|
157
|
+
};
|
|
158
|
+
type AttributeKind = 'float' | 'vec2' | 'vec3' | 'vec4' | 'mat2' | 'mat3' | 'mat4' | 'mat2x3' | 'mat2x4' | 'mat3x2' | 'mat3x4' | 'mat4x2' | 'mat4x3' | 'int' | 'ivec2' | 'ivec3' | 'ivec4' | 'uint' | 'uvec2' | 'uvec3' | 'uvec4';
|
|
159
|
+
interface AttributeOptions {
|
|
160
|
+
kind: AttributeKind;
|
|
161
|
+
instanced?: boolean;
|
|
162
|
+
buffer?: WebGLBuffer;
|
|
163
|
+
}
|
|
164
|
+
type AttributeSchema = Record<string, AttributeOptions>;
|
|
165
|
+
interface AttributeMethods<T = AttributeKind> {
|
|
166
|
+
buffer: WebGLBuffer;
|
|
167
|
+
bind(): void;
|
|
168
|
+
set(data: Float32Array, usage?: GLUsage): {
|
|
169
|
+
bind(): void;
|
|
170
|
+
};
|
|
171
|
+
dispose(): void;
|
|
172
|
+
}
|
|
173
|
+
type AttributeView<T extends AttributeSchema> = {
|
|
174
|
+
[K in keyof T]: AttributeMethods<T[K]['kind']>;
|
|
175
|
+
};
|
|
176
|
+
/**********************************************************************************/
|
|
177
|
+
/**********************************************************************************/
|
|
178
|
+
interface InterleavedAttributeLayout {
|
|
179
|
+
name: string;
|
|
180
|
+
kind: AttributeKind;
|
|
181
|
+
}
|
|
182
|
+
interface InterleavedAttributeOptions {
|
|
183
|
+
layout: InterleavedAttributeLayout[];
|
|
184
|
+
instanced?: boolean;
|
|
185
|
+
}
|
|
186
|
+
type InterleavedAttributeSchema = Record<string, InterleavedAttributeOptions>;
|
|
187
|
+
interface InterleavedAttributeMethods<T extends InterleavedAttributeLayout[] = InterleavedAttributeLayout[]> {
|
|
188
|
+
bind(): void;
|
|
189
|
+
unbind(): void;
|
|
190
|
+
set(data: Float32Array, usage?: GLUsage): void;
|
|
191
|
+
dispose(): void;
|
|
192
|
+
}
|
|
193
|
+
type InterleavedAttributeView<T extends InterleavedAttributeSchema> = {
|
|
194
|
+
[K in keyof T]: InterleavedAttributeMethods<T[K]['layout']>;
|
|
195
|
+
};
|
|
196
|
+
/**********************************************************************************/
|
|
197
|
+
/**********************************************************************************/
|
|
198
|
+
interface BufferOptions {
|
|
199
|
+
target?: GLTarget;
|
|
200
|
+
usage?: GLUsage;
|
|
201
|
+
}
|
|
202
|
+
type BufferSchema = Record<string, BufferOptions>;
|
|
203
|
+
interface BufferMethods {
|
|
204
|
+
set(data: Float32Array | Uint16Array | Uint32Array): void;
|
|
205
|
+
bind(): void;
|
|
206
|
+
dispose(): void;
|
|
207
|
+
}
|
|
208
|
+
type BufferView<T extends BufferSchema> = {
|
|
209
|
+
[K in keyof T]: BufferMethods;
|
|
210
|
+
};
|
|
211
|
+
/**********************************************************************************/
|
|
212
|
+
/**********************************************************************************/
|
|
213
|
+
interface ViewOptions {
|
|
214
|
+
signal?: AbortSignal;
|
|
215
|
+
}
|
|
216
|
+
interface ViewSchema {
|
|
217
|
+
uniforms?: UniformSchema;
|
|
218
|
+
attributes?: AttributeSchema;
|
|
219
|
+
interleavedAttributes?: InterleavedAttributeSchema;
|
|
220
|
+
buffers?: BufferSchema;
|
|
221
|
+
}
|
|
222
|
+
type View<T extends ViewSchema = ViewSchema> = {
|
|
223
|
+
attributes: T['attributes'] extends AttributeSchema ? AttributeView<T['attributes']> : undefined;
|
|
224
|
+
interleavedAttributes: T['interleavedAttributes'] extends InterleavedAttributeSchema ? InterleavedAttributeView<T['interleavedAttributes']> : undefined;
|
|
225
|
+
buffers: T['buffers'] extends BufferSchema ? BufferView<T['buffers']> : undefined;
|
|
226
|
+
uniforms: T['uniforms'] extends UniformSchema ? UniformView<T['uniforms']> : never;
|
|
227
|
+
};
|
|
228
|
+
/**********************************************************************************/
|
|
229
|
+
/**********************************************************************************/
|
|
230
|
+
interface GLSL {
|
|
231
|
+
template: string;
|
|
232
|
+
uniforms: Record<string, UniformOptions>;
|
|
233
|
+
attributes: Record<string, AttributeOptions>;
|
|
234
|
+
interleavedAttributes: Record<string, InterleavedAttributeOptions>;
|
|
235
|
+
}
|
|
236
|
+
type UniformTag<TName extends string = string, TKind extends UniformKind = UniformKind, TOptions extends Partial<UniformOptions> = UniformOptions> = TOptions extends {
|
|
237
|
+
size: infer TSize;
|
|
238
|
+
} ? {
|
|
239
|
+
type: 'uniform';
|
|
240
|
+
kind: TKind;
|
|
241
|
+
name: TName;
|
|
242
|
+
size: TSize;
|
|
243
|
+
} : {
|
|
244
|
+
type: 'uniform';
|
|
245
|
+
kind: TKind;
|
|
246
|
+
name: TName;
|
|
247
|
+
};
|
|
248
|
+
interface AttributeTag<TName extends string = string, TKind extends AttributeKind = AttributeKind, TInstanced extends boolean | undefined = boolean | undefined> {
|
|
249
|
+
type: 'attribute';
|
|
250
|
+
kind: TKind;
|
|
251
|
+
instanced: TInstanced;
|
|
252
|
+
name: TName;
|
|
253
|
+
}
|
|
254
|
+
interface AttributeTagFn<TKey extends AttributeKind> {
|
|
255
|
+
<TName extends string, TOptions extends Omit<AttributeOptions, 'kind'>>(name: TName, options: TOptions): Prettify<AttributeTag<TName, TKey, TOptions['instanced']>>;
|
|
256
|
+
<TName extends string>(name: TName): Prettify<AttributeTag<TName, TKey, undefined>>;
|
|
257
|
+
}
|
|
258
|
+
type InterleaveTag<TName extends string = string, TLayout extends Array<AttributeTag<string, AttributeKind, undefined>> = Array<AttributeTag<string, AttributeKind, undefined>>, TOptions extends Omit<AttributeOptions, 'kind'> = Omit<AttributeOptions, 'kind'>> = TOptions & {
|
|
259
|
+
name: TName;
|
|
260
|
+
type: 'interleavedAttribute';
|
|
261
|
+
layout: {
|
|
262
|
+
[TKey in keyof TLayout]: Prettify<Pick<TLayout[TKey], 'kind' | 'name'>>;
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
export type { AttributeSchema as A, BufferSchema as B, GL as G, InterleavedAttributeSchema as I, Merge as M, Prettify as P, UniformSchema as U, ViewSchema as V, ViewOptions as a, View as b, UniformView as c, AttributeView as d, InterleavedAttributeView as e, BufferView as f, UniformKind as g, UniformOptions as h, UniformTag as i, AttributeTagFn as j, AttributeTag as k, AttributeKind as l, AttributeOptions as m, InterleaveTag as n, GLSL as o };
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigmistqke/view.gl",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Minimal library for WebGL shader resource management with type-safe GLSL template literals.",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
|
-
"import": "./index.mjs",
|
|
8
|
-
"types": "./index.d.mts"
|
|
7
|
+
"import": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.mts"
|
|
9
9
|
},
|
|
10
10
|
"./tag": {
|
|
11
|
-
"import": "./tag.mjs",
|
|
12
|
-
"types": "./tag.d.mts"
|
|
11
|
+
"import": "./dist/tag.mjs",
|
|
12
|
+
"types": "./dist/tag.d.mts"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"keywords": [],
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"dev": "vite serve dev",
|
|
27
|
-
"build": "tsup"
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"prepublish": "pnpm build"
|
|
28
29
|
}
|
|
29
30
|
}
|
package/src/tag.ts
CHANGED
|
@@ -76,7 +76,7 @@ export function interleave<
|
|
|
76
76
|
const TName extends string,
|
|
77
77
|
const TLayout extends Array<AttributeTag<string, AttributeKind, undefined>>,
|
|
78
78
|
const TOptions extends Omit<AttributeOptions, 'kind'>,
|
|
79
|
-
>(name: TName, layout: TLayout, { instanced, buffer }
|
|
79
|
+
>(name: TName, layout: TLayout, { instanced, buffer }: Partial<TOptions> = {}) {
|
|
80
80
|
return {
|
|
81
81
|
type: 'interleavedAttribute',
|
|
82
82
|
name,
|