2011-04-27 63 views
2

在OpenGL中,一切都与主回路的工作(据我所知)。如果你想绘制一个物体给定的时间,这是一个问题。现在,我做的是以下几点:我测量我的应用程序的近似FPS,并设置一个计数器,以减少主循环中的每次迭代。当计数器达到0时,我停止绘图。因此,例如,如果我想在屏幕上绘制一个物体2秒,并且我的FPS为30,则将计数器设置为60并绘制对象,直到计数器达到0.绘制X秒对象在OpenGL

这可以正常工作,但它不是大。例如,由于对象有时距主循环“远”,所以很难写出类似 drawObjectFor(object, time)的东西。有没有更好的方法来做到这一点?

回答

5

你的FPS可能(而且通常会)有所不同,所以计算帧是不是一个好主意。

假设这个例子,看看这可能会咬你:
你的应用程序运行vsynced到60 FPS,你的帧时间是16.58ms。这意味着在屏幕上显示对象2秒钟,您将不得不绘制120帧的对象。简单,让我们走吧!
绘制对象增加了0.1 ms,总帧时间为16.68ms。哦,sh * t。现在你有30 FPS,你的对象显示4秒...

使用适当的时间决定是否绘制你的对象。当你得出结论,你的对象的时间到了,只需设置一个标记,这样你就不会绘制它(或者,从场景图中删除它,如果你有一个,或删除它,或其他)。

这可以通过多种方式来实现:

  • 在Windows
    • 使用SetTimer,这将发布一条消息到你的窗口的消息队列。当您收到WM_TIMER通知时,将该对象的do_draw标志(或任何您想调用它的标志)设置为false。
    • 如果您已经使用WaitFor(Single|Multiple)Object某处一次架,做一个CreateWaitableTimer,并等待这一点。您可以使用MsgWaitForMultipleObjectsEx来执行消息泵送和一次等待,并同时检查APC。
    • 没有什么能阻止你从每帧读取时间手动一次。 GetTickCount一次,加2000,并做一个if(new_count <= old_count + 2000) draw_object()。尽管GetTickCount的准确度很差(几十毫秒),但在等待2秒时完全没有关系。
  • 在Linux下
    • 使用timerfdepoll检查准备情况,或设置timerfd它非阻塞,看看是否从中读取返回EAGAIN
    • 使用clock_gettime和做手工(如GetTickCount
    • 使用setitimer
1

你可以有一个“生存时间”字段中的对象本身,这倒计数,直到对象被销毁(或至少不可见)。

然后drawObjectFor(object, time)将只设置object.timeToLive = time。然后,您还需要将帧时间传递给对象,可能在渲染时,可以相应地减少它的timeToLive

+0

是的,我也想过类似的东西,但我想知道是否没有更直接的方法来实现它,例如通过创建独立于程序其余部分的新线程 – seb 2011-04-27 11:14:31

+0

适当的实时循环对于OpenGL应用程序通常比线程更好(至少对于渲染部分 - 你可以使用线程来处理其他任何事情,注意线程同步)。然而,为场景中的每个对象生成一个线程并不是真正可扩展的,并且对于所有消失的对象和其他任何对象都有一个线程,就像没有多线程一样好。 – Kos 2011-04-27 14:49:26