@thi.ng/webgl 6.6.11 → 6.6.13

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/shader.js CHANGED
@@ -11,8 +11,12 @@ import { targetGLSL } from "@thi.ng/shader-ast-glsl/target";
11
11
  import { program } from "@thi.ng/shader-ast/ast/scope";
12
12
  import { input, output, sym, uniform } from "@thi.ng/shader-ast/ast/sym";
13
13
  import { vals } from "@thi.ng/transducers/vals";
14
- import { GL_EXT_INFO, } from "./api/ext.js";
15
- import { DEFAULT_OUTPUT, } from "./api/shader.js";
14
+ import {
15
+ GL_EXT_INFO
16
+ } from "./api/ext.js";
17
+ import {
18
+ DEFAULT_OUTPUT
19
+ } from "./api/shader.js";
16
20
  import { getExtensions } from "./canvas.js";
17
21
  import { isGL2Context } from "./checks.js";
18
22
  import { error } from "./error.js";
@@ -20,379 +24,382 @@ import { LOGGER } from "./logger.js";
20
24
  import { GLSL_HEADER, NO_PREFIXES, SYNTAX } from "./syntax.js";
21
25
  import { UNIFORM_SETTERS } from "./uniforms.js";
22
26
  const ERROR_REGEXP = /ERROR: \d+:(\d+): (.*)/;
