[C++/Modern OpenGL] 1. OpenGL 개발 환경 세팅하기

2021. 1. 25. 05:35C++/Modern OpenGL

2. OpenGL 개발 환경 세팅하기 

 "시작이 반이다. (Well begun is half done.)" - Aristotle

 

 라이브러리를 사용한 경험이 잦은 사람들은 어떤 라이브러리를 가져올 때, 세팅하는 것이 어렵지는 않을 것입니다. 하지만 그러지 못한 사람에게 제일 어려운 것 중 하나가, 라이브러리를 세팅하는 것입니다. 그래서 시작이 반이라는 말이 있듯이, 이번 주제에서는 OpenGL을 세팅하는 방법에 대해 소개하려 합니다. 경로를 설정하는 것조차 놓치지 않고, 자세히 설명할 테니 세팅이 어려우신 분들은 참고해도 괜찮을 것입니다. 

 

2.1 GLFW 세팅

 GLFW는 OpenGL을 위한 오픈 소스 멀티 플랫폼 라이브러리입니다. GLFW는 OpenGL 외에도 OpenGL ES 혹은 Vulkan 개발을 도와줍니다. GLFW는 윈도우, 컨텍스트, 표면을 생성하거나 입력 혹은 이벤트를 수신받기 위해 간단한 API를 제공합니다. 따라서 우리는 OpenGL을 사용하기 위해 GLFW를 세팅할 것입니다. 

 

[실습 ①] GLFW 설치하기

① GLFW를 설치하기 위해 아래 링크에 접속합니다.
② 자신의 OS와 컴파일 할 때의 설정에 해당하는 버전의 GLFW를 설치합니다. (64bit 운영체제에서 개발을 진행한다고 해서, 무조건 64bit binaries 다운로드해야 하는 것이 아닙니다. 저는 Window10 64bit 운영체제를 사용하지만, 실제로 컴파일을 진행할 때 Visual Studio에서 x86을 설정하기 때문에 32-bit Windows binaries를 다운로드 했습니다.) 

Visual Studio에서 위와 같이 Debug x86에서 개발하시는 분들은 32-bit Windows binaries를 다운로드 해야 합니다.

 

 이제 OpenGL 코드를 작성할 솔루션과 프로젝트를 만들어 봅시다. 저의 경우 Visual Studio 2019 버전을 사용하고 있으며, 당연한 얘기지만 2019 버전에 초점을 맞춰 설명을 진행할 것입니다. 이후에 Visual Studio 202x 등.. 의 업그레이드 버전이 등장하겠지만, 어차피 솔루션과 프로젝트를 생성하는 것은 본질적으로 차이점이 없기 때문에 크게 문제가 발생하지 않을 것입니다.  

 

[실습 ②] Solution과 Project 생성하기

① Visual Studio를 실행합니다.
② [새 프로젝트 만들기] 버튼을 누른 후, [C++] / [Windows] / [모든 프로젝트 형식(T)]를 설정하여 [빈 프로젝트]두번 클릭하거나 [다음] 버튼을 누릅니다.
③ 프로젝트 이름을 OpenGL Setup으로 설정한 후, 솔루션 이름을 OpenGL Tutorial로 설정한 후 만들기(C) 버튼을 누릅니다. 물론 솔루션 및 프로젝트를 같은 디렉터리에 배치 옆의 체크박스는 체크 되지 않아야 합니다.(이름은 OpenGL Setup/Tutorial로 하지 않고, 자신이 원하는 대로 설정해도 괜찮습니다.)

 자, 설명에 맞춰 Solution과 Project를 완성했나요? 완성하면 위 이미지의 4번째(오른쪽 하단)와 같은 화면일 것입니다. 우리는 이 단계에서, Visual Studio 솔루션 탐색기 세팅을 약간 수정할 것입니다. 왜냐하면 세팅을 수정함으로써 더 직관적인 개발 환경을 만들 수 있기 때문이죠. 

 

[실습 ③] 개발 환경 세팅하기

