오옷~!! 이게 제 두번째 강좌로군요 ^^
이번 강좌엔 게임 플그래밍에서 중요한 시간재기 방법을 알려드리겠습니다~
시간재기... 프레임 부분에서 아주 중요한 부분이죠? ^^;;;
보통 분들은 모두 GetTickCount로 해결하시곤 합니다.
그러나 여기엔 세가지 문제점이 있습니다.
1. 리턴값=DWORD(4바이트), 즉 4294967296ms (대략 49.7일)가 지나면 GetTickCount가 다시 첨부터 0을 반환하게 됩니다. (물론 49일동안 컴터를 틀어놓을 인간은 없지만 -_-;;;)
2. 대략 정확도 부족;;;
3. 스피트핵의 대부분이 이넘을 노립니다. 즉 조심!
QueryPerformanceCounter 방식은 위의 모든 단점을 대체 가능합니다.
즉 윈도우 틱을 사용하지 않고 CPU 틱을 쓰기 땜시 엄청나게 정확합니다.
다만 두가지 단점이 있는데...
1. 사용법이 어렵다는... ㅠ.ㅠ
2. 구형 컴터는 지원하지 않거나 오히려 느려진다는... ㅠ.ㅠ
이 방식을 사용하기 위해 필요한 함수는 2개입니다.
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
위쪽 함수는 씨퓨 틱의 속도를 초 단위로 구하구요... 아래는 틱값을 구합니다.
LARGE_INTEGER 구조체는 떨 거 없습니다 -_-;;;
typedef struct _LARGE_INTEGER {
LONGLONG QuadPart;
} LARGE_INTEGER;
typedef __int64 LONGLONG;
걍 간단히 말해 64bit 정수를 담는 구조체라는... -_-;;; ㅋㅋㅋ;;;
__int64는 VC++에서 64bit 정수를 말합니다~
자... 그럼 시간을 재볼까요?
LARGE_INTEGER start,end,freq;
QueryPerformanceCounter(&start);
//...
//... 뭐시기 작업;;;
//...
QueryPerformanceCounter(&end);
QueryPerformanceFrequency(&freq);
double gap_second=((double)(end.QuadPart-start.QuadPart)/(double)(freq.QuadPart));
이때 gap_second가 초단위(ms가 아님에 주의!)로 걸린 시간을 갖게 되는 겁니다.
글구 주파수(Frequency)는 보통 120만 정도의 큰 수니까 플로팅 오버플로우 Exception 같은 극단은 걱정 안하셔도 됩니다 ^^;;;
자... 그럼 GetTickCount 방식으로 바꿔볼까요?
double GetPerformanceFreq(){ //static을 위한 궁여지책;;;
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li)) //지원 안함
return 0.;
return double(li.QuadPart); //C++에서 새로 추가된 캐스팅법 : "(타입)변수" 가 아니라 "타입(변수)"
}
double GetDoubleTickTime(){ //초단위 double 반환
static double freq=GetPerformanceFreq(); //매번 주파수 구하는 거 시간걸려서;;;
if(freq==0.) //지원 안함
return double(GetTickCount())/1000.; //역시 궁여지책;;;
LARGE_INTEGER cnt;
QueryPerformanceCounter(&cnt);
return double(cnt)/freq;
}
히히히... 이럼 더 정확해지겠죠? ^^;;;
함 프레임 구하는 부분에서 써보세요~
글구
이상입니다~
첫댓글 오호~~~ 좋은 강좌 고맙습니당 ㅎㅎ
오오.. 예전에 리플레이에 저거 쓰려고 삽질하다가 그냥 GetTick 을 했던 기억이.. ( 아.. 역시 난 멀었어.. )