Snow24
Snow24

Reputation: 337

PyOpenGL: glutTimerFunc callback missing required param 'value'

Using PyOpenGL, I am trying to create a simple triangle that changes colour on every refresh call and I'm trying to use glutTimerFunc(...) to do this.

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

This is the error I am getting...

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

I have tried passing 'value' and placing it in the parameter list for display() with no luck.

Upvotes: 2

Views: 1105

Answers (1)

Rabbid76
Rabbid76

Reputation: 210909

The callback function required by glutDisplayFunc has no paramter, but the callback function required by glutTimerFunc has on parameter. So you can't use the same function for both.
Something like the following would be possibe:

def timer(value):
    display()

def display()

    glutTimerFunc(1000, timer, 5)

But that wont solve your issue, because glutPostRedisplay marks the current window as needing to be redisplayed and causes that the display callback function, which is set by glutDisplayFunc, is called.

If you want to change the color by time, then create a timer function, which sets a new color and restarts the timer:

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)

Remove the timer initialization form the display function

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

But call the timer function once at startup:

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

Upvotes: 2

Related Questions