DXUT11框架浅析(12)--CDXUTTimer
先看下下面三个回调函数都有两个形参double fTime, float fElapsedTime。前者是程序运行了多长时间,后者是每帧用了多长时间。
LPDXUTCALLBACKFRAMEMOVE
LPDXUTCALLBACKD3D9FRAMERENDER
LPDXUTCALLBACKD3D11FRAMERENDER
绘制动画必不可少的一个条件是时间信息,动画是建立在时间变化的基础上,DXUT11提供了一个很简单的管理时钟的类CDXUTTimer,并为几个回调函数提供时间信息。
1. 类的原理和使用
1.1 原理
这个类只用了两个API来实现时间的获取。其实是使用硬件提供的一个计数器,用计数器当前记录的值和计数器本身的频率算出当前的时间。
BOOL WINAPI QueryPerformanceFrequency(
_Out_ LARGE_INTEGER *lpFrequency
);
获取高分辨率性能计数器的频率值。如果成功则返回非零。这个在初始化时获得一次即可。
BOOL WINAPI QueryPerformanceCounter(
_Out_ LARGE_INTEGER *lpPerformanceCount
);
获取高分辨率性能计数器的当前值。需要获取时间时调用一次,然后根据上面的频率计算时间。
1.2 使用
通过全局函数DXUTGetGlobalTimer获取一个静态CDXUTTimer对象。
2. CDXUTTimer类的成员变量
m_bTimerStopped
时钟是否停止。
m_llQPFTicksPerSec
计算机的高分辨率性能计数器的频率。
m_llStopTime
停止时钟时,计数器的值,这个值是个计数值,不是时间。
m_llLastElapsedTime
每次调用GetElapsedTime()时记录当前的计数值。
m_llBaseTime
在Reset()中记录计数值。用于记录程序启动时的计数值。
3. CDXUTTimer类的成员函数
Reset
重置时钟。
Start
启动时钟,获取当前计数器的值,记录m_llLastElapsedTime的值,如果时钟已经被停止了,那么要更新m_llBaseTime,当然,这里要把记录停止状态的有关变量清零(m_llStopTime/m_bTimerStopped)。
Stop
停止时钟,如果前面没有停止那么要获取当前计数器的值,并更新m_llLastElapsedTime的值,当然要把记录停止状态的有关变量m_llStopTime和m_bTimerStopped设值。
Advance
将停止时的计数值m_llStopTime加上一个单位(频率值的十分之一)
GetAbsoluteTime
得到当前系统时间。
GetTime
得到自Start()调用至此的时间。
GetElapsedTime
得到据上次调用该函数的时间差。
GetTimeValues
得到多个时间值。
pfTime返回自Start()至现在的时间值。
pfAbsoluteTime返回系统时间值。
pfElapsedTime返回上次调用GetElapsedTime()至现在的时间值。
IsStopped
当前时钟是否被停止。
LimitThreadAffinityToCurrentProc
将使用时钟类的线程限制在同一个处理器上运行。
GetAdjustedCurrentTime
得到当前计数器的值。如果时钟被停止了,则返回停止时的计数值m_llStopTime。