如何在MacOS上使用QGLFormat更改OpenGL版本?

2024-04-20 08:45:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Mac上使用PyOpenGL。默认情况下,使用OpenGL 2.1。然而,根据我的研究和OpenGL扩展查看器,我应该能够使用opengl4.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_())

输出如下:

^{pr2}$

你知道我的问题在哪里吗?我做错什么了吗? 我使用的是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

我在尝试@ekhurvo提供的补丁(第二个版本)时得到以下输出:

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-天然气并试图编译。我得到以下错误:

[...]/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)

Tags: 版本formatversionmaccontextopenglprintpyqt4
2条回答

要回答将特定于Mac的解决方案转换成Python的具体问题:这是不可能的,因为PyQt绑定不包装虚拟方法chooseMacVisual。没有这个,就没有办法重新实现它,因为Qt只是看不到PyQt没有预先定义为虚拟的任何Python方法。在

所以让它工作的唯一方法就是修补PyQt4并重新编译它。幸运的是,已经有人这样做了,并在这里提供了代码:

但是,构建说明并不完全清楚,而且是针对PyQt-4.9.4的。所以我准备了一个比较容易操作的diff。我没有尝试编译它,因为我没有访问Mac系统的权限。在

要应用修补程序,请将latest PyQt4 OSX sources和cd解压到目录中。然后复制下面的diff并将其另存为macgl.diff,并运行以下命令:

patch -Np1 -i macgl.diff

然后,您可以使用下面显示的说明编译已修补的PyQt4:

更新

我以前认为对PyQt-4.9.4的一个差异可以完全适用于所有更新的PyQt4版本,但我错了。我试图用下面的修改过的diff来补救这个问题,它已经被改编为PyQt-4.12.1 mac source code。在

区别如下:

^{pr2}$

值得一提的是,在我的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++文档>,看起来^ {< CD2>}实际上可以从<强>< < /强>QGLWidget itself或它的子QGLContext对象调用。因为您是从QGLContext调用它,结果发现上下文是reset,使其无效。解决方案是在设置格式之后调用myW.context().create(),从而用新参数创建一个有效的format对象!修改如下:

^{pr2}$

另一种选择是在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电脑可以测试这些代码。请告诉我这是否能为您解决问题,并希望能有所帮助!在

相关问题 更多 >