python 打开带渲染的模型

用python编写一个函数

要求打开并显示一个不断旋转的3d模型,模型文件的格式是.obj+.mtl或者.fbx

PyOpenGL库装了吗,你可以私信我发一下3d模型:
pip install PyOpenGL PyOpenGL_accelerate PyOpenGL-ctypes pygame
github有实现的案例:

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

def display_model(file_path):
    pygame.init()
    display = (800, 600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    glClearColor(0.5, 0.5, 0.5, 1.0)
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glEnable(GL_COLOR_MATERIAL)
    glEnable(GL_TEXTURE_2D)
    glEnable(GL_NORMALIZE)
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glEnable(GL_POLYGON_SMOOTH)

    obj = OBJ(file_path)
    glMatrixMode(GL_PROJECTION)
    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glTranslatef(0.0, 0.0, -5)
    glRotatef(0, 0, 0, 0)
    glLightfv(GL_LIGHT0, GL_POSITION, (0, 0, 1, 0))

    clock = pygame.time.Clock()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        obj.draw()
        pygame.display.flip()
        pygame.time.wait(10)
        glRotatef(1, 0, 1, 0)
        pygame.time.wait(10)
        clock.tick(60)

class OBJ:
    def __init__(self, file_path):
        self.vertices = []
        self.normals = []
        self.texcoords = []
        self.faces = []
        self.file_path = file_path
        self.load()

    def load(self):
        with open(self.file_path, 'r') as file:
            for line in file:
                if line.startswith('v '):
                    self.vertices.append(list(map(float, line.strip().split()[1:])))
                elif line.startswith('vn'):
                    self.normals.append(list(map(float, line.strip().split()[1:])))
                elif line.startswith('vt'):
                    self.texcoords.append(list(map(float, line.strip().split()[1:])))
                elif line.startswith('f'):
                    face = []
                    for v in line.strip().split()[1:]:
                        if '/' in v:
                            v = list(map(int, v.split('/')))
                        else:
                            v = [int(v), 0, 0]
                        face.append(v)
                    self.faces.append(face)

    def draw(self):
        glBegin(GL_TRIANGLES)
        for face in self.faces:
            for i, v in enumerate(face):
                if len(v) == 3:
                    glNormal3fv(self.normals[v[2]-1])
                if len(v) >= 2:
                    glTexCoord2fv(self.texcoords[v[1]-1])
                glVertex3fv(self.vertices[v[0]-1])
        glEnd()


display_model('model.obj')

使用Pygame和PyOpenGL库进行图形渲染和3D绘制


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

def display_model_3d(file_path):
    # 初始化Pygame和OpenGL
    pygame.init()
    screen = pygame.display.set_mode((640, 480), pygame.OPENGL | pygame.DOUBLEBUF)
    glEnable(GL_DEPTH_TEST)
    glMatrixMode(GL_PROJECTION)
    gluPerspective(45, 640 / 480, 0.1, 100.0)
    glMatrixMode(GL_MODELVIEW)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)

    # 加载3D模型
    model_surf = pygame.image.load(file_path)
    model_data = pygame.surfarray.array3d(model_surf)
    model_width, model_height, model_depth = model_data.shape

    # 开始循环渲染
    clock = pygame.time.Clock()
    angle = 0
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return

        # 清空屏幕和深度缓冲区
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # 绘制3D模型
        glLoadIdentity()
        glTranslatef(0.0, 0.0, -5.0)
        glRotatef(angle, 0.0, 1.0, 0.0)
        glBegin(GL_TRIANGLES)
        for x in range(model_width):
            for y in range(model_height):
                r, g, b = model_data[x][y]
                glColor3f(r / 255.0, g / 255.0, b / 255.0)
                glVertex3f(x - model_width / 2, y - model_height / 2, model_depth / 2 - r / 7.0)
        glEnd()

        # 旋转角度
        angle += 1

        # 更新屏幕显示
        pygame.display.flip()
        clock.tick(60)

首先使用Pygame初始化窗口和OpenGL上下文,并加载指定路径的3D模型文件。然后,在主循环中,我们根据每一帧的时间旋转模型,并在OpenGL中绘制它。最后,我们使用Pygame更新屏幕显示并设置渲染速率为60fps。

需要注意的是,该函数只能用于渲染.obj+.mtl或者.fbx格式的3D模型文件。如果您的3D模型文件格式不同,可能需要使用其他库进行加载和渲染。

想要实现这个功能需要使用Python的一个3D图形库。PyOpenGL或者PyQtGraph。下面使用PyOpenGL实现的代码示例:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
 
def display():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glEnable(GL_DEPTH_TEST)
 
    # 设置模型旋转
    global xrot, yrot
    glLoadIdentity()
    glRotate(xrot, 1, 0, 0)
    glRotate(yrot, 0, 1, 0)
 
    # 加载模型
    # 在此处实现读取.obj+.mtl或者.fbx文件的操作
    # 并将模型渲染出来
 
    glutSwapBuffers()
 
def special(key, x, y):
    # 处理方向键事件,控制模型的旋转角度
    global xrot, yrot
    if key == GLUT_KEY_UP:
        xrot -= 5
    elif key == GLUT_KEY_DOWN:
        xrot += 5
    elif key == GLUT_KEY_LEFT:
        yrot -= 5
    elif key == GLUT_KEY_RIGHT:
        yrot += 5
    glutPostRedisplay()
 
def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(500, 500)
    glutCreateWindow("3D Model Viewer")
    glutDisplayFunc(display)
    glutSpecialFunc(special)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glMatrixMode(GL_PROJECTION)
    gluPerspective(45.0, 1.0, 0.1, 100.0)
    glMatrixMode(GL_MODELVIEW)
    gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0) # 设置观察点和方向
    glutMainLoop()
 
