이를 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 에 의해 자원회수 코드를 구현한다.
다음 글에서는 이를 기반으로 렌더링 데모를 시연해 보도록 하자.
댓글 없음:
댓글 쓰기