2018년 1월 12일 금요일

OpenGL - Initialize OpenGL

OpenGL - Initialize OpenGL

MSVC ignores floating point exceptions by default, BCB doesn't..

#ifndef _WIN64
_control87(MCW_EM, MCW_EM);
#endif

_clear87();
_control87(MCW_EM, MCW_EM);

before each frame is rendered, works fine for me..


Creating an OpenGL Context on Window

프로그램적으로 OpenGL Context가 생성되기 전에는 OpenGL이 존재하지 않는다. 그러므로 OpenGL의 표준 Spec에 의한 재약은 없다.

다시 말해서 각각의 시스템(OS system)에서 OpenGL Context 를 생성하는 방식에 대해서는 특정한 규정이 없다는 것이다.

그러므로 각각의 윈도우 시스템(MS Windows 또는 OSX , Linux 등등) 에서 제공하는 API를 이용하여 OpenGL Context를 만들어 주면 된다.

여기서는 Microsoft Windows System을 가정하여 설명하게 될 것이다. 즉 WGL 부분이 된다.

MS-Windows 에서 윈도우를 생성하면 HWND 가 만들어 진다. HWND는 반드시 생성 type으로 CS_OWNDC 옵션을 넣어서 만들어야 한다.

다음의 과정을 알아볼 것이다.

Pixel Format 설정 -> OpenGL Context 생성 -> Context 의 사용 -> OpenGL Context의 제거

Pixel Format

MS-Windows의 각 창에는 그와 연결된 Device Context(DC) 가 있다.  이러한 DC에는 Pixel Format이라는 형식을 지정할 수 있다.

이러한 Pixel Format 은 해당 윈도우에 만들어지는 OpenGL Context의 기본적인 Framebuffer의 속성으로 적용될 것이다.

Pixel Format 을 설정하는 것은 그렇게 직관적이지 않다.
픽셀 포맷을 만드는 방법은 원하는 기능을 설명하는 구조체의 각 필드들을 원하는 값으로 채우는 것이다.

다음 설정은 일반적으로 OpenGL 윈도우를 만들기 위한 Pixel Format을 보여주고 있다.

PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,    // Flags
PFD_TYPE_RGBA,        // The kind of framebuffer. RGBA or palette.
32,                   // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24,                   // Number of bits for the depthbuffer
8,                    // Number of bits for the stencilbuffer
0,                    // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};

보다시피 많은 필드들이 값 0 으로 세팅되어 있다는 것을 알 수 있으나 개의치 말기 바란다. 각 필드들에 대한 보다 더 자세한 내용을 알고 싶으면 Window SDK를 참조하기 바란다.


이렇게 준비한 Descriptor 를 우리는 ChoosePixelFormat 함수를 이용하여 하나의 숫자(정수)로 만들 수 있다.

int PixelFormat = ChoosePixelFormat(hdc, &pfd);

여기서 hdc는 적용하고자 하는 윈도우의 Device Context (DC) 값으로 Hand of Device Context 의 약자를 사용한 것이다.

Windows SDK에서 설명하는 HDC Data Type은 다음과 같다.

HDC
A handle to a device context (DC).

HDC 및 PIXELFORMATDESCRIPTOR 에 의한 PixelFormat값을 만들었다면 SetPixelFormat 함수를 이용하여 HDC 의 PixelFormat 을 설정할 수 있다.

아래의 내용은 이러한 과정을 보여주고 있다.

HWND hwnd = ***; // target window handle , 윈도우를 생성하면 얻을 수 있다.
HDC hdc = GetDC(hwnd)
BOOL ret = SetPixelFormat(hdc, PixelFormat, &pfd);

ret 값이 true이면 성공 , false 성공하지 못한것이다.

Create the Context
Pixel Format이 적용된 DC 에서 OpenGL Context를 만드는 것은 어렵지 않다.
바로 wglCreateContext 함수를 이용하면 된다.

HGLRC WINAPI wglCreateContext(
  HDC hdc
);
HGLRC hrc = wglCreateContext(hdc);

여기서 HGLRC 는 OpenGL Rendering Context Handle 이다.

만약 이 함수를 호출하기 이전에 이미 Context 가 생성되어 있다면, 기존 Context는 무효화 되며 새로운 Context를 만들게 될 것이며, 이렇게 생성된 이후의 OpenGL 명령들은 기존의 Context에 작동하지 않고 새롭게 만들어진 Context에서만 작동될 것이다.
여기서 무효화 된다는 것은 제거 된다는 것이 아니고, 더이상 해당 Context가 OpenGL Context로 작동하지 않는다는 뜻이다.

Delete the Context
다음 함수에 의하여 만들어진 OpenGL Context는 제거할 수 있다.
제거하기 이전에 우리는 해당 Context가 최근에 만들어진 최신의 Context 인지를 살펴봐야 한다. 사실 살펴보는 방법은 없다. 그러므로 우리는 제거하고자 하는 Context를 무효화 해야한다. 이는 wglMakeCurrent  함수에 HDC 인자로 NULL을 입력하면 된다.

wglMakeCurrent(NULL)


To be continue...

댓글 없음:

댓글 쓰기

Vertex , 정점 정보의 확장

Vertex , 정점 정보의 확장 그동안의 설명에 있어서 우리는 VERTEX 정보에 대하여 3 차원의 위치 정보만 사용하였다. struct VERTEX {float x,y,z;}; 이제 이를 확장하여 색상을...