Search code examples
pythonrotationcubepyopenglcoordinate-transformation

How to rotate two wire frame cubes on different axis using classes and pyopengl


I am trying to figure out how to rotate two 3D cubes on different axis. I can create two cubes, and I can rotate both cubes in the same direction, but when I try and rotate them in different directions it seems like it is just mixing the two rotations to form a new axis of rotation for both cubes. Also I am new to Python and to Object Oriented Programming. Thanks

Here is my Code.

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


class cubeClass:
    def __init__(self):

        self.rotation = [0,0,0,0]

        self.verticies =[
            (1, -1, -1),
            (1, 1, -1),
            (-1, 1, -1),
            (-1, -1, -1),
            (1, -1, 1),
            (1, 1, 1),
            (-1, -1, 1),
            (-1, 1, 1)
            ]

        self.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)
            )

    def cube(self):

        glBegin(GL_LINES)
        for self.edge in self.edges:
            for self.vertex in self.edge:
                glVertex3fv(self.verticies[self.vertex])
        glEnd()

        glRotatef(self.rotation[0],self.rotation[1],
                  self.rotation[2],self.rotation[3])
        print(self.rotation)

def main():
    pygame.init()
    display = (800,600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)

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

    cube1 = cubeClass()
    cube1.rotation= [1,1,0,0]

    cube2 = cubeClass()
    cube2.rotation = [1,0,1,0]

    glTranslatef(0.0,0.0, -5)

    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)

        cube1.cube()  
        cube2.cube()

        pygame.display.flip()

        pygame.time.wait(10)
        #time.sleep(.04)

main()    

Solution

  • OpenGL operations like glRotatef manipulate the top most element of the OpenGL matrix stack. Use glPushMatrix and glPopMatrix to push matrices on and pop matrices from the matrix stack. glMatrixMode specify the current matrix for the matrix operations.
    (see Legacy OpenGL)
    The matrix which defines the location and orientation of the mesh is the model view matrix.
    (see Transform the modelMatrix)

    You have to set the rotation separately for each cube and you have to progressively increment the rotation angle. Adapt your code like this:

    def cube(self):
    
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glRotatef(self.rotation[0],self.rotation[1],
                  self.rotation[2],self.rotation[3])
    
        glBegin(GL_LINES)
        for self.edge in self.edges:
            for self.vertex in self.edge:
                glVertex3fv(self.verticies[self.vertex])
        glEnd()
    
        print(self.rotation)
    
        glPopMatrix()
        self.rotation[0] = self.rotation[0] + 1