Search code examples
pythonopenglpyopengl

PyOpenGL not drawing anything after clearing


I used Glut for making window and wanted to draw triangle, then on click button redraw it, but after clearing window I can't draw again. Does something wrong with Buffer depth and buffer bit? If I cleared it do I need to setup both again in my draw function?

def drawSomething():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()
    glTranslatef(-2.5, 0.5, -6.0)
    glColor3f( 1.0, 1.5, 0.0 )
    glPolygonMode(GL_FRONT, GL_FILL)
    glBegin(GL_TRIANGLES)
    glVertex3f(2.0,-1.2,0.0)
    glVertex3f(2.6,0.0,0.0)
    glVertex3f(2.9,-1.2,0.0)
    glEnd()
    glFlush()


def funcForUpdate():
    glClearColor(0.0, 0.0, 0.0, 0)
    glClear(GL_COLOR_BUFFER_BIT)
    glEnable(GL_TEXTURE_2D)
    glBegin(GL_QUADS)
    glTexCoord2f(0.0, 0.0)
    glVertex2f(0.0, 0.0)
    glTexCoord2f(0.0, 1.0)
    glVertex2f(0.0, width)
    glTexCoord2f(1.0, 1.0)
    glVertex2f(height, width)
    glTexCoord2f(1.0, 0.0)
    glVertex2f(height, 0.0)
    glEnd()
    glFlush()

def resizeUpdateFunc(width, height):
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    gluOrtho2D(0.0, width, 0.0, height)
    
def handleKey(bkey,x,y):
    key = bkey.decode("utf-8")
    if key == "a":
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        drawSomething()
        glFlush()
        
    

glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize(width, height)
glutInitWindowPosition(0, 0)
glutCreateWindow("test") 
drawSomething()
glutDisplayFunc(funcForUpdate)
glutReshapeFunc(resizeUpdateFunc)
glutKeyboardFunc(handleKey) 
glutMainLoop()

Solution

  • See glutDisplayFunc:

    [...] sets the display callback for the current window. [...] The redisplay state for a window can be either set explicitly by calling glutPostRedisplay or implicitly as the result of window damage reported by the window system.

    In fact, a triangle is drawn in drawSomething, but it is immediately overdrawn in funcForUpdate.

    Add a state drawTriangle and set the state in handleKey:

    drawTriangle = False
    
    def handleKey(bkey, x, y):
        global drawTriangle
        key = bkey.decode("utf-8")
        if key == "a":
            drawTriangle = not drawTriangle
            glutPostRedisplay()
    

    Draw depending on the variable drawTriangle in funcForUpdate:

    def funcForUpdate():
        glClearColor(0, 0, 0, 0)
        glClear(GL_COLOR_BUFFER_BIT)
    
        # [...]
    
        if drawTriangle:
            # [...]
    
        glFlush()
    

    A complete example:

    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
    
    drawTriangle = False
    
    def funcForUpdate():
        glClearColor(0, 0, 0, 0)
        glClear(GL_COLOR_BUFFER_BIT)
        glColor3f(1, 1, 0)
        glBegin(GL_QUADS)
        glVertex2f(0.0, 0.0)
        glVertex2f(0, height)
        glVertex2f(width, height)
        glVertex2f(width, 0)
        glEnd()
    
        if drawTriangle:
            glPushMatrix()
            glLoadIdentity()
            glTranslate(width/2, height/2, 0)
            glColor3f(1, 0, 0)
            glBegin(GL_TRIANGLES)
            glVertex3f(-width/4, -height/4, 0)
            glVertex3f(width/4, -height/4, 0)
            glVertex3f(width/4, height/4, 0)
            glEnd()
            glPopMatrix()
        glFlush()
    
    def resizeUpdateFunc(width, height):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluOrtho2D(0.0, width, 0.0, height)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
    
    def handleKey(bkey, x, y):
        global drawTriangle
        key = bkey.decode("utf-8")
        if key == "a":
            drawTriangle = not drawTriangle
            glutPostRedisplay()
            
    
    width, height = 320, 200
    
    glutInit()
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutInitWindowSize(width, height)
    glutInitWindowPosition(0, 0)
    glutCreateWindow("test") 
    glutDisplayFunc(funcForUpdate)
    glutReshapeFunc(resizeUpdateFunc)
    glutKeyboardFunc(handleKey) 
    glutMainLoop()