我正在使用实例化渲染渲染大片草,为此我使用了由大量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
轻松解决问题,但这并没有给我带来明显的性能下降,但我很好奇是什么导致了这种行为?
答案 0 :(得分:2)
glBindBuffer(GL_ARRAY_BUFFER, VBO_Models);
glBufferData(GL_ARRAY_BUFFER, grass.size() * sizeof(glm::vec4), NULL, GL_STREAM_DRAW);
此处传递的大小小于您要更新的大小。这会导致GL_INVALID_VALUE并将更新变为noop。