Search code examples
pyopengl

How can I use glDebugMessageCallback in PyOpenGL


I am new to Python and PyOpenGL. Trying to port my C++ code to PyOpenGL, I attempted to use the debug messaging feature and defined the following code.

def onDebugMessage(*args, **kwargs):
    println('args = {0}, kwargs = {1}'.format(args, kwargs))

def initializeGL(self):
    super().initializeGL()
    glEnable(GL_DEBUG_OUTPUT)
    glDebugMessageCallback(onDebugMessage, None)
    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, None, GL_TRUE)
    glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG, GL_DEBUG_TYPE_MARKER, 0, GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Starting debug messaging service")

Unfortunately, it crashes at the call to glDebugMessageCallback.

The error message reads:

Traceback (most recent call last):
File "debug.py", line 12, in initializeGL
  glDebugMessageCallback(onDebugMessage, None)
File "C:\Python34\lib\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
    return self( *args, **named )
ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected WinFunctionType instance instead of function

Does this mean that I need to feed native function and that it is not possible to do with Python callback code?

Thanks for your advice.


Solution

  • I just ran into the same error. Here's a self-contained example of the solution I came up with:

    from OpenGL import GL as gl
    import cyglfw3 as glfw
    
    def cb_dbg_msg(source, msg_type, msg_id, severity, length, raw, user):
        msg = raw[0:length]
        print 'debug', source, msg_type, msg_id, severity, msg
    
    glfw.Init()
    glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 2)
    glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    glfw.WindowHint(glfw.OPENGL_DEBUG_CONTEXT, True)
    
    window = glfw.CreateWindow(640, 480, "test")
    glfw.MakeContextCurrent(window)
    
    # Install our debug message callback
    gl.glDebugMessageCallback(gl.GLDEBUGPROC(cb_dbg_msg), None)
    
    # This shader program doesn't exist so you can expect the debug
    # message callback to receive an error message
    gl.glUseProgram(1234)
    

    And an example of running it:

    $ virtualenv venv
    $ . venv/bin/activate
    $ pip install cyglfw3==3.1.0.2 PyOpenGL==3.1.0
    $ python gldbg.py 
    debug 33350 33356 2 37190 GL_INVALID_VALUE in glUseProgram
    Traceback (most recent call last):
      File "gldbg.py", line 22, in <module>
        gl.glUseProgram(1234)
      File "/home/nicholasbishop/pygldbg/venv/lib/python2.7/site-packages/OpenGL/platform/baseplatform.py", line 402, in __call__
        return self( *args, **named )
      File "/home/nicholasbishop/pygldbg/venv/lib/python2.7/site-packages/OpenGL/error.py", line 232, in glCheckError
        baseOperation = baseOperation,
    OpenGL.error.GLError: GLError(
        err = 1281,
        description = 'invalid value',
        baseOperation = glUseProgram,
        cArguments = (1234,)
    )