2

I'm trying to load and display an obj file (model.obj), however, I can't seem to find a way to display its textures (from .mtl file) using PyopenGL. I know how to load the model, but the textures don't work.

Here is my current code so far:

main.py:

import pygame
from pygame.locals import *

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

import math
import time

pygame.init()
display = (400, 300)
screen = pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glShadeModel(GL_SMOOTH)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)

glEnable(GL_LIGHT0)
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5, 1])
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1])

sphere = gluNewQuadric() 

glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)

glMatrixMode(GL_MODELVIEW)
gluLookAt(0, -8, 0, 0, 0, 0, 0, 0, 1)
viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()

def loadOBJ(model):
    scene = pywavefront.Wavefront(model, 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)]
    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()

# init mouse movement and center mouse on screen
displayCenter = [screen.get_size()[i] // 2 for i in range(2)]
mouseMove = [0, 0]
pygame.mouse.set_pos(displayCenter)

camX = 0
camY = 0
camZ = 0
translation = (0, 0, 0)

up_down_angle = 0.0
paused = False
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN:
                run = False
            if event.key == pygame.K_PAUSE or event.key == pygame.K_p:
                paused = not paused
                pygame.mouse.set_pos(displayCenter) 
        if not paused: 
            if event.type == pygame.MOUSEMOTION:
                mouseMove = [event.pos[i] - displayCenter[i] for i in range(2)]
            pygame.mouse.set_pos(displayCenter)    

    if not paused:
        # get keys
        keypress = pygame.key.get_pressed()
        #mouseMove = pygame.mouse.get_rel()

        # init model view matrix
        glLoadIdentity()

        # apply the look up and down
        up_down_angle += mouseMove[1]*0.1
        glRotatef(up_down_angle, 1.0, 0.0, 0.0)

        # init the view matrix
        glPushMatrix()
        glLoadIdentity()

        # apply the movment
        if keypress[pygame.K_w]:
            #glTranslatef(0,0,0.1)
            camY += 0.1
        if keypress[pygame.K_s]:
            #glTranslatef(0,0,-0.1)
            camY += -0.1
        if keypress[pygame.K_d]:
            #glTranslatef(-0.1,0,0)
            camX += 0.1
        if keypress[pygame.K_a]:
            #glTranslatef(0.1,0,0)
            camX += -0.1
        if keypress[pygame.K_q]:
            #glTranslatef(0,-0.1,0)
            camZ += -0.1
        if(keypress[pygame.K_e]):
            #glTranslatef(0,0.1,0)
            camZ += 0.1

        #print("X = " + str(camX))
        #print("Y = " + str(camY))
        #print("Z = " + str(camZ))

        # apply the left and right rotation
        glRotatef(mouseMove[0]*0.1, 0.0, 1.0, 0.0)

        # multiply the current matrix by the get the new view matrix and store the final vie matrix 
        glMultMatrixf(viewMatrix)
        viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)

        # apply view matrix
        glPopMatrix()
        glMultMatrixf(viewMatrix)

        glLightfv(GL_LIGHT0, GL_POSITION, [1, -1, 1, 0])

        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

        glPushMatrix()

        glColor4f(0.5, 0.5, 0.5, 1)
        glBegin(GL_QUADS)
        glVertex3f(-10, -10, -2)
        glVertex3f(10, -10, -2)
        glVertex3f(10, 10, -2)
        glVertex3f(-10, 10, -2)
        glEnd()

        #glTranslatef(camX, camY, camZ)
        glColor4f(0.5, 0.2, 0.2, 1)
        gluSphere(sphere, 1.0, 32, 16)

        glTranslatef(camX + 0.2, camY + 0.3, camZ)
        glColor4f(0.2, 0.2, 0.5, 1)
        loadOBJ("./model.obj")

        glPopMatrix()

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

pygame.quit()


I have tried many tutorials online, however, many don't work with Python 3 or don't work in a way which would suit my needs.

Bluebot
  • 166
  • 15

0 Answers0