【Python库】OpenGL完整安装步骤

该文章已生成可运行项目,

一、环境准备

1、适用系统:Windows,MacOS,Linux

2、适用Python版本:Python3

3、前提条件:Python环境

二、安装步骤

1、安装命令

pip install  PyOpenGL  -i   https://pypi.tuna.tsinghua.edu.cn/simple

三、使用与测试

1、使用测试环境Python版本:Python3.9

2、测试代码

代码1:

from OpenGL.GL import *
from OpenGL.GLUT import *

def draw():
    glClear(GL_COLOR_BUFFER_BIT)
    glBegin(GL_TRIANGLES)
    glColor3f(1,0,0); glVertex2f(-0.6,-0.6)
    glColor3f(0,1,0); glVertex2f(0.6,-0.6)
    glColor3f(0,0,1); glVertex2f(0,0.6)
    glEnd()
    glutSwapBuffers()

glutInit()
glutCreateWindow(b"OpenGL Test")  # 字节串标题
glutDisplayFunc(draw)
glutMainLoop()

运行结果:

代码2:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import math
import time
import sys
import numpy as np

# 全局变量
window_width = 800
window_height = 600
rotation_x = 0.0
rotation_y = 0.0
zoom_level = -8.0
mouse_dragging = False
prev_mouse_x = 0
prev_mouse_y = 0
animation_enabled = True
current_time = 0.0
render_mode = 0  # 0:填充, 1:线框, 2:点
light_enabled = True
texture_enabled = False
current_shape = 0  # 0:立方体, 1:球体, 2:茶壶
texture_id = None
current_mouse_button = None  # 跟踪当前按下的鼠标按钮


# 纹理数据(简单的棋盘格纹理)
def create_checker_texture():
    texture_data = []
    for i in range(64):
        for j in range(64):
            c = 255 if ((i & 8) ^ (j & 8)) else 127
            texture_data.extend([c, c, c, 255])  # RGBA
    return (GLubyte * len(texture_data))(*texture_data)


# 初始化函数
def init():
    global texture_id

    print("=== OpenGL复杂测试环境信息 ===")
    print(f"OpenGL版本: {glGetString(GL_VERSION).decode('utf-8')}")
    print(f"显卡供应商: {glGetString(GL_VENDOR).decode('utf-8')}")
    print(f"渲染器: {glGetString(GL_RENDERER).decode('utf-8')}")
    print(f"GLSL版本: {glGetString(GL_SHADING_LANGUAGE_VERSION).decode('utf-8')}")

    # 设置基本OpenGL状态
    glEnable(GL_DEPTH_TEST)
    glClearColor(0.1, 0.1, 0.2, 1.0)  # 深蓝色背景

    # 设置光照
    setup_lighting()

    # 设置材质
    setup_material()

    # 创建纹理
    setup_texture()

    print("\n=== 控制说明 ===")
    print("鼠标左键拖拽: 旋转场景")
    print("鼠标右键拖拽: 缩放场景")
    print("空格键: 切换动画")
    print("R键: 重置视角")
    print("L键: 切换光照")
    print("T键: 切换纹理")
    print("M键: 切换渲染模式")
    print("S键: 切换形状")
    print("ESC键: 退出程序")


# 设置光照
def setup_lighting():
    # 环境光
    ambient_light = [0.2, 0.2, 0.2, 1.0]
    # 漫反射光
    diffuse_light = [0.8, 0.8, 0.8, 1.0]
    # 光源位置
    light_position = [2.0, 2.0, 2.0, 1.0]

    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light)
    glLightfv(GL_LIGHT0, GL_POSITION, light_position)

    glEnable(GL_LIGHT0)
    glEnable(GL_LIGHTING)


# 设置材质
def setup_material():
    # 材质环境光反射
    mat_ambient = [0.7, 0.7, 0.7, 1.0]
    # 材质漫反射
    mat_diffuse = [0.8, 0.8, 0.8, 1.0]
    # 材质镜面反射
    mat_specular = [1.0, 1.0, 1.0, 1.0]
    # 镜面反射指数
    mat_shininess = [100.0]

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient)
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse)
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular)
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess)


# 设置纹理
def setup_texture():
    global texture_id

    # 生成纹理ID
    texture_id = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture_id)

    # 设置纹理参数
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    # 创建并上传纹理数据
    texture_data = create_checker_texture()
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, texture_data)


