【问题标题】:Confusion regarding frequent updates of instanced array using glBufferSubData关于使用 glBufferSubData 频繁更新实例数组的困惑
【发布时间】: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,但这不能解释我在glBufferDataglBufferSubData 之间注意到的行为,对吧?无论如何我都会尝试一下,看看它是否会给出类似的结果
  • 我认为这可能是因为您使用 sizeof(glm::vec4) 进行分配时使用 sizeof(glm::mat4) 进行更新
  • 是的,你是对的,我觉得自己像个白痴;调试和阅读 GL 文档数小时,它是如此简单。在我到达一定的草叶门槛后,使用glMapBuffer 确实崩溃了,导致我出错。感谢您成为我在这里显然需要的第二双眼睛;)
  • 这也解释了为什么它只发生在移动之后。在移动过程中,它只会在周围的草叶适合分配的内存时更新缓冲区,但并不总是这样做。如果您愿意,您可以回答这个问题,或者我会在接下来的一个小时内自己回答。谢谢,再次

标签: c++ opengl buffer gpu


【解决方案1】:
glBindBuffer(GL_ARRAY_BUFFER, VBO_Models);
glBufferData(GL_ARRAY_BUFFER, grass.size() * sizeof(glm::vec4), NULL, GL_STREAM_DRAW);

此处传入的大小小于您正在更新的大小。这会导致 GL_INVALID_VALUE​,并将更新变为 noop。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 2022-07-17
    相关资源
    最近更新 更多