GLM

Date:     Updated:

카테고리:

태그:

Main Reference
- Learn OpenGL
- Rinthel Kwon - OpenGL Lecture


GLM Library

# glm
ExternalProject_Add(
    dep_glm
    GIT_REPOSITORY "https://github.com/g-truc/glm"
    GIT_TAG "0.9.9.8"
    GIT_SHALLOW 1
    UPDATE_COMMAND ""
    PATCH_COMMAND ""
    CONFIGURE_COMMAND ""
    BUILD_COMMAND ""
    TEST_COMMAND ""
    INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory
    ${PROJECT_BINARY_DIR}/dep_glm-prefix/src/dep_glm/glm
    ${DEP_INSTALL_DIR}/include/glm
)
set(DEP_LIST ${DEP_LIST} dep_glm)
  • C++ 선형대수 라이브러리
    • Eigen3 : 가장 많이 사용되는 라이브러리. N차원 행렬을 지원하므로 무거움
    • GLM : OpenGL Math 라이브러리. 3D 그래픽스에 필요한 4차원 행렬 연산 지원
  • 선형대수 라이브러리는 앞으로도 계속 사용하므로 cmake로 설치 후 common.h에 헤더 추가


Transform Matrix

07_transform_process

  • Model : Loacl → World
  • View : World → Camera
    • camera basis로 좌표계 변환 (Lookup matrix 이용)
  • Projection : Camera → Canonical ([-1,1] Clip Space)
    • Orthogonal or Perspective
  • Clip Space에서 범위 벗어난 면들 Clipping
  • Local → Clip으로 한 번에 가는 변환을 MVP 변환이라고 함.


Example

void Program::SetUniform(const std::string& name, int value) const {
    auto loc = glGetUniformLocation(m_program, name.c_str());
    glUniform1i(loc, value);
}

void Program::SetUniform(const std::string& name, const glm::mat4& value) const {
    auto loc = glGetUniformLocation(m_program, name.c_str());
    glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(value));
}

// vertex shader
uniform mat4 transform;

out vec4 vertexColor;
out vec2 texCoord;

void main() {
    gl_Position = transform * vec4(aPos, 1.0);
    vertexColor = vec4(aColor, 1.0);
    texCoord = aTexCoord;
}
  • 일반적으로 transform matrix(MVP)는 uniform 변수로 shader에 넘겨줘야 한다.
  • 일일이 변수 찾고 넘겨주기 귀찮으니 Program class에 함수 구현


void Context::Render() {
    glClear(GL_COLOR_BUFFER_BIT);

    auto model = glm::rotate(glm::mat4(1.0f), glm::radians((float)glfwGetTime() * 120.0f), glm::vec3(1.0f, 0.5f, 0.0f));
    auto view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -3.0f));
    auto projection = glm::perspective(glm::radians(45.0f), (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.01f, 10.0f);
    auto transform = projection * view * model;
    m_program->SetUniform("transform", transform);

    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
}
  • model 변환은 Scale → Rotation → Translation 순으로 변환
    • 시간에 따라 계속 회전하는 케이스
  • view 변환은 카메라 챕터에서 다시 다룰 예정 (여기서는 그냥 원점에서 뒤로 조금 간 케이스)
  • projection 변환은 glm 함수로 구현되어 있기 때문에 가져다 쓰면 됨.
    • perspective의 경우 frustum 화각, 크기, near, far


Result

OpenGLExample2024-07-2120-33-07-ezgif com-video-to-gif-converter

그런데 막상 큐브를 그려보면 이상한 면들이 그려지게 된다. 이는 Rasterization 단계에서 진행하는 depth test를 하지 않았기 때문이다. Depth test는 depth buffer(Z buffer)를 통해 하게 되는데, OpenGL에서는 간단한 옵션만 추가해주면 사용할 수 있다.

// Render...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
  • frame buffer 초기화 할 때 depth buffer도 같이 진행
  • depth test 옵션 on

OpenGLExample2024-07-2120-34-09-ezgif com-video-to-gif-converter



맨 위로 이동하기

OpenGL 카테고리 내 다른 글 보러가기

댓글 남기기