본문 바로가기
프로그램

[파이썬] OpenGL의 3D 사각형을 시점 바꾸기

by 오디세이99 2024. 7. 14.
728x90
반응형
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import sys

def generate_cube_vertices(size):        # 큐브의 꼭짓점을 생성하는 함수 정의
    s = size / 2.0                       # 크기를 반으로 나눔
    return [                             # 큐브의 8개 꼭짓점 좌표 반환
        ( s, -s, -s),                    # 오른쪽 아래 뒤
        ( s,  s, -s),                    # 오른쪽 위 뒤
        (-s,  s, -s),                    # 왼쪽 위 뒤
        (-s, -s, -s),                    # 왼쪽 아래 뒤
        ( s, -s,  s),                    # 오른쪽 아래 앞
        ( s,  s,  s),                    # 오른쪽 위 앞
        (-s, -s,  s),                    # 왼쪽 아래 앞
        (-s,  s,  s)                     # 왼쪽 위 앞
    ]

def generate_cube_edges():               # 큐브의 모서리를 생성하는 함수 정의
    return [                             # 큐브의 12개 모서리를 정의하는 꼭짓점 쌍 반환
        (0, 1),                          # 0번 꼭짓점과 1번 꼭짓점 연결 (오른쪽 뒤 아래 -> 오른쪽 뒤 위)
        (1, 2),                          # 1번 꼭짓점과 2번 꼭짓점 연결 (오른쪽 뒤 위 -> 왼쪽 뒤 위)
        (2, 3),                          # 2번 꼭짓점과 3번 꼭짓점 연결 (왼쪽 뒤 위 -> 왼쪽 뒤 아래)
        (3, 0),                          # 3번 꼭짓점과 0번 꼭짓점 연결 (왼쪽 뒤 아래 -> 오른쪽 뒤 아래)
        (4, 5),                          # 4번 꼭짓점과 5번 꼭짓점 연결 (오른쪽 앞 아래 -> 오른쪽 앞 위)
        (5, 7),                          # 5번 꼭짓점과 7번 꼭짓점 연결 (오른쪽 앞 위 -> 왼쪽 앞 위)
        (7, 6),                          # 7번 꼭짓점과 6번 꼭짓점 연결 (왼쪽 앞 위 -> 왼쪽 앞 아래)
        (6, 4),                          # 6번 꼭짓점과 4번 꼭짓점 연결 (왼쪽 앞 아래 -> 오른쪽 앞 아래)
        (0, 4),                          # 0번 꼭짓점과 4번 꼭짓점 연결 (오른쪽 뒤 아래 -> 오른쪽 앞 아래)
        (1, 5),                          # 1번 꼭짓점과 5번 꼭짓점 연결 (오른쪽 뒤 위 -> 오른쪽 앞 위)
        (2, 7),                          # 2번 꼭짓점과 7번 꼭짓점 연결 (왼쪽 뒤 위 -> 왼쪽 앞 위)
        (3, 6)                           # 3번 꼭짓점과 6번 꼭짓점 연결 (왼쪽 뒤 아래 -> 왼쪽 앞 아래)
    ]

def draw_cube(vertices, edges):          # 큐브를 그리는 함수 정의
    glBegin(GL_LINES)                    # 선 그리기 시작
    for edge in edges:                   # 각 모서리에 대해
        for vertex in edge:              # 모서리의 꼭짓점들에 대해
            glVertex3fv(vertices[vertex]) # 꼭짓점 좌표 설정
    glEnd()                              # 그리기 종료

def main():                              # 메인 함수 정의
    pygame.init()                        # Pygame 초기화
    display = (800, 600)                 # 창 크기 설정
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)  # OpenGL 창 생성
    gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)  # 3D 투시 설정
    glTranslatef(0.0, 0.0, -5)           # 카메라 위치 설정

    vertices = generate_cube_vertices(2)  # 크기가 2인 큐브 생성
    edges = generate_cube_edges()        # 큐브의 모서리 생성

    rot_x, rot_y = 25, 25                # 초기 카메라 회전 각도 설정
    mouse_dragging = False               # 마우스 드래그 상태 초기화
    last_pos = (0, 0)                    # 마지막 마우스 위치 초기화

    while True:                          # 무한 루프 시작
        for event in pygame.event.get(): # 이벤트 처리
            if event.type == pygame.QUIT: # 창 닫기 이벤트 처리
                pygame.quit()            # Pygame 종료
                sys.exit()               # 프로그램 종료
            elif event.type == MOUSEBUTTONDOWN:  # 마우스 버튼 눌림 이벤트 처리
                if event.button == 3:    # 오른쪽 마우스 버튼 눌림
                    mouse_dragging = True # 마우스 드래그 시작
                    last_pos = event.pos  # 마지막 마우스 위치 갱신
            elif event.type == MOUSEBUTTONUP:  # 마우스 버튼 떼기 이벤트 처리
                if event.button == 3:    # 오른쪽 마우스 버튼 떼기
                    mouse_dragging = False # 마우스 드래그 종료
            elif event.type == MOUSEMOTION:  # 마우스 이동 이벤트 처리
                if mouse_dragging:       # 마우스 드래그 중일 때
                    dx, dy = event.pos[0] - last_pos[0], event.pos[1] - last_pos[1]  # 마우스 이동 거리 계산
                    rot_x += dy * 0.1    # y축 회전 각도 갱신
                    rot_y += dx * 0.1    # x축 회전 각도 갱신
                    last_pos = event.pos  # 마지막 마우스 위치 갱신

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)  # 화면 지우기
        glLoadIdentity()               # 현재 변환 행렬을 단위 행렬로 초기화
        gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)  # 3D 투시 설정
        glTranslatef(0.0, 0.0, -5)     # 카메라 위치 설정
        glRotatef(rot_x, 1, 0, 0)      # x축 회전 적용
        glRotatef(rot_y, 0, 1, 0)      # y축 회전 적용

        draw_cube(vertices, edges)     # 큐브 그리기
        pygame.display.flip()          # 화면 업데이트
        pygame.time.wait(10)           # 잠시 대기

if __name__ == "__main__":             # 메인 함수 실행 조건
    main()                             # 메인 함수 실행

728x90
반응형

댓글