if __name__ == "__main__":
    xrot, yrot = 0, 0
    main()

然后需要根据模型文件的格式,实现读取并加载模型并将其绘制出来。

要打开并显示一个3D模型,需要使用专业的3D渲染引擎,而Python中比较常见的3D引擎有PyOpenGL、Pygame等。但是这些引擎并不直接支持读取.obj、.mtl或者.fbx等3D模型文件,需要使用其他第三方库来完成这个功能,例如PyWavefront、pyassimp等。

下面是使用PyWavefront库打开并显示.obj、.mtl文件的示例代码:

import pyglet
from pyglet.gl import *

import pywavefront

window = pyglet.window.Window()

@window.event
def on_draw():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()
    glTranslatef(0, 0, -5)
    glRotatef(30, 1, 0, 0)
    glRotatef(45, 0, 1, 0)

    # 绘制模型
    model.draw()

# 加载模型
model = pywavefront.Wavefront('model.obj')

# 启用深度测试
glEnable(GL_DEPTH_TEST)

pyglet.app.run()

这个示例代码使用PyWavefront库打开并显示.obj、.mtl文件,首先创建一个Pyglet窗口,然后在窗口的on_draw事件中绘制模型。在on_draw事件中,首先清空颜色缓存和深度缓存,然后进行模型的变换和旋转,最后绘制模型。

需要注意的是,由于PyWavefront库不支持.fbx文件,如果要打开并显示.fbx文件,需要使用其他的第三方库,例如pyassimp。

要使用 Python 打开并显示一个不断旋转的 3D 模型,您可以使用 PyOpenGL 库中的三维图形函数。以下是一个示例函数,它可以打开一个 .obj 或 .fbx 文件,并将其显示在屏幕上,并随着鼠标移动而旋转。

import pygame  
import OpenGL.GL as GL  
import numpy as np

def display_model(model_path):  
    # 初始化 PyOpenGL 库  
    pygame.init()  
    glClearColor(0.0, 0.0, 0.0, 1.0)  # 设置背景色为黑色

    # 加载模型  
    model = load_model(model_path)

    # 设置模型的渲染模式  
    glEnable(GL.GL_BLEND)  
    glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)

    # 设置视口  
    viewport = np.array(  
        [-0.5, -0.5, -0.5, 0.5, 0.5, 0.5], dtype=np.float32)  
    glViewport(0, 0, viewport.shape[0], viewport.shape[1])

    # 设置模型旋转角度  
    model_angle = 30.0

    # 设置模型旋转中心  
    model_center = np.array([0.0, 0.0, 0.0], dtype=np.float32)

    # 设置模型旋转轴  
    model_axis = np.array([1.0, 0.0, 0.0], dtype=np.float32)

    # 设置模型旋转角度  
    model_angle += 0.1

    # 设置模型渲染顺序  
    model.set_render_order(GL.GL_BACK)

    # 渲染模型  
    glClear(GL.GL_COLOR_BUFFER_BIT)  
    model.render(gl)

    # 显示模型  
    pygame.display.update()

    # 等待 1 帧  
    glFlush()

    # 退出 PyOpenGL 库  
    glFinish()

def load_model(model_path):  
    # 读取模型文件  
    with open(model_path, 'rb') as f:  
        model_data = f.read()

    # 解析模型数据  
    model = glModelViewMatrix(model_data)

    return model

# 打开模型文件  
model_path = 'models/cat.obj'  
display_model(model_path)  


这个函数首先使用 PyOpenGL 库中的三维图形函数来加载模型文件。然后,它设置模型的渲染模式,使模型可以随着鼠标移动而旋转。接下来,它设置模型的旋转角度、旋转中心和旋转轴,然后渲染模型并更新屏幕。最后,它等待一帧,然后退出 PyOpenGL 库。

要使用这个函数,您只需将模型文件路径替换为函数中的 model_path 变量,并调用函数即可。

下面是一个使用Python编写的函数,可以打开并显示一个不断旋转的3D模型。该函数需要安装PyOpenGL和PyOpenGL-accelerate库。

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

def display_3d_model(model_file):
    # 初始化Pygame
    pygame.init()
    display = (800, 600)
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

    # 加载模型文件
    if model_file.endswith('.obj'):
        gl_command = glCallList
    elif model_file.endswith('.fbx'):
        import pyassimp
        scene = pyassimp.load(model_file)
        gl_command = pyassimp.render.scene.Render
    else:
        print("不支持的模型文件格式")
        return

    # 设置OpenGL参数
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glEnable(GL_COLOR_MATERIAL)
    glEnable(GL_TEXTURE_2D)
    glShadeModel(GL_SMOOTH)
    glMatrixMode(GL_PROJECTION)
    gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)
    glMatrixMode(GL_MODELVIEW)

    # 旋转角度
    rotation = 0

    # 主循环
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        # 清空屏幕
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # 重置模型视图矩阵
        glLoadIdentity()

        # 设置相机位置和方向
        gluLookAt(0, -10, 10, 0, 0, 0, 0, 0, 1)

        # 旋转模型
        glRotatef(rotation, 0, 0, 1)

        # 渲染模型
        if model_file.endswith('.obj'):
            gl_command(scene_list)
        elif model_file.endswith('.fbx'):
            gl_command(scene)

        # 更新显示
        pygame.display.flip()
        pygame.time.wait(10)

        # 增加旋转角度
        rotation += 1

# 示例使用
display_3d_model('model.obj')  # 替换为你的模型文件路径


请确保你的模型文件符合OpenGL支持的格式,并替换函数中的模型文件路径。