① 솔루션 상단에 [모든 파일 표시] 버튼을 누릅니다. 이 버튼을 누르면, 본래 솔루션 탐색기에 보이던 참조, 외부 종속성, 리소스 파일, 소스 파일, 그리고 헤더 파일이 사라집니다. 그리고 현재 프로젝트의 파일에 있는 파일들을 그대로 보여줍니다. 따라서 우리는 더 쉽게 파일 관리를 할 수 있습니다.
② 솔루션 탐색기에서 OpenGL Setup 프로젝트를 마우스 오른쪽 버튼으로 클릭한 뒤, [추가(D)] - [새 폴더(D)]를 통해 파일을 생성한 뒤, 이름을 Sources로 설정합니다. 앞으로 이 파일에는 소스 코드와 관련된 모든 데이터들을 담을 것입니다.
③ Sources 파일을 마우스 오른쪽 버튼으로 클릭한 뒤, [추가 (D)] - [새 항목 (W)] - [C++ 파일(.cpp)]을 누른 후, 이름을 main.cpp로 설정한 후 [추가 (A)] 버튼을 눌러, 새로운 소스파일을 생성합니다. 
④ 프로젝트가 제대로 작동하는지 확인하기 위해, 프로그래밍 언어를 처음 접하면 Hello, World를 치듯, Hello, OpenGL을 출력해볼까요? 저는 아래와 같은 방법으로 Hello OpenGL을 출력했습니다.

#include <iostream>

int main()
{
    std::cout << "Hello, OpenGL" << std::endl;
    
    return 0;
}

제 컴퓨터에서 실제로 진행했을 때의 Visual Studio 모습입니다.

 자, 이제 본격적으로 GLFW를 내 프로젝트에서 사용할 수 있도록, GLFW를 프로젝트에 어떻게 불러오는지 알아보자고요. 우선 GLFW에서 기본적으로 제공되는 예시 코드를 갖고 와, 프로젝트에 미리 입력해보고, 한 단계 한 단계 차근차근 진행해볼까요? :)

 

[실습 ④] GLFW 예시 코드 가져오기

GLFW Documentation의 Example Code를 모두 복사합니다.
② 복사한 코드를 프로젝트에 그대로 붙여 넣습니다. 

지금 당장은 Visual Studio에 붙여넣어도, 많은 에러가 나타날 것입니다.

 왜 에러가 나타날까요? 이유는 간단합니다. 아직 GLFW 라이브러리를 프로젝트에 추가하지 않았기 때문입니다. 따라서 우리는 발생하는 에러를 하나하나 지워가며, GLFW가 프로젝트에서 정상적으로 작동할 수 있게끔 환경을 개선할 것입니다. 먼저 GLFW 라이브러리부터 추가해봐요 :)

 

[실습 ⑤] GLFW 프로젝트에 추가하기 ①

Visual Studio 솔루션 탐색기에서 OpenGL Setup 프로젝트를 마우스 [오른쪽 버튼]으로 클릭한 후, [파일 탐색기에서 폴더 열기 (X)]를 선택해 현재 프로젝트의 파일 브라우저를 열어봅시다.
② 파일 브라우저의 빈 공간을 마우스 [오른쪽 버튼]으로 클릭한 뒤, [새로 만들기(W)] - [폴더 (F)]를 눌러 새로운 폴더를 생성하고 이름을 Dependencies로 변경합니다.
③ [Dependencies] 폴더 내부에 GLFW라는 이름을 가진 새로운 폴더를 생성합니다. 

폴더는 꼭 정리해주는 편이 프로젝트 관리하기에 용이합니다.

 이제 우리가 [실습 ①]에서 다운로드 받은 GLFW 라이브러리를 압축 해제하여 직접 열어봅시다. 아마 아래와 같은 폴더구조가 여러분들의 폴더에도 그대로 보일 것입니다.

