이를 OpenGL로 변경하여 손쉽게 개발환경을 구축해 보자. 참고로 버전업된 SDL2 가 최신버전이므로 이를 기반으로 OpenGL 테스트용 환경을 만들어 보자.
기본 구조는 https://github.com/MetaCipher/sdl-2.0-basics 을 참고하였으며, 입맞에 맞게 대폭 수정하였다.
SDL 이 처음이신분들은 http://lazyfoo.net/tutorials/SDL/index.php 에서 다양한 예제를 제공하고 있으니 방문 바란다.
사용된 SDL2 버전은 2.0.3 이며 OpenGL2.1 및 1024*768 해상도에서 동작한다.
1. App.h
#ifndef APP_H #define APP_H /******************************************************************************* SDL2 Demo Application ---------------- | App | ---------------- | Execute | | OnInit | | OnEvent | | OnLoop | | OnRender | | OnCleanUp | ---------------- /|\ | | | your inherited class email : sepwind@gmail.com (blog : http://sepwind.blogspot.com) base code from : https://github.com/MetaCipher/sdl-2.0-basics (Tim Jones @ SDLTutorials.com) and revisied by sepwind. *******************************************************************************/ #include "SDL.h" #include "SDL_opengl.h" #include <gl\gl.h> #include <gl\glu.h> #include <stdio.h> #include <tchar.h> #pragma comment(lib, "sdl2.lib") #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glu32.lib") class App { protected: int _windowWidth; int _windowHeight; bool _running; SDL_Window* _pWindow; SDL_GLContext _glcontext; private: bool Init(); bool InitGL(); void Render(); void CleanUp(); public: virtual bool OnInit(int argc, TCHAR* argv[])=0; virtual void OnEvent(SDL_Event* Event)=0; virtual void OnLoop()=0; virtual void OnRender()=0; virtual void OnCleanUp()=0; public: App(); virtual ~App(); int Execute(int argc, TCHAR* argv[]); int GetWindowWidth(); int GetWindowHeight(); }; #endif
2. App.cpp
#include "app.h" #include "log.h" App::App() { _running = true; _pWindow = NULL; _glcontext = NULL; _windowWidth = 1024; _windowHeight = 768; } App::~App() { } int App::GetWindowWidth() { return _windowWidth; } int App::GetWindowHeight() { return _windowHeight; } bool App::Init() { if(SDL_Init(SDL_INIT_VIDEO) < 0) { Log("Unable to Init SDL: %s", SDL_GetError()); return false; } if(!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) { Log("Unable to Init hinting: %s", SDL_GetError()); } if((_pWindow = SDL_CreateWindow( "SDL2 DEMO - sepwind@gmail.com (http://sepwind.blogspot.kr)", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _windowWidth, _windowHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL)) == NULL) { Log("Unable to create SDL Window: %s", SDL_GetError()); return false; } _glcontext = SDL_GL_CreateContext(_pWindow); SDL_GL_SetSwapInterval(1); this->InitGL(); Log("success to initialized ... "); return true; } bool App::InitGL() { glShadeModel( GL_SMOOTH ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClearDepth( 1.0f ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_LEQUAL ); glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); GLfloat ratio = ( GLfloat )_windowWidth / ( GLfloat )_windowHeight; glViewport( 0, 0, ( GLsizei )_windowWidth, ( GLsizei )_windowHeight ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 45.0f, ratio, 0.1f, 1000.0f ); // z-near/far glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); return true; } void App::Render() { SDL_GL_MakeCurrent(_pWindow, _glcontext); this->OnRender(); SDL_GL_SwapWindow(_pWindow); } void App::CleanUp() { Log("cleaning up ... "); this->OnCleanUp(); if (_glcontext) { SDL_GL_DeleteContext(_glcontext); _glcontext = NULL; } if(_pWindow) { SDL_DestroyWindow(_pWindow); _pWindow = NULL; } SDL_Quit(); } int App::Execute(int argc, TCHAR* argv[]) { if(!this->Init()) { Log("fail to initialize SDL2"); return -1; } if (false == this->OnInit(argc, argv)) { Log("fail to initialize OnInit"); return -1; } SDL_Event e; while(_running) { while(SDL_PollEvent(&e) != 0) { this->OnEvent(&e); if(e.type == SDL_QUIT) { _running = false; } } this->OnLoop(); this->Render(); SDL_Delay(0); } Log("stopping ... "); this->CleanUp(); return 0; }
3. Log.h
/* Basic macro for logging (can be extended for other target builds; i.e, using NSLog for OS X / iOS). Could also be modified to log to a file instead of console. 3/11/2014 SDLTutorials.com Tim Jones */ #ifndef LOG_H #define LOG_H #include <stdio.h> #if defined(DEBUG) || defined(_DEBUG) #define Log(...) printf(__VA_ARGS__); printf( "\n" ); #else #define Log(...) ; #endif #endif
- 제일 처음 할것은 App 클래스를 상속받아 필요한 함수를 구현해 주어야 한다.
- 이후 명령행 인자들과 함께 Execute() 함수를 호출하여 가동을 시작한다.
- 가동을 위해 최초 OnInit() 이벤트가 한번 발생하고,
- 사용자 입력(키보드, 마우스, 조이스틱 등)이 있을때 마다 OnEvent 가 발생한다.
- 또한 게임로직등 다양한 일처리는 OnLoop 에서 구현하고
- 매 프레임 렌더링 코드는 OnRender 에서 구현한다.
- 프로그램 종료시에는 OnCleanUp 에 의해 자원회수 코드를 구현한다.
다음 글에서는 이를 기반으로 렌더링 데모를 시연해 보도록 하자.
댓글 없음:
댓글 쓰기