# 绘制彩色立方体
def draw_color_cube():
    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],
        # 上面 (蓝色)
        [-1, 1, -1], [-1, 1, 1], [1, 1, 1], [1, 1, -1],
        # 下面 (黄色)
        [-1, -1, -1], [1, -1, -1], [1, -1, 1], [-1, -1, 1],
        # 右面 (洋红色)
        [1, -1, -1], [1, 1, -1], [1, 1, 1], [1, -1, 1],
        # 左面 (青色)
        [-1, -1, -1], [-1, -1, 1], [-1, 1, 1], [-1, 1, -1]
    ]

    colors = [
        [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0],  # 红
        [0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0],  # 绿
        [0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1],  # 蓝
        [1, 1, 0], [1, 1, 0], [1, 1, 0], [1, 1, 0],  # 黄
        [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1],  # 洋红
        [0, 1, 1], [0, 1, 1], [0, 1, 1], [0, 1, 1]  # 青
    ]

    indices = [
        [0, 1, 2, 3],  # 前面
        [4, 5, 6, 7],  # 后面
        [8, 9, 10, 11],  # 上面
        [12, 13, 14, 15],  # 下面
        [16, 17, 18, 19],  # 右面
        [20, 21, 22, 23]  # 左面
    ]

    glBegin(GL_QUADS)
    for i, face in enumerate(indices):
        for vertex_idx in face:
            if not light_enabled:
                glColor3fv(colors[vertex_idx])
            glVertex3fv(vertices[vertex_idx])
    glEnd()


# 绘制纹理立方体
def draw_textured_cube():
    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],  # 后面
        [-1, 1, -1], [-1, 1, 1], [1, 1, 1], [1, 1, -1],  # 上面
        [-1, -1, -1], [1, -1, -1], [1, -1, 1], [-1, -1, 1],  # 下面
        [1, -1, -1], [1, 1, -1], [1, 1, 1], [1, -1, 1],  # 右面
        [-1, -1, -1], [-1, -1, 1], [-1, 1, 1], [-1, 1, -1]  # 左面
    ]

    tex_coords = [
        [0, 0], [1, 0], [1, 1], [0, 1],
        [0, 0], [0, 1], [1, 1], [1, 0],
        [0, 1], [0, 0], [1, 0], [1, 1],
        [0, 1], [1, 1], [1, 0], [0, 0],
        [0, 0], [0, 1], [1, 1], [1, 0],
        [1, 0], [0, 0], [0, 1], [1, 1]
    ]

    indices = [
        [0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11],
        [12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]
    ]

    glBegin(GL_QUADS)
    for face in indices:
        for i, vertex_idx in enumerate(face):
            glTexCoord2fv(tex_coords[vertex_idx])
            glVertex3fv(vertices[vertex_idx])
    glEnd()


# 绘制球体
def draw_sphere():
    slices = 20
    stacks = 20
    radius = 1.0

    for i in range(stacks):
        lat0 = math.pi * (-0.5 + float(i) / stacks)
        z0 = math.sin(lat0)
        zr0 = math.cos(lat0)

        lat1 = math.pi * (-0.5 + float(i + 1) / stacks)
        z1 = math.sin(lat1)
        zr1 = math.cos(lat1)

        glBegin(GL_QUAD_STRIP)
        for j in range(slices + 1):
            lng = 2 * math.pi * float(j) / slices
            x = math.cos(lng)
            y = math.sin(lng)

            glNormal3f(x * zr0, y * zr0, z0)
            glVertex3f(x * zr0 * radius, y * zr0 * radius, z0 * radius)

            glNormal3f(x * zr1, y * zr1, z1)
            glVertex3f(x * zr1 * radius, y * zr1 * radius, z1 * radius)
        glEnd()


# 绘制场景
def draw_scene():
    global current_time

    # 清空缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    # 设置模型视图矩阵
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    # 设置相机位置
    gluLookAt(0, 0, zoom_level,  # 相机位置
              0, 0, 0,  # 观察点
              0, 1, 0)  # 上方向

    # 应用旋转
    glRotatef(rotation_x, 1, 0, 0)
    glRotatef(rotation_y, 0, 1, 0)

    # 动画旋转
    if animation_enabled:
        current_time = time.time()
        glRotatef(current_time * 30, 0, 1, 0)  # Y轴旋转
        glRotatef(current_time * 20, 1, 0, 0)  # X轴旋转

    # 设置渲染模式
    if render_mode == 1:
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
    elif render_mode == 2:
        glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)
    else:
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

    # 启用/禁用光照
    if light_enabled:
        glEnable(GL_LIGHTING)
    else:
        glDisable(GL_LIGHTING)

    # 启用/禁用纹理
    if texture_enabled and texture_id:
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, texture_id)
    else:
        glDisable(GL_TEXTURE_2D)
        if not light_enabled:
            glColor3f(0.8, 0.8, 0.8)  # 默认颜色

    # 绘制选定的形状
    if current_shape == 0:
        if texture_enabled:
            draw_textured_cube()
        else:
            draw_color_cube()
    elif current_shape == 1:
        draw_sphere()
    elif current_shape == 2:
        glutSolidTeapot(1.0)

    # 重置多边形模式
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

    # 交换缓冲区
    glutSwapBuffers()


