简介
本文将介绍如何使用Python、Pygame和OpenGL创建一个可交互的3D立方体。这个立方体支持旋转、缩放等操作,是理解3D图形编程的良好入门示例。
技术栈
- Python
- Pygame:用于创建窗口和处理用户输入
- OpenGL:用于3D图形渲染
- PyOpenGL:Python的OpenGL绑定
核心功能
- 3D立方体的渲染
- 自动旋转
- 键盘控制旋转
- 鼠标滚轮缩放
- 视角重置
实现细节
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) # 旋转
使用说明
-
控制方式:
- 方向键:控制旋转方向
- 空格键:开启/关闭自动旋转
- 鼠标滚轮:缩放
- R键:重置视角
- +/-键:调整旋转速度
-
运行环境:
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.5glLoadIdentity()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 = -5glLoadIdentity()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图形应用。通过这个例子,我们可以学习到:
- OpenGL的基本使用
- 3D图形的矩阵变换
- 用户输入处理
- 实时渲染循环的实现
这些知识点都是3D图形编程的基础,掌握它们将有助于开发更复杂的3D应用。