From a0840d07c71ce9d20f5c6c035a2af69fc8513252 Mon Sep 17 00:00:00 2001 From: MrKBear Date: Sun, 13 Feb 2022 18:11:16 +0800 Subject: [PATCH] Add group onject group shader --- source/GLRender/BasicGroup.ts | 74 ++++++++++++++++++++++++++ source/GLRender/ClassicRenderer.ts | 12 ++++- source/GLRender/GroupShader.ts | 84 ++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 source/GLRender/GroupShader.ts diff --git a/source/GLRender/BasicGroup.ts b/source/GLRender/BasicGroup.ts index e69de29..a03cfc5 100644 --- a/source/GLRender/BasicGroup.ts +++ b/source/GLRender/BasicGroup.ts @@ -0,0 +1,74 @@ +import { GLContextObject } from "./GLContext"; +import { GroupShader } from "./GroupShader"; +import { ObjectData } from "@Model/Renderer"; + +class BasicGroup extends GLContextObject{ + + private pointVertexBuffer: WebGLBuffer | null = null; + private pointVecMaxCount: number = 100 * 3; + private pointVecCount: number = 0; + + public onLoad() { + + // 创建缓冲区 + this.pointVertexBuffer = this.gl.createBuffer(); + + // 绑定缓冲区 + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.pointVertexBuffer); + this.gl.bufferData(this.gl.ARRAY_BUFFER, this.pointVecMaxCount, this.gl.DYNAMIC_DRAW); + } + + /** + * 向 GPU 上传数据 + */ + public upLoadData(data: ObjectData) { + + // 绑定缓冲区 + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.pointVertexBuffer); + this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(data), this.gl.DYNAMIC_DRAW); + + this.pointVecCount = data.length / 3; + } + + /** + * 大小 + */ + public size = 100; + + /** + * 颜色 + */ + public color = [1, 1, 1]; + + /** + * 绘制立方体 + */ + public draw(shader: GroupShader){ + + // 使用程序 + shader.use(); + + // 绑定缓冲区 + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.pointVertexBuffer); + + // 指定指针数据 + this.gl.vertexAttribPointer( + shader.attribLocate("aPosition"), + 3, this.gl.FLOAT, false, 0, 0); + + // mvp参数传递 + shader.mvp(this.camera.transformMat); + + // 半径传递 + shader.radius(this.size); + + // 指定颜色 + shader.color(this.color); + + // 开始绘制 + this.gl.drawArrays(this.gl.POINTS, 0, this.pointVecCount); + } +} + +export default BasicGroup; +export { BasicGroup }; \ No newline at end of file diff --git a/source/GLRender/ClassicRenderer.ts b/source/GLRender/ClassicRenderer.ts index 1a74a55..db04e5a 100644 --- a/source/GLRender/ClassicRenderer.ts +++ b/source/GLRender/ClassicRenderer.ts @@ -3,6 +3,8 @@ import { BasicRenderer } from "./BasicRenderer"; import { BasicsShader } from "./BasicShader"; import { Axis } from "./Axis"; import { BaseCube } from "./BasicCube"; +import { GroupShader } from "./GroupShader"; +import { BasicGroup } from "./BasicGroup"; interface IClassicRendererParams {} @@ -11,6 +13,8 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { private basicShader: BasicsShader = undefined as any; private axisObject: Axis = undefined as any; private cubeObject: BaseCube = undefined as any; + private groupShader: GroupShader = undefined as any; + private basicGroup: BasicGroup = undefined as any; public onLoad(): void { @@ -18,10 +22,13 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { this.autoResize(); this.basicShader = new BasicsShader().bindRenderer(this); - this.axisObject = new Axis().bindRenderer(this); - this.cubeObject = new BaseCube().bindRenderer(this); + this.groupShader = new GroupShader().bindRenderer(this); + this.basicGroup = new BasicGroup().bindRenderer(this); + + // 生成随机数据测试 + this.basicGroup.upLoadData(new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2)); this.canvas.on("mousemove", () => { @@ -52,6 +59,7 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { this.camera.generateMat(); this.axisObject.draw(this.basicShader); this.cubeObject.draw(this.basicShader); + this.basicGroup.draw(this.groupShader); } clean(id?: ObjectID | ObjectID[]): this { diff --git a/source/GLRender/GroupShader.ts b/source/GLRender/GroupShader.ts new file mode 100644 index 0000000..0ead727 --- /dev/null +++ b/source/GLRender/GroupShader.ts @@ -0,0 +1,84 @@ +import { ObjectData } from "@Model/Renderer"; +import { GLContext } from "./GLContext"; +import { GLShader } from "./GLShader"; + +export { GroupShader } + +interface IGroupShaderAttribute { + aPosition: ObjectData +} + +interface IGroupShaderUniform { + uRadius: number, + uMvp: ObjectData, + uColor: ObjectData +} + +/** + * 基础绘制 Shader + * @class BasicsShader + */ +class GroupShader extends GLShader{ + + public onLoad() { + + // 顶点着色 + const vertex = ` + attribute vec3 aPosition; + + uniform float uRadius; + uniform mat4 uMvp; + + void main(){ + gl_Position = uMvp * vec4(aPosition, 1.); + gl_PointSize = uRadius / gl_Position.z; + } + `; + + // 片段着色 + const fragment = ` + precision lowp float; + + uniform vec3 uColor; + + void main(){ + gl_FragColor = vec4(uColor, 1.); + } + `; + + // 保存代码 + this.setSource(vertex, fragment); + + // 编译 + this.compile(); + } + + /** + * 传递半径数据 + */ + public radius(r: number){ + this.gl.uniform1f( + this.uniformLocate("uRadius"), r + ); + 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 + ); + } +} \ No newline at end of file