Как использовать renderdoc в приложениях Python OpenGL
Я пытаюсь выяснить, как использовать renderdoc для отладки некоторых моих приложений на python opengl. На данный момент некоторые из моих тестов на python opengl используют либо pyopengl(glut), либо pyqt. Вот пара минимальных тестов, показывающих, как инициализировать перенасыщение или pyqt:
GLUT
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()
Если я запускаю renderdoc с приведенным выше фрагментом, используя путь к исполняемому файлу (путь к 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_())
Если я запускаю renderdoc с приведенным выше фрагментом, используя путь к исполняемому файлу (путь к Python) и аргументы командной строки (-u path_to_the_pyqt_example.py), я получу следующий вывод:
Итак, я не знаю, как ни glutCreateWindow (glut), ни initializeGL (pyqt) не инициализируют контекст opengl за кулисами, но кажется, что renderdoc не нравится способ создания контекста opengl. Я хотел бы знать, как я могу сделать рабочий renderdoc с помощью тестов glut и pyqt.
В качестве примечания:
glGetIntegerv(GL_MAJOR_VERSION) ---> 4
glGetIntegerv(GL_MINOR_VERSION) ---> 5
Итак, эта проблема не о версии opengl для контекста (которая достаточно хороша), а о том, как она была создана.
1 ответ
Официальный GLUT не поддерживает какой-либо современный контекст OpenGL. Однако у freeglut есть некоторые расширения, и PyOpenGL поддерживает эти расширения. Поскольку 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)
перед созданием окна.
Но не то, что ваш код теперь будет генерировать ошибку GL на glLoadIdentity
, поскольку эта устаревшая функция вообще не доступна в профиле ядра OpenGL.
Если вы хотите пойти по маршруту Qt, то все концептуально одинаково. Qt имеет QGLFormat
класс для работы с такими свойствами, поэтому ваш пример становится:
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
import, поскольку он вообще не нужен при использовании Qt.
Оба из этих примеров создают профиль ядра в моей системе Linux, используя python3. Я понятия не имею, будет ли renderdoc теперь доволен контекстами, которые вы ему предоставляете. Эти изменения, по крайней мере, будут касаться как сообщений об ошибках, которые он представил для ваших оригинальных примеров, так и в принципе, это должно работать.