OpenTK (OpenGL) 正确使用 BufferData 和 BufferSubData

本文关键字:BufferData BufferSubData OpenGL OpenTK | 更新日期: 2023-09-27 18:30:45

我正在使用OpenTK在C#中实现Marching Cubes,我对算法没有任何问题,但我无法弄清楚如何让BufferData和BufferSubData正常运行。

我已经确认顶点和索引通过在每次更新时删除和创建新缓冲区来照常运行,但是每一帧都这样做会对性能产生巨大影响,因此没有选择。

在谷歌搜索它之后,我当前的设置如下所示:

class ChunkVertexBuffer : IIndexSource, IVertexSource, IDisposable
{
    private int indexBufferHandle;
    private int vertexBufferHandle;
    [StructLayout(LayoutKind.Sequential)]
    public struct N3fV3f
    {
        public Vector3 normal;
        public Vector3 position;
    }
    public ChunkVertexBuffer()
    {
        int[] handles = new int[2];
        GL.GenBuffers(2, handles);
        indexBufferHandle = handles[0];
        vertexBufferHandle = handles[1];
    }
    public void BufferData(N3fV3f[] vertices, uint[] indices)
    {
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBufferHandle);
        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferHandle);
        int vertexStride = BlittableValueType.StrideOf(vertices);
        int indexStride = sizeof(uint);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * vertexStride), IntPtr.Zero, BufferUsageHint.StreamDraw);
        GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)0, (IntPtr)(vertices.Length * vertexStride), vertices);
        GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * indexStride), IntPtr.Zero, BufferUsageHint.StreamDraw);
        GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)0, (IntPtr)(indices.Length * indexStride), indices);
    }
}

我也尝试了很多变化,但结果总是相同的,没有画出任何东西。GL.GetError() 在此设置返回了 NoError。

编辑数组、顶点和索引的长度在每次更新时都会有所不同。

OpenTK (OpenGL) 正确使用 BufferData 和 BufferSubData

好的,我发现一旦分配,就无法更改 openGL 缓冲区的大小。但是,如果正确的扩展可用,则可以使用 openCL 来管理缓冲区。这对我减少 Terrain 解决方案的内存占用有很大帮助。