OpenGL Core Context on OS-X 10.8.5 crashes
So my battles with OpenGL rage on...
On Mac Os X 10.8.5, this will reliably crash:
@int main(int argc, char *argv)
QApplication a(argc, argv);
auto glWidget = new QOpenGLWidget;
@2014-12-22 02:29:54.375 qoglwidgetmac[6421:707] invalid share context
2014-12-22 02:29:54.376 qoglwidgetmac[6421:707] invalid context
The program has unexpectedly finished.@
So, how can I get access to OpenGL 3.2? I know it is supported by the platform:
All my shaders are currently glsl 1.40, and I need FBO's and such, so dropping all the way back to GL 2 in a compatibility context doesn't seem like a way forward for me. As far as I can tell, I am not doing anything forbidden by the Qt documentation. The simple test doesn't seem to crash with a QGlWidget instead of a QOpenGLWidget, but isn't QGlWidget supposed to be deprecated, and I'm supposed to use QOpenGLWidget at this point? So far QOpenGLWidget seems remarkably half-baked for something that users waited so long for...
Hi I noticed there is a comment in the QOpenGLWidget docs about calling setFormat on the widget before showing. I can't see that in your code.
Might that be the cause of the crash?
QOpenGLWidget *widget = new QOpenGLWidget(parent);
widget->setFormat(format); // must be called before the widget or its parent window gets shown
Move the call to setAttribute under the creation of your QApplication.
QApplication a(argc, argv); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
Before doing anything related to GUI you have to create the application instance.
I finally found something that does work, but it's the reverse logic of what you suggest. If I set the default format before I create the QApplication, it seems to work. If I then set the default format again during the application run, I get the same crash. But as long as I do it before anything else, I seem to be able to get a valid core context. (Still haven't gotten pixels to happen, but at least glsl 1.40 shaders are compiling.)
The reason is that QOpenGLWidget uses another context behind the scenes to do any compositing and by default that is a version 2.1 context which is incompatible with your request for a shared version 3.2 core profiles context. Hence when you set the default version prior to creating the widget you do end up with 2 3.2 core profile contexts.
If you don't need to composite any widgets with your OpenGL scene, it's less error prone to use QWindow along with a QOpenGLContext.
OpenGL 3.2 core corresponds to #version 150 core shaders, not 140 by the way. Also, remember that the core profile stipulates that you must have a vertex array object created and bound for rendering.
It's a little frustrating that it has to be set before QApplication is created, considering that the docs indicate the exact opposite is what you are supposed to do here: http://doc-snapshot.qt-project.org/qt5-5.4/qopenglwidget.html
Likewise, this sample code : https://qt.gitorious.org/qt/qtbase/source/e453484bca5add5973602044ff0fbc224f819a07:tests/manual/qopenglwidget/openglwidget/main.cpp uses the arguments to QApplication after it is instantiated to pick whether or not to use core profile. So your logic that the hidden FBO is the cause makes sense, but it's not at all obvious that this is the case until you bash your head against it. Especially since it seems like that FBO shouldn't exist until the QOpenGLWidget is created, rather than being tied to QApplication lifetime.
I may well just give up on using QOpenGLWidget. It seems to be causing more problems for me than providing benefit. The "cool new thing that finally lets us deprecate QGL*" seems to be a turkey.
I didn't say before the application, I said before the QOpenGLWidget. The hidden FBO is owned by the QOpenGLWidget but it gets created according to he default format at the time the QOpenGLWidget is created.
It's been possible to largely deprecate QGL* before now by using QWindow and QOpenGLContext. There is now also QOpenGLWindow which is a thin wrapper around these two. Unless you need to composite other widget or raster content on top of your GL rendering, I wouldn't bother with QOpenGLWidget anyway and use one of the above options.
Another common approach is to use QQuickView and tie your rendering into it's beforeRendering() signal and share the QQ2 renderer's context. The format of which needs to be set in the ctor of a subclass of QQuickView if you want to use a core profile context.
Erm, obviously I tried doing it after QAppliation instantiation but before instantiation a QOpenGLWidget like you suggest. That's what led me to post a thread titled "OpenGL Core Context on OS-X 10.8.5 crashes," with code doing exactly that in the first post of the thread.
I may well do what you suggest and abandon QOpenGLWidget and do a QWindow based attempt. Coming from a Qt 4.x background, I was used to the Widgets stuff just sort of working. I guess I just didn't have my expectations correctly calibrated. I don't really need compositing GL with other widgets, just a standard OpenGL viewport wodget in a window with other widgets.
I added this in my main and it solved that very exact same crash:
I noticed that I need to use CoreProfile. With CompatibilityProfile, I get stuck at 2.1 (on MacOSX 10.8.5)