我正在创建一个依赖系统时间的DirectX应用程序(因为它必须准确),
而且我需要在后台每秒执行60行代码(在boost :: thread创建的线程中)。等于60 FPS(每秒帧),但不取决于主要应用程序的帧速率。

//.................
void frameThread()
{
    // I want to run codes inside this loop for *exactly* 60 times in a second.
    // In other words, every 16.67 (1000/60) milliseconds
    for(;;)
    {
      DoWork();
      //.........
    }
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
   initialize();
   //.....stuffs
   boost::thread framethread(frameThread);
   //......
}


有没有办法做到这一点?

任何帮助,将不胜感激:)

最佳答案

由于60 Hz是常见的监视器刷新频率,因此听起来像是要启用垂直同步,而不是搞乱计时器和睡眠。

您提到使用的是DirectX-如果使用的是DirectX 9,则在创建设备时指定D3DPRESENT_INTERVAL_ONE,应用程序将同步到监视器刷新率。通常为60 Hz-但理论上也可以为50Hz,85Hz或120Hz之类的任何值。但是,您会获得非常漂亮的无撕裂显示-如果不使用V-sync,则滚动时可能会撕裂伪像。

这就提出了一个问题:如果帧率变化很大,如何使游戏以相同的速度前进?答案很简单-使用高分辨率计时器(如Windows上的QueryPerformanceCounter),并测量每帧之间的时间。然后,您需要使所有运动或运动都基于此“增量时间”值。无论如何,这都是一件好事,即使使用固定的帧速率-如果计算机速度很慢并且玩家只能获得20fps,它也可以防止游戏突然慢动作运行。

这是一个示例,无论帧速率如何,均以每秒100像素的速度水平移动对象:

object.x += 100.0f * delta_time; // same speed no matter the framerate


此IMO是一种更好的方法,尤其是考虑到它具有无撕裂,独立于帧率并且与用户的显示器同步的情况,而不是您自己设置的任意帧率。

09-10 04:02
查看更多