95 lines
2.5 KiB
JavaScript
95 lines
2.5 KiB
JavaScript
|
class ShaderHandler {
|
||
|
constructor(gl) {
|
||
|
this.gl = gl;
|
||
|
this.shaderNames = [];
|
||
|
this.shaders = {};
|
||
|
this.programs = {};
|
||
|
}
|
||
|
|
||
|
setGL(gl) {
|
||
|
this.gl = gl;
|
||
|
}
|
||
|
|
||
|
async loadShader(name, path) {
|
||
|
this.shaderNames.push(name);
|
||
|
await this.load(name, path + name + ".vert", this.gl.VERTEX_SHADER);
|
||
|
await this.load(name, path + name + ".frag", this.gl.FRAGMENT_SHADER);
|
||
|
}
|
||
|
|
||
|
async load(name, url, type) {
|
||
|
let realName = name + "_" + type;
|
||
|
if (!this.shaders[realName]) {
|
||
|
let data = await fetch(url);
|
||
|
let shader = this.createShader(await data.text(), type);
|
||
|
if (shader) {
|
||
|
this.shaders[realName] = shader;
|
||
|
}
|
||
|
}
|
||
|
return !!this.shaders[realName];
|
||
|
}
|
||
|
|
||
|
getShader(name, type) {
|
||
|
let realName = name + "_" + type;
|
||
|
return this.shaders[realName];
|
||
|
}
|
||
|
|
||
|
getAllShaders() {
|
||
|
return this.shaderNames;
|
||
|
}
|
||
|
|
||
|
async createProgramForEach(arr) {
|
||
|
arr = arr || this.shaderNames;
|
||
|
for (let i = 0; i < arr.length; i++) {
|
||
|
let shader = arr[i];
|
||
|
let v = await shaderHandler.createProgram(shader, [shader])
|
||
|
if (!v) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
createShader(source, type) {
|
||
|
let gl = this.gl;
|
||
|
let shader = gl.createShader(type);
|
||
|
gl.shaderSource(shader, source);
|
||
|
gl.compileShader(shader);
|
||
|
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||
|
return shader;
|
||
|
}
|
||
|
console.error(gl.getShaderInfoLog(shader));
|
||
|
gl.deleteShader(shader);
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
createProgram(name, shaders) {
|
||
|
let gl = this.gl;
|
||
|
let pro = gl.createProgram();
|
||
|
for (let i = 0; i < shaders.length; i++) {
|
||
|
gl.attachShader(pro, this.getShader(shaders[i], gl.VERTEX_SHADER));
|
||
|
gl.attachShader(pro, this.getShader(shaders[i], gl.FRAGMENT_SHADER));
|
||
|
}
|
||
|
gl.linkProgram(pro);
|
||
|
var success = gl.getProgramParameter(pro, gl.LINK_STATUS);
|
||
|
if (success) {
|
||
|
this.programs[name] = pro;
|
||
|
return pro;
|
||
|
}
|
||
|
|
||
|
console.log(gl.getProgramInfoLog(pro));
|
||
|
gl.deleteProgram(pro);
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
getProgram(name) {
|
||
|
return this.programs[name];
|
||
|
}
|
||
|
|
||
|
async loadArray(list, path) {
|
||
|
let self = this;
|
||
|
for (const e of list) {
|
||
|
await self.loadShader(e, path)
|
||
|
}
|
||
|
await self.createProgramForEach(list)
|
||
|
}
|
||
|
}
|