💫 Window 운영체제를 사용하며, 해당 정보는 LearnOpenGL 이라는 사이트에 기반해 작성했습니다. 부정확한 내용이 있을 수 있으니, 그러한 내용이 있는 경우 알려주시면 감사하겠습니다.
이 글은 이전 포스트인 OpenGL #1의 방식으로 생성한 프로젝트에 기반합니다.
최하단에 전체 코드를 넣어놨으니, 만약 문제가 있다면 참고하시기 바랍니다.
먼저 .cpp파일을 생성 후 아래 두 include 문장이 정상적으로 입력되는지 확인합니다.
#include <glad/glad.h>
#include <GLFW/glfw3.h>
GLAD에는 필수 OpenGL 헤더가 포함되므로 GLAD를 GLFW보다 먼저 include 해야 합니다.
그러고, main 함수를 만든 후 아래와 같이 작성합니다.
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
GLFW를 초기화하는 함수입니다.
이 함수를 통해 GLFW를 구성할 수 있습니다.
첫번째 파라미터는 우리가 설정할 옵션이고, 두번째 파라미터는 그 값입니다.
이 링크에서 모든 옵션과 값들에 대한 정보를 확인할 수 있습니다.
GLFW_CONTEXT_VERSION_MAJOR와 GLFW_CONTEXT_VERSION_MINOR는 우리가 사용할 OpenGL 버전을 GLFW에게 알려주는 겁니다. 만약 OpenGL 4.6을 사용하고 있다면 MAJOR에는 4, MINOR에는 6을 넣으면 됩니다.
GLFW_OPENGL_PROFILE은 현재 사용하는 프로파일이 Core 프로파일이므로 해당 정보를 GLFW에 전달합니다.
이제 본격적으로 Window 객체를 생성합니다.
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW Window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
설정된 GLFW 정보를 기반으로 윈도우를 생성합니다.
너비, 높이, 창 이름을 파라미터로 받으며, 마지막 두 파라미터는 아직은 무시해도 됩니다.
파라미터에 입력된 window를 Double Buffer로 사용하며, 현재 스레드의 메인 컨텍스트로 설정합니다. 아직 뭔소린지 잘 모르겠네요..
OpenGL 관련 함수들을 사용하기 전에 GLAD를 초기화해야 합니다.
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
GLAD를 초기화하는 함수입니다.
렌더링 시작 전에 먼저 OpenGL에게 렌더링 화면 사이즈를 알려줘야 합니다.
그렇게 해야 OpenGL이 어떻게 윈도우에 관해 데이터와 좌표를 표시할지 알 수 있습니다.
glViewport 함수를 통해 설정할 수 있습니다.
그러나, 사용자가 창 크기를 조절하는 순간의 뷰포트도 조정해야 하기에 창 크기를 조절할 때마다 호출되는 콜백 함수를 등록합니다.
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
창을 처음 표시할 때 초기 창 크기로 해당 함수가 호출됩니다.
현재까지의 코드는 순간적으로 창이 잠깐 뜨고 꺼집니다. 그러나 우리는 계속해서 창이 표시되고 그 창에 그림을 그리길 원합니다.
우리는 Render Loop를 만들어 GLFW에게 우리가 그만 하라고 호출할 때까지 화면을 띄워놓도록 할 겁니다.
while(!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
위 while문은 간단한 Render Loop입니다.
각 루프가 시작될 때마다 GLFW가 종료되도록 지시되었는지 확인합니다.
이전 프레임의 Buffer와 현재 프레임의 Buffer를 swap합니다.
키보드 입력이나 마우스 이벤트가 발생하는지 확인하고 정해진 콜백 함수를 호출합니다.
Render Loop가 끝난 후 모든 자원을 정리하는 함수입니다.
여기까지 모든 코드를 정상적으로 입력했다면 다음과 같이 화면이 뜰겁니다.
저는 전체코드이기 때문에 색이 들어가있지만, 검은색 창으로 뜰겁니다!
이제 GLFW에서의 입력을 처리할 겁니다.
esc키를 입력했다면, 창이 꺼지도록 설정합니다.
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
키보드 키가 입력이 되었는지 확인하는 함수입니다. 입력되었다면 GLFW_PRESS, 입력하지 않는다면 GLFW_RELEASE를 반환합니다.
이 함수를 Render Loop문 안에 넣어놔 매 프레임 체크하도록 합니다.
while (!glfwWindowShouldClose(window))
{
processInput(window);
glfwSwapBuffers(window);
glfwPollEvents();
}
앞으로 우리는 모든 렌더링 관련 명령을 Render Loop 안에 넣어야 합니다.
while (!glfwWindowShouldClose(window))
{
processInput(window);
// 여기에 렌더링 명령
glfwSwapBuffers(window);
glfwPollEvents();
}
이것이 실제로 작동하는지 확인하기 위해 선택한 색상으로 화면을 지우도록 설정해보겠습니다.
렌더링 루프를 돌 때마다 화면을 지웁니다. 그래야 이전 프레임의 이미지가 남지 않습니다.
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
어떤 색으로 화면을 지울지 설정합니다.
우리가 지우려 하는 버퍼의 비트를 전달해 지웁니다.
GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT 와 같은 것들이 있지만, 현재 컬러 버퍼만 있으므로 GL_COLOR_BUFFER_BIT를 전달해 지웁니다.
이제 정말 해당 색으로 화면이 출력될 겁니다.