PyOpenGL: в обратном вызове glutTimerFunc отсутствует требуемый параметр «значение»

Используя PyOpenGL, я пытаюсь создать простой треугольник, который меняет цвет при каждом вызове обновления, и я пытаюсь использовать для этого glutTimerFunc(...).

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

import random

def display(value):
    v1 = [-.25,0]
    v2 = [0,.25]
    v3 = [.25, 0]
    r = random.randint(0,255)
    g = random.randint(0,255)
    b = random.randint(0,255)
    glClear(GL_COLOR_BUFFER_BIT)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(-1,1,-1,1,-1,1)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glBegin(GL_TRIANGLES)

    glColor3b(r,g,b)
    glVertex2f(v1[0], v1[1])
    glVertex2f(v2[0], v2[1])
    glVertex2f(v3[0], v3[1])

    glEnd()
    glFlush()

    glutTimerFunc(1000, display, 5)
    glutPostRedisplay()

if __name__ == '__main__':
    glutInit()
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutInitWindowSize(500,500)
    glutCreateWindow("First Shape")
    glutDisplayFunc(display)
    glutMainLoop()

Это ошибка, которую я получаю...

Traceback (most recent call last):
File "_ctypes/callbacks.c", line 232, in 'calling callback function'
TypeError: display() missing 1 required positional argument: 'value'

Я попытался передать «значение» и поместить его в список параметров для отображения (), но безуспешно.


person Snow24    schedule 12.09.2018    source источник


Ответы (1)


Функция обратного вызова, требуемая glutDisplayFunc, не имеет параметра, но функция обратного вызова, необходимая для glutTimerFunc, имеет параметр on. Таким образом, вы не можете использовать одну и ту же функцию для обоих.
Возможно следующее:

def timer(value):
    display()

def display()

    glutTimerFunc(1000, timer, 5)

Но это не решит вашу проблему, потому что glutPostRedisplay отмечает текущий окно, требующее повторного отображения, и приводит к тому, что функция обратного вызова display, которая устанавливается glutDisplayFunc, называется.

Если вы хотите изменить цвет по времени, то создайте функцию таймера, которая устанавливает новый цвет и перезапускает таймер:

r = 255
g = 255
b = 255

def timer(value):
    global r, b, g
    r = random.randint(0,255)
    g = random.randint(0,255)
    b = random.randint(0,255)
    glutTimerFunc(1000, timer, 5)

Удалите инициализацию таймера из функции display

def display():
    global r, b, g
    v1 = [-.25,0]
    v2 = [0,.25]
    v3 = [.25, 0]
    glClear(GL_COLOR_BUFFER_BIT)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(-1,1,-1,1,-1,1)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glBegin(GL_TRIANGLES)

    glColor3b(r,g,b)
    glVertex2f(v1[0], v1[1])
    glVertex2f(v2[0], v2[1])
    glVertex2f(v3[0], v3[1])

    glEnd()
    glFlush()

    glutPostRedisplay()

Но вызовите функцию timer один раз при запуске:

if __name__ == '__main__':
    glutInit()
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutInitWindowSize(500,500)
    glutCreateWindow("First Shape")
    glutDisplayFunc(display)
    timer(0);
    glutMainLoop()
person Rabbid76    schedule 12.09.2018