glfw 폴더구조

 이 많은 폴더들 중 우리는 [include] 폴더와 [lib-vc2019] 폴더가 필요합니다. 두 폴더의 역할에 대해 간단히 설명하자면, [include] 폴더에는 GLFW와 관련된 함수 혹은 변수들이 선언되어 있는 헤더 파일들이 모두 담겨 있다고 생각하면 됩니다. 그리고 해당 헤더 파일의 정의부에 해당하는 소스코드들은 [lib-vc2019] 폴더에 라이브러리 형태로 저장되어 있습니다. 라이브러리는 동적 라이브러리(.dll)와 정적 라이브러리(.lib) 두 종류로 나뉘는데, 우리는 정적 라이브러리를 프로젝트에 추가할 것입니다. 

우리는 glfw3.lib를 추가해야겠죠? :)

[실습 ⑥] GLFW 프로젝트에 추가하기 ②

우리가 만든 [Dependencies/GLFW] 폴더에 다운로드 받은 glfw 폴더 안에 있는 [include] 폴더와 [lib-vc2019] 폴더를 욺깁니다.

② 동적 라이브러리는 사용하지 않을 것이니, [lib-vc2019] 폴더 내부의 [glfw3.dll] 파일과 [glfw3dll.lib] 파일을 삭제합니다.

③ Visual Stduio로 돌아가 솔루션 탐색기에서 OpenGL Setup 프로젝트를 마우스 [오른쪽 버튼]으로 누른 후, [속성 (R)] 버튼을 누릅니다.

④ [OpenGL Setup 속성 페이지]에서 [구성(C)]를 모든 구성으로, [플랫폼(P)]를 Win32로 변경합니다. 

⑤ [OpenGL Setup 속성 페이지]에서 [C/C++] - [일반]을 선택한 후, [추가 포함 디렉토리]를 누른 후 <편집...> 버튼을 누릅니다.
⑥ 그리고 [추가 포함 디렉토리]$(ProjectDir)Dependencies\GLFW\include\를 입력합니다. 추가 포함 디렉토리에는 우리가 현재 프로젝트에 추가할 헤더들을 입력하는데, 우리는 지금 GLFW 라이브러리의 헤더를 입력한 것입니다. (반드시 [Dependencies] 폴더가 [OpenGL Setup] 프로젝트 폴더 내부에 존재해야 합니다.)

⑦ 이제 프로젝트에 헤더 파일의 경로를 알려주었으니, 헤더 파일의 선언부가 정의되어 있는 라이브러리 파일의 경로를 프로젝트에 입력해줘야 합니다. [OpenGL Setup 속성 페이지]에서 [링커] - [일반]을 선택한 후, [추가 라이브러리 디렉터리]를 누른 후, <편집...> 버튼을 눌러 $(ProjectDir)Dependencies\GLFW\lib-vc2019을 입력합니다.

⑧ 다시 [링커]로 돌아가, [링커] - [입력]을 선택한 후 [추가 종속성]을 선택합니다. 현재 추가 종속성에 kernel32.lib, user32.lib... 등의 라이브러리가 이미 추가된 분들이 계실 텐데, 이는 Visual Studio에서 기본적으로 설정되어 있는 라이브러리입니다. 이를 키보드의 [Delete] 버튼으로 모두 지운 후, glfw3.lib를 입력합니다. 

⑨ 앞의 과정을 모두 진행했다면, 이제 프로젝트에서 GLFW 라이브러리의 존재를 알아챘을 것입니다(의인법 ㅇㅁㅇ..). [OpenGL 속성 페이지]에서 [적용(A)] 버튼을 누른 후, [확인] 버튼을 누릅시다.

모두 저와 같은 화면이 나오시나요? :)

 이제 Visual Studio에서 [Ctrl + F5] 버튼을 눌러 컴파일을 진행해봅시다. 다들 깜짝 놀라셨나요? 아마 모든 분들이 컴파일 오류를 겪었을 것입니다. 처음 라이브러리를 추가하시는 분들은 위에 있는 실습까지는 잘 진행할 수 있어도, 지금 발생하는 컴파일 오류를 혼자의 힘으로 쉽게 처리하기가 힘듭니다. 그래서 어떻게 이 오류들을 처리할지 알아봅시다. 

