Hello World - 기초 만들기
윈도우를 만들고 운형하는 것은 여기서 설명하지는 않겠다.
이 글은 하나의 윈도우에 OpenGL을 적용하여 OpenGL Context 를 만들고 여기에 삼각형을 렌더링 하는 방법에 대하여 설명하고자 한다.
모든 언어의 처음은 대부분 “Hello World!!!” 일 것이다.
일반적으로 3D 그래픽 프로그램에서는 화면에 삼각형을 하나 그리는 것으로 Hello World 를 제시하게 된다.
이 글에서 우리는 OpenGL 과 Direct3D(다른페이지에서) 모두 설명할 것이다.
하나의 윈도우가 있고 이에 대한 HWND 가 있다고 하고 출발하도록 하자.
OpenGL
우리는 일차적으로 다음과 같은 내용에 대하여 프로그램 코딩을 할 것이다.
bool Init3D(HWND hwnd);
void SetBkColor(float r,float g,float b,float a);
void ClearBk();
void SwapBuffer();
void RenderScene();
Init3D
전달된 윈도우 핸들 hwnd 를 이용하여 HDC를 구하고 HDC에서 HGRC를 준비하여 OpenGL Context 를 만든다.
SetBkColor()
OpenGL Context의 배경색을 정한다.
RenderScene()
화면에 나타날 그림을 backbuffer에 준비한다.
ClearBk()
OpenGL Context를 정해진 배경색으로 지운다.
SwapBuffer()
화면을 갱신한다.
Color in OpenGL
Direct3D 와 OpenGL 에서 공통으로 사용하기 위하여 직접 class 를 만들어 사용하기로 한다.
OpenGL의 Color는 정하기 나름이지만 기본적으로 RGBA 를 사용한다고 보면 된다.
이는 OpenGL의 경우 PixelFormat을 준비할 때 설정한 값에 기인한다.
이에 대한 내용은 다음 링크 페이지에서 PixelFormat 부분을 살펴보기 바란다.
PIXELFORMATDESCRIPTOR 의 4번째 필드인 iPixelType 을 살펴보면 PFD_TYPE_RGBA 로 설정된 것을 알 수 있다.
Windows SDK의 내용을 보면
iPixelType
Specifies the type of pixel data. The following types are defined.
Value
|
Meaning
|
PFD_TYPE_RGBA
|
RGBA pixels. Each pixel has four components in this order: red, green, blue, and alpha.
|
PFD_TYPE_COLORINDEX
|
Color-index pixels. Each pixel uses a color-index value.
|
Pixel 데이터의 타입을 설정하는 값이며 위의 두가지 중 하나가 될 수 있다.
PFD_TYPE_RGBA 는 RGBA pixel 형식을 취하며 각 픽셀에 대하여 4개의 컴포넌트를 갖는다. 그 순서는 red, green, blue, alpha 이다.
만약 PFD_TYPE_COLORINDEX 로 설정 한다면 OpenGL 에서 color palette 를 만들어 적용해야 하는데 대부분 이 옵션을 사용하지 않는다. 만약 이 옵션을 사용하고 싶으면 다음 사이트를 참조하기 바라며 여기서는 설명하지 않겠다.
c_color4f.h
class c_color4f
{ public: // Color components: red, green, blue, alpha union { struct { float r; ///< Red component float g; ///< Green component float b; ///< Blue component float a; ///< Alpha component }; float f[4]; }; }; |
// 필요한 변수들... 초기화는 각자 적절하게 하기 바람...
int m_pixelformat=0; HGLRC m_hrc=0; HWND m_hwnd=0; HDC m_hdc=0; bool m_initialized=false; c_color4f m_bkcolor; // 초기화 함수 bool Init3D(HWND hwnd) { if(m_initialized) return false; m_hwnd = hwnd; m_hdc = GetDC(m_hwnd); // Set pixel format PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 24, 0,0,0,0,0,0, 0,0, 0,0,0,0,0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0,0,0 }; m_pixelformat = ChoosePixelFormat(m_hdc, &pfd); SetPixelFormat(m_hdc, m_pixelformat, &pfd); // Create GL Context m_hrc = wglCreateContext(m_hdc); wglMakeCurrent(m_hdc, m_hrc); m_initialized = true; return true; } |
배경 색상의 설정
void SetBkColor(float r,float g,float b,float a)
{ m_bkcolor = c_color4f(r,g,b,a); } |
다음과 같이 호출하여 background color를 설정한다.
아래의 색상 값은 위의 그림과 같은 진한 청색이 될 것이다.
SetBkColor(0.0f, 0.2f, 0.4f, 1.0f);
배경을 지우는 함수
void ClearBk()
{ // Clear the screen to bkcolor glClearColor(m_bkcolor.r,m_bkcolor.g,m_bkcolor.b,m_bkcolor.a); glClear(GL_COLOR_BUFFER_BIT); } |
Swap Buffer 함수
void SwapBuffer()
{ ::SwapBuffers(m_hdc); } |
화면 준비와 갱신
void RenderScene()
{ if(m_initialized==false) return; // back buffer에 적용하게 된다. ClearBk(); // 배경을 지운다 // 이부분에 실제 그림을 그리는 부분을 작성한다. // back buffer 와 front buffer를 교환한다. 즉 그려진 그림을 실제 화면에 뿌리는 기능. SwapBuffer(); } |
SwapBuffer의 경우 함수를 따로 만들지 않고 직접 호출해도 되지만, 작성된 실제의 프로젝트 코드는 이런 함수 들이 virtual class로 작성 하여 virtual class에 의한 OpenGL 과 Direct3D를 같은 구조로 작동 시키기 위하여 만들게 된 것이다.
위의 코드들에서 보고 다음과 같은 규칙을 알아두어야 한다.
Windows API의 함수인 경우 대문자로 시작되었다.
예를 들면 GetDC,SetPixelFormat, SwapBuffers 와 같은…
또한 OpenGL API 함수들의 이름은 gl*** 형식으로 되어 있다는 것…
예를 들면 glClear, glClearColor 와 같은…
또한 wgl*** 로 된 함수도 있다.
이들 차이에서 gl*** 과 wgl*** 차이는
gl*** 은 OpenGL 표준 함수들이다.
wgl*** 은 OpenGL 함수 이지만 Microsoft Windows 에 적용되는 함수라는 것이다.
이에 대해서는 위키
를 참조하기 바란다.
이들 함수의 이름도 그렇지만 전달되는 인수를 살펴보기 바란다.
순수 Windows API는 그 인수가 일단 Windows 관련 인자들로 구성된다.
예를 들면 ChoosePixelFormat 함수
gl*** 은 역시 OpenGL 에서 사용할 수 있는 인자들로 구성된다.
예를 들면 glClear 함수
wgl*** 함수를 보면 두가지가 혼합되는 것을 볼 수 있다.
예를 들면 wglCreateContext 함수. 이 함수의 인수는 hdc 로 윈도우 관련이지만 그 return 값은 hrc 로 Rendering Context 값으로 OpenGL 과 관련된 인자이기 때문이다.
이렇게 함수의 네이밍 규칙을 알면 프로그램 코드를 이해하는데 많은 도움이 될 것이다.
위에 설명된 코드로 실제 프로그램에 적용을 하게 되면 적용된 윈도우가 다음과 같은 화면이 될 것이다.
댓글 없음:
댓글 쓰기