当前位置: 首页 > article >正文

使用Python和OpenGL实现3D立方体的交互式显示

简介

本文将介绍如何使用Python、Pygame和OpenGL创建一个可交互的3D立方体。这个立方体支持旋转、缩放等操作,是理解3D图形编程的良好入门示例。

技术栈

  • Python
  • Pygame:用于创建窗口和处理用户输入
  • OpenGL:用于3D图形渲染
  • PyOpenGL:Python的OpenGL绑定

核心功能

  1. 3D立方体的渲染
  2. 自动旋转
  3. 键盘控制旋转
  4. 鼠标滚轮缩放
  5. 视角重置

实现细节

1. 立方体的定义

首先,我们需要定义立方体的顶点和面:

vertices = (
    (1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1),
    (1, -1, 1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1)
)

surfaces = (
    (0,1,2,3), # 后面
    (3,2,7,6), # 左面
    (6,7,5,4), # 前面
    (4,5,1,0), # 右面
    (1,5,7,2), # 上面
    (4,0,3,6)  # 下面
)

2. 绘制函数

立方体的绘制包括实心面和边框:

def draw_cube():
    # 绘制实心面(绿色)
    glColor3f(0.0, 1.0, 0.0)
    glBegin(GL_QUADS)
    for surface in surfaces:
        for vertex in surface:
            glVertex3fv(vertices[vertex])
    glEnd()
    
    # 绘制边框(白色)
    glColor3f(1.0, 1.0, 1.0)
    glBegin(GL_LINES)
    for surface in surfaces:
        for i in range(4):
            glVertex3fv(vertices[surface[i]])
            glVertex3fv(vertices[surface[(i+1)%4]])
    glEnd()

3. 交互控制

实现了多种交互方式:

  • 旋转控制

    • 方向键:手动控制旋转方向
    • 空格键:切换自动旋转
    • +/-键:调整旋转速度
  • 视角控制

    • 鼠标滚轮:缩放
    • R键:重置视角

4. 关键技术点

OpenGL初始化
glEnable(GL_DEPTH_TEST)  # 启用深度测试
glDisable(GL_LIGHTING)   # 禁用光照
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)  # 设置透视
矩阵变换
glLoadIdentity()  # 重置矩阵
glTranslatef(0.0, 0.0, zoom)  # 平移
glRotatef(rot_speed, 0, 1, 0)  # 旋转

使用说明

  1. 控制方式

    • 方向键:控制旋转方向
    • 空格键:开启/关闭自动旋转
    • 鼠标滚轮:缩放
    • R键:重置视角
    • +/-键:调整旋转速度
  2. 运行环境

    pip install pygame PyOpenGL PyOpenGL_accelerate
    

完整代码

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

vertices = (
    (1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1),
    (1, -1, 1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1)
)

surfaces = (
    (0,1,2,3), # 后面
    (3,2,7,6), # 左面
    (6,7,5,4), # 前面
    (4,5,1,0), # 右面
    (1,5,7,2), # 上面
    (4,0,3,6)  # 下面
)

def draw_cube():
    glLineWidth(5.0)
    
    # 绘制实心面
    glDisable(GL_LIGHTING)
    glColor3f(0.0, 1.0, 0.0)  # 绿色
    
    glBegin(GL_QUADS)
    for surface in surfaces:
        for vertex in surface:
            glVertex3fv(vertices[vertex])
    glEnd()
    
    # 绘制边框
    glColor3f(1.0, 1.0, 1.0)  # 白色
    glBegin(GL_LINES)
    for surface in surfaces:
        for i in range(4):
            glVertex3fv(vertices[surface[i]])
            glVertex3fv(vertices[surface[(i+1)%4]])
    glEnd()

