I'm using PyOpenGL on a Mac. By default, OpenGL 2.1 is used. However, according to my research and to OpenGL Extension Viewer, I should be able to use OpenGL 4.1. I'm trying to pass a QGLFormat to my QGLWidget, as I've seen done on many threads here, but the context version does not change. If I try to force it, it tells me that the context is not valid. I have been experimenting a lot - here is a very simple example that shows my problem:
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_())
Here is the output:
Format version: 4
Widget context valid: True
Widget format version: 1
Widget context format version: 1
Forced format valid: False
Forced format version: 4
Any idea where my problem lies? Am I doing something wrong? I'm using macOS Sierra version 10.12.6. I use Qt version 4.8.7, sip version 4.19.3, and pyqt version 4.12, in case that's relevant. Here is what OpenGL Extension Viewer tells me.
Any help would be greatly appreciated!
Edit:
I found what looks like a similar problem with C++ here. I'm not sure how to translate the solution to PyQt, but I will look into this: Changing the OpenGL Context Version for QGLWidgets in Qt 4.8.6 on OS X.
Edit 3:
I get the following output when trying (the second version of) the patch provided by @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 is patched correctly now, but it still fails for qgl.sip.
Update:
Here is the content of the reject file for 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();
Out of curiosity, I ran configure-ng.py and tried to compile. I get the following error:
[...]/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)
For what it is worth, running your code on my Windows 10 laptop gives the following output:
Therefore, I suspect that your issue might not actually be a platform-specific one, but rather with your
myW.context().setFormat(glFormat)call. Interestingly, I took a look at the PyQt documentation for QGLWidget and it appears to be missing for setFormat(), which is pretty unhelpful!Looking instead at the corresponding C++ documentation, it looks like
setFormat()can actually be called from either the QGLWidget itself, or it child QGLContext object. Since you are calling it from theQGLContext, it turns out that the context is reset, making it invalid. The solution is to callmyW.context().create()after setting the format, thus creating a valid format object with the new parameters! That modification would look like this:The other alternative is to just call
setFormat()at theQGLWidgetlevel, which automatically creates a new context, resulting in this:That being said, all of this is conjecture since I do not have a Mac on which I can test this code. Let me know if this fixes the problem for you, and hope it helps!