【发布时间】:2015-05-04 00:19:45
【问题描述】:
我正在使用实例化渲染来渲染大片草地,为此我使用了一个包含大量 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 轻松解决此问题,这不会显着降低性能,但我很好奇是什么导致了这种行为?
【问题讨论】:
-
glMapBuffer 工作吗?
-
我还没有尝试过
glMapBuffer,但这不能解释我在glBufferData和glBufferSubData之间注意到的行为,对吧?无论如何我都会尝试一下,看看它是否会给出类似的结果 -
我认为这可能是因为您使用 sizeof(glm::vec4) 进行分配时使用 sizeof(glm::mat4) 进行更新
-
是的,你是对的,我觉得自己像个白痴;调试和阅读 GL 文档数小时,它是如此简单。在我到达一定的草叶门槛后,使用
glMapBuffer确实崩溃了,导致我出错。感谢您成为我在这里显然需要的第二双眼睛;) -
这也解释了为什么它只发生在移动之后。在移动过程中,它只会在周围的草叶适合分配的内存时更新缓冲区,但并不总是这样做。如果您愿意,您可以回答这个问题,或者我会在接下来的一个小时内自己回答。谢谢,再次