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

时间:2013-09-09 17:32:34

标签: c++ opengl

这个问题有两个(主要是)独立部分

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

现在我明白这是一个可怕的 thing to do所以我正在寻找替代品。自我提出的是在开始时有一些具有大VBO的管理事物,Object可以从中请求空间,并在其中编辑点。这减少了加载VBO的开销,但是在创建和调试这样的野兽(基本上是整个内存管理系统)时需要大量的能量/时间。

我的问题((a)部分)是否是这种做法的“最佳”方法,或者是否有一些我没想过的更好的方法。

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

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

1 个答案:

答案 0 :(得分:2)

上次我检查了缓冲区更新的首选方式是 orphaning 。 基本上,每当您想要更新缓冲数据时,都会在缓冲区上调用glBindBuffer,这会使缓冲区的当前内容无效,然后使用glMapBuffer / glBufferSubdata编写新数据

因此:

  1. 使用单个大VBO来获取静态数据确实是一个好主意。您必须处理允许的最大VBO大小,并在必要时将静态数据拆分为多个VBO。但在大多数情况下这可能是一种过度优化(即“我不会打扰”)。
  2. 经常更新的数据应该归入同一个VBO(使用= GL_STREAM_DRAW),你应该使用孤立来更新它。
  3. 不幸的是,这些东西的实际性能因不同的实现而异。 This guy对实际游戏进行了一些测试,值得一读。

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