133 lines
3.2 KiB
JavaScript
133 lines
3.2 KiB
JavaScript
import { SmcErr } from './errors.js';
|
|
|
|
export { SmcProgramBuilder };
|
|
|
|
class SmcProgramBuilder {
|
|
#gl;
|
|
#program;
|
|
|
|
#isBuilt = false;
|
|
#hasVertexShader = false;
|
|
#hasFragmentShader = false;
|
|
|
|
#defaultVertexShader = `
|
|
attribute vec4 aVertex;
|
|
|
|
void main() {
|
|
gl_Position = aVertex;
|
|
}
|
|
`;
|
|
|
|
// TODO: reset the sample fragment shader back to the rainbow
|
|
#sampleFragmentShader = `
|
|
precision mediump float;
|
|
|
|
// uniform float uTime;
|
|
uniform vec2 uResolution;
|
|
|
|
void main() {
|
|
vec2 uv = gl_FragCoord.xy / uResolution.xy;
|
|
// vec3 col = 0.5 + 0.5 * cos(uTime + uv.xyx + vec3(0, 2, 4));
|
|
// gl_FragColor = vec4(col, 1.0);
|
|
// gl_FragColor = vec4(216., 43., 72., 255.) / 255.;
|
|
|
|
|
|
// float maxfc = max(gl_FragCoord.x, gl_FragCoord.y);
|
|
// gl_FragColor = vec4(gl_FragCoord.xy, maxfc, maxfc) / maxfc;
|
|
|
|
float maxuv = max(uv.x, uv.y);
|
|
gl_FragColor = vec4(216. * maxuv, 43., 72., 255.) / 255.;
|
|
|
|
|
|
// vec3 col = 0.5 + 0.5*cos(uv.xyx+vec3(0,2,4));
|
|
// gl_FragColor = vec4(col, 1.);
|
|
}
|
|
`;
|
|
|
|
|
|
constructor(gl, raiseError) {
|
|
this.#gl = gl;
|
|
this.#program = this.#gl.createProgram();
|
|
this.raiseError = raiseError;
|
|
}
|
|
|
|
addVertexShader(source) {
|
|
this.#gl.attachShader(
|
|
this.#program,
|
|
this.#newShader(
|
|
this.#gl.VERTEX_SHADER,
|
|
source
|
|
)
|
|
)
|
|
this.#hasVertexShader = true;
|
|
return this;
|
|
}
|
|
|
|
addFragmentShader(source) {
|
|
this.#gl.attachShader(
|
|
this.#program,
|
|
this.#newShader(
|
|
this.#gl.FRAGMENT_SHADER,
|
|
source
|
|
)
|
|
)
|
|
console.log(source)
|
|
this.#hasFragmentShader = true;
|
|
return this;
|
|
}
|
|
|
|
// fetchVertexShader(uri) {
|
|
// (async () => this.#fetchShader(uri, (source) => this.addVertexShader(source)))();
|
|
// return this;
|
|
// }
|
|
|
|
// async fetchFragmentShader(uri) {
|
|
// var delegate = (source) => this.addFragmentShader(source);
|
|
// var source = await this.#fetchShader(uri);
|
|
// return this;
|
|
// }
|
|
|
|
build() {
|
|
// avoid user accidental calls to build()
|
|
if (!this.#isBuilt) {
|
|
if (!this.#hasVertexShader)
|
|
this.addVertexShader(this.#defaultVertexShader)
|
|
if (!this.#hasFragmentShader)
|
|
this.addFragmentShader(this.#sampleFragmentShader);
|
|
|
|
this.#gl.linkProgram(this.#program);
|
|
this.#gl.useProgram(this.#program);
|
|
}
|
|
return this.#program;
|
|
}
|
|
|
|
// Creates a shader of the given type, uploads the source and compiles
|
|
#newShader(type, source) {
|
|
const shader = this.#gl.createShader(type);
|
|
this.#gl.shaderSource(shader, source);
|
|
this.#gl.compileShader(shader);
|
|
|
|
if (!this.#gl.getShaderParameter(shader, this.#gl.COMPILE_STATUS)) {
|
|
this.#gl.deleteShader(shader);
|
|
const infoLog = this.#gl.getShaderInfoLog(shader);
|
|
this.raiseError(
|
|
SmcErr.SHADER_COMPILATION,
|
|
new Error(`An error occurred while compiling the shader: ${infoLog}`)
|
|
);
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
|
|
// async #fetchShader(uri, delegate) {
|
|
// const res = await fetch(uri);
|
|
// if (res.ok)
|
|
// return await res.text();
|
|
// this.raiseError(
|
|
// SmcErr.FETCH_SHADER,
|
|
// `Failed to load shader source ${url}: ${res.status} ${res.json()}`);
|
|
// return ""
|
|
// }
|
|
|
|
}
|
|
|