Add basic shader
This commit is contained in:
		
							parent
							
								
									2550e2e14f
								
							
						
					
					
						commit
						2235063a24
					
				
							
								
								
									
										97
									
								
								source/GLRender/BasicShader.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								source/GLRender/BasicShader.ts
									
									
									
									
									
										Normal 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 | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @ -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(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -24,5 +24,7 @@ export abstract class GLContextObject< | ||||
| 	/** | ||||
| 	 * 初始化生命周期 | ||||
| 	 */ | ||||
| 	public abstract onLoad(context: GLContext): any; | ||||
| 	public onLoad(context: GLContext): any { | ||||
|         this.gl = context; | ||||
|     }; | ||||
| } | ||||
| @ -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; | ||||
|         } | ||||
|  | ||||
| @ -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 = {} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user