100 lines
2.6 KiB
JavaScript
100 lines
2.6 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 FetchHandler.loadFile(url, false);
|
|
let shader = this.createShader(data, 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);
|
|
if (gl.getProgramParameter(pro, gl.LINK_STATUS)) {
|
|
this.programs[name] = pro;
|
|
return pro;
|
|
}
|
|
|
|
console.log(gl.getProgramInfoLog(pro));
|
|
gl.deleteProgram(pro);
|
|
return null;
|
|
}
|
|
|
|
getProgram(name) {
|
|
return this.programs[name];
|
|
}
|
|
|
|
use(name) {
|
|
let pro = this.programs[name];
|
|
this.gl.useProgram(pro);
|
|
return pro;
|
|
}
|
|
|
|
async loadArray(list, path) {
|
|
let self = this;
|
|
for (const e of list) {
|
|
await self.loadShader(e, path)
|
|
}
|
|
await self.createProgramForEach(list)
|
|
}
|
|
} |