Search code examples
openglglfwpyopengl

I can't make working keyCallback function in OpenGL and glfw


import glfw
from OpenGL.GL import *
import numpy as np

currentMode = GL_LINE_LOOP

def render(currentMode):


def key_callback(window, key, scancode, action, mods):
    if key==glfw.KEY_1:
        if action==glfw.PRESS:
            currentMode = GL_POINTS
    elif key==glfw.KEY_2:
        if action==glfw.PRESS:
            currentMode = GL_LINES
    elif key==glfw.KEY_3:
        if action==glfw.PRESS:
            currentMode = GL_LINE_STRIP

while not glfw.window_should_close(window):
    glfw.poll_events()
    render(currentMode)
    glfw.swap_buffers(window)
    print(currentMode)
glfw.terminate()

I try to change primitive type to use render function's parameter. But, It doesn't work. What should I do?


Solution

  • You missed the global statement in key_callback:

    def key_callback(window, key, scancode, action, mods):
        global currentMode # <--- THIS IS MISSING
       
        if key==glfw.KEY_1:
            if action==glfw.PRESS:
                currentMode = GL_POINTS
        # [...]
    
    

    The variable currentMode exists twice. It is a variable in global namespace, and local variable in the scope of the function key_callback. Use the global statement to interpreted currentMode as global and to write to the global variable currentMode with key_callback.

    Of course the same applies to the main function, too:

    def main():
        global currentMode
        # [...]
    

    Furthermore you have to clear the framebuffer in render:

    def render(currentMode):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    

    See the example:

    import glfw
    from OpenGL.GL import *
    import numpy as np
    
    def render(currentMode):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()
        
        print(currentMode)
        glBegin(currentMode)
        #Draw Something
        glVertex2f(-0.5, -0.5)
        glVertex2f(0.5, 0.5)
        glVertex2f(-0.5, 0.5)
        glEnd()
    
    def key_callback(window, key, scancode, action, mods):
        global currentMode
        if key==glfw.KEY_1:
            if action==glfw.PRESS:
                currentMode = GL_POINTS
        elif key==glfw.KEY_2:
            if action==glfw.PRESS:
                currentMode = GL_LINES
        elif key==glfw.KEY_3:
            if action==glfw.PRESS:
                currentMode = GL_LINE_STRIP
        
    def main():
        global currentMode
    
        if not glfw.init():
            return
        window = glfw.create_window(480, 480, "Test", None, None)
        
        if not window:
            glfw.terminate()
            return
        glfw.make_context_current(window)
        glfw.set_key_callback(window, key_callback)
        glfw.swap_interval(1)    
    
        while not glfw.window_should_close(window):
            glfw.poll_events()
            render(currentMode)
            glfw.swap_buffers(window)
        glfw.terminate()
            
    if __name__ == "__main__":
        currentMode = GL_LINE_LOOP
        main()