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

我当前的设置是我在游戏空间中有很多Object。每个对象都分配有一个VBO,该VBO保留每个顶点的“顶点属性”数据。如果Object想要更改其顶点数据(位置等),它将在内部数组中进行更改,然后调用glBufferSubDataARB来更新GPU中的版本。

现在我知道这是可怕的 thing to do,因此我正在寻找替代方法。出现的一种情况是,要有一些管理对象,它的开头有一个很大的VBO,并且Object可以从中请求空间,并在其中编辑点。这减少了加载VBO的开销,但是在创建和调试此类野兽(基本上是整个内存管理系统)时会花费大量的能量/时间。

我的问题((a)部分)是这样做的“最佳”方法,还是我没有想到的更好的方法。

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

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

最佳答案

上次我检查执行缓冲区更新的首选方法是orphaning
基本上,只要您想更新缓冲的数据,就可以在缓冲区上调用glBindBuffer,这会使缓冲区的当前内容无效,然后使用glMapBuffer / glBufferSubdata写入新数据。

因此:

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

  • 不幸的是,这些东西的实际性能在不同的实现上有所不同。 This guy对实际游戏进行了一些测试,可能值得阅读。

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

    关于c++ - OpenGL:对VBO进行大量编辑的推荐方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18703790/

    10-13 03:32