From 14718e6326ca8903dee753fba8f2b5860327cb3b Mon Sep 17 00:00:00 2001 From: blobt Date: Mon, 26 Apr 2021 20:18:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90GLAttribState?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js.bak | 7 + package.json | 2 +- src/App.tsx | 2 +- src/render/webgl/WebGLAttribState.ts | 331 +++++++++++++++++++++++++++ 4 files changed, 340 insertions(+), 2 deletions(-) create mode 100755 .eslintrc.js.bak diff --git a/.eslintrc.js.bak b/.eslintrc.js.bak new file mode 100755 index 00000000..8921dd77 --- /dev/null +++ b/.eslintrc.js.bak @@ -0,0 +1,7 @@ +module.exports = { + rules: { + 'no-debugger' : 'off', + 'no-unused-vars': 'warn', + 'vue/no-unused-vars': "off" + } +} diff --git a/package.json b/package.json index 7ae0b6e5..e8a49ce8 100755 --- a/package.json +++ b/package.json @@ -40,4 +40,4 @@ "last 1 safari version" ] } -} \ No newline at end of file +} diff --git a/src/App.tsx b/src/App.tsx index daaf1822..865b80e6 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import React from 'react'; import './App.css'; import { vec3, vec4 } from "./render/math" - +// eslint-disable-next-line function App() { let a: vec3 = new vec3([1, 1, 1]); diff --git a/src/render/webgl/WebGLAttribState.ts b/src/render/webgl/WebGLAttribState.ts index b69f1283..191daf5a 100755 --- a/src/render/webgl/WebGLAttribState.ts +++ b/src/render/webgl/WebGLAttribState.ts @@ -39,9 +39,340 @@ export class GLAttribState { public static readonly FLOAT32_SIZE = Float32Array.BYTES_PER_ELEMENT; public static readonly UINT16_SIZE = Uint16Array.BYTES_PER_ELEMENT; + /** + * 使用一个number类型的位数去存储attrib的使用情况 + * @param useTexcoord0 + * @param useTexcoord1 + * @param useNormal + * @param useTangent + * @param useColor + * @returns + */ public static makeVertexAttribs(useTexcoord0: boolean, useTexcoord1: boolean, useNormal: boolean, useTangent: boolean, useColor: boolean): GLAttribBits { let bits: GLAttribBits = GLAttribState.POSITION_BIT; // 总是要使用位置属性 + if (useTexcoord0 === true) { + bits |= GLAttribState.TEXCOORD_BIT; + } + if (useTexcoord1 === true) { + bits |= GLAttribState.TEXCOORD1_BIT; + } + if (useNormal === true) { + bits |= GLAttribState.NORMAL_BIT; + } + if (useTangent === true) { + bits |= GLAttribState.TANGENT_BIT; + } + if (useColor === true) { + bits |= GLAttribState.COLOR_BIT; + } + return bits; } + + /** + * 判断是否使用了position + * @param attribBits + * @returns + */ + public static hasPosition(attribBits: GLAttribBits): boolean { + return (attribBits & GLAttribState.POSITION_BIT) !== 0; + } + + /** + * 判断是否使用了normal + * @param attribBits + * @returns + */ + public static hasNormal(attribBits: GLAttribBits): boolean { + return (attribBits & GLAttribState.NORMAL_BIT) !== 0; + } + + /** + * 判断是否使用了texcoord0 + * @param attribBits + * @returns + */ + public static hasTexCoord_0(attribBits: GLAttribBits): boolean { + return (attribBits & GLAttribState.TEXCOORD_BIT) !== 0; + } + + /** + * 判断是否使用了texcoord1 + * @param attribBits + * @returns + */ + public static hasTexCoord_1(attribBits: GLAttribBits): boolean { + return (attribBits & GLAttribState.TEXCOORD1_BIT) !== 0; + } + + /** + * 判断是否使用了color + * @param attribBits + * @returns + */ + public static hasColor(attribBits: GLAttribBits): boolean { + return (attribBits & GLAttribState.COLOR_BIT) !== 0; + } + + /** + * 判断是否使用了tangent + * @param attribBits + * @returns + */ + public static hasTangent(attribBits: GLAttribBits): boolean { + return (attribBits & GLAttribState.TANGENT_BIT) !== 0; + } + + /** + * 设置Vertex Array Pointer + * @param gl + * @param offsetMap + */ + public static setAttribVertexArrayPointer(gl: WebGLRenderingContext, offsetMap: GLAttribOffsetMap): void { + let stride: number = offsetMap[GLAttribState.ATTRIBSTRIDE]; + + if (stride === 0) { + throw new Error("vertex Array ERROR!"); + } + + if (stride !== offsetMap[GLAttribState.ATTRIBBYTELENGTH]) { + stride = 0; + } + + if (stride === undefined) { + stride = 0; + } + + let offset: number = offsetMap[GLAttribState.POSITION_NAME]; + if (offset !== undefined) { + gl.vertexAttribPointer(GLAttribState.POSITION_LOCATION, GLAttribState.POSITION_COMPONENT, gl.FLOAT, false, stride, offset); + } + + offset = offsetMap[GLAttribState.NORMAL_NAME]; + if (offset !== undefined) { + gl.vertexAttribPointer(GLAttribState.NORMAL_LOCATION, GLAttribState.NORMAL_COMPONENT, gl.FLOAT, false, stride, offset); + } + + offset = offsetMap[GLAttribState.TEXCOORD_NAME]; + if (offset !== undefined) { + gl.vertexAttribPointer(GLAttribState.TEXCOORD_LOCATION, GLAttribState.TEXCOORD_COMPONENT, gl.FLOAT, false, stride, offset); + } + + offset = offsetMap[GLAttribState.TEXCOORD1_NAME]; + if (offset !== undefined) { + gl.vertexAttribPointer(GLAttribState.TEXCOORD1_LOCATION, GLAttribState.TEXCOORD1_COMPONENT, gl.FLOAT, false, stride, offset); + } + + offset = offsetMap[GLAttribState.COLOR_NAME]; + if (offset !== undefined) { + gl.vertexAttribPointer(GLAttribState.COLOR_LOCATION, GLAttribState.COLOR_COMPONENT, gl.FLOAT, false, stride, offset); + } + + offset = offsetMap[GLAttribState.TANGENT_NAME]; + if (offset !== undefined) { + gl.vertexAttribPointer(GLAttribState.TANGENT_LOCATION, GLAttribState.TANGENT_COMPONENT, gl.FLOAT, false, stride, offset); + } + } + + /** + * 设置各个vertex array 是否开启 + * @param gl + * @param attribBits + * @param enable + */ + public static setAttribVertexArrayState(gl: WebGLRenderingContext, attribBits: number, enable: boolean = true): void { + + if (GLAttribState.hasPosition(attribBits) && enable === true) { + gl.enableVertexAttribArray(GLAttribState.POSITION_LOCATION); + } else { + gl.disableVertexAttribArray(GLAttribState.POSITION_LOCATION); + } + + if (GLAttribState.hasNormal(attribBits) && enable === true) { + gl.enableVertexAttribArray(GLAttribState.NORMAL_LOCATION); + } else { + gl.disableVertexAttribArray(GLAttribState.NORMAL_LOCATION); + } + + if (GLAttribState.hasTexCoord_0(attribBits) && enable === true) { + gl.enableVertexAttribArray(GLAttribState.TEXCOORD_LOCATION); + } else { + gl.disableVertexAttribArray(GLAttribState.TEXCOORD_LOCATION); + } + + if (GLAttribState.hasTexCoord_1(attribBits) && enable === true) { + gl.enableVertexAttribArray(GLAttribState.TEXCOORD1_LOCATION); + } else { + gl.disableVertexAttribArray(GLAttribState.TEXCOORD1_LOCATION); + } + + if (GLAttribState.hasColor(attribBits) && enable === true) { + gl.enableVertexAttribArray(GLAttribState.COLOR_LOCATION); + } else { + gl.disableVertexAttribArray(GLAttribState.COLOR_LOCATION); + } + + if (GLAttribState.hasTangent(attribBits) && enable === true) { + gl.enableVertexAttribArray(GLAttribState.TANGENT_LOCATION); + } else { + gl.disableVertexAttribArray(GLAttribState.TANGENT_LOCATION); + } + } + + public static getVertexBytesStride(attribBits: GLAttribBits): number { + let byteOffset: number = 0; + + if (GLAttribState.hasPosition(attribBits)) { + byteOffset += GLAttribState.POSITION_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasNormal(attribBits)) { + byteOffset += GLAttribState.NORMAL_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTexCoord_0(attribBits)) { + byteOffset += GLAttribState.TEXCOORD_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTexCoord_1(attribBits)) { + byteOffset += GLAttribState.TEXCOORD1_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasColor(attribBits)) { + byteOffset += GLAttribState.COLOR_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTangent(attribBits)) { + byteOffset += GLAttribState.TANGENT_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + return byteOffset; + } + + public static getSequenceLayoutAttribOffsetMap(attribBits: GLAttribBits, vertexCount: number): GLAttribOffsetMap { + let offsets: GLAttribOffsetMap = {}; + let byteOffset: number = 0; + + if (GLAttribState.hasPosition(attribBits)) { + offsets[GLAttribState.POSITION_NAME] = 0; + byteOffset += vertexCount * GLAttribState.POSITION_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasNormal(attribBits)) { + offsets[GLAttribState.NORMAL_NAME] = byteOffset; + byteOffset += vertexCount * GLAttribState.NORMAL_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTexCoord_0(attribBits)) { + offsets[GLAttribState.TEXCOORD_NAME] = byteOffset; + byteOffset += vertexCount * GLAttribState.TEXCOORD_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTexCoord_1(attribBits)) { + offsets[GLAttribState.TEXCOORD1_NAME] = byteOffset; + byteOffset += vertexCount * GLAttribState.TEXCOORD1_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasColor(attribBits)) { + offsets[GLAttribState.COLOR_NAME] = byteOffset; + byteOffset += vertexCount * GLAttribState.COLOR_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTangent(attribBits)) { + offsets[GLAttribState.TANGENT_NAME] = byteOffset; + byteOffset += vertexCount * GLAttribState.TANGENT_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + offsets[GLAttribState.ATTRIBSTRIDE] = byteOffset / vertexCount;// 总的字节数 / 顶点数量 = 每个顶点的stride,实际上顺序存储时不需要这个值 + offsets[GLAttribState.ATTRIBBYTELENGTH] = byteOffset;// 总的字节数 + + return offsets; + } + + public static getInterleaveLayoutAttribOffsetMap(attribBits: GLAttribBits): GLAttribOffsetMap { + + let offsets: GLAttribOffsetMap = {}; + let byteOffset: number = 0; + + if (GLAttribState.hasPosition(attribBits)) { + offsets[GLAttribState.POSITION_NAME] = 0; + byteOffset += GLAttribState.POSITION_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasNormal(attribBits)) { + offsets[GLAttribState.NORMAL_NAME] = byteOffset; + byteOffset += GLAttribState.NORMAL_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTexCoord_0(attribBits)) { + offsets[GLAttribState.TEXCOORD_NAME] = byteOffset; + byteOffset += GLAttribState.TEXCOORD_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTexCoord_1(attribBits)) { + offsets[GLAttribState.TEXCOORD1_NAME] = byteOffset; + byteOffset += GLAttribState.TEXCOORD1_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasColor(attribBits)) { + offsets[GLAttribState.COLOR_NAME] = byteOffset; + byteOffset += GLAttribState.COLOR_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + if (GLAttribState.hasTangent(attribBits)) { + offsets[GLAttribState.TANGENT_NAME] = byteOffset; + byteOffset += GLAttribState.TANGENT_COMPONENT * GLAttribState.FLOAT32_SIZE; + } + + offsets[GLAttribState.ATTRIBSTRIDE] = byteOffset; + offsets[GLAttribState.ATTRIBBYTELENGTH] = byteOffset; + + return offsets; + } + + public static getSepratedLayoutAttribOffsetMap(attribBits: GLAttribBits): GLAttribOffsetMap { + let offsets: GLAttribOffsetMap = {}; + + if (GLAttribState.hasPosition(attribBits)) { + offsets[GLAttribState.POSITION_NAME] = 0; + } + + if (GLAttribState.hasNormal(attribBits)) { + offsets[GLAttribState.NORMAL_NAME] = 0; + } + + if (GLAttribState.hasTexCoord_0(attribBits)) { + offsets[GLAttribState.TEXCOORD_NAME] = 0; + } + + if (GLAttribState.hasTexCoord_1(attribBits)) { + offsets[GLAttribState.TEXCOORD1_NAME] = 0; + } + + if (GLAttribState.hasColor(attribBits)) { + offsets[GLAttribState.COLOR_NAME] = 0; + } + + if (GLAttribState.hasTangent(attribBits)) { + offsets[GLAttribState.TANGENT_NAME] = 0; + } + + return offsets; + } + + public static isAttribStateValid(attribBits: number): boolean { + if (!GLAttribState.hasPosition(attribBits)) { + return false; + } + if (GLAttribState.hasTangent(attribBits)) { + if (!GLAttribState.hasTexCoord_0(attribBits)) { + return false; + } + if (!GLAttribState.hasNormal(attribBits)) { + return false; + } + } + return true; + } } \ No newline at end of file