每帧多次调用 glBufferSubData

Posted

技术标签:

【中文标题】每帧多次调用 glBufferSubData【英文标题】:Calling glBufferSubData several times per frame 【发布时间】:2016-10-28 10:45:38 【问题描述】:

我正在进行渲染,每帧调用 glBufferSubData 几次。

这是我在代码中的做法:

    glBindBuffer(GL_ARRAY_BUFFER,_vboID);

//Buffering the data
glBufferData(GL_ARRAY_BUFFER,_vboDATA[type].size()*sizeof(vboData),nullptr,GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER,0,_vboDATA[type].size()*sizeof(vboData),_vboDATA[type].data());

   glBindBuffer(GL_ARRAY_BUFFER,0);

我问是因为我有不同类型的元素,每个元素都有自己的向量来表示 vbo 数据(我在我的程序中使用 1 个 VBO(用于颜色、UV、位置和 1 个 VAO)和我m 像这样进行渲染:

1.) 将元素 1 的向量加载到缓冲区

2.) 渲染元素 1

3.) 将元素 2 的向量加载到缓冲区

4.) 渲染元素 2

...

这样做是正确的方法吗?

【问题讨论】:

【参考方案1】:

正确的方法取决于您的使用场景。当数据大多是静态的时,最好的方法是将数据一次上传到 GPU。这可以通过为每个对象创建一个 VBO 来完成,或者通过将所有对象拼凑到一个 VBO 中来完成。

如果数据是完全动态的(并且在每一帧中都在变化),那么无论如何您都必须上传数据,因此只使用一个缓冲区就可以了。但是您仍然应该尝试仅上传数据(glBufferSubData)并避免分配新内存(glBufferData)。例如,您可以选择足够大以容纳所有数据的缓冲区的初始大小。另一种选择是使用persistently mapped buffer。

【讨论】:

“那么最好的方法是为每个对象创建一个 VBO” - 这是非常值得商榷的,不仅因为“最好的”建议您可以对有关静态数据的每个问题应用一个解决方案,而不管他是问题域,但是因为您可以例如轻松地使用一个缓冲区、一个索引数组和不同的顶点数组,您可以根据需要启用和禁用它们并使用gl[Multi]DrawElementsBaseVertex 进行绘制。在这里达到目标的方法很多。另外,您应该指出使用持久映射缓冲区的可能性,您不要使用glBufferSubData修改。 @thokra:感谢您的反馈。我试图将您的建议包含在答案中。

以上是关于每帧多次调用 glBufferSubData的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI |警告:绑定首选项 _ 尝试每帧更新多次。可能的原因?

带有 CurrentValueSubject 绑定的 TextField 上的“Binding<String> 操作尝试每帧更新多次”

Unity3D的杂记

每帧调用 glGetUniformLocation()

XMLSocket 可以在一帧中多次发送吗?

2023-02-22:请用go语言调用ffmpeg,保存mp4文件的视频帧,每帧用ppm图片保存。