꿈이 너무 많은 한 대학생의 공간

OpenGL 정리본 1 - 윈도우 열기 본문

개발만담

OpenGL 정리본 1 - 윈도우 열기

청울울청 2020. 12. 6. 00:18

1. 준비물

- Visual Studio (2019 권장)

- CMake (C/C++ 프로젝트 빌트 툴)

- 튜토리얼 코드 

 

위 준비물이 모두 갖춰진 상태에서 CMake를 연다.

.zip 파일인 튜토리얼 코드를 압축 해제한 후, CMake의 Where is the source code: 부분에서 압축 푼 디렉토리를 선택한다. 

이후 원하는 폴더를 하나 새로 만들고, 그 경로를 지정한다. (그 폴더로 완전히 빌드가 완료된 파일들이 들어갈 것이다)

Configure을 한번 누르고, Visual Studio 16 (2019) 를 선택한 뒤 아래 Finish를 누른다.

CMake가 해당 IDE에 대해 여러 설정을 하면

위의 화면처럼 빨갛게 항목이 그어질 것이다.

아래 Configure를 한번 더 눌러주자.

그렇게 한다면 빨간색으로 지정된 부분이 사라지고 하얀색 부분만 남게 된다.

Generate 버튼을 눌러 빌드를 완료한다.

 

시간이 지나고 커맨드 창에 Generate Done 이 뜨면 창을 끄고 아까 만든 폴더에 들어간다.

수많은 파일들이 있을 텐데 아래로 내리다 보면 Tutorials.sln 이 있다.

더블클릭해 열어주자.

 

VS 2019가 열리면 아래와 같이 빌드 -> 솔루션 빌드를 눌러 다시 한번 전체적인 빌드를 해준다.

모두 완료된다면 시작할 준비가 된 것이다.

 

본론에 들어가기 전, 모든 코드는 오른쪽 솔루션 탐색기 -> playground 솔루션 -> Source Files -> playground.cpp 에서만 한다. 절대로 다른 솔루션(tutorial01_first_window, tutorial02_red_triangle) 등을 절대로 수정하지 않는다.

이 솔루션들은 혹여나 코드가 작동이 되지 않거나 이해가 가지 않을 때, 예시로 참고하기 위해 존재하는 솔루션이다.

절대로, 절대로 수정하지 않는다. 다만, 필자는 playground.cpp에서 해당 코드가 정상적으로 작동하는지 확인하고 주석을 달아 코드 해석을 한 뒤에 tutorial01_first_window 등의 솔루션에 붙어넣는 공부 방식을 활용한다. 다만, 이 방법은 너무 위험하고 CMake를 통해 한번 더 빌드를 해서 원상복구 시켜야 할 수도 있으니 비추천한다.

 

2. 코드 작성

#include <stdio.h>
#include <stdlib.h>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
using namespace glm;

기본적인 라이브러리를 가져온다.

stdio.h, stdlib.h는 C++을 사용해봤다면 알 만한 라이브러리들이고, glew는 OpenGL이 매끄럽게 작동할 수 있도록 도와주는 라이브러리이다. 그 밑의 glfw3는 키보드, 마우스를 다루기 위해 사용되며 glm은 3차원 계산에서 활용된다. 또, 귀찮게 glm::vec 이렇게 쓰기 귀찮으니 namespace를 선언해 빠르게 사용하도록 하자.

int main() {

	if (!glfwInit()) { // GLFW 초기화
		fprintf(stderr, "GLFW 초기화 실패");
		return -1;
	}

	glfwWindowHint(GLFW_SAMPLES, 4); // 4x 안티에일리어싱
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // OpenGL 3.3 사용
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // 이하 동문
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // MacOS에 친화적
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // OpenGL 3.3에서 성능 향상

glfwInit() 함수는 GLFW 라이브러리들을 모두 초기화하며 정상적으로 작동하는지 체크한다. 만약 제대로 작동된다면 GL_TRUE(단순히 true, false를 리턴하지 않는다), 아니라면 GL_FALSE를 리턴한다.

 

glfwWindowHint는 새로운 윈도우를 만들 때 기본적으로 사용되는 설정들이다. 예를 들어 glfwWindowHint(항목, 값) 이라면 항목에 대한 값을 해당 값으로 바꾼다는 의미이다. GLFW_SAMPLE은 안티에일리어싱, GLFW_CONTEXT_VERSION_MAJOR, MINOR은 사용할 OpenGL 버전을 설정하며, GLFW_OPENGL_FORWARD_COMPAT은 MacOS에서 더 깔끔하게 작동하도록 만들어준다. GLFW_OPENGL_PROFILE은 OpenGL 3 에서 생긴 기능인데, 만약 Intel GPU 등을 사용해서 OpenGL 3을 사용하지 못하는 경우 이 항목을 지워주도록 하자.

	GLFWwindow* window; // GLFWWindow 개체 생성
	window = glfwCreateWindow(600, 800, "Tutorial 01", NULL, NULL); // 600x800, 제목은 Tutorial 01을 가진 윈도우 생성. 4번째 항목은 전체화면인지 아닌지, 5번째 화면은 리소스를 공유하는지 아닌지

	if (window == NULL) {
		fprintf(stderr, "GLFW 윈도우를 여는데 실패했습니다. Intel GPU를 사용한다면 2.1 버전 튜토리얼을 사용하세요.");
		glfwTerminate(); // GLFW 실행 중 에러가 난다면 바로 프로그램 종료
		return -1;
	}

GLFWwindow 개체를 생성한다. 윈도우를 새로 만드는 데에 기초적인 부분이다.

glfwCreateWindow 함수를 통해 새로운 윈도우를 생성한다. glfwCreateWindow(가로, 세로, 창 제목, 전체화면 유무, 창들끼리 리소스를 공유하는지의 여부) 이다.

만약 glfwCreateWindow가 제대로 실행되지 않아 window가 null이 된다면, 치명적인 버그가 생기므로 즉시 glfwTerminate()를 통해 프로그램을 강제 종료시킨다.

	glfwMakeContextCurrent(window); // GLFW 초기화
	glewExperimental = true; // 코어 프로파일을 위해 필요함.

	if (glfwInit() != GL_TRUE) {
		fprintf(stderr, "GLFW Initializing 실패");
		return -1;
	}

	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); // Escape 키가 눌러지는지를 감지함
	do {
		glfwSwapBuffers(window);
		glfwPollEvents();
	} while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);

glfwMakeContextCurrent는 생성되는 window의 상태를 확인할 수 있게 한다.

물론 이걸 눈으로 직접 볼 수는 없겠지만 프로그램 내에서 자동으로 감시가 된다.

glfwExperimental은 실제로 어디서 나온 건지는 모르겠지만... 어찌 되었든 미리 변수로 선언이 되어서 저렇게 사용한다.

또, window 생성 이후에도 제대로 작동하는지 확인하기 위해 glfwInit()을 한번 더 사용한다.

이후, window 내에서 키보드를 활성화시키기 위해 glfwSetInputMode를 사용한다.

그리고 do while 구문을 이용해 window가 활성화되는 동안 화면의 버퍼를 교환한다. 이는 너무 복잡하므로 나중에 설명한다. glfwPollEvents 함수는 window가 활성화되는 동안 이뤄지는 모든 함수를 처리하는 역할을 한다.

Comments