【翻(xue)译(xi)】3D Game Programming With DirectX11 - 4.3

来源:互联网 发布:阿里云域名 跳转 编辑:程序博客网 时间:2024/06/09 17:18

4.3 计时和动画

为了正确的播放动画,我们需要一直计时。准确的说,我们需要计算两帧动画之间的时间。如果我们的帧率高,那么两帧动画之间的时间会很短,这样一来我们就需要一个比较精确地计时。

4.3.1 性能计数器
为了精确计时,我们使用性能计数器。使用win32的性能计时函数我们需要包含< window.h>这个头文件。
性能计数器的计时单位叫做计数(counts)。我们使用性能计数器的QueryPerformanceCounter这个函数来获得当前的时间值,以计时单位度量。
__int64 currTime;
QueryPerformanceCounter(LARGE_INTERGER*)&currTime);
注意到这个函数通过参数返回一个64位整数值。要得到性能计数器的频率,我们可以使用QueryPerformanceFrequency这个函数:
__int64 coutsPerSec;
QueryPerformanceFrequency((LARGE_INTERGER*)&coursPerSec);
每个count的秒数就是每秒的计数个数的倒数。所以当我们需要把计数所代表的时间转换“秒”所代表的时间的时候,我们需要乘以每个计数所需的秒数。
我们并不很在意counter所直接返回的计数数量,我们要把计数和频率结合起来得到时间,然后得到两个时间的时间差,而不是单个的计数。

Tips: 在MSDN上有一个关于QueryPerformanceCounter的标签:在一个多进程电脑上,在哪个进程上被调用应该是一样的。但是因为BIOS和HAL的bug,你总是会获得一个不同的值。你可以用SetThreadAffinityMask函数来确保主线程不会被切换到其他进程。

4.3.2 游戏的计时类
接下来我们要实现下边这个游戏计时类。代码略。

4.3.3 两帧之间的时间
当我们渲染动画的帧时,我们需要知道帧之间的时间过去了多少,以便更新我们的游戏显示。计算过程如下:
令t(i)表示性能计数器在第i个帧时返回的计数,t(i-1)为前一帧时的计数。那么两帧之间的时间就是 delta_t = t(i) - t(i-1)。在实时渲染中,我们典型的要求每秒至少30帧,来保证动画的流畅。这样一来,delta_t必须是一个相对比较小的数。
书中有代码来展示这个是如何计算的。略。
书中的代码写的很棒嗯。值得一看。

4.3.4 总的时间
另一个时间度量也很有用,那就是自从程序启动开始到现在的时间,不计算暂停了的时间。我们把这个叫做总时间(total time)。这个例子展示了这个会怎样有用:假设一个玩家有300秒完成一个关卡,那么从开始之后,我们可以一直检查过去的时间是否大于300秒,超过了玩家就输了;这里我们不应该计算暂停时间。
另一个总时间的用途是,当我们需要根据时间来动画一个大量的值的时候。比如我们希望按照时间来显示一个光的圆形轨道。它的位置可以用下边这个含参的方程来表达:
x = 10 cos t
y = 20
z = 10 sin t
这里t代表时间。随着时间增加,光的位置也按照一个10为半径的圆形轨道运动。在这里我们也不想要计入暂停了的时间。
我们用了 baseTime, pauseTime, stopTime来计算总时间:
baseTime表示启动或者重启的时候的时间点
pauseTime表示暂停所用的时间段。
mStopTime上次暂停的时间点。
mPrevTime上次启动的时间点。
与之相辅,我们会在Stop和Start这两个函数中用到这些属性。
接下来是代码。

0 0