使用DirectX和C ++保持稳定帧速率的最有效方法是什么?

时间:2009-10-17 22:54:02

标签: c++ windows directx frame-rate

我正在从一本关于游戏编程的书中学习DirectX,它使用以下方法进行游戏循环:

long int start = GetTickCount();
while(true)
    GameRun();

void GameRun()
{
     if(GetTickCount() - start >= 30)
         //do stuff
}

这使start等于任何时间(我猜测得到滴答计数给出自程序启动以来'滴答'的数量),然后,30个滴答以后,做所有的AI,渲染等等。

我的问题是,首先执行所有AI等是不是更有效率,然后,如果剩下的时间结束,等到帧需要更改?

那么,保持稳定帧速率的更好方法是什么? (最好只使用我已用于声音,图像和输入的DirectX标题(如d3d9.h))

而且,在相关的说明中,GetTickCount()究竟做了什么,以及'tick'有多长

2 个答案:

答案 0 :(得分:5)

对于您的游戏循环,请阅读this article。它总结了您的选择并使您的选择清晰。

现在对于GetTickCount(),这是在Windows中获取时间的最简单方法(我不知道unix操作系统的那个)。 QueryPerformanceFrequency和QueryPerformanceCounter提供了更高的精度,但可能很难理解如何正确使用它们。

您可能有兴趣阅读Ogre::Timer class worksOgre is a well-known open-source real-time 3D rendering library)的方式。他们添加了一些代码来处理这些函数的一些潜在问题,并且有几个平台的代码。

您可以获取代码并在应用中使用它。the license of the coming version of Ogre is MIT

这样你就可以专注于你的游戏循环和游戏代码。


更新时间精度:现在,如果你可以使用最后一个升级版本,那么boost.chrono提供高精度时钟,steady_clock,即跨平台和uses QueryPerformanceFrequency and QueryPerformanceCounter on windows。实际上,chrono是添加到C ++标准库的命题。

答案 1 :(得分:2)

您提供的示例代码是实现游戏循环的最糟糕方式。正如您所注意到的那样,等到刷新时间真的是一个巨大的浪费。

只需选择一个任意的时间步长(例如,一秒钟),并相对于此时间步骤表达所有测量值。

这看起来像是:

while ( !done )
{
    float alphaTime = timeConstant / (currentTime - lastLoopTime);
    dispatchEvents();
    gameLogic( alphaTime );
}

void gameLogic( float alphaTime )
{
    movePlayer( playerSpeed * alphaTime );
}

这样你就不会浪费时间等待帧速率,你可以让你的AI脚本运行,......并且一切都将以相同的速度移动,因为移动乘以时间因素。