PyOpenGL ничего не рисует после очистки

#python #opengl #pyopengl

#python #opengl #pyopengl

Вопрос:

Я использовал Glut для создания окна и хотел нарисовать треугольник, затем при нажатии кнопки перерисовать его, но после очистки окна я не могу рисовать снова. Что-то не так с глубиной буфера и битом буфера? Если я очистил его, нужно ли мне снова настроить оба в моей функции рисования?

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

Ответ №1:

Смотрите glutDisplayFunc :

[…] устанавливает обратный вызов отображения для текущего окна. […] Состояние повторного отображения для окна может быть задано либо явно путем вызова glutPostRedisplay, либо неявно в результате повреждения окна, о котором сообщает оконная система.

Фактически, треугольник рисуется 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()
 

Рисовать в зависимости от переменной drawTriangle в funcForUpdate :

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