Files
legolog/client/public/brick-renderer/shader.mjs
Benjamin Kyd 4a83c84d3d something
Former-commit-id: 41811c2d7d98c1d3ad65e0d1dd559de64f96845e
2022-03-25 15:57:12 +00:00

128 lines
4.0 KiB
JavaScript

export default class Shader {
constructor(gl, vSource, fSource) {
this.gl = gl;
this.vSource = vSource;
this.fSource = fSource;
this.uniformBlockNum = 0;
this.shaderProgram = 123;
this.vShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(this.vShader, this.vSource);
this.gl.compileShader(this.vShader);
if (!this.gl.getShaderParameter(this.vShader, this.gl.COMPILE_STATUS)) {
console.error(this.gl.getShaderInfoLog(this.vShader));
}
this.fShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(this.fShader, this.fSource);
this.gl.compileShader(this.fShader);
if (!this.gl.getShaderParameter(this.fShader, this.gl.COMPILE_STATUS)) {
console.error(this.gl.getShaderInfoLog(this.fShader));
}
}
get vertexShader() {
return this.vShader;
}
get fragmentShader() {
return this.fShader;
}
get program() {
return this.shaderProgram;
}
getUniformBlock(name) {
const location = this.gl.getUniformBlockIndex(this.shaderProgram, name);
this.gl.uniformBlockBinding(this.shaderProgram, location, this.uniformBlockNum);
this.uniformBlockNum++;
return location;
}
getUniform(name) {
return this.gl.getUniformLocation(this.shaderProgram, name);
}
attribLocation(location, name) {
this.gl.bindAttribLocation(this.shaderProgram, location, name);
}
setUniform(uniform, value) {
switch (uniform.type) {
case this.gl.FLOAT:
this.gl.uniform1f(uniform, value);
break;
case this.gl.FLOAT_VEC2:
this.gl.uniform2f(uniform, value[0], value[1]);
break;
case this.gl.FLOAT_VEC3:
this.gl.uniform3f(uniform, value[0], value[1], value[2]);
break;
case this.gl.FLOAT_VEC4:
this.gl.uniform4f(uniform, value[0], value[1], value[2], value[3]);
break;
case this.gl.INT:
this.gl.uniform1i(uniform, value);
break;
case this.gl.INT_VEC2:
this.gl.uniform2i(uniform, value[0], value[1]);
break;
case this.gl.INT_VEC3:
this.gl.uniform3i(uniform, value[0], value[1], value[2]);
break;
case this.gl.INT_VEC4:
this.gl.uniform4i(uniform, value[0], value[1], value[2], value[3]);
break;
case this.gl.BOOL:
this.gl.uniform1i(uniform, value);
break;
case this.gl.BOOL_VEC2:
this.gl.uniform2i(uniform, value[0], value[1]);
break;
case this.gl.BOOL_VEC3:
this.gl.uniform3i(uniform, value[0], value[1], value[2]);
break;
case this.gl.BOOL_VEC4:
this.gl.uniform4i(uniform, value[0], value[1], value[2], value[3]);
break;
case this.gl.FLOAT_MAT2:
this.gl.uniformMatrix2fv(uniform, false, value);
break;
case this.gl.FLOAT_MAT3:
this.gl.uniformMatrix3fv(uniform, false, value);
break;
case this.gl.FLOAT_MAT4:
this.gl.uniformMatrix4fv(uniform, false, value);
break;
case this.gl.SAMPLER_2D:
this.gl.uniform1i(uniform, value);
break;
case this.gl.SAMPLER_CUBE:
this.gl.uniform1i(uniform, value);
break;
default:
console.error(`Unsupported uniform type ${uniform.type}`);
}
}
link() {
this.shaderProgram = this.gl.createProgram();
this.gl.attachShader(this.shaderProgram, this.vShader);
this.gl.attachShader(this.shaderProgram, this.fShader);
this.gl.linkProgram(this.shaderProgram);
if (!this.gl.getProgramParameter(this.shaderProgram, this.gl.LINK_STATUS)) {
console.error(this.gl.getProgramParameter(this.shaderProgram));
}
}
attatch() {
this.gl.useProgram(this.shaderProgram);
}
}