def main():
    pygame.init()
    display = (800, 600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    
    # 基础设置
    glEnable(GL_DEPTH_TEST)
    glDisable(GL_LIGHTING)
    
    # 设置视角
    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
    glTranslatef(0.0, 0.0, -5)
    
    # 初始化变量
    rot_speed = 1  # 旋转速度
    auto_rotate = True  # 自动旋转开关
    zoom = -5  # 缩放程度
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return
            # 鼠标滚轮控制缩放
            elif event.type == pygame.MOUSEWHEEL:
                zoom += event.y * 0.5
                glLoadIdentity()
                gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
                glTranslatef(0.0, 0.0, zoom)
            # 空格键切换自动旋转
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    auto_rotate = not auto_rotate
                # R键重置视角
                elif event.key == pygame.K_r:
                    zoom = -5
                    glLoadIdentity()
                    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
                    glTranslatef(0.0, 0.0, zoom)

        keys = pygame.key.get_pressed()
        
        # 方向键控制旋转
        if keys[pygame.K_LEFT]:
            glRotatef(rot_speed, 0, -1, 0)
        if keys[pygame.K_RIGHT]:
            glRotatef(rot_speed, 0, 1, 0)
        if keys[pygame.K_UP]:
            glRotatef(rot_speed, -1, 0, 0)
        if keys[pygame.K_DOWN]:
            glRotatef(rot_speed, 1, 0, 0)
        
        # 调整旋转速度
        if keys[pygame.K_PLUS] or keys[pygame.K_KP_PLUS]:
            rot_speed = min(rot_speed + 0.1, 5.0)
        if keys[pygame.K_MINUS] or keys[pygame.K_KP_MINUS]:
            rot_speed = max(rot_speed - 0.1, 0.1)
            
        # 自动旋转
        if auto_rotate:
            glRotatef(rot_speed, 3, 1, 1)
        
        glClearColor(0.0, 0.0, 0.2, 1.0)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        
        draw_cube()
        
        pygame.display.flip()
        pygame.time.wait(10)

if __name__ == "__main__":
    main()

总结

这个示例展示了如何使用Python和OpenGL创建一个基础的3D图形应用。通过这个例子,我们可以学习到:

  1. OpenGL的基本使用
  2. 3D图形的矩阵变换
  3. 用户输入处理
  4. 实时渲染循环的实现

这些知识点都是3D图形编程的基础,掌握它们将有助于开发更复杂的3D应用。


http://www.kler.cn/a/429282.html

相关文章:

  • 数字化时代,传统代理模式的变革之路
  • Windows图形界面(GUI)-QT-C/C++ - QT 对话窗口
  • MySQL 事务
  • 港科夜闻 | 香港科大与微软亚洲研究院签署战略合作备忘录,推动医学健康教育及科研协作...
  • 【matlab】matlab知识点及HTTP、TCP通信
  • 低代码独特架构带来的编译难点及多线程解决方案
  • 康托展开和逆康托展开
  • java-数组—acwing
  • 【C语言】数据库事物的ACID属性
  • 在Ubuntu上使用IntelliJ IDEA:开启你的Java开发之旅!
  • osi七层模型
  • 电子商务人工智能指南 6/6 - 人工智能生成的产品图像
  • Linux DNS之进阶篇bind-chroot企业级部署方式
  • Electron小案例
  • 超详细搭建PhpStorm+PhpStudy开发环境
  • git提交时出现merge branch main of xxx
  • Win11 配置 TeXstudio 编辑器教程
  • C# Winform飞机大战小游戏源码
  • docker的网络类型和使用方式
  • 【计算机图形学】实验2:橡皮筋技术及拾取操作
  • 运维排错系列:Excel上传失败,在剪切板有大量信息。是否保存其内容...
  • 基于yolov10的反光衣和安全帽检测系统,支持图像检测,视频检测和实时摄像检测功能(pytorch框架,python源码)
  • ensp实验-vrrp多网关配置
  • 【Android】结构型设计模式—代理模式、装饰模式、外观模式、享元模式
  • golang实现单例日志对象
  • Centos在2024年6月30日停止维护后如何换yum源安装组件