본문 바로가기

Library/Computer Graphics

Create OpenGL 3.x RenderingContext with WGL

WGL을 사용하여 OpenGL 3.x 렌더링 컨텍스트(RC)를 얻어내는 과정은, 이전의 RC를 얻어내는 과정과 크게 다르지 않다. 간단히 설명하면, 원하는 RC를 얻어내기 전에, 레거시(legacy) RC를 생성하고, 이를 바탕으로 원하는 속성을 기술한 구조체와 함께 wglCreateContextAttribsARB를 호출하는 것이 전부이다. 사실, OpenGL 3.0 이상의 구현에서 wglCreateContext는 wglCreateContextAttribsARB에서 Attribs에 해당하는 인자 값을 널로 호출하는 것이다. 대략적인 코드는 다음과 같다.


// get default RenderingContext
HDC hDC = GetDC(hWnd);
HGLRC hRC = wglCreateContext(hdc);

....
// PIXELFORMATDESCRIPTOR 구조체를 적절하게 초기화..
ChoosePixelFormat(....);
SetPixelFormat(....);
....

wglMakeCurrent(hDC, hRC);

int major, minor;
GetIntegerv(GL_MAJOR_VERSION, major);
GetIntegerv(GL_MINOR_VERSION, minor);

// attribs 구조체는 반드시 0으로 끝나야 한다
int attribs[] = {
   WGL_CONTEXT_MAJOR_VERSION_ARB, major,   
   WGL_CONTEXT_MINOR_VERSION_ARB, minor,
   
   WGL_CONTEXT_FLAGS_ARB,
   WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB |
   WGL_CONTEXT_DEBUG_BIT_ARB,
   
   WGL_CONTEXT_PROFILE_MASK_ARB,
   WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
   
   0
};

....

// 위글 확장 함수를 통해 CreateContextAttribsARB에 대한 함수 포인터를 얻어낸다
PFNGLCREATECONTEXTATTRIBSARB f =
    wglGetProcAddress("wglCreateContextAttribsARB");

HGLRC tmp_hRC = f(hDC, 0, attribs);
wglMakeCurrent(0, 0);
wglDeleteContext(hRC); // tmp_hRC가 제대로 얻어졌다면, 레거시 RC를 삭제한다
wglMakeCurrent(hDC, tmp_hRC); // 생성된 RC를 선택한다

....


여기서, attribs 구조체는 descriptor / value 짝으로 구성되어 있다. 즉, WGL_CONTEXT_MAJOR_VERSION은 다음 major라는 값과 짝을 이루며, 다른 모든 항목들도 이와 마찬가지이다. 이 항목에 대해서 좀 더 자세히 알고 싶다면, http://www.opengl.org/registry/specs/ARB/wgl_create_context.txt를 참조하라.

위의 코드는 에러 처리가 모두 생략되어 있는데, 실제로 코드를 작성한다면 원하는 버전의 OpenGL WGL 확장 함수가 존재하는지, 렌더링 컨텍스트(RC)가 정확하게 생성되었는지 따위를 모두 점검해야 한다.


Reference
http://www.opengl.org/registry/specs/ARB/wgl_create_context.txt