/// <summary> /// 在使用<see cref="VertexArrayObject"/>后,此方法只会执行一次。 /// This method will only be invoked once when using <see cref="VertexArrayObject"/>. /// </summary> /// <param name="shaderProgram"></param> /// <param name="varNameInVertexShader"></param> public void Standby(ShaderProgram shaderProgram, string varNameInVertexShader) { int location = shaderProgram.GetAttributeLocation(varNameInVertexShader); if (location < 0) { throw new ArgumentException(); } uint loc = (uint)location; VBOConfigDetail detail = this.Config.Parse(); int patchVertexes = this.PatchVertexes; uint divisor = this.InstancedDivisor; // 选中此VBO // select this VBO. glBindBuffer(OpenGL.GL_ARRAY_BUFFER, this.BufferId); for (uint i = 0; i < detail.locationCount; i++) { // 指定格式 // set up data format. switch (detail.pointerType) { case VertexAttribPointerType.Default: glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit)); break; case VertexAttribPointerType.Integer: glVertexAttribIPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit)); break; case VertexAttribPointerType.Long: glVertexAttribLPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit)); break; default: throw new Exception("Unexpected VertexAttribPointerType type!"); } if (patchVertexes > 0)// tessellation shading. { glPatchParameteri(OpenGL.GL_PATCH_VERTICES, patchVertexes); } // 启用 // enable this VBO. glEnableVertexAttribArray(loc + i); if (divisor > 0)// instanced rendering. { glVertexAttribDivisor(loc + i, divisor); } } glBindBuffer(OpenGL.GL_ARRAY_BUFFER, 0); }
/// <summary> /// Gets parameter values for glVertexAttribPointer() and glEnable/DisableVertexAttribArray(). /// </summary> /// <param name="config"></param> internal static VBOConfigDetail Parse(this VBOConfig config) { var result = new VBOConfigDetail(); switch (config) { case VBOConfig.Byte: result.dataSize = 1; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec2: result.dataSize = 2; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec3: result.dataSize = 3; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec4: result.dataSize = 4; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.Int: result.dataSize = 1; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec2: result.dataSize = 2; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec3: result.dataSize = 3; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec4: result.dataSize = 4; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UInt: result.dataSize = 1; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec2: result.dataSize = 2; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec3: result.dataSize = 3; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec4: result.dataSize = 4; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.Float: result.dataSize = 1; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec2: result.dataSize = 2; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec3: result.dataSize = 3; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec4: result.dataSize = 4; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Double: result.dataSize = 1; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec2: result.dataSize = 2; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec3: result.dataSize = 3; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec4: result.dataSize = 4; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.Mat2: result.locationCount = 2; result.dataSize = 2; result.dataType = GL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat2)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec2)); result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Mat3: result.locationCount = 3; result.dataSize = 3; result.dataType = GL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat3)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec3)); result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Mat4: result.locationCount = 4; result.dataSize = 4; result.dataType = GL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat4)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec4)); result.pointerType = VertexAttribPointerType.Default; break; default: throw new Exception("Unexpected VBOConfig!"); } return(result); }
/// <summary> /// Gets parameter values for glVertexAttribPointer() and glEnable/DisableVertexAttribArray(). /// </summary> /// <param name="config"></param> internal static VBOConfigDetail Parse(this VBOConfig config) { var result = new VBOConfigDetail(); switch (config) { case VBOConfig.Byte: result.dataSize = 1; result.dataType = OpenGL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec2: result.dataSize = 2; result.dataType = OpenGL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec3: result.dataSize = 3; result.dataType = OpenGL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec4: result.dataSize = 4; result.dataType = OpenGL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.Int: result.dataSize = 1; result.dataType = OpenGL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec2: result.dataSize = 2; result.dataType = OpenGL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec3: result.dataSize = 3; result.dataType = OpenGL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec4: result.dataSize = 4; result.dataType = OpenGL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UInt: result.dataSize = 1; result.dataType = OpenGL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec2: result.dataSize = 2; result.dataType = OpenGL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec3: result.dataSize = 3; result.dataType = OpenGL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec4: result.dataSize = 4; result.dataType = OpenGL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.Float: result.dataSize = 1; result.dataType = OpenGL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec2: result.dataSize = 2; result.dataType = OpenGL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec3: result.dataSize = 3; result.dataType = OpenGL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec4: result.dataSize = 4; result.dataType = OpenGL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Double: result.dataSize = 1; result.dataType = OpenGL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec2: result.dataSize = 2; result.dataType = OpenGL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec3: result.dataSize = 3; result.dataType = OpenGL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec4: result.dataSize = 4; result.dataType = OpenGL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.Mat2: result.locationCount = 2; result.dataSize = 2; result.dataType = OpenGL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat2)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec2)); result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Mat3: result.locationCount = 3; result.dataSize = 3; result.dataType = OpenGL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat3)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec3)); result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Mat4: result.locationCount = 4; result.dataSize = 4; result.dataType = OpenGL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat4)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec4)); result.pointerType = VertexAttribPointerType.Default; break; default: throw new NotImplementedException(); } return result; }