【发布时间】:2015-10-19 18:12:13
【问题描述】:
在单个帧中,是否“允许”连续更新相同的GL_ARRAY_BUFFER 并在每次更新后继续调用glDrawArrays?
我知道这可能不是最好的,也不是最推荐的方法,但我的问题是:我可以这样做并期望在每次调用 glDrawArrays 之前更新 GL_ARRAY_BUFFER 吗?
代码示例如下所示:
// setup a single buffer and bind it
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
while (!renderStack.empty())
{
SomeObjectClass * my_object = renderStack.back();
renderStack.pop_back();
// calculate the current buffer size for data to be drawn in this iteration
SomeDataArrays * subArrays = my_object->arrayData();
unsigned int totalBufferSize = subArrays->bufferSize();
unsigned int vertCount = my_object->vertexCount();
// initialise the buffer to the desired size and content
glBufferData(GL_ARRAY_BUFFER, totalBufferSize, NULL, GL_STREAM_DRAW);
// actually transfer some data to the GPU through glBufferSubData
for (int j = 0; j < subArrays->size(); ++j)
{
unsigned int subBufferOffset = subArrays->get(j)->bufferOffset();
unsigned int subBufferSize = subArrays->get(j)->bufferSize();
void * subBufferData = subArrays->get(j)->bufferData();
glBufferSubData(GL_ARRAY_BUFFER, subBufferOffset, subBufferSize, subBufferData);
unsigned int subAttributeLocation = subArrays->get(j)->attributeLocation();
// set some vertex attribute pointers
glVertexAttribPointer(subAttributeLocation, ...);
glEnableVertexAttribArray(subAttributeLocation, ...);
}
glDrawArrays(GL_POINTS, 0, (GLsizei)vertCount);
}
您可能会问 - 我为什么要这样做,而不是一次将所有内容预加载到 GPU 上……嗯,很明显的答案,因为当有太多数据无法容纳时,我不能这样做到单个缓冲区中。
我的问题是,我只能看到glDrawArrays 调用之一的结果(我相信第一个),或者换句话说,看起来好像GL_ARRAY_BUFFER 是在每次glDrawArrays 调用之前没有更新,这让我回到了我的问题,如果这可能的话。
我正在使用 OpenGL 3.2 CoreProfile(在 OS X 下)并与 GLEW 链接以进行 OpenGL 设置以及 Qt 5 以设置窗口创建。
【问题讨论】:
-
你试过glBufferSubData
-
是的,我实际上是在使用
glBufferSubData复制缓冲区的不同部分,但我仍然需要调用glBufferData来调整它的大小......无论哪种方式 - 哪个有区别我打电话问我的问题? -
@Chris:你的方法是有效的。 GL 将完成所有必要的隐式同步,以便为您工作。实际上,由于调用
glBufferData()为缓冲区对象分配了一个新的存储空间,因此无需任何进一步的同步就可以实现合理的实现,因此该方法甚至不应该像您想象的那么糟糕(但您也不能依赖它)。我不知道你的情况出了什么问题,但我可以明确确认缓冲区更新本身不是问题。 -
@derhass 感谢您的确认,您可以想象使用包含数百万个点的数据集进行调试有点痛苦……我扩展了我的示例以表明我也在使用 @987654332 @ 转移部分缓冲区,但我认为这也不会产生任何影响,对吧?
-
@Chris:
BufferSubData部分没问题(假设您的尺寸和偏移量正确)。但是,代码没有意义,因为您在内部循环中设置了VertexAttribPointer。只有最后一个有效,当你最后调用DrawArrays。
标签: c++ opengl rendering opengl-3