c++ - 关于使用 glBufferSubData 频繁更新实例化数组的困惑

标签 c++ opengl buffer gpu

我使用实例化渲染来渲染大片草地,为此我使用由大量 4x4 变换矩阵组成的实例化数组。

我在草叶上使用 LOD 算法,根据叶子到相机的距离来确定要渲染的叶子。因此,我更新实例化数组以仅包含相关的变换矩阵,然后通过 glDrawArraysInstanced 渲染它们各自的叶子。

我的困惑来自于更新实例化数组。我按如下方式创建实例化数组一次:

glBindBuffer(GL_ARRAY_BUFFER, VBO_Models);
glBufferData(GL_ARRAY_BUFFER, grass.size() * sizeof(glm::vec4), NULL, GL_STREAM_DRAW);

那么最有效的方法是使用 glBufferSubData 来更新其内容(以节省昂贵的内存重新分配),我的做法如下:

glBufferSubData(GL_ARRAY_BUFFER, 0, grassModels.size() * sizeof(glm::mat4), &grassModels[0]);

但这就是事情变得奇怪的地方。如果我使用 glBufferSubData ,它似乎只会在我在场景周围移动一定距离(我想说大约每 1000 帧)后在渲染期间更新实例化数组,而如果我在同一位置保持静态则不会更新实例化数组。

当我使用 glBufferData 重新分配内存时,它确实可以正常工作。所以我认为这可能是一个同步问题,所以我实现了具有多个缓冲区的循环方法;没用。我尝试了孤立,这确实有效(因为我再次使用glBufferData),但我不想使用这种方法。

然而,同步问题通常只发生在几帧内(在我的例子中,不是大约 1000 帧,仅在移动后发生)。也许涉及到移动,因为这会显着改变缓冲区的内容,迫使 GPU 使用新更新的内存?

我不确定是什么导致了 glBufferSubData 的这种行为,并且在文档中找不到与我的问题类似的任何内容。我可以使用 glBufferData 轻松解决该问题,这不会使我的性能明显下降,但我很好奇是什么导致了这种行为?

最佳答案

glBindBuffer(GL_ARRAY_BUFFER, VBO_Models);
glBufferData(GL_ARRAY_BUFFER, grass.size() * sizeof(glm::vec4), NULL, GL_STREAM_DRAW);

此处传入的大小小于您要更新的大小。这会导致 GL_INVALID_VALUE​并将更新变成空操作。

关于c++ - 关于使用 glBufferSubData 频繁更新实例化数组的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28830270/

相关文章:

linux - Linux 的 C++ 中等效的 mmap 是什么?

opengl - 如何在 GLSL 中实现 2D raycasting 光效

opengl - 如何使用计时器移动顶点着色器中的点

c++ - 如何将 Char** 插入 uin8_t vector ?

c - 为什么这个 fgets() 循环永远不会结束?

c++ - 检测模板方法和自由函数的存在

C++ 将字符串数组 [] 复制到 vector <string>

c++ - 使用 babeltrace API 计算流中的所有事件

python - 如何使用 Python 和 PyGame 在 OpenGL 上显示 2D 形状

ASP.NET MVC 3 在 <body> 呈现之前发送 <head>