gpt4 book ai didi

c# - 在 C# 中使用交错顶点的 VBO

转载 作者:太空宇宙 更新时间:2023-11-03 14:16:17 25 4
gpt4 key购买 nike

我正在尝试使用 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.) 是 [可序列化] [StructLayout(LayoutKind.Sequential)]真的有必要吗?我从网上找到的一个例子中复制了这个,所以......

最佳答案

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

2.) 我听说在 32-byte-aligned 边界上对齐交错顶点数据 block 可以提高性能,良好的缓存行一致性,但我还没有看到任何一个很好的例子性能增益。

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

关于c# - 在 C# 中使用交错顶点的 VBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6521618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com