我在 Mac 上使用 PyOpenGL。默认情况下,使用 OpenGL 2.1。但是,根据我的研究和 OpenGL Extension Viewer,我应该能够使用 OpenGL 4.1。 我正在尝试将 QGLFormat 传递给我的 QGLWidget,正如我在此处的许多线程上看到的那样,但上下文版本不会更改。如果我尝试强制它,它会告诉我上下文无效。 我已经进行了很多实验 - 这是一个非常简单的示例,显示了我的问题:
from PyQt4 import QtGui, QtCore, QtOpenGL
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
glFormat = QtOpenGL.QGLFormat()
glFormat.setVersion(4,1)
glFormat.setProfile(QtOpenGL.QGLFormat.CoreProfile)
glFormat.setSampleBuffers(True)
glFormat.setDefaultFormat(glFormat)
print("Format version: " + str(glFormat.majorVersion()))
myW = QtOpenGL.QGLWidget(glFormat)
print ("Widget context valid: " + str(myW.context().isValid()))
print ("Widget format version: " + str(myW.format().majorVersion()))
print ("Widget context format version: " + str(myW.context().format().majorVersion()))
myW.context().setFormat(glFormat)
print ("Forced format valid: " + str(myW.context().isValid()))
print ("Forced format version: " + str(myW.format().majorVersion()))
myW.show()
sys.exit(app.exec_())
这是输出:
Format version: 4
Widget context valid: True
Widget format version: 1
Widget context format version: 1
Forced format valid: False
Forced format version: 4
知道我的问题出在哪里吗?难道我做错了什么? 我使用的是 macOS Sierra 版本 10.12.6。 我使用 Qt 版本 4.8.7、sip 版本 4.19.3 和 pyqt 版本 4.12(如果相关的话)。 这是what OpenGL Extension Viewer tells me .
任何帮助将不胜感激!
编辑:
我在这里发现了与 C++ 类似的问题。我不确定如何将解决方案转换为 PyQt,但我会研究一下: Changing the OpenGL Context Version for QGLWidgets in Qt 4.8.6 on OS X .
编辑3:
在尝试@ekhumoro 提供的补丁(第二个版本)时,我得到以下输出:
patching file qpy/QtOpenGL/core_profile_attributes.mm
patching file qpy/QtOpenGL/qpyopengl.pro
patching file sip/QtOpenGL/qgl.sip
patch unexpectedly ends in middle of line
Hunk #3 FAILED at 493.
1 out of 3 hunks FAILED -- saving rejects to file sip/QtOpenGL/qgl.sip.rej
qpyopengl.pro 现在已正确修补,但 qgl.sip 仍然失败。
更新:
以下是 qgl.sip 的拒绝文件的内容:
***************
*** 478,481 ****
%ModuleHeaderCode
#include <qpyopengl_api.h>
--- 493,498 ----
%ModuleHeaderCode
#include <qpyopengl_api.h>
+ typedef struct GDevice** GDHandle;
+ void* select_3_2_mac_visual();
出于好奇,我运行了configure-ng.py并尝试编译。我收到以下错误:
[...]/PyQt4_gpl_mac-4.12.1/sip/QtOpenGL/qgl.sip:269:5: error: 'virtual' can only appear on non-static member functions
virtual void* chooseMacVisual(GDHandle handle)
^
[...]/PyQt4_gpl_mac-4.12.1/sip/QtOpenGL/qgl.sip:271:16: error: use of undeclared identifier 'select_3_2_mac_visual'
return select_3_2_mac_visual();
^
[...]/PyQt4_gpl_mac-4.12.1/sip/QtOpenGL/qgl.sip:269:44: warning: unused parameter 'handle' [-Wunused-parameter]
virtual void* chooseMacVisual(GDHandle handle)
最佳答案
无论如何,在我的 Windows 10 笔记本电脑上运行代码会得到以下输出:
Format version: 4
Widget context valid: True
Widget format version: 4
Widget context format version: 4
Forced format valid: False
Forced format version: 4
因此,我怀疑您的问题实际上可能不是特定于平台的问题,而是与您的 myW.context().setFormat(glFormat)
调用有关。有趣的是,我看了一下PyQt documentation for QGLWidget而且 setFormat() 似乎缺少它,这非常没有帮助!
查看相应的C++文档,看起来setFormat()
实际上可以从QGLWidget itself任一调用。 ,或者它 child QGLContext目的。由于您是从 QGLContext
调用它,因此上下文被重置,从而使其无效。解决方案是在设置格式后调用myW.context().create()
,从而使用新参数创建一个有效的格式对象!该修改如下所示:
from PyQt4 import QtGui, QtCore, QtOpenGL
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
glFormat = QtOpenGL.QGLFormat()
glFormat.setVersion(4,1)
glFormat.setProfile(QtOpenGL.QGLFormat.CoreProfile)
glFormat.setSampleBuffers(True)
glFormat.setDefaultFormat(glFormat)
print("Format version: " + str(glFormat.majorVersion()))
myW = QtOpenGL.QGLWidget(glFormat)
print ("Widget context valid: " + str(myW.context().isValid()))
print ("Widget format version: " + str(myW.format().majorVersion()))
print ("Widget context format version: " + str(myW.context().format().majorVersion()))
myW.context().setFormat(glFormat)
myW.context().create()
print ("Forced format valid: " + str(myW.context().isValid()))
print ("Forced format version: " + str(myW.format().majorVersion()))
myW.show()
sys.exit(app.exec_())
另一种选择是在 QGLWidget
级别调用 setFormat()
,这会自动创建一个新上下文,结果如下:
from PyQt4 import QtGui, QtCore, QtOpenGL
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
glFormat = QtOpenGL.QGLFormat()
glFormat.setVersion(4,1)
glFormat.setProfile(QtOpenGL.QGLFormat.CoreProfile)
glFormat.setSampleBuffers(True)
glFormat.setDefaultFormat(glFormat)
print("Format version: " + str(glFormat.majorVersion()))
myW = QtOpenGL.QGLWidget(glFormat)
print ("Widget context valid: " + str(myW.context().isValid()))
print ("Widget format version: " + str(myW.format().majorVersion()))
print ("Widget context format version: " + str(myW.context().format().majorVersion()))
myW.setFormat(glFormat)
print ("Forced format valid: " + str(myW.context().isValid()))
print ("Forced format version: " + str(myW.format().majorVersion()))
myW.show()
sys.exit(app.exec_())
话虽这么说,所有这些都是推测,因为我没有可以测试此代码的 Mac。请告诉我这是否可以解决您的问题,并希望它有所帮助!
关于python - 如何在 MacOS 上使用 QGLFormat 更改 OpenGL 版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46834905/