OpenGL 윈도우 띄우기 [Learn OpenGL 쉬운 번역]

728x90
반응형
※ 본 포스팅은 learnopengl.com을 번역 및 가감한 포스팅이며, learnopengl에서는 번역 작업 참여를 적극 장려하고 있습니다!
아래 링크에서 원문을 확인할 수 있습니다.

 

Hello Window

이제 GLFW가 잘 되는지 테스트 해봅시다. cpp파일을 생성해서 include 헤더문을 추가하세요.

#include <glad/glad.h>
#include <GLFW/glfw3.h>

 

GLAD를 GLFW위에 선언해야하는데, GLAD의 include 파일들은 GL/gl.h와 같은 OpenGL 헤더 파일들을 백그라운드에서 포함하기 때문에 OpenGL이 필요한 GLFW 등보다 먼저 선언해주어야 합니다.

 

다음으로 GLFW 창을 만들 main 함수를 작성합니다.

 

int main()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  
    return 0;
}

 

main 함수에서는 glfwInit 함수로 GLFW를 초기화 먼저 합니다. 

 

그 다음 glfwWindowHint 함수로 GLFW를 구성합니다. 첫 번째 인수는 구성 옵션이고, GLFW_로 시작하는 enum type 중에서 선택가능합니다. 두 번째 인수는 옵션의 값을 설정합니다.

 

위 문서에서 어떤 값을 설정할 수 있는지 알 수 있습니다. 실행을 해보고 에러가 발생하면, GLFW 라이브러리 링크가 잘못되었으니 이전 포스팅 과정을 다시 시도해보세요.

 

learn opengl은 OpenGL 3.3 버전을 중심으로 진행합니다. 그러니까 GLFW에게도 우리가 3.3 버전을 쓴다고 알려줘야합니다. 그러면 OpenGL context 생성 시 적절하게 설정할 수 있고, 버전이 맞지 않으면 GLFW가 실행 안되도록 해주기도 합니다.

그래서 위 코드에서는 메이저 버전 마이너 버전 모두 3으로 설정하고, GLFW에 Core profile을 사용하고 싶다고 명시적으로 알려줍니다. 코어 프로파일을 사용하게 설정하면, 불필요한 하위 호환 기능 등 없이도 OpenGL 기능의 특정 부분을 마음껏 사용 가능합니다. 

(Mac OS X의 경우 초기화 코드에 주석된 부분을 추가해야합니다)

 

여러분이 사용하는 기기가 OpenGL 3.3 이상 버전이 설치되었는지 확인이 필요합니다. 아니라면 프로그램에서 충돌이 생기거나 이상한 동작이 나올 수도 있습니다.
Linux에선느 glxinfo를 호출하여 확인할 수 있고, windows에서는 OpenGL Extension Viewer와 같은 툴로 OpenGL 버전 확인이 가능합니다.
현재 낮은 버전이라면 그래픽 카드가 opengl 3.3 을 지원하는 기기인지 확인하고 드라이버를 업데이트 하셔야합니다. 

 

 

이제 window object를 생성합시다. window object는 window 관련 데이터를 가지는데 다른 GLFW 함수에서 많이 쓰입니다.

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);

 

glfwCreateWindow 함수는 첫 번째 인자와 두 번째 인자로 각각 창의 너비 높이를 필요로 합니다. 세 번째 인수는 window의 이름이고, 마지막 두 매개변수는 아직은 필요가 없습니다.

함수를 통해 GLFWwindow object를 반환하고, 다른 GLFW 함수에 또 작업하게 됩니다.

그 다음에 GLFW가 현재 스레드에서 window context를 main context로 설정합니다.

 

GLAD

이전 포스팅에서 GLAD가 OpenGL 함수 포인터를 관리한다고 했습니다. 함수를 호출하는데 사용되기 전에 반드시 초기화를 해야합니다.

if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
}

GLAD에 OpenGL함수 포인터 주소를 로드하는 함수를 전달해야 하는데, 방법은 OS에 따라서 다릅니다. GLFW는 glfwGetProcAddress라고 하는 함수를 통해 현재 OS에 맞는 함수를 정의할 수 있게 해줍니다.

 

Viewport

렌더링하기 전에 마지막으로 렌더링 window의 크기를 알려주고 데이터 좌표들을 창에 맞게 표시할 수 있게 해줍니다.

 

렌더링 되는 창의 크기는 glViewport 함수로 설정 가능합니다.

glViewport(0, 0, 800, 600);

첫 번째와 두 번째 매개변수는 창의 왼쪽 하단 모서리 좌표이고, 세 번째 네 번째 매개변수는 너비와 높이의 픽셀 단위 설정입니다. 이 값은 GLFW window의 크기와 같은 값으로 해줍니다. 

 

실제 viewport의 크기를 GLFW window 크기보다 작게 설정은 가능합니다. 그러면 OpenGL 렌더링이 창보다 더 작은 화면에 출력되고, viewport 외 나머지 부분에는 또 다른 것을 띄울 수 있겠죠?

 

백그라운드에서 OpenGL은 glViewport를 통해 지정한 데이터를 사용해서 2D 좌표를 화면에서의 좌표로 변환합니다.
예를 들어서 위치가 (-0.5, 0.5)인 점은 최종 변환으로 화면 좌표에서 절반 절반인 (200, 450) 위치로 매핑됩니다. OpenGL에서 처리된 좌표는 -1에서 1 사이이므로, 이를 보간해서 (-1~1) 범위에서 너비 (0~800) 및 높이 (0~600) 범위로 매핑합니다.

 

사용자가 window 크기를 조정하면 viewport는 꼭 맞게 수정되어야합니다. 그래서 창 크기 조절시마다 호출되는 콜백 함수를 설정할 수 있습니다. resize시 콜백하는 함수는 다음과 같습니다.

void framebuffer_size_callback(GLFWwindow* window, int width, int height);

framebuffer size callback 함수는 첫 번째 인수로 GLFWwindow object를 받고, 새로 바뀌는 창 크기 두 정수를 다음 두 세 번째 인자로 받습니다. 창의 크기가 변경될 때마다 GLFW는 함수를 호출하고, 처리할 수 있도록 적절한 인수를 채워줍니다. 

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

그러면 이 함수를 창의 크기가 조정될 때마다 호출되도록 GLFW에 등록해야겠죠?

glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

창이 처음 표시될 때도 framebuffer_size_callback이 호출되고 창의 크기가 함수로 전달됩니다. retina 화면에서는 너비와 높이가 원래보다 크게 나타나는 경우도 있습니다. 

 

비슷한 방식으로 여러 콜백 함수를 만들어서 등록할 수 있습니다. 예를 들어 조이스틱 입력 변경 처리나 오류 메시지 처리 등이 가능한데, 콜백 함수들을 창 생성 후 render loop를 시작하기 전에 등록해야합니다. 

 

 

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유