【发布时间】:2013-09-05 13:33:48
【问题描述】:
我现在关心的应用程序是一个 3d 模型查看器。用户偶尔会加载一个大的新网格进行渲染,并且应该(必须)丢弃旧的网格。
因此,GL_STATIC_DRAW 显然是 VBO 的正确提示。
此时我有点不确定是 glDeleteBuffers() 我的 VBO 和 IBO,还有 glDeleteVertexArrays[OES]() 我的 VAO,或者什么都不做,只是 glBufferData() 我新加载的 VBO 和 IBO网格无需删除和重新生成任何内容或重新定义glVertexAttribPointer VAO 状态。 (子问题:如果我只删除我的 VBO 然后重新生成它,但我的 VAO 保持不变,我还能跳过glVertexAttribPointer()吗?)
如果我调用glBufferData() 时OpenGL 确实会丢弃VBO 中的先前数据,那么这是完美的。据我所知,glBufferData() 应该重新分配 VBO。
但实际上,我正在寻找的是一个具体的解释,说明我重新加载到这个洋葱的不同层之间会有什么不同,以及如果我只想改变我需要走多远我在应用程序中的顶点和索引缓冲区内容(原始几何图形),或者是否存在可能需要重新生成或删除 VBO 的情况。我确实看到相同的 VBO 可能在不同的 VAO 集之间有用地共享,我可以想象这样一种情况,你有一些你永远不会再使用的 VAO,所以你会释放它们,但看起来像 VBO如果存在供您重新分配其中包含的数据的 API,则可以继续回收。
我发现那里的所有教程和解释都只涉及帮助您进行设置,但现在我已经了解了那个阶段,不太清楚如何正确处理其余这些细节。
【问题讨论】:
-
VAO 没有显着的开销,将它们视为轻量级状态块。它们不负责实际的数据存储(VBO 会这样做),它们会持续保存绘制一个或多个 VBO 所需的状态。现在,如果您将 VAO 保留在不再存在的参考 VBO 周围,它们可能会成为一个问题,但防止这种情况发生的重担实际上落在您的肩上,而不是 OpenGL 的肩上。我很少删除 VAO,如果不再需要它,它会进入一个未使用的 VAO 池以供重复使用,这将 OpenGL 名称的动态分配保持在最低限度;也适用于其他类型的对象。
-
啊哈。因此,您对待 VAO 的方式与我打算对待我的 VBO 的方式相同。作为将不断重复使用的资源池中的句柄。