Add class GLCanvas GLContext

This commit is contained in:
MrKBear 2022-02-06 23:26:26 +08:00
parent 670e2e4d11
commit 5f03f1e51f
3 changed files with 201 additions and 2 deletions

View File

@ -1,4 +1,4 @@
import { Emitter } from "../Common/Emitter"; import { Emitter } from "@Common/Emitter";
import { ResizeObserver as Polyfill } from '@juggle/resize-observer'; import { ResizeObserver as Polyfill } from '@juggle/resize-observer';
export { GLCanvas, GLCanvasOption }; export { GLCanvas, GLCanvasOption };

View File

@ -0,0 +1,29 @@
import { Emitter, EventType } from "@Common/Emitter";
export type GLContext = WebGL2RenderingContext | WebGLRenderingContext;
/**
* 使 GLContext
*/
export abstract class GLContextObject<
E extends Record<EventType, any> = {}
> extends Emitter<E> {
/**
* GL
*/
protected gl: GLContext = undefined as any;
/**
*
*/
public get isLoad(): boolean {
return !!this.gl;
}
/**
*
*/
public abstract onLoad(context: GLContext): any;
}

170
source/GLRender/GLShader.ts Normal file
View File

@ -0,0 +1,170 @@
import { EventType } from "@Common/Emitter";
import { GLContextObject } from "./GLContext"
/**
* Shader类
*/
abstract class GLShader<
E extends Record<EventType, any> = {}
> extends GLContextObject<E> {
/**
*
*/
protected vertexShaderSource:string = "";
/**
*
*/
protected fragmentShaderSource:string = "";
/**
*
*/
protected vertexShader: WebGLShader | null = null;
/**
*
*/
protected fragmentShader: WebGLShader | null = null;
/**
*
*/
protected program: WebGLProgram | null = null;
/**
*
*/
protected setSource(vert:string, frag:string){
this.vertexShaderSource = vert.replace(/^\s+/, "");
this.fragmentShaderSource = frag.replace(/^\s+/, "");
return this;
}
/**
*
*/
protected compile() {
// 创建程序
this.program = this.gl.createProgram();
// 创建顶点着色器
this.vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
// 创建片段着色器
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.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.fragmentShader, this.gl.COMPILE_STATUS)){
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.linkProgram(!this.program);
// 检测链接错误
if(!this.gl.getProgramParameter(!this.program, this.gl.LINK_STATUS)){
console.error("link:\r\n" + this.gl.getProgramInfoLog(!this.program));
}
return this;
}
/**
* attrib
*/
private attribLocationCache: Map<string, GLint> = new Map();
/**
* attrib
*/
private uniformLocationCache: Map<string, WebGLUniformLocation> = new Map();
/**
* attribLocation
*/
public attribLocate(attr: string){
// 获取缓存
let cache = this.attribLocationCache.get(attr);
// 缓存搜索
if (cache === undefined || cache <= -1){
cache = this.gl.getAttribLocation(!this.program, attr);
if (cache === undefined || cache <= -1) {
console.error("Attrib: can not get locate of " + attr);
} else {
this.gl.enableVertexAttribArray(cache);
}
this.attribLocationCache.set(attr, cache);
return cache;
}
// 搜索到返回
else {
this.gl.enableVertexAttribArray(cache);
return cache
}
}
/**
* attribLocation
*/
public uniformLocate(uni: string) {
// 获取缓存
let cache: WebGLUniformLocation | null = this.uniformLocationCache.get(uni) as any;
if (cache === undefined) cache = null;
// 缓存搜索
if (!cache) {
cache = this.gl.getUniformLocation(!this.program, uni);
if (!cache) console.error("Uniform: can not get locate of " + uni);
this.uniformLocationCache.set(uni, cache as any);
return cache;
}
// 搜索到返回
else return cache;
}
/**
* 使
*/
public use(){
this.gl.useProgram(this.program);
return this;
}
}
export default GLShader;
export { GLShader };