代码
定时器代码
#ifndef __CTimer_H__
#define __CTimer_H__
#include <windows.h>
class CTimer{
private:
LONGLONG m_CurrenntTime,
m_LastTime,
m_NextTime,
m_FrameTime,
m_PerfCountFreq;
double m_TimeElapsed,
m_TimeScale;
float m_FPS;
public:
CTimer();
CTimer(float fps);
void Start();
bool ReadyForNextFrame();
double GetTimeElapsed(){return m_TimeElapsed;}
double TimeElapsed();
};
#endif
#include "CTimer.h"
CTimer::CTimer():m_FPS(0),
m_TimeElapsed(0.0f),
m_FrameTime(0),
m_LastTime(0),
m_PerfCountFreq(0)
{
QueryPerformanceFrequency((LARGE_INTEGER*) &m_PerfCountFreq);
m_TimeScale = 1.0f / m_PerfCountFreq;
}
CTimer::CTimer(float fps):m_FPS(fps),
m_TimeElapsed(0.0f),
m_LastTime(0),
m_PerfCountFreq(0)
{
QueryPerformanceFrequency((LARGE_INTEGER*) &m_PerfCountFreq);
m_TimeScale = 1.0f / m_PerfCountFreq;
m_FrameTime = (LONGLONG)(m_PerfCountFreq / m_FPS);
}
void CTimer::Start(){
QueryPerformanceCounter((LARGE_INTEGER*) &m_LastTime);
m_NextTime = m_LastTime + m_FrameTime;
return;
}
bool CTimer::ReadyForNextFrame(){
if(!m_FPS){
MessageBox(NULL, "No FPS set in timer", "Doh", 0);
return false;
}
QueryPerformanceCounter((LARGE_INTEGER*) &m_CurrentTime);
if(m_CurrentTime > m_NextTime){
m_TimeElapsed = (m_CurrentTime - m_LastTime) * m_TimeScale;
m_LastTime = m_CurrentTime;
m_NextTime = m_CurrentTime + m_FrameTime;
return true;
}
return false;
}
double CTimer::TimeElapsed(){
QueryPerformanceCounter((LARGE_INTEGER*) &m_CurrentTime);
m_TimeElapsed = (m_CurrentTime - m_LastTime) * m_TimeScale;
m_LastTime = m_CurrentTime;
return m_TimeElapsed;
}
定时器使用
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow){
WNDCLASSEX winclass;
HWND hwnd;
MSG msg;
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = NULL;
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = NULL;
winclass.lpszMenuName = NULL;
winclass.lpszClassName = szWindowClassName;
winclass.hIconSm = NULL;
if(!RegisterClassEx(&winclass)){
MessageBox(NULL, "Error Registering Class!", "Error", 0);
return 0;
}
if(!(hwnd = CreateWindowEx(NULL,
szWindowClassName,
szApplicationName,
WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
GetSystemMetrics(SM_CXSCREEN)/2 - CParams::WindowWidth/2,
GetSystemMetrics(SM_CYSCREEN)/2 - CParams::WindowHeight/2,
CParams::WindowWidth,
CParams::WindowHeight,
NULL,
NULL,
hinstance,
NULL)))
{
MessageBox(NULL, "Error Creating Window!", "Error", 0);
return 0;
}
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
CTimer timer(CParams::iFramesPerSecond);
timer.Start();
bool bDone = false;
while(!bDone){
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message == WM_QUIT){
bDone = TRUE;
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if(timer.ReadyForNextFrame() || g_pController->FastRender()){
if(!g_pController->Update())
bDone = true;
InvalidateRect(hwnd, NULL, NULL);
UpdateWindow(hwnd);
}
}
Cleanup();
UnregisterClass(szWindowClassName, winclass.hInstance);
return 0;
}