Search code examples
pythonpygamepyopengl

PyOpenGl Pygame window freezes when run


I am using PyOpenGl for the first time and watched this YouTube tutorial about it. Here is the video: https://www.youtube.com/watch?v=R4n4NyDG2hI&t=1464s

When I try the code however, pygame opens up and moves one frame and then it freezes and does not stop loading. I am not sure if this is because of the system that I am using or the version of python that I am using.

I have a 11-6 inch 2012 MacBook Air and am using python 2.7.15. The reason that I am using python 2 instead of python 3 is because when I try and pip3 install PyOpenGl, it gives me an error.

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
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),
        )
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():
        global edges
        glBegin(GL_LINES)
        for edges in edges:
                for vertex in edges:
                        glVertex3fv(verticies[vertex])
        glEnd()
def main():
        pygame.init()
        display = (800,600)
        pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
        gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
        glTranslatef(0.0, 0.0, -5)
        glRotatef(20, 3, 1, 1)
        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)
                Cube()
                pygame.display.flip()
                pygame.time.wait(10)
main()

Another thing that happens is that when I run the program, IDLE gives me this error message:

Traceback (most recent call last):
  File "/Users/SplatM4n/Desktop/First3DGraphics.py", line 73, in                 <module>
    main()
  File "/Users/SplatM4n/Desktop/First3DGraphics.py", line 66, in main
    Cube()
  File "/Users/SplatM4n/Desktop/First3DGraphics.py", line 44, in Cube
    for vertex in edges:
TypeError: 'int' object is not iterable

I also have a feeling that this is part of the problem so please any kind of help is appriciated.

Thanks, SplatM4n


Solution

  • As shown in the tutorial video, the rotation matrix has to be applied inside the main loop.

    glTranslatef(0.0, 0.0, -5)
        while True:
            clock.tick(60)
            for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                            pygame.quit()
                            quit()
    
            glRotatef(1, 3, 1, 1)
    

    Note, glRotatef does not only generate a rotation matrix. It also multiplies the current matrix by the new rotation matrix. This causes that the cube is continuously and progressively rotated by 1 degree in every frame.
    If the glRotatef is done outside the loop, then only a single rotation is applied to the cube. After that the scene appears to be frozen.

    See the example, where I applied the changes to your original application:

    import pygame
    from pygame.locals import *
    from OpenGL.GL import *
    from OpenGL.GLU import *
    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))
    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():
        global edges
        glBegin(GL_LINES)
        for edge in edges:
            for vertex in edge:
                glVertex3fv(verticies[vertex])
        glEnd()
    
    def main():
        pygame.init()
        display = (800,600)
        pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
        gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
        glTranslatef(0.0, 0.0, -5)
        while True:
            for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                            pygame.quit()
                            quit()
    
            glRotatef(1, 3, 1, 1) # <--------------- rotate inside the main loop
    
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
            Cube()
            pygame.display.flip()
            pygame.time.wait(10)
    main()