Oh no! Where's the JavaScript?
Your Web browser does not have JavaScript enabled or does not support JavaScript. Please enable JavaScript on your Web browser to properly view this Web site, or upgrade to a Web browser that does support JavaScript.

OpenGL OBJ viewer using PyQt5 and PyOpenGL in Python

we will create an OpenGL OBJ viewer using PyQt5 and PyOpenGL in Python. This viewer will support color and lighting to make the 3D models look more realistic.

### Introduction
To start, ensure you have the required packages installed: `PyQt5`, `PyOpenGL`, and `numpy`. You can install these using pip.

pip install PyQt5 PyOpenGL numpy

### Code Overview

First, we import the necessary libraries.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QFileDialog
from PyQt5.QtCore import QTimer
from PyQt5.QtOpenGL import QGLWidget
from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np

### Loading OBJ Files

We define a function to load the OBJ file. This function reads the vertices and faces from the file and returns them as numpy arrays.

def load_obj(filename):
    vertices = []
    faces = []
    with open(filename, 'r') as f:
        for line in f:
            if line.startswith('v '):
                vertices.append(list(map(float, line.strip().split()[1:])))
            elif line.startswith('f '):
                face = [int(val.split('/')[0]) - 1 for val in line.strip().split()[1:]]
    return np.array(vertices, dtype=np.float32), np.array(faces, dtype=np.int32)

### OpenGL Widget

Next, we create the `OpenGLWidget` class, inheriting from `QGLWidget`. This class will handle the OpenGL context and rendering.

class OpenGLWidget(QGLWidget):
    def __init__(self, parent=None):
        super(OpenGLWidget, self).__init__(parent)
        self.vertices = None
        self.faces = None
        self.timer = QTimer(self)
        self.timer.start(16)  # Approximately 60 FPS

### Initializing OpenGL

The `initializeGL` method sets up the OpenGL context, enabling depth testing and lighting.

    def initializeGL(self):
        glLightfv(GL_LIGHT0, GL_POSITION, [1, 1, 1, 0])
        glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
        glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0])
        glLightfv(GL_LIGHT0, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
        glLightfv(GL_LIGHT1, GL_POSITION, [-1, -1, -1, 0])
        glLightfv(GL_LIGHT1, GL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
        glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0])
        glLightfv(GL_LIGHT1, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
        glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, [0.5, 0.5, 0.5, 1.0])
        glMaterialfv(GL_FRONT, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
        glMaterialf(GL_FRONT, GL_SHININESS, 50)
        gluPerspective(45, 1.33, 0.1, 50.0)
        glTranslatef(0.0, 0.0, -5)

### Drawing the Model

The `paintGL` method clears the screen and calls the `draw_model` method if vertices and faces are loaded. The `draw_model` method uses OpenGL commands to render the model.

    def paintGL(self):
        if self.vertices is not None and self.faces is not None:

    def draw_model(self):
        for face in self.faces:
            for vertex in face:
                glColor3fv([0.8, 0.3, 0.3])  # Red color

### Updating the View

The `updateGL` method rotates the model and updates the view.

    def updateGL(self):
        glRotatef(1, 3, 1, 1)  # Rotate the object

### Loading OBJ Files

The `load_obj_file` method is used to load the OBJ file into the OpenGL widget.

    def load_obj_file(self, filename):
        self.vertices, self.faces = load_obj(filename)

### Main Window

Next, we create the `MainWindow` class. This class creates the main application window with an OpenGL widget and a button to open OBJ files.

class MainWindow(QMainWindow):
    def __init__(self):
        self.setWindowTitle('OpenGL OBJ Viewer')
        self.setGeometry(100, 100, 800, 600)
        self.opengl_widget = OpenGLWidget(self)
        self.button = QPushButton('Open OBJ File', self)
        layout = QVBoxLayout()
        container = QWidget()
    def open_file_dialog(self):
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getOpenFileName(self, "Open OBJ File", "", "OBJ Files (*.obj);;All Files (*)", options=options)
        if fileName:

### Running the Application

Finally, we create an instance of the `QApplication`, create the main window, and start the application loop.

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()

### Conclusion

And that's it! We now have a fully functional OpenGL OBJ viewer with color and lighting using PyQt5 and PyOpenGL in Python. You can open OBJ files, and the viewer will render them with realistic lighting and shading.

caa July 01 2024 103 reads 0 comments Print


Leave a Comment

Please Login to Post a Comment.
  • No Comments have been Posted.

Sign In
Not a member yet? Click here to register.
Forgot Password?