본문 바로가기

Graphics Note

OpenGL 강좌 - 1. 소개와 준비

소개에 앞서 잡소리..

입문자를 위한 OpenGL 강좌를 써보려한다. OpenGL 강좌야 찾아보면 수두룩 하다지만 대부분의 강좌는 예전 API 명세(OpenGL 2.0)를 기초로 진행한다. 물론 최신 API 명세는 복잡하고 더 정교해졌기 때문에 예전 API로 진행되는 강좌가 입문자들에겐 훨씬 쉽다고 말할 수 있다. 하지만 시대는 변하고 API는 점점 더 발전했으며 앞으로 예전 API는 더 이상 지원하지 않을것이라는 공식적인 입장이 발표된 현재, 다소 쉽다고 느껴지는 구시대의 강좌가 정말로 현명한 선택일런지는 잘 판단해야할 부분이다.


개인적으로는 새롭게 공부하 분들은 최신 API에 맞춰 공부를 하는게 바람직하다고 생각한다. 그런데 안타깝게도 여전히 많은 분들이 예전에 쓰여진 강좌를 보고 OpenGL을 공부한다. 심지어 대학에서도 예전 버전으로 가르치니 말 다했다. 가장 정확한 방법은 OpenGL 공식 페이지(http://www.opengl.org/)에서 최신 라이브러리 명세 문서를 찾아 공부하는 것이겠지만, 당연하게도 영어로 쓰여있고, 재미도 없게 구성되어있다. 그렇다 보니 웹을 통해 강좌를 찾게되고, 옛 시대의 강좌를 보게된다.


...그런고로 OpenGL 4.5에 맞춰 입문자를 위한 강좌를 써보자고 계획했다. 나 스스로도 깊이 있게 아는게 아니기 때문에 최대한 OpenGL 4.5 core spec.을 참고해 가며 진행할 예정이다.



소개

그래서 OpenGL이 뭔데? OpenGL은 Khronos(http://www.khronos.org)에서 만들기 시작한, 그래픽스 하드웨어를 위한 열린(open) 그래픽스 라이브러리(Graphics Library) 이다. 대응되는 Microsoft의 DirectX와 다르게 관련된 많은 업체가 함께 참여하여 표준안을 만들어간다.


중요한 점은 크로스 플랫폼(cross-platform)을 지원한다는 것이며, 점점 개방되어가는 이 시대에 MS의 OS에만 국한된 DirectX에 비해 주목받는것은 사실이다. 게다가 성능도 굉장히 많이 향상돼서 'OpenGL은 느리다'라는 관념은 깨진지 오래되었다. (그렇다곤 해도 최적화된 DirectX 어플리케이션을 따라가긴 힘들다고 본다.)


또한 모바일 플랫폼의 부상과 함께 등장한 OpenGL ES, 그리고 웹 그래픽 표준으로 자리잡은 WebGL 등 OpenGL의 활동범위는 점점 넓어져 가고 있으며 그에 따라 수요도 증가하고있다.



준비

강좌를 본격적으로 시작하기 전에 개발 환경에 대해 몇 가지 설명하려 한다. 우선 이 강좌는 OpenGL 4.5 명세에 최대한 맞춰 진행될 것이기 때문에 코드를 직접 실행해 보려면 이 명세를 지원하는 그래픽 카드를 사용해야한다(요즘의 PC라면 다 지원 할 것이다). 그리고 윈도우 이벤트 등 부차적인 개발사항을 최소화 하기 위해 GLFW 라는 유틸리티 라이브러리를 활용하려 한다. 또한 모든 예제 코드는 MS Windows7 OS의 VisualStudio 2013 환경에서 작성 및 테스트 될 것이다.


* OpenGL 설치

정상적인 그래픽 드라이버를 설치했다면 기본적으로 GL이 설치되어 있을것이다. 혹시라도 GL/GL.h 파일을 포함할 수 없다면 자신의 그래픽카드 제조사에 맞는 그래픽 드라이버를 설치했는지 확인해보자.


* GLEW 설치

윈도우 컨텍스트를 다루기 위해서는 기본적인 GL 만으론 부족하다. 이를 위해서 GLEW(OpenGL Extension Wrangler)라는 확장 라이브러리를 제공한다. https://glew.sourceforge.net/ 에서 바이너리를 받아 경로를 설정하면 된다.


프로젝트를 생성할 때 마다 매번 경로설정하는 작업이 귀찮다면 아래 경로에 파일들을 넣어둬도 괜찮다. 

(경로는 조금 다를 수 있지만 대체로 비슷한 형태이다. 잘 모르겠으면 gl.h 파일을 찾아 같은 곳에 넣어주면 된다.)

 - C:\Program Files (x86)\Windows Kits\8.1\Include\um\gl 에 glew\include\GL 의 파일들 넣기

 - C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86 에 glew\lib\Release\Win32 의 파일들 넣기

 - C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64 에 glew\lib\Release\x64 의 파일들 넣기


그리고 새로 만든 프로젝트의 실행 경로 아래 glew\bin\Release\Win32\glew32.dll 을 복사하여 넣어두는 것으로 glew에 대한 준비는 끝난다.

* OpenGL 버전 확인
GLEW를 설정한 후 내려받은 GLEW폴더 안에 bin\Release\Win32\glewinfo.exe 를 실행해보자. 그러면 opengl과 glew 정보를 포함하는 파일 glewinfo.txt가 생성된다. 파일을 열어 GL_VERSION_4_5 까지 모두 지원하는지 확인하면 된다. 만약 최신 GL 버전을 사용할 수 없다면 그래픽 카드를 교체해야한다.

* GLFW 설치
사실 기본적인 OpenGL 만으로는 그리기 위한 컨텍스트 혹은 윈도우를 생성하거나 다룰 수 없다. 윈도우 핸들러를 통해 직접 디바이스 컨택스트를 생성하고 설정해주는 꽤 복잡한 작업을 거쳐야만 한다. (이때 GLEW가 사용된다.) 하지만 복잡하고 크게 중요한 부분이 아니므로 이 강좌에서는 GLFW라는 유틸리티 라이브러리를 사용하여 윈도우를 다룰것이다. GLFW 설치법은 따로 정리해뒀다(http://alleysark.tistory.com/258). GLEW와 마찬가지로 실행 결로 아래 glfw3.dll을 복사하여 넣어두자.

* GLM 설치
물체를 다루는데는 벡터와 행렬 연산을 포함해서 상당히 다양한 수학적 연산이 필요하다. OpenGL Mathematics GLM은 이를 위한 라이브러리이다. GLM은 header only 라이브러리이기 때문에 http://glm.g-truc.net/0.9.6/index.html에서 다운받아 헤더만 포함해주면 된다.


테스트

이정도로 기본적인 준비는 끝났다. 아래 코드가 제대로 동작하는지 빌드해보자. 새하얀 창이 뜬다면 성공이다.

#define GLFW_DLL #define GLFW_INCLUDE_GLU #include <GL/glew.h> #include <GLFW/glfw3.h> #include <iostream> #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glew32.lib") #pragma comment(lib, "glfw3dll.lib") void InitApp() { // 클리어 색상(배경색) 지정 glClearColor(1, 1, 1, 1); } void ErrorCallback(int error, const char* description) { std::cout << description << std::endl; } void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); } void WindowSizeChangeCallback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } int main() { // GLFW 윈도우 핸들러 GLFWwindow* window = NULL; // 에러 핸들러 등록 glfwSetErrorCallback(ErrorCallback); // GLFW 초기화 if (!glfwInit()) exit(EXIT_FAILURE); // 윈도우 생성 window = glfwCreateWindow(640, 480, "Tutorial 00: Test", NULL, NULL); if (!window) { // 만약 윈도우 생성에 실패했다면 어플리케이션 종료 glfwTerminate(); exit(EXIT_FAILURE); } // 컨텍스트 생성 glfwMakeContextCurrent(window); // swap 간격 조정 glfwSwapInterval(1); // 키 핸들러 등록 glfwSetKeyCallback(window, KeyCallback); // 윈도우 사이즈 변경 핸들러 등록 glfwSetWindowSizeCallback(window, WindowSizeChangeCallback); // GLEW 초기화 glewInit(); // 어플리케이션의 초기화 InitApp(); // 주 렌더링 루프. 윈도우가 종료되기 전까지 반복한다. while (!glfwWindowShouldClose(window)) { // 버퍼 지우기 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 여기에 Update/Render 코드 // 렌더 버퍼 교체. (그린 결과를 디스플레이하는 명령) glfwSwapBuffers(window); // 윈도우 이벤트 (키 스트로크 등) 폴링. glfwPollEvents(); } // 윈도우 제거 glfwDestroyWindow(window); // GLFW 종료 glfwTerminate(); return 0; }


소스코드

앞으로 강좌가 진행되면서 여러 프로그램을 만들어볼텐데 강좌 안에 모든 코드를 삽입하기란 쉽지 않으므로 전체 코드는 github에 올릴 예정이다. 필요하다면 가져다 쓰시길.

https://github.com/alleysark/OpenGL-Tutorials


'Graphics Note' 카테고리의 다른 글

OpenGL 강좌 - 3. 삼각형 그리기(셰이더)  (0) 2015.05.25
OpenGL 강좌 - 2. 삼각형 그리기(설정)  (0) 2015.05.25
asymptotic discrete spot noise (ADSN)  (0) 2014.12.11
random phase noise  (0) 2014.12.10
implementing EPA in 3D  (0) 2014.05.29