尝试调用未定义的函数glDetachShader

时间:2017-07-26 20:37:44

标签: pyopengl

在我的python代码中,我有以下几行:

def __del__(self):
    for shader in self.shaders:
        GL.glDetachShader(self.program, shader)
        GL.glDeleteShader(shader)

    GL.glDeleteProgram(self.program)

但是当代码执行这些行时,我最终会看到这个问题:

Exception ignored in: <bound method Shader.__del__ of <__main__.Shader object at 0x0000016E4AFFE550>>
Traceback (most recent call last):
  File "C:\Germano\Dev\Gartic\tests\modernOpenGL2.py", line 214, in __del__
    GL.glDetachShader(self.program, shader)
  File "C:\Users\Germano\AppData\Local\Programs\Python\Python36\lib\site-packages\OpenGL\platform\baseplatform.py", line 407, in __call__
    self.__name__, self.__name__,
OpenGL.error.NullFunctionError: Attempt to call an undefined function glDetachShader, check for bool(glDetachShader) before calling

发生了什么事?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

__del__可能仅在OpenGL上下文被销毁后被称为 ,导致NullFunctionError。如果在销毁窗口之后,程序/着色器类存活到应用程序的生命周期结束时,当Python解释器调用所有自定义删除函数时,所有gl*函数调用基本上都不可用。在这种情况下,您可以依赖上下文破坏来删除所有与OpenGL相关的对象。

但是,当上下文仍然存在时,在应用程序的生命周期内不再使用着色器/程序对象时,释放内存仍然是一个好主意(请参阅{{3更多信息)!我个人在删除纹理或缓冲区时也遇到了类似的问题。我建议将代码包装在try/except块中,所以它看起来像这样:

def __del__(self):
    try:
        #if the context is alive, you want to try and delete shader/program stuff manually
        #this could be triggered with e.g. `del my_awesome_program_class_object`
        for shader in self.shaders:
            GL.glDetachShader(self.program, shader)
            GL.glDeleteShader(shader)
        GL.glDeleteProgram(self.program)
    except OpenGL.error.NullFunctionError as error:
        pass#do nothing; context already deleted my shader/program stuff!

希望这种解释能让事情变得更加清晰,因为NullFunctionErrors在不知道为什么的情况下首先发现它们绝对是难以理解的!