大家都知道,在游戏制作里面,控制帧率是一件很重要的事情,那么我们在DirectX里面又是怎样来控制游戏的帧率呢?其实有两个方法可以实现:
一、控制窗口刷新率
在新建一个Direct3DDevice的时候我们会用到CreateDevice这个函数,如果是全屏模式下,我们可以通过修改D3DPRESENT_PARAMETERS结构参数中的PresentationInterval 值为 D3DPRESENT_INTERVAL_ONE ,窗口模式下是D3DPRESENT_INTERVAL_DEFAULT,这样游戏的刷新率会跟屏幕的刷新周期一样,从而达到控制帧率的目的。
二、控制主循环的事件频率
如果上述的控制窗口刷新率的方法不管用的话,我们就可以直接通过控制接收到消息后进入主循环的频率来控制帧率。话不多说,直接上代码。
MSG msg = {0};
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg,0,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
const float constFps = 60.0f; //定义帧数
DWORD timeInPerFrame = 1000.0f / constFps; //计算每帧的频率
DWORD timeBegin = GetTickCount(); //循环开始的时间
DirectX_Update(hwnd); //directX循环
DirectX_Render(hwnd); //directX渲染
DWORD timePhase = GetTickCount() - timeBegin; //循环耗费的时间
if(timePhase < timeInPerFrame) //循环耗费的时间<每帧的时间
{
Sleep(DWORD(timeInPerFrame - timePhase)); //将剩余的时间等待
}
}
}
同时,我们可以通过下面的函数来检验一下看看我们的帧率控制是否妥当:
float GetFPS()
{
static float fps = 0;
static int frameCount = 0;
static float currentTime = 0.0f;//当前时间
static float lastTime = 0.0f;//持续时间
frameCount++;//每调用一次Get_FPS()函数,帧数+1
currentTime = timeGetTime()*0.001f;//获取系统时间,并转化成秒为单位
//经过了一秒,就进行一次FPS的计算和持续时间的更新,并将帧数值清零
if (currentTime - lastTime > 1.0f) //将时间控制在1秒钟
{
fps = (float)frameCount / (currentTime - lastTime);//计算这1秒钟的FPS值
lastTime = currentTime; //将当前时间currentTime作为下一秒的基准时间
frameCount = 0;//将本次帧数frameCount值清零
}
return fps;
}