我可以在更新相同的 `GL_ARRAY_BUFFER` 的同时多次调用 `glDrawArrays` 吗?
Can I call `glDrawArrays` multiple times while updating the same `GL_ARRAY_BUFFER`?
在单帧中,是否"allowed"连续更新同一个GL_ARRAY_BUFFER
,每次更新后一直调用glDrawArrays
?
我知道这可能不是最好的方法,也不是最推荐的方法,但我的问题是:我可以这样做并期望在每次调用 [=13 之前更新 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 下)和 link 以及用于 OpenGL 设置的 GLEW 以及用于设置 window 创作.
是的,这是合法的 OpenGL 代码。这绝不是任何人实际上应该做的事情。但这是合法的。事实上,它在你的情况下更没有意义,因为你正在为每个对象调用 glVertexAttribPointer
。
如果您不能将所有顶点数据放入内存,或者需要在 GPU 上生成它,那么您应该使用适当的 buffer streaming techniques.
流式传输数据
在单帧中,是否"allowed"连续更新同一个GL_ARRAY_BUFFER
,每次更新后一直调用glDrawArrays
?
我知道这可能不是最好的方法,也不是最推荐的方法,但我的问题是:我可以这样做并期望在每次调用 [=13 之前更新 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 下)和 link 以及用于 OpenGL 设置的 GLEW 以及用于设置 window 创作.
是的,这是合法的 OpenGL 代码。这绝不是任何人实际上应该做的事情。但这是合法的。事实上,它在你的情况下更没有意义,因为你正在为每个对象调用 glVertexAttribPointer
。
如果您不能将所有顶点数据放入内存,或者需要在 GPU 上生成它,那么您应该使用适当的 buffer streaming techniques.
流式传输数据