清除后 PyOpenGL 不绘制任何内容

PyOpenGL not drawing anything after clearing

我用 Glut 制作 window 想画三角形,然后点击按钮重新画它,但是清除后 window 我不能再画了。缓冲区深度和缓冲区位有问题吗?如果我清除了它,我是否需要在我的绘图功能中再次设置?

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()

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.

其实在drawSomething画了一个三角形,但是在funcForUpdate马上透支了。

添加一个状态drawTriangle并在handleKey中设置状态:

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

根据funcForUpdate中的变量drawTriangle绘制:

def funcForUpdate():
    glClearColor(0, 0, 0, 0)
    glClear(GL_COLOR_BUFFER_BIT)

    # [...]

    if drawTriangle:
        # [...]

    glFlush()

一个完整的例子:

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()