OpenGL:推荐对VBO进行大量编辑的方法

OpenGL: recommended way of making lots of edits to VBO

本文关键字:编辑 方法 VBO OpenGL      更新时间:2023-10-16

这个问题有两个(大部分)独立的部分

我目前的设置是我在游戏空间中有很多Object。 每个顶点都分配有一个 VBO,其中包含每个顶点的顶点属性数据。 如果Object想要更改其顶点数据(位置等),它会在内部数组中执行此操作,然后调用glBufferSubDataARB更新 GPU 中的版本。

现在我明白这是一件可怕的事情,所以我正在寻找替代方案。 一个呈现自己的是有一些管理的东西,它在开始时有一个大的 VBO,Object可以从中请求空间,并在其中编辑点。 这降低了加载 VBO 的开销,但在创建和调试这样一个野兽(基本上是一个完整的内存管理系统)时会产生大量的精力/时间支出。

我的问题((a)部分)是,这是否是执行此操作的"最佳"方法,或者是否有我没有想到的更好的方法。

这样的系统应该允许尽可能快地轻松添加/删除顶点并进行编辑。

(b)部分是关于对每个物体采取的一些简单动作,即旋转和平移。 目前我正在移动每个顶点(哎哟),但这必须有更好的选择。 我正在考虑将旋转和平移矩阵上传到我的着色器以在那里进行。 这似乎很好,但我有点担心更改uniform变量的开销。 这样做最终对我有利吗? 更改uniform变量的速度有多快?

上次我检查进行缓冲区更新的首选方法是孤立。基本上,每当要更新缓冲数据时,都会在缓冲区上调用glBindBuffer,这会使缓冲区的当前内容无效,然后使用 glMapBuffer/glBufferSubdata 写入新数据。

因此:

  1. 为您的静态数据使用单个大的 VBO 确实是一个好主意。您必须注意允许的最大 VBO 大小,并在必要时将静态数据拆分为多个 VCO。但在大多数情况下,这可能是过度优化(即"我不会打扰")。
  2. 经常更新的数据应分组在同一 VBO 中(使用 = GL_STREAM_DRAW ),并且您应该使用孤立来更新它。

不幸的是,这些东西的实际性能在不同的实现中有所不同。这家伙在实际游戏中做了一些测试,可能值得一读。

对于问题的第二部分,显然使用制服是这样做的方法。是的,有一些(小)开销,但它肯定比在每一帧流式传输所有数据要好 1000 倍。