使用 OpenGL 保存和渲染过程的渲染问题之前的延迟
Delay before rendering issue using OpenGL save and render process is used
我使用 GLFW OpenGL 创建了一个 c++ 计算程序,该程序计算预定义时间段内粒子上的简单引力物理,并将计算结果保存为标准 GL_ARRAY_BUFFER。这是以标准方式设置的:
glGenBuffers(1, &vboSTATE);
glBindBuffer(GL_ARRAY_BUFFER, vboSTATE);
int bufferSize = (pCount * (4 * sizeof(GLfloat))) * (totalSteps);
glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_DYNAMIC_DRAW);
数据保存使用glCopyBufferSubData获取GPU缓冲区之间传输的数据。
一旦模拟时间过去,结果(位置)将通过简单的绘制调用呈现如下,循环遍历记录的数据:
glDrawArrays(GL_POINTS, step, particleCount);
"step" 是在当前帧中渲染的物理步骤。在渲染循环开始之前有一个暂停,这与粒子数成线性关系。使用 1 个粒子,延迟似乎消失了,100 个,延迟大约 5 秒,1000 个粒子,延迟在一分钟左右,甚至可能挂起并导致程序崩溃。
我唯一注意到的是缓冲区大小随着模拟中粒子的数量而增加,但这并不是我认为的疯狂 - 100 个粒子不到 1mb。
我之前有一个程序可以在同一帧内实时计算和渲染但是粒子的数量是有限的(我希望最后能有几千个),但是没有遇到延迟。当我转到这个 post-解决显示样式程序时发生了这种情况。
有什么想法吗??谢谢,
为了读取由 CS 写入的数据,必须生成该数据。需要生成的数据越多,所需的时间就越长。因此,写入和读取命令之间的时间越长。
您布置的缓冲区复制操作毫无意义。 OpenGL 缓冲区对象没有类型。在一个操作中将缓冲区用作 SSBO 是 100% 可以的,然后将其附加到 VAO 以用作另一个操作的源顶点数组数据。
现在,因为写入 SSBO 使用 incoherent writing,您将需要在写入和消耗缓冲区的呈现操作之间适当 glMemoryBarrier
。但是无论如何,您在写入和缓冲区复制之间需要其中之一。
此问题已通过在每次复制操作后使用 glFinish() 解决,以确保数据已实际复制。我在社区提供的建议的帮助下找到了解决方案。这确实会大大增加循环时间,但至少您可以确定 openGL 已完成写入并且数据已准备好使用...
谢谢大家!
我使用 GLFW OpenGL 创建了一个 c++ 计算程序,该程序计算预定义时间段内粒子上的简单引力物理,并将计算结果保存为标准 GL_ARRAY_BUFFER。这是以标准方式设置的:
glGenBuffers(1, &vboSTATE);
glBindBuffer(GL_ARRAY_BUFFER, vboSTATE);
int bufferSize = (pCount * (4 * sizeof(GLfloat))) * (totalSteps);
glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_DYNAMIC_DRAW);
数据保存使用glCopyBufferSubData获取GPU缓冲区之间传输的数据。
一旦模拟时间过去,结果(位置)将通过简单的绘制调用呈现如下,循环遍历记录的数据:
glDrawArrays(GL_POINTS, step, particleCount);
"step" 是在当前帧中渲染的物理步骤。在渲染循环开始之前有一个暂停,这与粒子数成线性关系。使用 1 个粒子,延迟似乎消失了,100 个,延迟大约 5 秒,1000 个粒子,延迟在一分钟左右,甚至可能挂起并导致程序崩溃。
我唯一注意到的是缓冲区大小随着模拟中粒子的数量而增加,但这并不是我认为的疯狂 - 100 个粒子不到 1mb。
我之前有一个程序可以在同一帧内实时计算和渲染但是粒子的数量是有限的(我希望最后能有几千个),但是没有遇到延迟。当我转到这个 post-解决显示样式程序时发生了这种情况。
有什么想法吗??谢谢,
为了读取由 CS 写入的数据,必须生成该数据。需要生成的数据越多,所需的时间就越长。因此,写入和读取命令之间的时间越长。
您布置的缓冲区复制操作毫无意义。 OpenGL 缓冲区对象没有类型。在一个操作中将缓冲区用作 SSBO 是 100% 可以的,然后将其附加到 VAO 以用作另一个操作的源顶点数组数据。
现在,因为写入 SSBO 使用 incoherent writing,您将需要在写入和消耗缓冲区的呈现操作之间适当 glMemoryBarrier
。但是无论如何,您在写入和缓冲区复制之间需要其中之一。
此问题已通过在每次复制操作后使用 glFinish() 解决,以确保数据已实际复制。我在社区提供的建议的帮助下找到了解决方案。这确实会大大增加循环时间,但至少您可以确定 openGL 已完成写入并且数据已准备好使用...
谢谢大家!