GLM을 이용한 선형 변환
GLM(OpenGL Mathematics)을 사용해 선형 변환을 처리하는 방법을 다뤄보겠다. OpenGL에서 물체의 위치, 크기, 방향을 조정하는 데 필수적인 수학적 연산을 GLM을 통해 쉽게 구현할 수 있다. 이번 예제는 점을 변환하는 과정을 통해 GLM의 기본 기능을 살펴볼 것이다.
GLM을 사용한 벡터 및 행렬 연산
OpenGL에서 물체의 위치나 방향을 변경하려면 벡터와 행렬을 이용한 선형 변환을 사용해야 한다. GLM은 이를 쉽게 처리할 수 있도록 다양한 연산 함수를 제공한다.
다음 코드는 GLM을 사용하여 평행이동, 회전, 확대 등의 변환을 적용한 예시이다.
// 위치 (1, 0, 0)의 점. 동차 좌표계 사용
glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f);
// 단위행렬 기준 (1, 1, 0)만큼 평행이동하는 행렬
auto trans = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f, 1.0f, 0.0f));
// 단위행렬 기준 z축으로 90도만큼 회전하는 행렬
auto rot = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
// 단위행렬 기준 모든 축에 대해 3배율 확대하는 행렬
auto scale = glm::scale(glm::mat4(1.0f), glm::vec3(3.0f));
// 확대 -> 회전 -> 평행이동 순으로 선형 변환 적용
vec = trans * rot * scale * vec;
SPDLOG_INFO("transformed vec: [{}, {}, {}]", vec.x, vec.y, vec.z);
위의 코드에서는 세 가지 변환이 적용되었다:
- 평행이동:
(1, 1, 0)
만큼 물체를 이동 - 회전: z축을 기준으로 90도 회전
- 확대: 각 축에 대해 3배로 크기 확대
이러한 변환을 순차적으로 적용한 후, 변환된 좌표를 출력한다. trans * rot * scale
의 순서대로 행렬이 적용되며, 그 결과는 (0.9999999, 4, 0)
이 된다.
정점 변환 (Vertex Transformation)
정점에 대한 변환은 OpenGL의 vertex shader에서 처리된다. 물체의 정점은 VBO(Vertex Buffer Object)에 저장되어 있으며, 변환은 vertex shader를 통해 이루어진다. 변환 행렬을 uniform 변수로 셰이더에 전달하고, 그 행렬을 사용하여 정점에 변환을 적용한다.
다음은 vertex shader에서 변환 행렬을 적용하는 방법이다:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
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;
}
위 셰이더에서 uniform mat4 transform
은 변환 행렬을 받아서 정점의 위치에 적용하는데, 이 행렬은 OpenGL 프로그램에서 glUniformMatrix4fv
함수를 통해 전달된다.
변환 행렬 전달하기
Context::Init() 함수에서 변환 행렬을 생성하고, 이를 셰이더에 전달하는 코드이다. 이 예시에서는 물체를 0.5배 축소한 후, z축을 기준으로 90도 회전하는 변환을 적용했다.
auto transform = glm::rotate(
glm::scale(glm::mat4(1.0f), glm::vec3(0.5f)),
glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f)
);
auto transformLoc = glGetUniformLocation(m_program->Get(), "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
이 코드는 GLM을 이용하여 변환 행렬을 만든 후, 그 값을 셰이더의 transform
uniform 변수에 전달한다.
'Computer Graphics > OpenGL' 카테고리의 다른 글
OpenGL 정리 - 12. 카메라, View Transform (0) | 2024.09.19 |
---|---|
OpenGL 정리 - 11. 큐브 그리기, Depth Buffer, 여러 큐브 그리기 (0) | 2024.09.13 |
OpenGL 정리 - 9. 백터와 행렬 (0) | 2024.09.13 |
OpenGL 정리 - 8. Texture 사용 과정, 다중 Texture, Mipmap (0) | 2024.09.12 |
OpenGL 정리 - 7. Texture 입히기 (0) | 2024.09.12 |