1

Pls I have been trying this for past few month but all prevail I tried alot of online resources to read and display OBJ file without MTl stuff all in vain, I write my codes still errors so I finally arrive at my self made code that can read obj file of any faces type e.g (v//vn)(v/by/vn)(v) I hope you understand this. After I read the file I got no error but rendering with pyopengl I got no error but the object didn't show. Pls check my obj loader code, and the opengl code in the screen with the result in another screenshot. Note I got no error I don't know if I wrote something wrong in the obj loader but pls check and help me pls. OBJ code:

from OpenGL.GL import *
from pyopengltk import OpenGLFrame
class OBJ:
    def __init__(self,filename):
    self.faces = []
    self.vertices = []
    with open(filename, 'r') as f:
        lines = f.readlines()
        #print(lines)
        if lines:
            for line in lines:
                if line[0] == 'v':
                    index1 = line.find(' ')
                    index2 = line.find(' ', index1+1)
                    index3 = line.find(' ', index2+1)

                    v1 = float(line[index1: index2])
                    v2 = float(line[index2: index3])
                    v3 = float(line[index3:])
                    self.vertices.append((v1,v2,v3))
                    #print(self.vertices)
        for line in open(filename, "r"):
            face = []
            texcoords = []
            norms = []
            if line.startswith('#'): continue
            values = line.split()
            #print(values)
            if not values: continue
            if values[0] == 'v':continue
            elif values[0] == 'vn':continue
            elif values[0] == 'vt':continue
            if values[0] == 'f':
                for v in values[1:]:
                    #print(len(v))
                    if len(v) == 4:
                        if ['/' for s in values[1:]]:
                            w = v.split('//')
                            face.append(int(w[0]))
                            norms.append(int(w[1]))
                            self.faces.extend(tuple((face, norms)))
                            #self.faces = [y for x in self.faces for y in x]
                            #print(self.faces)
                            glBegin(GL_QUADS)
                            glColor3f(0,1,1)
                            for surface in self.faces:
                                for vertex in surface:
                                    glVertex3fv(self.vertices[vertex])
                            glEnd
                        else:
                            self.faces.append(v)
                            glBegin(GL_QUADS)
                            glColor3f(0,1,1)
                            for surface in self.faces:
                                for vertex in surface:
                                    glVertex3fv(self.vertices[vertex])
                            glEnd
                            print(self.faces)
                    elif len(v) == 3:
                        w = v.split('/')
                        face.append(int(w[0]))
                        texcoords.append(int(w[1]))
                        norms.append(int(w[2]))
                        self.faces.append((face, norms, texcoord))
                        glBegin(GL_TRIANGLES)
                        glColor3f(0,1,1)
                        for surface in self.faces:
                            for vertex in surface:
                                glVertex3fv(self.vertices[vertex])
                        glEnd
                        #print('v/vt/vn')
                        print(self.faces)
#to run this code just use file path to any obj file on your pc
#OBJ('filename_path')
                    

Rendering code

import tkinter as tk
from OpenGL.GL import *
from OpenGL.GLU import *
from pyopengltk import OpenGLFrame
from obj import *

class frame(OpenGLFrame):

  def initgl(self):
        glViewport(0,0,self.width,self.height)
        glClearColor(0.902,0.902,1,0.0)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        #glOrtho(-10,10,-10,10,-10,10)
        gluPerspective(60, self.width/self.height,0.1,100.0)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_BLEND)
        glEnable(GL_CULL_FACE)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        
  
  def redraw(self):
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
        OBJ('C:\\Users\\DANIEL\\Desktop\\v-cam\\me.obj')
        #that is what I did here obj suff
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        gluLookAt(0,-10,0,0,0,0,1,0,20)
        

root = tk.Tk()
app = frame(root, width=900, height=600)
app.pack(fill=tk.BOTH,expand=tk.YES)
app.mainloop()

result screenshots

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • 1
    Are you really loading the object each frame? It seems to me that you are perhaps missing parentheses after `glEnd`? Do not post the codes as an image, that does not help anybody. If you want proper help, make a [mcve](https://stackoverflow.com/help/minimal-reproducible-example). – Quimby Jun 30 '20 at 11:35
  • Ok pls refresh the page I have add every necessary details – Lord_daniel Jun 30 '20 at 12:04
  • No, you did not. The indentation in obj constructor is wrong. There's no info about how to compile the program - the first file is obj.py? And when I run it, i (obviously) get `FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\DANIEL\\Desktop\\v-cam\\me.obj'`. The easier you make it for someone to run your code, the chance for someone to answer. Did you try to add the parentheses? That's definitely a mistake and part of the problem. – Quimby Jun 30 '20 at 12:16
  • *the better chance – Quimby Jun 30 '20 at 12:25
  • To run the code you use OBJ(filename) in the rendering part!,. In the filename input any obj file path on your PC. Check the code you will see ive add it – Lord_daniel Jun 30 '20 at 12:51

1 Answers1

0

I recommend to use the object loader which you have introduced in one of your previous questions (Pyopengl reading obj file).

Create an OBJ instance in initgl:

self.obj =  OBJ('C:\\Users\\DANIEL\\Desktop\\v-cam\\me.obj')

And use glCallList to draw the mesh in redraw.

glCallList(self.obj.gl_list)

Class frame:

class frame(OpenGLFrame):

    def initgl(self):
        glViewport(0,0,self.width,self.height)
        glClearColor(0.902,0.902,1,0.0)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        #glOrtho(-10,10,-10,10,-10,10)
        gluPerspective(60, self.width/self.height,0.1,100.0)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_BLEND)
        glEnable(GL_CULL_FACE)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        self.obj =  OBJ('C:\\Users\\DANIEL\\Desktop\\v-cam\\me.obj')
  
    def redraw(self):
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
        #that is what I did here obj suff
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        gluLookAt(0,-10,0,0,0,0,1,0,20) 

        glCallList(self.obj.gl_list)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174