Add basic shader

This commit is contained in:
MrKBear 2022-02-08 17:36:26 +08:00
parent 2550e2e14f
commit 2235063a24
5 changed files with 138 additions and 25 deletions

View File

@ -0,0 +1,97 @@
import { ObjectData } from "@Model/Renderer";
import { GLContext } from "./GLContext";
import { GLShader } from "./GLShader";
export { BasicsShader }
interface IBasicsShaderAttribute {
aPosition: ObjectData
}
interface IBasicsShaderUniform {
uRadius: ObjectData,
uMvp: ObjectData,
uPosition: ObjectData,
uColor: ObjectData
}
/**
* Shader
* @class BasicsShader
*/
class BasicsShader extends GLShader<IBasicsShaderAttribute, IBasicsShaderUniform>{
public onLoad(context: GLContext) {
super.onLoad(context);
// 顶点着色
const vertex = `
attribute vec3 aPosition;
uniform vec3 uRadius;
uniform mat4 uMvp;
uniform vec3 uPosition;
void main(){
gl_Position = uMvp * vec4(aPosition * uRadius + uPosition, 1.);
}
`;
// 片段着色
const fragment = `
precision lowp float;
uniform vec3 uColor;
void main(){
gl_FragColor = vec4(uColor, 1.);
}
`;
// 保存代码
this.setSource(vertex, fragment);
// 编译
this.compile();
}
/**
*
*/
public radius(r: ObjectData){
this.gl.uniform3fv(
this.uniformLocate("uRadius"), r
);
return this;
}
/**
*
*/
public position(position: ObjectData){
this.gl.uniform3fv(
this.uniformLocate("uPosition"), position
);
return this;
}
/**
*
*/
public mvp(mat: ObjectData, transpose: boolean = false){
this.gl.uniformMatrix4fv(
this.uniformLocate("uMvp"), transpose, mat
);
return this;
}
/**
*
*/
public color(rgb: ObjectData){
this.gl.uniform3fv(
this.uniformLocate("uColor"), rgb
);
}
}

View File

@ -1,13 +1,21 @@
import { ObjectID, ObjectData, ICommonParam } from "@Model/Renderer";
import { BasicRenderer, IRendererParams } from "./BasicRenderer";
import { BasicsShader } from "./BasicShader";
interface IClassicRendererParams {}
class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
onLoad(param: Partial<IClassicRendererParams & IRendererParams>): void {
this.run();
// 自动调节分辨率
this.autoResize();
let shader = new BasicsShader();
!shader.isLoad && shader.onLoad(this.gl);
// 运行
this.run();
}
clean(id?: ObjectID | ObjectID[]): this {
@ -22,7 +30,7 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
throw new Error("Method not implemented.");
}
loop(): void {
loop(t: number): void {
this.cleanCanvas();
}
}

View File

@ -24,5 +24,7 @@ export abstract class GLContextObject<
/**
*
*/
public abstract onLoad(context: GLContext): any;
public onLoad(context: GLContext): any {
this.gl = context;
};
}

View File

@ -1,10 +1,14 @@
import { EventType } from "@Model/Emitter";
import { GLContextObject } from "./GLContext"
type IAnyObject = Record<string, any>;
/**
* Shader类
*/
abstract class GLShader<
A extends IAnyObject = {},
U extends IAnyObject = {},
E extends Record<EventType, any> = {}
> extends GLContextObject<E> {
@ -60,34 +64,36 @@ abstract class GLShader<
this.fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
// 绑定源代码
this.gl.shaderSource(!this.vertexShader, this.vertexShaderSource);
this.gl.shaderSource(!this.fragmentShader, this.fragmentShaderSource);
this.gl.shaderSource(this.vertexShader!, this.vertexShaderSource);
this.gl.shaderSource(this.fragmentShader!, this.fragmentShaderSource);
// 编译
this.gl.compileShader(!this.vertexShader);
this.gl.compileShader(!this.fragmentShader);
this.gl.compileShader(this.vertexShader!);
this.gl.compileShader(this.fragmentShader!);
// 检测编译错误
if(!this.gl.getShaderParameter(!this.vertexShader, this.gl.COMPILE_STATUS)){
console.error("vertex:\r\n" + this.gl.getShaderInfoLog(!this.vertexShader));
if(!this.gl.getShaderParameter(this.vertexShader!, this.gl.COMPILE_STATUS)){
return console.error("vertex:\r\n" + this.gl.getShaderInfoLog(this.vertexShader!));
}
if(!this.gl.getShaderParameter(!this.fragmentShader, this.gl.COMPILE_STATUS)){
console.error("fragment:\r\n" + this.gl.getShaderInfoLog(!this.fragmentShader));
if(!this.gl.getShaderParameter(this.fragmentShader!, this.gl.COMPILE_STATUS)){
return console.error("fragment:\r\n" + this.gl.getShaderInfoLog(this.fragmentShader!));
}
// 附加到程序
this.gl.attachShader(!this.program, !this.vertexShader);
this.gl.attachShader(!this.program, !this.fragmentShader);
this.gl.attachShader(this.program!, this.vertexShader!);
this.gl.attachShader(this.program!, this.fragmentShader!);
// 连接程序
this.gl.linkProgram(!this.program);
this.gl.linkProgram(this.program!);
// 检测链接错误
if(!this.gl.getProgramParameter(!this.program, this.gl.LINK_STATUS)){
console.error("link:\r\n" + this.gl.getProgramInfoLog(!this.program));
if(!this.gl.getProgramParameter(this.program!, this.gl.LINK_STATUS)){
return console.error("link:\r\n" + this.gl.getProgramInfoLog(this.program!));
}
console.log("shader compile success");
return this;
}
@ -104,15 +110,15 @@ abstract class GLShader<
/**
* attribLocation
*/
public attribLocate(attr: string){
public attribLocate<T extends keyof A>(attr: T){
// 获取缓存
let cache = this.attribLocationCache.get(attr);
let cache = this.attribLocationCache.get(attr as string);
// 缓存搜索
if (cache === undefined || cache <= -1){
cache = this.gl.getAttribLocation(!this.program, attr);
cache = this.gl.getAttribLocation(!this.program, attr as string);
if (cache === undefined || cache <= -1) {
console.error("Attrib: can not get locate of " + attr);
@ -120,7 +126,7 @@ abstract class GLShader<
this.gl.enableVertexAttribArray(cache);
}
this.attribLocationCache.set(attr, cache);
this.attribLocationCache.set(attr as string, cache);
return cache;
}
@ -136,19 +142,19 @@ abstract class GLShader<
/**
* attribLocation
*/
public uniformLocate(uni: string) {
public uniformLocate<T extends keyof U>(uni: T) {
// 获取缓存
let cache: WebGLUniformLocation | null = this.uniformLocationCache.get(uni) as any;
let cache: WebGLUniformLocation | null = this.uniformLocationCache.get(uni as string) as any;
if (cache === undefined) cache = null;
// 缓存搜索
if (!cache) {
cache = this.gl.getUniformLocation(!this.program, uni);
cache = this.gl.getUniformLocation(!this.program, uni as string);
if (!cache) console.error("Uniform: can not get locate of " + uni);
this.uniformLocationCache.set(uni, cache as any);
this.uniformLocationCache.set(uni as string, cache as any);
return cache;
}

View File

@ -45,7 +45,7 @@ type ObjectID = Symbol | string | number;
/**
*
*/
type ObjectData = Array<number> | Float32Array | Float64Array;
type ObjectData = Array<number> | Float32Array;
interface IRendererConstructor<
M extends IAnyObject = {}