1

我现在关心的应用程序是一个 3d 模型查看器。用户偶尔会加载一个大的新网格进行渲染,并且应该(必须)丢弃旧的网格。

正因为如此,这GL_STATIC_DRAW显然是对 VBO 的正确提示。

在这一点上我有点不确定是glDeleteBuffers()我的 VBO 和 IBO,还有glDeleteVertexArrays[OES]()我的 VAO,还是不做这些,只glBufferData()用我新加载的网格做 VBO 和 IBO,而不必删除和重新生成任何东西重新-定义VAOglVertexAttribPointer状态。(子问题:如果我只删除我的 VBO 然后重新生成它,但我的 VAO 完好无损,我还能跳过glVertexAttribPointer()吗?)

如果我调用 OpenGL 确实会丢弃 VBO 中的先前数据glBufferData(),那么这是完美的。据我所知,glBufferData()应该重新分配 VBO。

但实际上,我正在寻找的是一个具体的解释,说明我重新加载到这个洋葱的不同层之间会有什么不同,如果我只想改变我的顶点和我需要走多远应用程序中的索引缓冲区内容(原始几何),或者甚至存在一种可能需要重新生成或删除 VBO 的情况。我确实看到相同的 VBO 可能在不同的 VAO 集之间有用地共享,我可以想象这样一种情况,你有一些你永远不会再使用的 VAO,所以你会释放它们,但看起来像 VBO如果存在 API 供您重新分配其中包含的数据,则可以继续回收。

我发现那里的所有教程和解释都只涉及帮助您设置东西,但是现在我已经弄清楚了如何正确处理其余的这些细节并不太清楚。

4

1 回答 1

2

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

就标准而言,你可以为所欲为。提示就是提示;你不需要跟随他们。

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

NVIDIA 实际上很在意这些提示,并让您坚持下去。在某种程度上,提示定义明确,足以让你坚持下去。如果您使用错误的提示,您将永远降低性能。而 AMD 最终会弄清楚你的真正意思。

在任何情况下,如果您想真正遵守提示,GL_STATIC_DRAW其意思是“您将只上传一次到此缓冲区对象”。现在,这应该如何与缓冲区对象的重新分配相协调,这取决于您。

但是,如果您想猜测 ARB 的意见,请考虑最近的 ARB_buffer_storage 4.4 功能。在那里,它们明确地完全禁止重新分配缓冲区对象的存储空间(不管提示如何)。您可以将其视为“提示”,即重新分配存储(除了用于使现有缓冲区无效之外)是一个坏主意,无论您使用glBufferData何种使用提示。

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

我认为这是一个暗示,GL_STATIC_DRAW意思是“删除,不要重新分配或重新上传到”。

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

于 2013-09-05T05:33:48.233 回答