Search code examples
openglpyopenglglulookat

pyopengl gluLookAt() clarity


I'm trying to understand what I'm doing wrong displaying two different cubes with a grid through the x and z axis. I'm using gluLookAt() to view both cubes at the same angle. I'm very confused why the first viewport does not show the grid but the second one does. Here's my code and an example picture of why I'm confused.

def draw(c1, c2):
    glClearColor(0.7, 0.7, 0.7, 0)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glBegin(GL_LINES)
    for edge in grid_edges:
        for vertex in edge:
            glColor3fv((0.0, 0.0, 0.0))
            glVertex3fv(grid_vertices[vertex])
    glEnd()

    glViewport(0, 0, WIDTH // 2, HEIGHT)
    glLoadIdentity()
    gluPerspective(90, (display[0] / display[1]) / 2, 0.1, 50.0) 
    gluLookAt(c1.center_pos[0], c1.center_pos[1], c1.center_pos[2] + 8, c1.center_pos[0], c1.center_pos[1], c1.center_pos[2], 0, 1, 0)


    glPushMatrix()
    glTranslatef(c1.center_pos[0], c1.center_pos[1], c1.center_pos[2])
    glRotatef(c1.rotation[0], c1.rotation[1], c1.rotation[2], c1.rotation[3])
    glTranslatef(-c1.center_pos[0], -c1.center_pos[1], -c1.center_pos[2])
    glBegin(GL_LINES)
    for edge in c1.edges:
        for vertex in edge:
            glColor3fv((0, 0, 0))
            glVertex3fv(c1.vertices[vertex])
    glEnd()
    glPopMatrix()

    glViewport(WIDTH // 2, 0, WIDTH // 2, HEIGHT)
    glLoadIdentity()
    gluPerspective(90, (display[0] / display[1]) / 2, 0.1, 50.0) 
    gluLookAt(c2.center_pos[0], c2.center_pos[1], c2.center_pos[2] + 8, c2.center_pos[0], c2.center_pos[1], c2.center_pos[2], 0, 1, 0)
    glPushMatrix()
    glTranslatef(c2.center_pos[0], c2.center_pos[1], c2.center_pos[2])
    glRotatef(c2.rotation[0], c2.rotation[1], c2.rotation[2], c2.rotation[3])
    glTranslatef(-c2.center_pos[0], -c2.center_pos[1], -c2.center_pos[2])
    glBegin(GL_LINES)
    for edge in c2.edges:
        for vertex in edge:
            glColor3fv((0, 0, 0))
            glVertex3fv(c2.vertices[vertex])
    glEnd()
    glPopMatrix()


Solution

  • OpenGL is a state machine. Once a state is set, it persists even beyond frames. This means if you change the viewport or set a matrix, that viewport and matrix are the same at the beginning of the next frame. These states are not "reset" from one frame to the next. You need to set the viewport and set the identity matrix at the beginning of draw:

    def draw(c1, c2):
        glClearColor(0.7, 0.7, 0.7, 0)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    
        glViewport(0, 0, WIDTH, HEIGHT)
        glLoadIdentity()
        glBegin(GL_LINES)
        for edge in grid_edges:
            for vertex in edge:
                glColor3fv((0.0, 0.0, 0.0))
                glVertex3fv(grid_vertices[vertex])
        glEnd()
    
        # [...]