我正在研究LWJGL游戏,其中世界经常变化,并且因为它相当大,它导致游戏每次世界时都会冻结几分之一秒,从而更新相应的VBO。我通过将所有逻辑移动到一个单独的线程来减少游戏冻结的时间(好吧,它实际上是在一个单独的线程中的渲染代码),但是将数据推送到图形卡似乎仍然会产生明显的延迟。是否有可能在我的逻辑线程中发送VBO以免减慢游戏速度?
此外,如果这属于gamedev.so,请告诉我,我可以移动它。我不太确定,所以我决定在这里发帖。
答案 0 :(得分:2)
你不能使用多任务处理来使用OpenGL进行渲染。 显然我错了,虽然其余的答案仍然很好,如果你想只用一个修复问题OpenGL上下文。
虽然我在制作无限程序地形生成器时遇到了同样的问题,但问题与您的问题相同,每次世界更新或生成新的 Terrain Chunk < / em>它会冻结只有几分之一秒。
基本上我是如何通过以下方式解决这个问题的。
创建线程池/线程队列,每次世界更改时,您都会单独Thread
进程/更新或重新创建FloatBuffer
(或其他缓冲区)你用)。因为通常这就是冻结的原因,因为它需要花费大量时间来创建缓冲区,输入和更改所有数据等。
这是我的意思的布局。
class VBOAntiFreeze {
FloatBuffer vertex_data;
// Just add the rest of the FloatBuffers you use as well, like FloatBuffer
// normal_data; FloatBuffer color_data; etc.
// You would also have all the other variables as the vbo_handle, vertices count, etc.
boolean fresh = true;
boolean dirty, updating;
public void updateVBO() {
if (fresh && !updating) {
updating = true;
// You could execute new Threads by creating a
// Thread Pool/Thread Queue, that way, you will
// have some more control over all the threads.
new Thread(new Runnable() {
public void run() {
// Update and process all the FloatBuffers here!
dirty = true;
fresh = false;
updating = false;
}
}).start();
}
}
public void renderVBO() {
if (updating) {
return;
}
else if (fresh) {
updateVBO();
return;
}
if (dirty) {
// Buffer all the newly updated data
}
// Render the VBO here
}
}
通过使用这个想法,你可能不会遇到随机冻结,除非你的VBO非常庞大,因此if (dirty) buffer new data
将会/可能仍然会冻结一点,尽管我以前从未经历过这种情况。 但只是说,通知你!
答案 1 :(得分:1)
通常,GL上下文可以在任何时间对单个线程是最新的,并且线程可以随时具有一个当前GL上下文。如果要对GL对象进行并行更新,则有两种选择:
答案 2 :(得分:1)
我决定把我的评论写成答案,因为它与绘图线程的开销中的其他两个答案略有不同。在上传顶点数据或取消映射缓冲区时,我建议使用双缓冲并将用于绘图的VBO与工作线程完成更新后用于提交数据的VBO交换,而不是停止管道。
此方法需要两个渲染上下文,每个渲染上下文共享资源。
在您的工作线程中,您可以像在当前方法中一样将子数据分配/流式传输到VBO中,唯一的区别是您将对未用于绘制的VBO执行此操作。当你用数据完成这个VBO的填充时,让你的绘图线程知道,然后在绘制时将用于绘图的VBO与用于流顶点数据的VBO交换。您的工作线程应该阻塞,直到绘图线程在这种情况下交换VBO。
这样,当新数据必须提交给GPU时,不会停止绘制线程,而是停止用于流式处理新数据的线程,直到绘图线程交换VBO。结果渲染将是平滑的(呃),但更新可能以更多可变频率发生。这通常是游戏等交互式软件中的一个理想特征 - 在弹出新内容之前,额外的延迟帧通常比需要两倍长时间完成的帧更好。
如果你想一次排队多个更新,以便你的更新线程不必经常阻塞,我建议实现一个循环缓冲区,如他的答案中提到的derhass。但听起来你只需要问题描述中的前/后缓冲区。