Search code examples
pythonopenglpyglet

pyglet window.flip() not updating


I'm drawing a circle and some text with pyglet. I'd like it to update after a keypres, but instead on calling window.flip() the second time, the window is just empty. Any suggestions are appreciated.

from math import *
from pyglet.gl import *

window = pyglet.window.Window()


def make_circle(x_pos, y_pos, radius, numPoints):
    verts = []

    glMatrixMode(GL_PROJECTION)
    glOrtho(0, 640, 0, 480, -1, 1)
    glMatrixMode(GL_MODELVIEW)

    glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
    glColor3f(1, 1, 0)
    for i in range(numPoints):
        angle = radians(float(i) / numPoints * 360.0)
        x = radius * cos(angle) + x_pos
        y = radius * sin(angle) + y_pos
        verts += [x, y]
    circle = pyglet.graphics.vertex_list(numPoints, ('v2f', verts))
    circle.draw(GL_LINE_LOOP)


def text(x, y, text):
    label = pyglet.text.Label(text, font_size=36,
                              x=x, y=y, anchor_x='left', anchor_y='bottom',
                              color=(255, 123, 255, 255))
    label.draw()


make_circle(5, 5, 100, 10)
text(10, 10, 'Test1')
text(30, 30, 'Text2')

window.flip()
input()

make_circle(5, 5, 22, 10)
text(23, 10, 'This text does not appear')
text(30, 23, 'Neither does this one')
window.flip()
input()

Solution

  • If you don't use the default event loop, then you've to do the steps of the event loop your self. It is not sufficient to call window.flip().
    Befor the drawing you've to call pyglet.clock.tick() to signify that one frame has passed and window.dispatch_events() to poll the operating system event queue for new events and call attached event handlers.
    Note, Since the events are dispatched manually, it is not necessary to set the projection matrix.

    See also Dispatching events manually

    e.g.:

    from math import *
    from pyglet.gl import *
    
    def make_circle(x_pos, y_pos, radius, numPoints):
        verts = []
    
        glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
        glColor3f(1, 1, 0)
        for i in range(numPoints):
            angle = radians(float(i) / numPoints * 360.0)
            x = radius * cos(angle) + x_pos
            y = radius * sin(angle) + y_pos
            verts += [x, y]
        circle = pyglet.graphics.vertex_list(numPoints, ('v2f', verts))
        circle.draw(GL_LINE_LOOP)
    
    
    def text(x, y, text):
        label = pyglet.text.Label(text, font_size=36,
                                  x=x, y=y, anchor_x='left', anchor_y='bottom',
                                  color=(255, 123, 255, 255))
        label.draw()
    
    window = pyglet.window.Window()
    # make OpenGL context current
    window.switch_to()
    
    # signify that one frame has passed
    pyglet.clock.tick()
    # poll the operating system event queue
    window.dispatch_events()
    
    make_circle(5, 5, 100, 10)
    text(10, 10, 'Test1')
    text(30, 30, 'Text2')
    
    # swap buffers
    window.flip()
    
    input()
    
    # signify that one frame has passed
    pyglet.clock.tick()
    # poll the operating system event queue
    window.dispatch_events()
    
    make_circle(5, 5, 22, 10)
    text(23, 10, 'This text does not appear')
    text(30, 23, 'Neither does this one')
    
    # swap buffers
    window.flip()
    
    input()