머리가 어지러워지는 감당할 수 없는 숫자의 컴파일 오류.. ㅠㅠ

 저는 현재 111개의 컴파일 오류가 발생하였는데, 어떤 분들은 이보다 숫자가 많거나 적을 수도 있고, 아니면 같을 수도 있습니다. 여하튼 오류가 많고 적고는 큰 문제가 아닙니다. 중요한 것은 이 많은 오류들을 어떻게 처리하느냐입니다. 제 컴퓨터에 나오는 오류들을 기준으로 컴파일 오류들을 하나하나 고쳐봅시다.

 

[실습 ⑦] 컴파일 오류를 해결하자 ①

① Visual Studio의 출력 창을 쉽게 볼 수 있도록 확대한 후, 마우스의 [스크롤] 버튼을 올려 맨 위로 올라가 봅시다. 

1>------ 빌드 시작: 프로젝트: OpenGL Setup, 구성: Debug Win32 ------ 이 보일때까지 올립시다

② 출력 창의 첫 줄은 경고(warning)이기 때문에 건너뜁니다(경고를 고치는 것도 중요하지만, 일단 오류부터 해결하는 것이 급선무입니다.). 두 번째 줄에 "1>main.obj :  error LNK2019: __imp__glClear@4_main 함수에서 참조되는 확인할 수 없는 외부 기호"라고 버그가 출력되는군요. error LNK2019: __imp__glClear@4_main을 복사하여 구글에 붙여 넣은 뒤 검색해봅시다. 

구글에 위와 같이 에러의 출력을 검색하면, 맨 위에 GLFW - Failed To Open A Window - Stack Overflow라는 글이 보일 것입니다. 이 글을 클릭한 후, 이 글의 목적이 우리가 해결하려 하는 컴파일 오류와 관련 있는지 확인해 봅니다. 글의 내용을 보니, 우리가 해결하려는 오류와 관련 있네요(구글은 절대 거짓말을 하지 않습니다.). 그리고 밑에 어떤 착한 개발자가 이를 해결하는 방법에 대해 답변을 남긴 것을 확인할 수 있습니다.

③ 답변에 올라온 대로, [링커] - [입력] - [추가 종속성]opengl32.lib를 입력해 주어야 이 문제를 해결할 수 있다고 나오네요. 그대로 우리 프로젝트의 [프로젝트 속성 페이지]에 들어가 [링커] - [입력] - [추가 종속성]에 opengl32.ilb를 입력합니다. ;(새미 콜론)으로 라이브러리들을 구분시켜 놓는 것 까먹지 마세요~

④ 이제 [적용(A)] - [확인] 버튼을 누른 후, 오류가 해결됐는지 확인하기 위해 프로젝트를 다시 컴파일해봅시다. 오류가 111개에서 110개로 줄었네요 :) 이렇게 다른 110개의 오류들도 구글을 통해 차근차근 해결하면 성공적으로 컴파일할 수 있습니다.

오류가 111개에서 110개로 ㅇㅁㅇ~

 저는 그대로 제 프로젝트에 나오는 오류들을 위와 같은 방법으로 해결해 보겠습니다. 아직 덜 익숙하신 분들은 계속 글을 읽으시면 되고, 감을 잡으신 분들은 저처럼 문제를 해결해봅시다.

 

[실습 ⑧] 컴파일 오류를 해결하자 ②

1>glfw3.lib(win32_init.obj) : error LNK2019: __imp__TranslateMessage@4__glfwPlatformInit 함수에서 참조되는 확인할 수 없는 외부 기호라는 문제에서 빨간색 글자에 해당하는 버그를 복사한 후 구글에 입력한 후, 이와 관련된 글을 찾아봅니다..

 

② 답변에서 해당 링크에 들어가서 아래로 페이지를 내리면, 페이지 하단에 User32.lib를 추가하라는 글을 볼 수 있다고 나와있네요. 

실제로 해당 링크에 User32.lib를 추가하라는 말이 있습니다.

