python - PyOpenGL 如何导入 obj 文件?

标签 python opengl blender pyopengl wavefront

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


scene = pywavefront.Wavefront('Handgun_obj.obj')

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),
    )

edges = (
    (0,1),
    (0,3),
    (0,4),
    (2,1),
    (2,3),
    (2,7),
    (6,3),
    (6,4),
    (6,7),
    (5,1),
    (5,4),
    (5,7)
    )

colors = (
    (1,0,0),
    (0,1,0),
    (0,0,1),
    (0,1,0),
    (1,1,1),
    (0,1,1),
    (1,0,0),
    (0,1,0),
    (0,0,1),
    (1,0,0),
    (1,1,1),
    (0,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 Cube():
    glBegin(GL_QUADS)
    for surface in surfaces:
        x = 0
        for vertex in surface:
            x += 1
            glColor3fv(colors[x])
            glVertex3fv(vertices[vertex])
    glEnd()

    glBegin(GL_LINES) #tells OpenGL dass code erhalten wird der als line-drawing code benutzt wird
    for edge in edges:
        for vertex in edge:
            glVertex3fv(vertices[vertex])
    glEnd()

def main():
        pygame.init()
        display = (800, 600)
        pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
        gluPerspective(45, (display[0] / display[1]), 1, 500.0)
        glTranslatef(0.0, 0.0, -10)

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

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        glTranslatef(-0.5,0,0)
                    if event.key == pygame.K_RIGHT:
                        glTranslatef(0.5,0,0)
                    if event.key == pygame.K_UP:
                        glTranslatef(0,1,0)
                    if event.key == pygame.K_DOWN:
                        glTranslatef(0,-1,0)


            glRotatef(1, 5, 1, 1)
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
            Cube()
            pygame.display.flip()
            pygame.time.wait(10)

main()

现在我想将场景添加到带有立方体的窗口中或将其替换为任何内容

有人可以告诉我如何实现这一目标吗?

找不到太多关于如何在 opengl 和 pygame 中正确使用波前的信息

opengl 编程新手

所以我想我必须从场景中添加新顶点,对吗?

我现在想添加 obj 以了解如何将 blender 模型导入游戏

谢谢

最佳答案

当您阅读Wavefront .obj file时,设置关键字参数collect_faces = True 。这会导致为每个网格收集三角形面数据。:
(参见PyWavefront)

scene = pywavefront.Wavefront('Handgun_obj.obj', collect_faces=True)

计算场景框。顶点包含在scene.vertices中。每个顶点都是具有 3 个分量(x、y、z 坐标)的元组:

scene_box = (scene.vertices[0], scene.vertices[0])
for vertex in scene.vertices:
    min_v = [min(scene_box[0][i], vertex[i]) for i in range(3)]
    max_v = [max(scene_box[1][i], vertex[i]) for i in range(3)]
    scene_box = (min_v, max_v)

计算一个平移,将对象的中心移动到原点,并计算一个比例,将对象缩放到定义的大小(scaled_size):

scene_trans    = [-(scene_box[1][i]+scene_box[0][i])/2 for i in range(3)]

scaled_size    = 5
scene_size     = [scene_box[1][i]-scene_box[0][i] for i in range(3)]
max_scene_size = max(scene_size)
scene_scale    = [scaled_size/max_scene_size for i in range(3)]

每个场景都由网格 (scene.mesh_list) 组成,每个网格都有三角形面 (mesh.faces)。每个 fac 都是一个由 3 个独立的数组组成的数组,它们引用顶点数组 [scene.vertices]。创建一个函数,用于设置比例和平移并在嵌套循环中绘制模型:

def Model():
    glPushMatrix()
    glScalef(*scene_scale)
    glTranslatef(*scene_trans)

    for mesh in scene.mesh_list:
        glBegin(GL_TRIANGLES)
        for face in mesh.faces:
            for vertex_i in face:
                glVertex3f(*scene.vertices[vertex_i])
        glEnd()

    glPopMatrix()

另请参阅PyGame and OpenGL immediate mode (Legacy OpenGL)

<小时/>

最小示例( Stanford bunny ):

repl.it/@Rabbid76/pygame-opengl-wavefront-obj

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

scene = pywavefront.Wavefront('bunny.obj', collect_faces=True)

scene_box = (scene.vertices[0], scene.vertices[0])
for vertex in scene.vertices:
    min_v = [min(scene_box[0][i], vertex[i]) for i in range(3)]
    max_v = [max(scene_box[1][i], vertex[i]) for i in range(3)]
    scene_box = (min_v, max_v)

scene_size     = [scene_box[1][i]-scene_box[0][i] for i in range(3)]
max_scene_size = max(scene_size)
scaled_size    = 5
scene_scale    = [scaled_size/max_scene_size for i in range(3)]
scene_trans    = [-(scene_box[1][i]+scene_box[0][i])/2 for i in range(3)]

def Model():
    glPushMatrix()
    glScalef(*scene_scale)
    glTranslatef(*scene_trans)

    for mesh in scene.mesh_list:
        glBegin(GL_TRIANGLES)
        for face in mesh.faces:
            for vertex_i in face:
                glVertex3f(*scene.vertices[vertex_i])
        glEnd()

    glPopMatrix()

def main():
        pygame.init()
        display = (800, 600)
        pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
        gluPerspective(45, (display[0] / display[1]), 1, 500.0)
        glTranslatef(0.0, 0.0, -10)

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

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        glTranslatef(-0.5,0,0)
                    if event.key == pygame.K_RIGHT:
                        glTranslatef(0.5,0,0)
                    if event.key == pygame.K_UP:
                        glTranslatef(0,1,0)
                    if event.key == pygame.K_DOWN:
                        glTranslatef(0,-1,0)

            glRotatef(1, 5, 1, 1)
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
            Model()
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

            pygame.display.flip()
            pygame.time.wait(10)

main()

关于python - PyOpenGL 如何导入 obj 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59923419/

相关文章:

python - 为什么调用带有 -m 选项的模块会将 sys.path[0] 设置为空字符串?

opengl - 为 OpenGL 实现细节级别算法

c++ - OpenGL 3.2 为什么我会收到 glTexStorage3D 的 INVALID_ENUM 错误?

blender - 搅拌器:我所有的图像都呈现黑色。怎么修?

python - Blender Python `bpy` `__init__.py` ,显然是从不存在的模块 `_bpy` 导入的

python - 使用 FloatLayout 在 Kivy 中重叠 TextInputs

python - 如何在没有符号链接(symbolic link)的情况下使用 git 和 buidout 构建具有共享子应用程序的 python 项目

Python - 将字符串对象转换为 ctypes (unsigned char *)

java - 我在使用 open gl 和 glfw (LWJGL) 将模型渲染到窗口时遇到问题

python - 如果在后台执行脚本,如何在 Blender Python 上使用旋转运算符?