如何在 python opengl 应用程序中使用 renderdoc

How to use renderdoc in python opengl apps

我正在尝试弄清楚如何使用 renderdoc 来调试我的一些 python opengl 应用程序。目前,我的一些 python opengl 测试正在使用 pyopengl(glut) 或 pyqt。这里有几个最小的测试显示了如何初始化 glut 或 pyqt:

过剩

from ctypes import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

if __name__ == "__main__":
    def display():
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()
        glutSwapBuffers()

    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
    glutInitWindowSize(800, 600)
    glutInitWindowPosition(800, 100)

    glutCreateWindow(b'TestGLUT')
    glutDisplayFunc(display)

    glClearColor(1.0, 0.0, 0.0, 0.0)

    glutMainLoop()

如果我使用可执行路径(python路径)和命令行参数( -u path_to_the_glut_example.py) 我会得到这个输出:

PYQT

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

from PyQt5 import QtWidgets
from PyQt5.QtOpenGL import QGLWidget

class Foo(QGLWidget):
    def __init__(self, *args, **kwargs):
        super(Foo, self).__init__(*args, **kwargs)

    def initializeGL(self):
        glClearColor(1.0, 0.0, 0.0, 0.0)

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

if __name__ == "__main__":
    global app
    app = QtWidgets.QApplication(sys.argv)
    ex = Foo()
    ex.move(800,100)
    ex.resize(800, 600)
    ex.show()

    sys.exit(app.exec_())

如果我使用可执行路径(python路径)和命令行参数( -u path_to_the_pyqt_example.py) 我会得到这个输出:

所以,我不知道 glutCreateWindow (glut) 和 initializeGL (pyqt) 是如何初始化 opengl 上下文的在幕后,但 renderdoc 似乎不喜欢他们创建 opengl 上下文的方式。我想知道如何使用 glut 和 pyqt 测试来制作 renderdoc。

旁注:

glGetIntegerv(GL_MAJOR_VERSION) ---> 4
glGetIntegerv(GL_MINOR_VERSION) ---> 5

所以,这个问题不是关于上下文 opengl 版本(这已经足够好了),而是关于它的创建方式。

官方 GLUT 不支持任何现代 OpenGL 上下文。然而,freeglut 对此有一些扩展,PyOpenGL 也有 support those extensions。由于 freeglut 是当今开发最活跃的 GLUT 实现,并且也可用于所有主要桌面平台,因此依赖 freeglut 是相当安全的。您需要做的就是添加

glutInitContextVersion(3,2) # at least 3.2 is required, you can use a higer version when needed
glutInitContextProfile(GLUT_CORE_PROFILE)
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE)

在创建 window.

之前

但并不是说您的代码现在会在 glLoadIdentity 上生成 GL 错误,因为核心配置文件 OpenGL 中根本不提供这个已弃用的函数。

如果你想走Qt路线,概念上是一样的。 Qt 有 QGLFormat class 来处理这些属性,所以你的例子变成:

from sys import *
from OpenGL.GL import *
from OpenGL.GLU import *

from PyQt5 import QtWidgets
from PyQt5.QtOpenGL import QGL
from PyQt5.QtOpenGL import QGLWidget
from PyQt5.QtOpenGL import QGLFormat

class Foo(QGLWidget):
    def __init__(self, *args, **kwargs):
        fmt = QGLFormat()
        fmt.setVersion(3,2)
        fmt.setProfile(QGLFormat.CoreProfile)
        fmt.setOption(QGL.NoDeprecatedFunctions) # a.k.a. forward compatible
        super(Foo, self).__init__(fmt, *args, **kwargs)

    def initializeGL(self):
        glClearColor(1.0, 0.0, 0.0, 0.0)
        print(glGetString(GL_VERSION))

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        #glMatrixMode(GL_MODELVIEW)  !!! not supported in core profile
        #glLoadIdentity()  !!! not supported in core profile

if __name__ == "__main__":
    global app
    app = QtWidgets.QApplication(argv)
    ex = Foo()
    ex.move(800,100)
    ex.resize(800, 600)
    ex.show()

    exit(app.exec_())

我基本上只扩展了 __init__ 方法,但我不得不从 PyQt5 导入更多的东西。请注意,我还删除了 GLUT 导入,因为当您使用 Qt 时根本不需要它。

这两个示例都使用 python3 在我的 Linux 系统上创建了核心配置文件。我不知道 renderdoc 现在是否会对您提供的上下文感到满意。这些更改至少会解决它为您的原始示例显示的两个错误消息,并且原则上应该有效。