Archived
Private
Public Access
1
0
This repository has been archived on 2026-02-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ProjectBackup/C#/TSEngine/Core/GL/shader.ts
2022-09-04 12:45:01 +02:00

106 lines
3.7 KiB
TypeScript

namespace TSE {
export abstract class Shader {
private _name: string;
private _program: WebGLProgram;
private _attributes: { [name: string]: number } = {};
private _uniforms: { [name: string]: WebGLUniformLocation } = {};
/**
* Create a new Shader.
* @param name The name of the Shader.
* @param vertexSource The source of the VertexShader
* @param fragementSource The source of the FragmentShader
*/
public constructor(name: string) {
this._name = name;
}
protected setSource(vertexSource: string, fragementSource: string): void {
let vertexShader = this.loadShader(vertexSource, gl.VERTEX_SHADER);
let fragmentShader = this.loadShader(fragementSource, gl.FRAGMENT_SHADER);
this.createProgram(vertexShader, fragmentShader);
this.detectAtrributes();
this.detectUniforms();
}
/** Use this Shader. */
public use(): void {
gl.useProgram(this._program);
}
private loadShader(source: string, shaderType: number): WebGLShader {
let shader: WebGLShader = gl.createShader(shaderType);
gl.shaderSource(shader, source);
gl.compileShader(shader);
const error = gl.getShaderInfoLog(shader);
if (error != "")
throw new Error("Error compiling shader '" + this._name + "': " + error);
return shader;
}
/** The name of this Shader. */
public get name(): string { return this._name; }
/**
* Get the Location of an Attribute with the provided Name.
* @param name The name of the Attribute.
*/
public getAttributeLocation(name: string): number {
if (this._attributes[name] === undefined) throw new Error(`Unable to find Attribute '${name}' in shader '${this._name}'`);
return this._attributes[name];
}
/**
* Get the Location of an Uniform with the provided Name.
* @param name The name of the Uniform.
*/
public getUniformLocation(name: string): WebGLUniformLocation {
if (this._uniforms[name] === undefined) throw new Error(`Unable to find Uniform '${name}' in shader '${this._name}'`);
return this._uniforms[name];
}
private createProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader): void {
this._program = gl.createProgram();
gl.attachShader(this._program, vertexShader);
gl.attachShader(this._program, fragmentShader);
gl.linkProgram(this._program);
const error = gl.getProgramInfoLog(this._program);
if (error != "")
throw new Error("Error linking shader '" + this._name + "': " + error);
}
private detectAtrributes(): void {
let attributeCount = gl.getProgramParameter(this._program, gl.ACTIVE_ATTRIBUTES);
for (let i = 0; i < attributeCount; i++) {
let attributeInfo: WebGLActiveInfo = gl.getActiveAttrib(this._program, i);
if (!attributeInfo) break;
this._attributes[attributeInfo.name] = gl.getAttribLocation(this._program, attributeInfo.name);
}
}
private detectUniforms(): void {
let uniformCount = gl.getProgramParameter(this._program, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < uniformCount; i++) {
let uniformInfo: WebGLActiveInfo = gl.getActiveUniform(this._program, i);
if (!uniformInfo) break;
this._uniforms[uniformInfo.name] = gl.getUniformLocation(this._program, uniformInfo.name);
}
}
}
}