需要 VAO 时有关VBO更新的OpenGL最佳实践

pinkon5k  于 2023-05-22  发布在  其他
关注(0)|答案(1)|浏览(191)

不久前我在一个团队中做了一个引擎,其中一个工程师告诉我使用2个顶点缓冲区并交换它们,给了我这个链接:https://www.khronos.org/opengl/wiki/GLAPI/glBufferSubData
上面写着:
当替换整个数据存储时,请考虑使用glBufferSubData,而不是使用glBufferData完全重新创建数据存储。这避免了重新分配数据存储的成本。
请考虑使用多个缓冲区对象,以避免在数据存储更新期间延迟渲染管道。如果流水线中的任何渲染引用由glBufferSubData更新的缓冲区对象中的数据,特别是来自正在更新的特定区域的数据,则该渲染必须在数据存储可以被更新之前从流水线中排出。
因此,回到那时,我们示例化2个VBO,用glBufferData给它们一个大小,然后每帧我们将通过绑定另一个来“交换”使用两个VBO中的哪一个(以避免glBufferSubData带来的同步减慢),使用glBufferSubData更新数据,然后绘制。
我在任何地方都找不到信息,好像这是使用OpenGL的最佳实践,或者如果只使用1 VBO并在每帧中使用glBufferData会更好。
我还想知道,由于GL 3.3核心需要声明一个 VAO ,在2个缓冲区的情况下,是否也声明2个VAO并在它们之间交换更好,或者只声明1个VAO并在这个VAO中的VBO之间交换更好?

rkue9o1l

rkue9o1l1#

我建议你研究一下OpenGL wiki中关于这个主题的内容:

流媒体

主条目:Buffer Object Streaming
流式传输是频繁地将数据上传到缓冲区对象,然后在某些OpenGL进程中使用该缓冲区对象的过程。
...

流媒体的关键在于并行度。OpenGL规范允许实现延迟绘图命令的执行。这允许你画很多东西,然后让OpenGL自己处理。因此,完全有可能在使用buffer对象调用渲染函数之后,开始尝试将顶点数据流式传输到该缓冲区中。如果发生这种情况,OpenGL规范要求线程暂停,直到所有可能受缓冲区对象更新影响的绘制命令完成为止。这显然错过了流媒体的全部意义。

有效流的关键是synchronization
有关VBO和 VAO 的更多信息可以在这里找到:Vertex Specification,尤其是顶点缓冲区对象和顶点数组对象。
您可能也会发现此信息很有用:Vertex Specification Best Practices(动态VBO -这可能是您问题的实际答案)。
你可以做的另一件事是双缓冲VBO。这意味着您可以创建2个VBO。在第N帧上,更新VBO 2并使用VBO 1进行渲染。在帧N+1上,更新VBO 1并从VBO 2渲染。

相关问题