23
- export class Shader {
24
- gl;
25
- program;
26
- attribs;
27
- uniforms;
28
- state;
29
- warnAttrib = doOnce((id) => LOGGER.warn(`unknown attrib: ${id} (no further warnings will be shown...)`));
30
- warnUni = doOnce((id) => LOGGER.warn(`unknown uniform: ${id} (no further warnings will be shown...)`));
31
- constructor(gl, program, attribs, uniforms, state) {
32
- this.gl = gl;
33
- this.program = program;
34
- this.attribs = attribs;
35
- this.uniforms = uniforms;
36
- this.state = state || {};
27
+ class Shader {
28
+ gl;
29
+ program;
30
+ attribs;
31
+ uniforms;
32
+ state;
33
+ warnAttrib = doOnce(
34
+ (id) => LOGGER.warn(
35
+ `unknown attrib: ${id} (no further warnings will be shown...)`
36
+ )
37
+ );
38
+ warnUni = doOnce(
39
+ (id) => LOGGER.warn(
40
+ `unknown uniform: ${id} (no further warnings will be shown...)`
41
+ )
42
+ );
43
+ constructor(gl, program2, attribs, uniforms, state) {
44
+ this.gl = gl;
45
+ this.program = program2;
46
+ this.attribs = attribs;
47
+ this.uniforms = uniforms;
48
+ this.state = state || {};
49
+ }
50
+ /**
51
+ * Returns a shallow copy of this shader with its state config merged with
52
+ * given options (priority). Useful for re-using a shader, but applying
53
+ * different settings.
54
+ *
55
+ * @param state
56
+ */
57
+ withState(state) {
58
+ return new Shader(this.gl, this.program, this.attribs, this.uniforms, {
59
+ ...this.state,
60
+ ...state
61
+ });
62
+ }
63
+ bind(spec) {
64
+ if (this.program) {
65
+ this.gl.useProgram(this.program);
66
+ this.bindAttribs(spec.attribs);
67
+ this.bindUniforms(spec.uniforms);
68
+ return true;
37
69
  }
38
- /**
39
- * Returns a shallow copy of this shader with its state config merged with
40
- * given options (priority). Useful for re-using a shader, but applying
41
- * different settings.
42
- *
43
- * @param state
44
- */
45
- withState(state) {
46
- return new Shader(this.gl, this.program, this.attribs, this.uniforms, {
47
- ...this.state,
48
- ...state,
49
- });
70
+ return false;
71
+ }
72
+ unbind() {
73
+ let shaderAttrib;
74
+ for (let id in this.attribs) {
75
+ if (shaderAttrib = this.attribs[id]) {
76
+ this.gl.disableVertexAttribArray(shaderAttrib.loc);
77
+ }
50
78
  }
51
- bind(spec) {
52
- if (this.program) {
53
- this.gl.useProgram(this.program);
54
- this.bindAttribs(spec.attribs);
55
- this.bindUniforms(spec.uniforms);
56
- return true;
57
- }
58
- return false;
79
+ this.gl.useProgram(null);
80
+ return true;
81
+ }
82
+ release() {
83
+ if (this.program) {
84
+ this.gl.deleteProgram(this.program);
85
+ delete this.program;
86
+ return true;
59
87
  }
60
- unbind() {
61
- let shaderAttrib;
62
- for (let id in this.attribs) {
63
- if ((shaderAttrib = this.attribs[id])) {
64
- this.gl.disableVertexAttribArray(shaderAttrib.loc);
65
- }
66
- }
67
- this.gl.useProgram(null);
68
- return true;
88
+ return false;
89
+ }
90
+ bindAttribs(specAttribs) {
91
+ const gl = this.gl;
92
+ let shaderAttrib;
93
+ for (let id in specAttribs) {
94
+ if (shaderAttrib = this.attribs[id]) {
95
+ const attr = specAttribs[id];
96
+ attr.buffer.bind();
97
+ gl.enableVertexAttribArray(shaderAttrib.loc);
98
+ gl.vertexAttribPointer(
99
+ shaderAttrib.loc,
100
+ attr.size || 3,
101
+ asGLType(attr.type || gl.FLOAT),
102
+ attr.normalized || false,
103
+ attr.stride || 0,
104
+ attr.offset || 0
105
+ );
106
+ } else {
107
+ this.warnAttrib(id);
108
+ }
69
109
  }
70
- release() {
71
- if (this.program) {
72
- this.gl.deleteProgram(this.program);
73
- delete this.program;
74
- return true;
75
- }
76
- return false;
110
+ }
111
+ bindUniforms(specUnis = {}) {
112
+ const shaderUnis = this.uniforms;
113
+ for (let id in specUnis) {
114
+ const u = shaderUnis[id];
115
+ if (u) {
116
+ let val = specUnis[id];
117
+ val = isFunction(val) ? val(shaderUnis, specUnis) : deref(val);
118
+ u.setter(val);
119
+ } else {
120
+ this.warnUni(id);
121
+ }
77
122
  }
78
- bindAttribs(specAttribs) {
79
- const gl = this.gl;
80
- let shaderAttrib;
81
- for (let id in specAttribs) {
82
- if ((shaderAttrib = this.attribs[id])) {
83
- const attr = specAttribs[id];
84
- attr.buffer.bind();
85
- gl.enableVertexAttribArray(shaderAttrib.loc);
86
- gl.vertexAttribPointer(shaderAttrib.loc, attr.size || 3, asGLType(attr.type || gl.FLOAT), attr.normalized || false, attr.stride || 0, attr.offset || 0);
87
- }
88
- else {
89
- this.warnAttrib(id);
90
- }
91
- }
123
+ for (let id in shaderUnis) {
124
+ if (shaderUnis.hasOwnProperty(id) && (!specUnis || !existsAndNotNull(specUnis[id]))) {
125
+ const u = shaderUnis[id];
126
+ const val = u.defaultFn ? u.defaultFn(shaderUnis, specUnis) : u.defaultVal;
127
+ u.setter(val);
128
+ }
92
129
  }
93
- bindUniforms(specUnis = {}) {
94
- const shaderUnis = this.uniforms;
95
- for (let id in specUnis) {
96
- const u = shaderUnis[id];
97
- if (u) {
98
- let val = specUnis[id];
99
- val = isFunction(val) ? val(shaderUnis, specUnis) : deref(val);
100
- // console.log(id, val);
101
- u.setter(val);
102
- }
103
- else {
104
- this.warnUni(id);
105
- }
106
- }
107
- // apply defaults for non-specified uniforms in user spec
108
- for (let id in shaderUnis) {
109
- if (shaderUnis.hasOwnProperty(id) &&
110
- (!specUnis || !existsAndNotNull(specUnis[id]))) {
111
- const u = shaderUnis[id];
112
- const val = u.defaultFn
113
- ? u.defaultFn(shaderUnis, specUnis)
114
- : u.defaultVal;
115
- // console.log("default", id, val);
116
- u.setter(val);
117
- }
118
- }
130
+ }
131
+ prepareState(state = this.state) {
132
+ const gl = this.gl;
133
+ state.depth !== void 0 && this.setState(gl.DEPTH_TEST, state.depth);
134
+ if (state.cull !== void 0) {
135
+ this.setState(gl.CULL_FACE, state.cull);
136
+ state.cullMode && gl.cullFace(state.cullMode);
119
137
  }
120
- prepareState(state = this.state) {
121
- const gl = this.gl;
122
- state.depth !== undefined && this.setState(gl.DEPTH_TEST, state.depth);
123
- if (state.cull !== undefined) {
124
- this.setState(gl.CULL_FACE, state.cull);
125
- state.cullMode && gl.cullFace(state.cullMode);
126
- }
127
- if (state.blend !== undefined) {
128
- this.setState(gl.BLEND, state.blend);
129
- state.blendFn && gl.blendFunc(state.blendFn[0], state.blendFn[1]);
130
- state.blendEq !== undefined && gl.blendEquation(state.blendEq);
131
- }
132
- if (state.stencil !== undefined) {
133
- this.setState(gl.STENCIL_TEST, state.stencil);
134
- state.stencilFn &&
135
- gl.stencilFunc(state.stencilFn[0], state.stencilFn[1], state.stencilFn[2]);
136
- state.stencilOp &&
137
- gl.stencilOp(state.stencilOp[0], state.stencilOp[1], state.stencilOp[2]);
138
- state.stencilMask !== undefined &&
139
- gl.stencilMask(state.stencilMask);
140
- }
138
+ if (state.blend !== void 0) {
139
+ this.setState(gl.BLEND, state.blend);
140
+ state.blendFn && gl.blendFunc(state.blendFn[0], state.blendFn[1]);
141
+ state.blendEq !== void 0 && gl.blendEquation(state.blendEq);
141
142
  }
142
- setState(id, val) {
143
- if (val) {
144
- this.gl.enable(id);
145
- }
146
- else {
147
- this.gl.disable(id);
148
- }
143
+ if (state.stencil !== void 0) {
144
+ this.setState(gl.STENCIL_TEST, state.stencil);
145
+ state.stencilFn && gl.stencilFunc(
146
+ state.stencilFn[0],
147
+ state.stencilFn[1],
148
+ state.stencilFn[2]
149
+ );
150
+ state.stencilOp && gl.stencilOp(
151
+ state.stencilOp[0],
152
+ state.stencilOp[1],
153
+ state.stencilOp[2]
154
+ );
155
+ state.stencilMask !== void 0 && gl.stencilMask(state.stencilMask);
149
156
  }
150
- }
151
- export const defShader = (gl, spec, opts) => {
152
- const version = isGL2Context(gl)
153
- ? GLSLVersion.GLES_300
154
- : GLSLVersion.GLES_100;
155
- const srcVS = isFunction(spec.vs)
156
- ? shaderSourceFromAST(spec, "vs", version, opts)
157
- : prepareShaderSource(spec, "vs", version);
158
- const srcFS = isFunction(spec.fs)
159
- ? shaderSourceFromAST(spec, "fs", version, opts)
160
- : prepareShaderSource(spec, "fs", version);
161
- const logger = opts?.logger || LOGGER;
162
- logger.debug(srcVS);
163
- logger.debug(srcFS);
164
- initShaderExtensions(gl, spec.ext);
165
- const vs = compileShader(gl, gl.VERTEX_SHADER, srcVS);
166
- const fs = compileShader(gl, gl.FRAGMENT_SHADER, srcFS);
167
- const program = gl.createProgram() || error("error creating shader program");
168
- gl.attachShader(program, vs);
169
- gl.attachShader(program, fs);
170
- gl.linkProgram(program);
171
- if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
172
- const attribs = initAttributes(gl, program, spec.attribs);
173
- const uniforms = initUniforms(gl, program, spec.uniforms);
174
- gl.deleteShader(vs);
175
- gl.deleteShader(fs);
176
- return new Shader(gl, program, attribs, uniforms, spec.state);
157
+ }
158
+ setState(id, val) {
159
+ if (val) {
160
+ this.gl.enable(id);
161
+ } else {
162
+ this.gl.disable(id);
177
163
  }
178
- throw new Error(`Error linking shader: ${gl.getProgramInfoLog(program)}`);
164
+ }
165
+ }
166
+ const defShader = (gl, spec, opts) => {
167
+ const version = isGL2Context(gl) ? GLSLVersion.GLES_300 : GLSLVersion.GLES_100;
168
+ const srcVS = isFunction(spec.vs) ? shaderSourceFromAST(spec, "vs", version, opts) : prepareShaderSource(spec, "vs", version);
169
+ const srcFS = isFunction(spec.fs) ? shaderSourceFromAST(spec, "fs", version, opts) : prepareShaderSource(spec, "fs", version);
170
+ const logger = opts?.logger || LOGGER;
171
+ logger.debug(srcVS);
172
+ logger.debug(srcFS);
173
+ initShaderExtensions(gl, spec.ext);
174
+ const vs = compileShader(gl, gl.VERTEX_SHADER, srcVS);
175
+ const fs = compileShader(gl, gl.FRAGMENT_SHADER, srcFS);
176
+ const program2 = gl.createProgram() || error("error creating shader program");
177
+ gl.attachShader(program2, vs);
178
+ gl.attachShader(program2, fs);
179
+ gl.linkProgram(program2);
180
+ if (gl.getProgramParameter(program2, gl.LINK_STATUS)) {
181
+ const attribs = initAttributes(gl, program2, spec.attribs);
182
+ const uniforms = initUniforms(gl, program2, spec.uniforms);
183
+ gl.deleteShader(vs);
184
+ gl.deleteShader(fs);
185
+ return new Shader(gl, program2, attribs, uniforms, spec.state);
186
+ }
187
+ throw new Error(`Error linking shader: ${gl.getProgramInfoLog(program2)}`);
179
188
  };
180
189
  const compileVars = (attribs, syntax, prefixes) => {
181
- let decls = [];
182
- for (let id in attribs) {
183
- if (attribs.hasOwnProperty(id)) {
184
- decls.push(syntax(id, attribs[id], prefixes));
185
- }
190
+ let decls = [];
191
+ for (let id in attribs) {
192
+ if (attribs.hasOwnProperty(id)) {
193
+ decls.push(syntax(id, attribs[id], prefixes));
186
194
  }
187
- decls.push("");
188
- return decls.join("\n");
195
+ }
196
+ decls.push("");
197
+ return decls.join("\n");
189
198
  };
190
199
  const compileExtensionPragma = (id, behavior, version) => {
191
- const ext = GL_EXT_INFO[id];
192
- const gl2 = version === GLSLVersion.GLES_300;
193
- return ext && ((!gl2 && ext.gl) || (gl2 && ext.gl2))
194
- ? `#extension ${(ext && ext.alias) || id} : ${isBoolean(behavior)
195
- ? behavior
196
- ? "enable"
197
- : "disable"
198
- : behavior}\n`
199
- : "";
200
+ const ext = GL_EXT_INFO[id];
201
+ const gl2 = version === GLSLVersion.GLES_300;
202
+ return ext && (!gl2 && ext.gl || gl2 && ext.gl2) ? `#extension ${ext && ext.alias || id} : ${isBoolean(behavior) ? behavior ? "enable" : "disable" : behavior}
203
+ ` : "";
200
204
  };
201
205
  const initShaderExtensions = (gl, exts) => {
202
- if (exts) {
203
- for (let id in exts) {
204
- const state = exts[id];
205
- if (state === true || state === "require") {
206
- getExtensions(gl, [id], state === "require");
207
- }
208
- }
206
+ if (exts) {
207
+ for (let id in exts) {
208
+ const state = exts[id];
209
+ if (state === true || state === "require") {
210
+ getExtensions(gl, [id], state === "require");
211
+ }
209
212
  }
213
+ }
210
214
  };
211
215
  const compilePrelude = (spec, version) => {
212
- let prelude = spec.pre
213
- ? spec.replacePrelude
214
- ? spec.pre
215
- : spec.pre + "\n" + GLSL_HEADER
216
- : GLSL_HEADER;
217
- if (spec.ext) {
218
- for (let id in spec.ext) {
219
- prelude += compileExtensionPragma(id, spec.ext[id], version);
220
- }
216
+ let prelude = spec.pre ? spec.replacePrelude ? spec.pre : spec.pre + "\n" + GLSL_HEADER : GLSL_HEADER;
217
+ if (spec.ext) {
218
+ for (let id in spec.ext) {
219
+ prelude += compileExtensionPragma(
220
+ id,
221
+ spec.ext[id],
222
+ version
223
+ );
221
224
  }
222
- return prelude;
225
+ }
226
+ return prelude;
223
227
  };
224
228
  const compileIODecls = (decl, src, dest) => {
225
- for (let id in src) {
226
- const a = src[id];
227
- dest[id] = isArray(a)
228
- ? decl(a[0], id, { loc: a[1] })
229
- : decl(a, id);
230
- }
229
+ for (let id in src) {
230
+ const a = src[id];
231
+ dest[id] = isArray(a) ? decl(a[0], id, { loc: a[1] }) : decl(a, id);
232
+ }
231
233
  };
232
234
  const varyingOpts = (v) => {
233
- const [vtype, opts] = isArray(v)
234
- ? [v[0], { num: v[1] }]
235
- : [v, {}];
236
- /(u?int|[ui]vec[234])/.test(vtype) && (opts.smooth = "flat");
237
- return [vtype, opts];
235
+ const [vtype, opts] = isArray(v) ? [v[0], { num: v[1] }] : [v, {}];
236
+ /(u?int|[ui]vec[234])/.test(vtype) && (opts.smooth = "flat");
237
+ return [vtype, opts];
238
238
  };
239
239
  const compileVaryingDecls = (spec, decl, acc) => {
240
- for (let id in spec.varying) {
241
- const [vtype, opts] = varyingOpts(spec.varying[id]);
242
- acc[id] = decl(vtype, id, opts);
243
- }
240
+ for (let id in spec.varying) {
241
+ const [vtype, opts] = varyingOpts(spec.varying[id]);
242
+ acc[id] = decl(vtype, id, opts);
243
+ }
244
244
  };
245
245
  const compileUniformDecls = (spec, acc) => {
246
- for (let id in spec.uniforms) {
247
- const u = spec.uniforms[id];
248
- acc[id] = isArray(u)
249
- ? uniform(u[0], id, u[0].indexOf("[]") > 0 ? { num: u[1] } : undefined)
250
- : uniform(u, id);
251
- }
246
+ for (let id in spec.uniforms) {
247
+ const u = spec.uniforms[id];
248
+ acc[id] = isArray(u) ? uniform(
249
+ u[0],
250
+ id,
251
+ u[0].indexOf("[]") > 0 ? { num: u[1] } : void 0
252
+ ) : uniform(u, id);
253
+ }
252
254
  };
253
- export const shaderSourceFromAST = (spec, type, version, opts = {}) => {
254
- let prelude = compilePrelude(spec, version);
255
- const inputs = {};
256
- const outputs = {};
257
- const outputAliases = {};
258
- const unis = {};
259
- spec.uniforms && compileUniformDecls(spec, unis);
260
- if (type === "vs") {
261
- compileIODecls(input, spec.attribs, inputs);
262
- spec.varying && compileVaryingDecls(spec, output, outputs);
263
- }
264
- else {
265
- spec.varying && compileVaryingDecls(spec, input, inputs);
266
- const outs = spec.outputs || DEFAULT_OUTPUT;
267
- if (version >= GLSLVersion.GLES_300) {
268
- compileIODecls(output, outs, outputs);
269
- }
270
- else {
271
- for (let id in outs) {
272
- const o = outs[id];
273
- if (isArray(o) && o[0] === "vec4") {
274
- prelude += `#define ${id} gl_FragData[${o[1]}]\n`;
275
- outputAliases[id] = sym("vec4", id);
276
- }
277
- else {
278
- unsupported(`GLSL ${version} doesn't support output vars`);
279
- }
280
- }
255
+ const shaderSourceFromAST = (spec, type, version, opts = {}) => {
256
+ let prelude = compilePrelude(spec, version);
257
+ const inputs = {};
258
+ const outputs = {};
259
+ const outputAliases = {};
260
+ const unis = {};
261
+ spec.uniforms && compileUniformDecls(spec, unis);
262
+ if (type === "vs") {
263
+ compileIODecls(input, spec.attribs, inputs);
264
+ spec.varying && compileVaryingDecls(spec, output, outputs);
265
+ } else {
266
+ spec.varying && compileVaryingDecls(spec, input, inputs);
267
+ const outs = spec.outputs || DEFAULT_OUTPUT;
268
+ if (version >= GLSLVersion.GLES_300) {
269
+ compileIODecls(output, outs, outputs);
270
+ } else {
271
+ for (let id in outs) {
272
+ const o = outs[id];
273
+ if (isArray(o) && o[0] === "vec4") {
274
+ prelude += `#define ${id} gl_FragData[${o[1]}]
275
+ `;
276
+ outputAliases[id] = sym("vec4", id);
277
+ } else {
278
+ unsupported(`GLSL ${version} doesn't support output vars`);
281
279
  }
280
+ }
282
281
  }
283
- const target = targetGLSL({
284
- type,
285
- version,
286
- prelude,
287
- prec: opts.prec,
288
- });
289
- return (target(program([
290
- ...vals(unis),
291
- ...vals(inputs),
292
- ...vals(outputs),
293
- ...spec[type](target, unis, inputs, {
294
- ...outputs,
295
- ...outputAliases,
296
- }),
297
- ])) + (spec.post ? "\n" + spec.post : ""));
282
+ }
283
+ const target = targetGLSL({
284
+ type,
285
+ version,
286
+ prelude,
287
+ prec: opts.prec
288
+ });
289
+ return target(
290
+ program([
291
+ ...vals(unis),
292
+ ...vals(inputs),
293
+ ...vals(outputs),
294
+ ...spec[type](target, unis, inputs, {
295
+ ...outputs,
296
+ ...outputAliases
297
+ })
298
+ ])
299
+ ) + (spec.post ? "\n" + spec.post : "");
298
300
  };
299
- export const prepareShaderSource = (spec, type, version) => {
300
- const syntax = SYNTAX[version];
301
- const prefixes = { ...NO_PREFIXES, ...spec.declPrefixes };
302
- const isVS = type === "vs";
303
- let src = "";
304
- src += `#version ${version}\n`;
305
- src += compilePrelude(spec, version);
306
- if (spec.generateDecls !== false) {
307
- src += isVS
308
- ? compileVars(spec.attribs, syntax.attrib, prefixes)
309
- : compileVars(spec.outputs || DEFAULT_OUTPUT, syntax.output, prefixes);
310
- src += compileVars(spec.varying, syntax.varying[type], prefixes);
311
- src += compileVars(spec.uniforms, syntax.uniform, prefixes);
312
- }
313
- src += spec[type];
314
- spec.post && (src += "\n" + spec.post);
315
- return src;
301
+ const prepareShaderSource = (spec, type, version) => {
302
+ const syntax = SYNTAX[version];
303
+ const prefixes = { ...NO_PREFIXES, ...spec.declPrefixes };
304
+ const isVS = type === "vs";
305
+ let src = "";
306
+ src += `#version ${version}
307
+ `;
308
+ src += compilePrelude(spec, version);
309
+ if (spec.generateDecls !== false) {
310
+ src += isVS ? compileVars(spec.attribs, syntax.attrib, prefixes) : compileVars(
311
+ spec.outputs || DEFAULT_OUTPUT,
312
+ syntax.output,
313
+ prefixes
314
+ );
315
+ src += compileVars(spec.varying, syntax.varying[type], prefixes);
316
+ src += compileVars(spec.uniforms, syntax.uniform, prefixes);
317
+ }
318
+ src += spec[type];
319
+ spec.post && (src += "\n" + spec.post);
320
+ return src;
316
321
  };
317
- export const compileShader = (gl, type, src) => {
318
- const shader = gl.createShader(type) || error("error creating shader");
319
- gl.shaderSource(shader, src);
320
- gl.compileShader(shader);
321
- if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
322
- return shader;
323
- }
324
- return parseAndThrowShaderError(gl, shader, src);
322
+ const compileShader = (gl, type, src) => {
323
+ const shader = gl.createShader(type) || error("error creating shader");
324
+ gl.shaderSource(shader, src);
325
+ gl.compileShader(shader);
326
+ if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
327
+ return shader;
328
+ }
329
+ return parseAndThrowShaderError(gl, shader, src);
325
330
  };
326
331
  const parseAndThrowShaderError = (gl, shader, src) => {
327
- const lines = src.split("\n");
328
- const log = gl.getShaderInfoLog(shader).split("\n");
329
- const errors = log
330
- .map((line) => {
331
- const matches = ERROR_REGEXP.exec(line);
332
- const ln = matches ? matches[1] : null;
333
- if (ln) {
334
- return `line ${ln}: ${matches[2]}\n${lines[parseInt(ln) - 1]}`;
335
- }
336
- })
337
- .filter(existsAndNotNull)
338
- .join("\n");
339
- return error(`Error compiling shader:\n${errors}`);
332
+ const lines = src.split("\n");
333
+ const log = gl.getShaderInfoLog(shader).split("\n");
334
+ const errors = log.map((line) => {
335
+ const matches = ERROR_REGEXP.exec(line);
336
+ const ln = matches ? matches[1] : null;
337
+ if (ln) {
338
+ return `line ${ln}: ${matches[2]}
339
+ ${lines[parseInt(ln) - 1]}`;
340
+ }
341
+ }).filter(existsAndNotNull).join("\n");
342
+ return error(`Error compiling shader:
343
+ ${errors}`);
340
344
  };
341
345
  const initAttributes = (gl, prog, attribs) => {
342
- const res = {};
343
- for (let id in attribs) {
344
- const val = attribs[id];
345
- const [type, loc] = isArray(val) ? val : [val, null];
346
- const aid = id;
347
- if (loc != null) {
348
- gl.bindAttribLocation(prog, loc, aid);
349
- res[id] = { type, loc };
350
- }
351
- else {
352
- res[id] = {
353
- type,
354
- loc: gl.getAttribLocation(prog, aid),
355
- };
356
- }
346
+ const res = {};
347
+ for (let id in attribs) {
348
+ const val = attribs[id];
349
+ const [type, loc] = isArray(val) ? val : [val, null];
350
+ const aid = id;
351
+ if (loc != null) {
352
+ gl.bindAttribLocation(prog, loc, aid);
353
+ res[id] = { type, loc };
354
+ } else {
355
+ res[id] = {
356
+ type,
357
+ loc: gl.getAttribLocation(prog, aid)
358
+ };
357
359
  }
358
- return res;
360
+ }
361
+ return res;
359
362
  };
360
363
  const initUniforms = (gl, prog, uniforms = {}) => {
361
- const res = {};
362
- for (let id in uniforms) {
363
- const val = uniforms[id];
364
- let type;
365
- let t1, t2, defaultVal, defaultFn;
366
- if (isArray(val)) {
367
- [type, t1, t2] = val;
368
- defaultVal = type.indexOf("[]") < 0 ? t1 : t2;
369
- if (isFunction(defaultVal)) {
370
- defaultFn = defaultVal;
371
- defaultVal = undefined;
372
- }
373
- }
374
- else {
375
- type = val;
376
- }
377
- const loc = gl.getUniformLocation(prog, id);
378
- if (loc != null) {
379
- const setter = UNIFORM_SETTERS[type];
380
- if (setter) {
381
- res[id] = {
382
- loc,
383
- setter: setter(gl, loc, defaultVal),
384
- defaultFn,
385
- defaultVal,
386
- type,
387
- };
388
- }
389
- else {
390
- error(`invalid uniform type: ${type}`);
391
- }
392
- }
393
- else {
394
- LOGGER.warn(`unknown uniform: ${id}`);
395
- }
364
+ const res = {};
365
+ for (let id in uniforms) {
366
+ const val = uniforms[id];
367
+ let type;
368
+ let t1, t2, defaultVal, defaultFn;
369
+ if (isArray(val)) {
370
+ [type, t1, t2] = val;
371
+ defaultVal = type.indexOf("[]") < 0 ? t1 : t2;
372
+ if (isFunction(defaultVal)) {
373
+ defaultFn = defaultVal;
374
+ defaultVal = void 0;
375
+ }
376
+ } else {
377
+ type = val;
396
378
  }
397
- return res;
379
+ const loc = gl.getUniformLocation(prog, id);
380
+ if (loc != null) {
381
+ const setter = UNIFORM_SETTERS[type];
382
+ if (setter) {
383
+ res[id] = {
384
+ loc,
385
+ setter: setter(gl, loc, defaultVal),
386
+ defaultFn,
387
+ defaultVal,
388
+ type
389
+ };
390
+ } else {
391
+ error(`invalid uniform type: ${type}`);
392
+ }
393
+ } else {
394
+ LOGGER.warn(`unknown uniform: ${id}`);
395
+ }
396
+ }
397
+ return res;
398
+ };
399
+ export {
400
+ Shader,
401
+ compileShader,
402
+ defShader,
403
+ prepareShaderSource,
404
+ shaderSourceFromAST
398
405
  };