③ 우리 프로젝트로 돌아와, [프로젝트 속성(P)] - [링커] - [입력] - [추가 종속성]에 User32.lib를 입력한 후, 다시 컴파일을 진행해봅시다. 

오류가 110개에서 18개로 ㅎㅁㅎ

 오류가 110개에서 18개로 줄어든 모습을 확인할 수 있습니다. User32.lib를 추가하지 않아서 컴파일 오류가 92개나 발생했네요 ㄷㄷ.. 이제 나머지 18개의 문제도 해결해봅시다.

 

[실습 ⑨] 컴파일 오류를 해결하자 ③

 1>glfw3.lib(win32_monitor.obj) : error LNK2019: __imp__CreateDCW@16__glfwPlatformGetGammaRamp 함수에서 참조되는 확인할 수 없는 외부 기호

② Microsoft 공식 문서에서 Gdi32.lib를 프로젝트에 추가하라고 나와있군요. 마찬가지로 [프로젝트 설정(P)] - [링커] - [입력] - [추가 종속성]에 Gdi32.lib를 추가합시다. 그리고 컴파일을 진행해야겠죠?

③ 이제 오류가 18개에서 5개로 줄어들었습니다. 나머지 5개도 같이 해결해봐요~

[실습 ⑩] 컴파일 오류를 해결하자 ④

1>glfw3.lib(win32_monitor.obj) :error LNK2019: __imp__DragQueryFileW@16_windowProc@16 함수에서 참조되는 확인할 수 없는 외부 기호

문서에서 Shell32.lib를 프로젝트에 추가하면 문제를 해결할 수 있다고 나와있네요. 마찬가지로 위와 같은 방법으로 추가를 진행한 후, 컴파일을 해봅시다.

③ 컴파일을 진행하니, 오류 문구가 발생하지 않고 컴파일이 완료되었다는 문구와 함께 콘솔 창과 Hello Window라는 타이틀을 가진 윈도우(window)가 보이네요 :) 

 

 모두 여기까지 달려오시느라 고생 많으셨습니다~ 사실 이렇게까지 자세하게 OpenGL Setup에 글을 다루었던 이유는 제가 OpenGL을 처음 시작할 때 이 부분에서 너무 많은 시간을 소비했기 때문입니다. 그래도 최소한 이 글을 보실 분들은 제가 겪었던 시행착오를 겪지 않고, 시간을 효율적으로 사용할 테니, 한편으로는 행복하고 뿌듯하기도 하네요 ㅎㅁㅎ~. OpenGL 첫 포스팅은 여기서 마무리하려고 합니다. 두 번째 포스팅에서 봬요~

 

 

REFERENCE

[1] Download - GLFW

 

An OpenGL library

GLFW project home page.

www.glfw.org

[2] Documentation - GLFW

 

Documentation

GLFW API documentation.

www.glfw.org

[3] GLFW - Failed To Open A Window - stackoverflow

 

GLFW - Failed To Open A Window

As my hunt for a cross-platform framework/library went in progress, GLFW was mentioned many times. So, I decided to try it out. Now, it seems as though I can't even init a window. :-/ #include #i...

stackoverflow.com

[4] Error Occurs when linking with glfw3 [duplicate] - stackoverflow

 

Error occurs when linking with glfw3

I've been trying to compile C++ code and dont reliant on IDE recently, and I decided to use an editor and command line to write and compile code. And the problem is I want to make a glfw app but I...

stackoverflow.com

[5] GetRawInputDeviceInfoA function (winuser.h) - microsoft document

 

GetRawInputDeviceInfoA function (winuser.h) - Win32 apps

Retrieves information about the raw input device.

docs.microsoft.com

[6] CreateDCW function (wingdi.h) - microsoft document

 

CreateDCW function (wingdi.h) - Win32 apps

The CreateDC function creates a device context (DC) for a device using the specified name.

docs.microsoft.com

[7] DragQueryFileW function (shellapi.h) - microsoft document

 

DragQueryFileW function (shellapi.h) - Win32 apps

Retrieves the names of dropped files that result from a successful drag-and-drop operation.

docs.microsoft.com