VBO在C#中使用交错顶点

我正在尝试使用VBO使用OpenTK在C#中绘制我的模型。 在我的在线研究中,我在许多地方读过,优先考虑使交错数据结构的大小为32字节的精确倍数,因此我编写了以下代码:

[Serializable] [StructLayout(LayoutKind.Sequential)] public struct Byte4 { public byte R, G, B, A; public Byte4(byte[] input) { R = input[0]; G = input[1]; B = input[2]; A = input[3]; } public uint ToUInt32() { byte[] temp = new byte[] { this.R, this.G, this.B, this.A }; return BitConverter.ToUInt32(temp, 0); } } [Serializable] [StructLayout(LayoutKind.Sequential)] public struct VertexInterleaved { // data section is exactly 36 bytes long??? - need padding to get multiple of 32? public Vector3 vertex; // Vertex public Vector3 normal; // Normal Vector public Vector2 textureCoord; // First Texture Coordinates public Byte4 rgbaColor; // RGBA value of this vertex //public byte[] padding; public static int VertexStride() { // if I'm using the padding I have to add the appropriate size to this... return (8 * sizeof(float) + 4 * sizeof(byte)); } } public class VertexBufferObject { private uint[] _VBOid; private int _vertexStride; private int _totalIndices; private int _totalVertices; public VertexBufferObject () { _VBOid = new uint[2]; GL.GenBuffers(2, _VBOid); } public bool DeleteVBO() { GL.DeleteBuffers(2, _VBOid); } private void BindBuffers() { GL.BindBuffer(BufferTarget.ArrayBuffer, _VBOid[0]); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _VBOid[1]); } private void ReleaseBuffers() { GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } public void BufferMeshData(Mesh3DCollection mesh3Ds) { _vertexStride = VertexInterleaved.VertexStride(); _totalIndices = mesh3Ds.TotalIndices(); _totalVertices = mesh3Ds.TotalVertices(); VertexInterleaved[] vboVertices = new VertexInterleaved[_totalVertices]; uint[] vboIndices = new uint[_totalIndices]; int vertexCounter = 0; int indexCounter = 0; foreach (Mesh3D m in mesh3Ds) { foreach (VertexInterleaved v in m.vertices) { vboVertices[vertexCounter] = v; vertexCounter++; } foreach (uint i in m.indices) { vboIndices[indexCounter] = i; indexCounter++; } } BindBuffers(); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr) (_totalIndices * sizeof(uint)), vboIndices, BufferUsageHint.StaticDraw); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(_totalVertices * _vertexStride), vboVertices, BufferUsageHint.StaticDraw); ReleaseBuffers(); } public void RenderVBO() { GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.NormalArray); GL.EnableClientState(ArrayCap.ColorArray); BindBuffers(); GL.VertexPointer(3, VertexPointerType.Float, _vertexStride, (IntPtr) (0)); GL.NormalPointer(NormalPointerType.Float, _vertexStride, (IntPtr) (3 * sizeof(float))); GL.TexCoordPointer(2, TexCoordPointerType.Float, _vertexStride, (IntPtr) (6 * sizeof(float))); GL.ColorPointer(4, ColorPointerType.Byte, _vertexStride, (IntPtr) (8 * sizeof(float))); GL.DrawElements(BeginMode.Quads, numIndices, DrawElementsType.UnsignedInt, startLocation); ReleaseBuffers(); GL.DisableClientState(ArrayCap.VertexArray); GL.DisableClientState(ArrayCap.NormalArray); GL.DisableClientState(ArrayCap.ColorArray); { } 

具体问题:

1.)我的交错顶点数据结构应该是结构还是类? 就VBO和/或内存占用而言,这是否有所不同? (我决定使用一个结构,即使它感觉不对,因为顶点在内存中不会被改变。)

2.)这个数据结构真的需要是32字节的倍数吗? (即,我需要一个“虚拟”填充成员来强制正确的大小?我在网上找到的所有例子都是用C ++编写的,所以我特别感兴趣的是同样的想法/动机是否会延续到C#。

3.)[Serializable] [StructLayout(LayoutKind.Sequential)]真的有必要吗? 我从我在网上找到的一个例子中复制了这个,所以……

1.)如果结构中的数据将定期更改,则建议使用类,即对内存位置的引用。 如果它几乎是静态的,正如我想象的那样,最好使用结构,即值类型。

2.)我听说在32 字节对齐边界上对齐交错顶点数据块具有性能增益,良好的高速缓存行一致性,但我还没有看到任何性能增益的良好示例。

3.)是的,它指定类型的字段应按照它们在源代码中声明的顺序在内存中布局。 这对交错数据显然很重要。