요즘 게임은 더 좋은 사양의 컴퓨터를 사용할때 더 좋은 장면을 보여주기위해 프레임율에 의존적이지 않게 루프를 작성하게 됩니다. 간단하게 말하자면 이전 프레임과 현재 프레임의 시간차(dt)를 이용하는거죠.
다만 이렇게 하면 약간 신경쓰이는것들이 생기게되고, 확실히 프레임 스키핑을 이용한 고정 프레임율을 사용하는것이 편할때가 있습니다.
void Main( HWND hWnd, float dt )
{
//******************************************************************
// 프레임율 비의존적인 코드
// dt에 의해 진행되기때문에 가능한한 빨리도는 코드들.
// 시스템이 좋을수록 더 자주 호출된다.
//******************************************************************
// Animation( dt );
if( fs.Update(dt) )
{
//******************************************************************
// 프레임율 의존적인 코드
// 이부분은 frame skip에 의해 고정 프레임율을 갖고 동작한다.
//******************************************************************
static long counter=0;
counter++;
if( counter%100 == 0 )
printf( "static frame rate code : %d\n", counter );
}
if( ! fs.IsFrameSkip() )
{
//******************************************************************
// 경우에 따라 호출되지 않아도 되는 코드
// 이부분은 frame skip에 의해 skip될수 있다.
// 렌더링따위의 시간을 많이 잡아먹는 코드를 넣는다.
// 역시 시스템이 좋을수록 더 자주 호출된다.
// 숫자는 제시스템에서 나온 fps입니다.
//******************************************************************
Sleep( 0.8f*1000 ); // 10fps
//Sleep( 0.2f*1000 ); // 10fps
//Sleep( 0.05f*1000 ); // 20fps
//Sleep( 0.02f*1000 ); // 50fps
//Sleep( 0.002f*1000 ); // 100fps
}
// printf frame / sec
PrintFPS( dt );
}
|
class FrameSkip
{
public:
void Clear()
{
SetFramePerSec( 60.0f );
m_Timer = 0.0f;
}
void SetFramePerSec( float fps )
{
m_SecPerFrame = 1.0f/fps;
}
// 원하는 프레임보다 너무 빠르면,
// false를 반환해서 코드를 동작시키지 않도록 한다.
// dt는 '초'단위 (밀리초 아님!!!)
bool Update( float dt )
{
m_Timer += dt;
if( m_Timer<0 ) return false;
// 한프레임에 해당하는 시간을 뺀다.
m_Timer -= m_SecPerFrame;
return true;
}
// Update후에 호출해서 frame skip을 수행해야 하는지 검사한다.
// frame skip이 일어나야 한다면 true를 반환한다.
bool IsFrameSkip()
{
return m_Timer >= 0;
}
// 멤버변수와 생성/소멸자.
FrameSkip(){ Clear(); }
virtual ~FrameSkip(){}
protected:
float m_Timer;
float m_SecPerFrame;
};
|
FrameSkip fs[2];
...
fs[0].SetFramePerSec( 10 );
fs[1].SetFramePerSec( 30 );
...
게임루프( float dt )
{
카메라이동( dt ); // 가능한한 빨리동작하는 부분
if( fs[0].Update(dt) ) 사용자 입력처리; // 10fps로 동작 하는 부분
if( fs[1].Update(dt) ) AI; // 30fps로 동작 하는 부분
if( ! ( fs[0].IsFrameSkip() || fs[1].IsFrameSkip() ) )
{
렌더링따위의 코드.....
}
}
|