프로그래밍 2014. 11. 23. 18:28
728x90

c++ tick

game tick

timeGetTime

QueryPerformanceFrequency

 

winmain()

{

.......

 

{

float fTick = Z_Tick();

Frame( fTick );

}

}

 

timeGetTime() 을 사용하여 틱계산을 하던 것을

좀 더 계산의 정밀도를 높이고자 QueryPerformanceFrequency() 를 사용하는 코드로 변경하였습니다.

 

QueryPerformanceFrequency() 사용하려고 보니,

QueryPerformanceFrequency() 가 모든 시스템에서 작동하도록 보장된 함수가 아닌 것을 알았습니다.

 

윈도우즈 OS 전용 함수이고,

구OS 에서는 문제를 일으킬 수 있습니다.

특정 노트북에서 작동이 않될 수도 있구요.

 

QueryPerformanceFrequency() 를 지원하는 환경에서는 호출,

지원하지 않을때는 timeGetTime() 를 호출하는

간단한 소스 코드 입니다.

 

 

DWORD sys_timeBase = 0;
DWORD Z_MilliSeconds( void )
{
      DWORD sys_curtime = 0;
      static bool initialized = false;

      if( !initialized ) 
      {
          ::timeBeginPeriod( 1 ); //-- timeGetTime() 을 1밀리세컨드 단위로 맞춘다
          sys_timeBase = ::timeGetTime();
          initialized  = true;
      }
      sys_curtime = timeGetTime() - sys_timeBase;

      return sys_curtime;
}

 

void Z_MilliSecondsTerminate( void )
{
     ::timeEndPeriod( 1 );
}

 

//--------------------------------------------------------------
//DESC: 메인 프로그램의 틱을 계산
//  must do call!
//  update g_fTick
//  update g_fGameTime
//--------------------------------------------------------------
float g_fTick = 0.f;
float g_fGameTime = 0.f;


const float Z_Tick()
{
     static bool bSTInit = false;
     static bool bSTFreq = false;

     static __int64 latestTime = 0;
     static __int64 freq = 0;


     __int64 curTime = 0;

     float fCurTick = 0.f;

 

     //최초 한번만 실행
     if( !bSTInit )
     { 
          bSTInit = true;
  
          //지원하지 않는 시스템도 있으므로 체크가 필요
          if( QueryPerformanceFrequency( (LARGE_INTEGER*)&(freq) ) )
          {
               if( QueryPerformanceCounter( (LARGE_INTEGER*)&(latestTime) ) )
               {
                    bSTFreq = true;
               }
          }
     }

 

     //QueryPerformanceFrequency 사용 가능할때
     if( bSTFreq )
     {
          if( QueryPerformanceCounter( (LARGE_INTEGER*)&(curTime) ) )
          {
               __int64 counter = curTime - latestTime;
               double dTick = (double)counter / (double)freq;

               //
               fCurTick = (float)dTick;
   
               //
               latestTime = curTime;
          }
          else
          {
              //에러코드
          }  
     }

     //QueryPerformanceFrequency 사용할수 없을때는
     else
     {
          curTime = (__int64)Z_MilliSeconds();

          __int64 counter = curTime - latestTime;
          double dTick = (double)counter / 1000;

          

   //
   fCurTick = (float)dTick;

        //
        latestTime = curTime;
    }

 

    //프레임이 많이 나올경우, 값이 0에 가까울 때가 있다
    if( fCurTick < 0.0001f )
   {
        fCurTick = 0.0001f;
   }

   //
   g_fTick = fCurTick;
   g_fGameTime += fCurTick;

     

   return fCurTick;
}

 

 

 

728x90

'프로그래밍' 카테고리의 다른 글

볼륨메트릭 라이팅 Volumetric Light - 01  (0) 2015.01.30
셰이더로 구현한 화면 노이즈  (0) 2015.01.23
d3d device lost, device reset  (0) 2014.10.07
셰이더 왜곡 distortion  (0) 2014.10.02
로그 log  (0) 2014.06.25
posted by BK dddDang
: