OpenGL(ES 2.0,但不是特定于ES):GL_STATIC_DRAW是否适用于glBufferData?

时间:2013-09-05 05:17:05

标签: opengl opengl-es

我现在关注的应用程序是一个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的情况,所以你要解除它们,但它似乎是VBOs如果存在用于重新分配其中包含的数据的API,则可以继续回收。

我发现那里的所有教程和解释只涉及帮助你设置内容,但现在我已经知道了如何正确地了解其余的这些细节是不是很清楚。

1 个答案:

答案 0 :(得分:2)

我不确定为什么你认为删除你的顶点数组对象会对 buffer 对象的内容产生任何影响。删除FBO不会影响附加到它的纹理或渲染缓冲区的存储,删除VAO也不会影响附加到它的任何缓冲区对象的存储。

就标准而言,你可以做你喜欢的事。提示是提示;你不需要遵循它们。

就AMD而言,你仍然可以做任何你喜欢的事情。原因是,由于人们不理解提示是如何工作的,人们已经完成了任何他们喜欢的事情,而AMD几乎完全忽略了提示。它会监视缓冲区对象的使用模式并移动它,直到你弄清楚你打算如何实际使用它。

NVIDIA实际上关心这些提示,并把握住你。在某种程度上,这些提示的定义足以让您了解它们。如果使用了错误的提示,则会永远降低性能。而AMD最终会找出你真正意味着什么。

在任何情况下,如果你想真正忠实于提示,GL_STATIC_DRAW意味着,“你将上传到这个缓冲区对象一次”。现在,如何调整缓冲区对象的重新分配取决于你。

但是,如果您想猜测ARB的意见,请考虑the recent ARB_buffer_storage 4.4 feature。在那里,他们明确地禁止完全重新分配缓冲区对象的存储(无论提示如何)。您可以将其视为“提示”,即重新分配存储(using glBufferData to invalidate an existing buffer之外)是一个坏主意,无论您使用何种使用提示。

此外,从buffer_storage中,GL_STATIC_DRAW 的“等效”禁止您从客户端存储上传任何内容。一旦它存在,您可以从其他缓冲区复制到它,或者将其用作in-GL流程的其他目的地。但你不能改变它的内容。你只能删除它。

我会将其视为GL_STATIC_DRAW旨在表示“删除,不重新分配或重新上传到”的提示。

现在,对于OpenGL ES来说,这意味着什么。这取决于不同的实现如何实现其缓冲区的存储(这就是为什么询问桌面GL和GL ES实现的行为是错误的)。但是,考虑到移动GPU通常没有两个独立的内存池,我想他们真的不在乎。当然,一个实现可以将内存分配为未缓存或者某些内容,以便更快地或更快地访问它。但除此之外,它可能并不重要。