PyOpenGL을 활용한 실시간 3D 모델링 및 애니메이션 구현

지금까지 PyOpenGL의 기본적인 사용법과 3D 그래픽스 프로그래밍의 기본 개념을 배웠습니다. 이번 포스트에서는 PyOpenGL을 사용하여 실시간 3D 모델링과 애니메이션을 구현하는 방법에 대해 알아보겠습니다.

1. 3D 모델링

실시간 3D 모델링은 3D 객체를 생성하고 변형하는 과정을 말합니다. PyOpenGL을 사용하면 다양한 형태의 3D 객체를 생성하고 관리할 수 있습니다. 아래는 PyOpenGL을 사용하여 간단한 육면체를 생성하는 예제 코드입니다.

import OpenGL.GL as gl

def create_cube():
    vertices = [
        (1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1),  # back face
        (1, -1, 1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1)  # front face
    ]

    indices = [
        0, 1, 2, 0, 2, 3,  # back face
        0, 4, 5, 0, 5, 1,  # right face
        1, 5, 6, 1, 6, 2,  # top face
        2, 6, 7, 2, 7, 3,  # left face
        0, 3, 7, 0, 7, 4,  # bottom face
        4, 7, 6, 4, 6, 5  # front face
    ]

    vao = gl.glGenVertexArrays(1)
    gl.glBindVertexArray(vao)

    vbo = gl.glGenBuffers(1)
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, 4 * len(vertices), vertices, gl.GL_STATIC_DRAW)

    ebo = gl.glGenBuffers(1)
    gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo)
    gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, 4 * len(indices), indices, gl.GL_STATIC_DRAW)

    gl.glEnableVertexAttribArray(0)
    gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, False, 0, None)

    return vao, len(indices)


def draw_cube(vao, num_indices):
    gl.glBindVertexArray(vao)
    gl.glDrawElements(gl.GL_TRIANGLES, num_indices, gl.GL_UNSIGNED_INT, None)


# 실행 코드
vao, num_indices = create_cube()

while True:
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
    draw_cube(vao, num_indices)
    # 모델 변형 코드 추가
    # 애니메이션 코드 추가
    gl.glSwapBuffers()

위의 코드는 육면체를 생성하고 그리는 코드입니다. create_cube 함수는 육면체의 정점과 인덱스를 생성하여 OpenGL 버퍼에 저장하고, draw_cube 함수는 저장된 데이터를 사용하여 육면체를 그립니다.

2. 애니메이션 구현

애니메이션은 물체의 움직임을 표현하는 기술입니다. PyOpenGL을 사용하여 3D 오브젝트에 애니메이션을 적용하기 위해서는 매 프레임마다 모델 변형을 업데이트해야 합니다. 아래는 육면체를 회전하는 간단한 애니메이션을 구현하는 예제 코드입니다.

import numpy as np
import OpenGL.GL as gl

rotation = 0

def update_model_transform():
    global rotation
    rotation += 1

def draw_cube(vao, num_indices):
    gl.glBindVertexArray(vao)
    gl.glDrawElements(gl.GL_TRIANGLES, num_indices, gl.GL_UNSIGNED_INT, None)

def main():
    # 육면체 생성 코드 생략

    while True:
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

        update_model_transform()

        model_transform = np.identity(4)
        model_transform = np.dot(model_transform, np.rotation_matrix(rotation, (0, 1, 0)))

        # 모델 변형 적용
        gl.glUniformMatrix4fv(model_transform_location, 1, gl.GL_FALSE, model_transform)

        draw_cube(vao, num_indices)
        gl.glSwapBuffers()

위의 코드에서 update_model_transform 함수는 매 프레임마다 모델의 변형을 업데이트하는 함수입니다. draw_cube 함수에서 model_transform을 적용할 때, glUniformMatrix4fv 함수를 사용하여 적절한 위치에 모델 변형 행렬을 전달합니다.

위 예제에서는 단순하게 회전 애니메이션을 적용했지만, 다른 변형 효과를 구현하려면 해당 변형을 적용하는 코드를 추가하면 됩니다.

이제 PyOpenGL을 활용하여 3D 모델링과 애니메이션을 구현하는 방법에 대해 알아보았습니다. 보다 복잡한 모델링과 애니메이션을 구현하려면 더 많은 OpenGL 기능을 활용해야 합니다. 추가적인 기능을 습득하고 응용하여 더 다양하고 흥미로운 3D 애플리케이션을 개발해보세요!

#PyOpenGL #3D모델링 #애니메이션 #파이썬