# 窗口调整大小回调
def reshape(width, height):
    global window_width, window_height
    window_width = width
    window_height = height

    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45, width / height, 0.1, 100.0)
    glMatrixMode(GL_MODELVIEW)


# 空闲回调(用于动画)
def idle():
    glutPostRedisplay()


# 鼠标点击回调
def mouse(button, state, x, y):
    global mouse_dragging, prev_mouse_x, prev_mouse_y, current_mouse_button

    if state == GLUT_DOWN:
        mouse_dragging = True
        prev_mouse_x = x
        prev_mouse_y = y
        current_mouse_button = button
    else:
        mouse_dragging = False
        current_mouse_button = None


# 鼠标移动回调 - 修正版
def motion(x, y):
    global rotation_x, rotation_y, zoom_level, prev_mouse_x, prev_mouse_y

    if mouse_dragging:
        dx = x - prev_mouse_x
        dy = y - prev_mouse_y

        # 根据鼠标按钮决定行为
        if current_mouse_button == GLUT_RIGHT_BUTTON:
            # 右键拖拽缩放
            zoom_level += dy * 0.1
        else:
            # 左键拖拽旋转
            rotation_x += dy * 0.5
            rotation_y += dx * 0.5

        prev_mouse_x = x
        prev_mouse_y = y
        glutPostRedisplay()


# 键盘回调
def keyboard(key, x, y):
    global animation_enabled, rotation_x, rotation_y, zoom_level
    global render_mode, light_enabled, texture_enabled, current_shape

    key = key.decode('utf-8').lower()

    if key == ' ':
        # 空格键切换动画
        animation_enabled = not animation_enabled
        print(f"动画: {'启用' if animation_enabled else '禁用'}")
    elif key == 'r':
        # R键重置视角
        rotation_x = 0.0
        rotation_y = 0.0
        zoom_level = -8.0
        print("视角已重置")
    elif key == 'l':
        # L键切换光照
        light_enabled = not light_enabled
        print(f"光照: {'启用' if light_enabled else '禁用'}")
    elif key == 't':
        # T键切换纹理
        texture_enabled = not texture_enabled
        print(f"纹理: {'启用' if texture_enabled else '禁用'}")
    elif key == 'm':
        # M键切换渲染模式
        render_mode = (render_mode + 1) % 3
        modes = ["填充", "线框", "点"]
        print(f"渲染模式: {modes[render_mode]}")
    elif key == 's':
        # S键切换形状
        current_shape = (current_shape + 1) % 3
        shapes = ["立方体", "球体", "茶壶"]
        print(f"当前形状: {shapes[current_shape]}")
    elif key == '\x1b':  # ESC键
        print("程序退出")
        sys.exit(0)

    glutPostRedisplay()


# 特殊键回调(方向键等)
def special_keys(key, x, y):
    global rotation_x, rotation_y

    if key == GLUT_KEY_UP:
        rotation_x -= 5
    elif key == GLUT_KEY_DOWN:
        rotation_x += 5
    elif key == GLUT_KEY_LEFT:
        rotation_y -= 5
    elif key == GLUT_KEY_RIGHT:
        rotation_y += 5

    glutPostRedisplay()


# 主函数
def main():
    # 初始化GLUT
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
    glutInitWindowSize(window_width, window_height)
    glutInitWindowPosition(100, 100)
    glutCreateWindow(b"OpenGL Complex Test - 3D Graphics Demo")

    # 初始化OpenGL
    init()

    # 注册回调函数
    glutDisplayFunc(draw_scene)
    glutReshapeFunc(reshape)
    glutIdleFunc(idle)
    glutMouseFunc(mouse)
    glutMotionFunc(motion)
    glutKeyboardFunc(keyboard)
    glutSpecialFunc(special_keys)

    print("\n=== 测试开始 ===")
    print("使用控制说明中的按键进行交互")

    # 进入主循环
    glutMainLoop()


if __name__ == "__main__":
    main()

运行结果:

茶壶:

球体:

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值