제가 모든 소스를 곁들어 가면서 설명하기에는 시간이 많지 않기 때문에 살펴보면 좋은 소스들의 리스트를 나열하고 몇 가지는 제가 인용해서 설명하겠습니다. 이 작업을 할 때 잃어버리지 않아야 할 것은 절대로 다른 소스까지 읽어가면서 다 분석하려고 하지 말고 메인 루프의 구성이 어떻게 되어 있나만 살펴 보는 것입니다. 물론 시간이 많아서 모든 소스를 다 분석하면 좋겠지만요 :)
1. Win32 Application의 메인 루프 구성
2. GLUT의 메인 루프 구성
3. SDL의 메인 루프 구성
4. Quake3의 메인 루프 구성
5. GameEngine Architecture(책)의 메인 루프 부분 챕터
우선 3번 SDL의 메인 루프 구성을 살펴 보도록 하죠.
참고 링크
http://sourcecodebrowser.com/a7xpg/0.11.dfsg1/classabagames_1_1util_1_1sdl_1_1_main_loop_1_1_main_loop.html
while (!done) { SDL_PollEvent(&event); input.handleEvent(&event); if (input.keys[SDLK_ESCAPE] == SDL_PRESSED || event.type == SDL_QUIT) done = 1; nowTick = SDL_GetTicks(); frame = (int) (nowTick-prvTickCount) / interval; if (frame <= 0) { frame = 1; SDL_Delay(prvTickCount+interval-nowTick); if (accframe) { prvTickCount = SDL_GetTicks(); } else { prvTickCount += interval; } } else if (frame > maxSkipFrame) { frame = maxSkipFrame; prvTickCount = nowTick; } else { prvTickCount += frame * interval; } for (i = 0; i < frame; i++) { gameManager.move(); } screen.clear(); gameManager.draw(); screen.flip(); }
Quake3의 메인 루프 부분
참고링크
http://fabiensanglard.net/quake3/index.php
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { Com_Init NET_Init while( 1 ) { // Common code IN_Frame() // Add Win32 joystick and mouse inputs as event_t to unified event queue. { IN_JoyMove IN_ActivateMouse IN_MouseMove } Com_Frame { // Common code Com_EventLoop // Pump win32 message, UDP socket and console commands to the queue (sysEvent_t eventQue[256]) Cbuf_Execute // Server code SV_Frame { SV_BotFrame // Jump in bot.lib VM_Call( gvm, GAME_RUN_FRAME, svs.time ) // Jump in Game Virtual Machine where game logic is performed SV_CheckTimeouts SV_SendClientMessages // Send snapshot or delta snapshot to connected clients } // Common code Com_EventLoop Cbuf_Execute // Client code CL_Frame { CL_SendCmd // Pump the event queue and send commands to server. SCR_UpdateScreen VM_Call( cgvm, CG_DRAW_ACTIVE_FRAME); // Send message to the Client Virtual Machine (do Predictions). or VM_Call( uivm, UI_DRAW_CONNECT_SCREEN); // If a menu is visible a message is sent to the UI Virtual Machine. S_Update // Update sound buffers } } } }
마지막으로 GLUT의 메인 루프 구성
참고링크
http://graphics.stanford.edu/courses/cs248-01/OpenGLHelpSession/code_example.html
int main(int argc, char** argv) { // GLUT Window Initialization: glutInit (&argc, argv); glutInitWindowSize (g_Width, g_Height); glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow ("CS248 GLUT example");
// Initialize OpenGL graphics state InitGraphics();
// Register callbacks: glutDisplayFunc (display); glutReshapeFunc (reshape); glutKeyboardFunc (Keyboard); glutMouseFunc (MouseButton); glutMotionFunc (MouseMotion); glutIdleFunc (AnimateScene);
// Create our popup menu BuildPopupMenu (); glutAttachMenu (GLUT_RIGHT_BUTTON);
// Get the initial time, for use by animation #ifdef _WIN32 last_idle_time = GetTickCount(); #else gettimeofday (&last_idle_time, NULL); #endif
// Turn the flow of control over to GLUT glutMainLoop (); return 0; }
그리고 렌더링, 키보드와 같은 것들은 다른 콜백 함수로 연결되어 있습니다.
가령 키보드를 처리하는 콜백 함수는
void Keyboard(unsigned char key, int x, int y) { switch (key) { case 27: // ESCAPE key exit (0); break;
case 'l': SelectFromMenu(MENU_LIGHTING); break;
case 'p': SelectFromMenu(MENU_POLYMODE); break;
case 't': SelectFromMenu(MENU_TEXTURING); break; } }
와 같습니다.리스트 5번에 말씀드린 책을 참고하시면 Uncharted의 경우도 비슷한 메인 루프를 구성하고 있습니다. 참고로 피파도 비슷합니다만 더 발전된 형태로 되어 있습니다. :)
여러 프로젝트의 메인 루프 구성을 살펴 보는것은 대단히 중요한데 그 이유는 이 메인 루프가 어떻게 구성되어 있는지 모르면 프로젝트의 전체를 볼 수 없기 때문입니다. 모든 프로젝트를 분석하기 이전에는 반드시 메인 루프 구성을 먼저 살펴 보는것이 분석을 순조롭게 하기 위해서 좋습니다.
생각해 볼 점.
1. SDL과 GLUT의 입력 처리를 하는 방식에 있어서 어떤 차이점이 존재하는가?
2. Win32 Application을 작성할 때 입력 처리를 하는 방식과 Quake3는 어떻게 다른가?
No comments:
Post a Comment