created ShadeMyCanvas (smc)
This commit is contained in:
parent
935cc44f66
commit
1d06470ccd
12 changed files with 539 additions and 24 deletions
127
www/js/smc/progbuilder.js
Normal file
127
www/js/smc/progbuilder.js
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
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;
|
||||
// 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;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
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
|
||||
)
|
||||
)
|
||||
this.#hasFragmentShader = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
fetchVertexShader(uri) {
|
||||
this.#fetchShader(uri, (source) => this.addVertexShader(source));
|
||||
return this;
|
||||
}
|
||||
|
||||
fetchFragmentShader(uri) {
|
||||
this.#fetchShader(uri, (source) => this.addFragmentShader(source));
|
||||
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;
|
||||
}
|
||||
|
||||
#fetchShader(uri, delegate) {
|
||||
return fetch(uri)
|
||||
.then(res => {
|
||||
if (res.ok)
|
||||
delegate(res.text());
|
||||
else {
|
||||
this.raiseError(
|
||||
SmcErr.FETCH_SHADER,
|
||||
`Failed to load shader source ${url}: ${res.status} ${res.json()}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue