DirectX

4. 타이머

Awesome Red Tomato 2021. 12. 20. 23:11

시간 측정을 위해 이 예제에서는 Windows가 제공하는 성능 타이머(performance timer)를 사용한다. 이를 성능 카운터(performance counter)라고도 한다.

 

성능 타이머 시간 측정 단위는 '지나간 클럭 틱 수'이다. 성능 타이머로부터 틱 수 단위의 현재 시간을 얻을 때에는 QueryPerformanceCounter()를 사용한다.

__int64 currTime;
QueryPerformanceCounter((LARGE_INTEGER*)&currTime));

 

지나간 틱 수를 얻었으니 초당 틱 수를 얻어야 한다. QueryPerformanceFrequency()를 이용한다.

__int64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&*countsPerSet);

 

countsPerSec의 역수를 구해서 1틱당 몇 초인지 구한다.

double mSecondsPerCount;
mSecondsPerCount = 1.0 / (double)countsPerSec;

 

구했으면 틱당 초 수에 지난 틱 수를 곱하면 초 단위 시간이 나온다.

 

 

GameTimer.cpp

#include <windows.h>
#include "GameTimer.h"

GameTimer::GameTimer()
	: 
	mSecondsPerCount(0.0), 
	mDeltaTime(-1.0), 
	mBaseTime(0),
	mPausedTime(0), 
	mPrevTime(0), 
	mCurrTime(0), 
	mStopped(false)
{
	__int64 countsPerSec;
	QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
	mSecondsPerCount = 1.0 / (double)countsPerSec;
}

float GameTimer::TotalTime()const
{
	if (mStopped)
	{
		return (float)(((mStopTime - mPausedTime) - mBaseTime) * mSecondsPerCount);
	}
	else
	{
		return (float)(((mCurrTime - mPausedTime) - mBaseTime) * mSecondsPerCount);
	}
}

float GameTimer::DeltaTime()const
{
	return (float)mDeltaTime;
}

void GameTimer::Reset()
{
	__int64 currTime;
	QueryPerformanceCounter((LARGE_INTEGER*)&currTime);

	mBaseTime = currTime;
	mPrevTime = currTime;
	mStopTime = 0;
	mStopped = false;
}

void GameTimer::Start()
{
	__int64 startTime;
	QueryPerformanceCounter((LARGE_INTEGER*)&startTime);

	if (mStopped)
	{
		mPausedTime += (startTime - mStopTime);

		mPrevTime = startTime;
		mStopTime = 0;
		mStopped = false;
	}
}

void GameTimer::Stop()
{
	if (!mStopped)
	{
		__int64 currTime;
		QueryPerformanceCounter((LARGE_INTEGER*)&currTime);

		mStopTime = currTime;
		mStopped = true;
	}
}

void GameTimer::Tick()
{
	if (mStopped)
	{
		mDeltaTime = 0.0;
		return;
	}

	__int64 currTime;
	QueryPerformanceCounter((LARGE_INTEGER*)&currTime);
	mCurrTime = currTime;

	mDeltaTime = (mCurrTime - mPrevTime) * mSecondsPerCount;

	mPrevTime = mCurrTime;

	if (mDeltaTime < 0.0)
	{
		mDeltaTime = 0.0;
	}
}