Can't set desired OpenGL version in QGLWidget
Asked Answered
N

2

11

I'm trying to use QGLWidget in Qt 4.8.2. I noticed that the default context QGLWidget creates doesn't show any output for OpenGL above 3.1. The Qt wiki has a tutorial that demonstrates using OpenGL 3.3 to draw a simple triangle. When I try to run the tutorial, I get a blank screen. If I change the OpenGL version to 3.1, I get the expected output (a red triangle).

My video card supports OpenGL 4.2, and calling QGLFormat::openGLVersionFlags() before creating the QGLWidget shows that Qt detects OpenGL 4.2 and all previous desktop versions.

Here's another minimal example:

#include <QApplication>
#include <QGLWidget>
#include <QDebug>
#include <QtDeclarative/qdeclarativeview.h>

int main(int argc, char * argv[])
{
    QApplication app(argc, argv);

    qDebug() << "OpenGL Versions Supported: " << QGLFormat::openGLVersionFlags();

    QGLFormat qglFormat;
    qglFormat.setVersion(4,2);  // get expected output with (3,1) and below, else blank window
    qglFormat.setProfile(QGLFormat::CoreProfile);
    qglFormat.setSampleBuffers(true);

    QGLWidget* qglWidget = new QGLWidget(qglFormat);

    QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
    qDebug() << "Driver Version String:" << versionString;
    qDebug() << "Current Context:" << qglWidget->format();

    QDeclarativeView mainView;
    mainView.setViewport(qglWidget);
    mainView.setSource(QString("helloworld.qml"));
    mainView.show();

    return app.exec();
}

Here's the output:

OpenGL Versions Supported:  QFlags(0x1|0x2|0x4|0x8|0x10|0x20|0x40|0x1000|0x2000|0x4000|0x8000|0x10000) 
Driver Version String: "4.2.0 NVIDIA 295.53" 
Current Context: QGLFormat(options QFlags(0x1|0x2|0x4|0x10|0x20|0x80|0x200|0x400) , plane  0 , depthBufferSize  24 , accumBufferSize  16 , stencilBufferSize  8 , redBufferSize  8 , greenBufferSize  8 , blueBufferSize  8 , alphaBufferSize  -1 , samples  4 , swapInterval  0 , majorVersion  4 , minorVersion  2 , profile  1 )  

The QFlags() enum list on the first line describes the OpenGL versions supported. The list shows I support all variants except for OpenGL/ES versions. QFlags() on the third line describes format options (alpha channel, stencil buffer, etc).

Anyone know why QGLWidget won't work with anything >= 3.1? I'm on Linux, have an Nvidia GT440, and glxinfo shows it supports OpenGL 4.2.0. The driver version is printed in the sample output above. I'm not too sure what else to try.

Edit: I made some pretty bad mistakes/assumptions with my explanation of the problem before this edit. The issue is still similar, but hopefully makes a bit more sense now. Sorry for any confusion.

Nee answered 12/6, 2012 at 15:38 Comment(7)
Are your shaders compiling/linking? If you are using a 4.2 context and incompatible/incorrect shaders, that is one cause for a blank window.Laing
I haven't gotten that far yet (shaders). I wanted to use QGLWidget as a viewport for a QDeclarativeView and then add some 3d content that used shaders. But even a simple file with default components like a Rectangle{} renders nothing. It'll render as expected if I don't set the QGLFormat version, but the whole point of this question is figuring out why I can't set it in the first place. Plus, I'd get errors if I (or Qt internally) was using incompatible shaders. The only output is what I pasted in my question.Nee
Hmm, the only reason why I suggest looking at the shader log, is that OpenGL 3.0 + requires that your own shaders are compiled and loaded, while OpenGL 2.0 and below does not. I have no experiance with using OpenGL through QT, so I do not know how much is handled for you. However, in the example you linked, the author prepares his or her own shaders. If you do not provide shaders to the graphics card using the core profile, you will not render anything.Laing
I just downloaded and ran the example that I linked, and it doesn't work (shows up blank) unless I set it to use the compatibility profile as opposed to the core profile.Nee
Any errors when you run using core?Laing
Have you tried compatibility profile ?For me I can't access the context of 4.0 at all if setting it in CORE profile but with compatibility it works.Well I am on Win so not sure it would help.Ehf
I want to explicitly disable the compatibility profile. The last post in this thread: qt-project.org/forums/viewthread/16041/#90717 has a suggestion that might work -- I have yet to try it.Nee
F
5

You should move the OpenGL queries down after mainView.show();. Before show() the OpenGL context has not been initialized.

Ferment answered 10/1, 2013 at 12:6 Comment(0)
H
4

Short version: update to Qt5, it's fixed there.

P.S And if you can use 5.4 you should probably use QtOpenGL... classes instead of QGL... ones.

Long version: So, in case anyone ever come across a problem like this one.

I tried to create NOT OpenGL 3.0 context with my Intel HD3000 on ubuntu 14.04 and Qt 4.8.6. I came up with this test code provided at the end of the answer. Tried creating 3.1, 1.2, 2.1.. etc. contexts Core Compatible.. but always end up with context->format().majorVersion() showing the requested version, and glGetString(GL_VERSION) showing 3.0.

After about 3 hours I noticed that by default Qt Creator uses Qt4 instead of recent Qt 5, installed on my system. And after I recompiled the project with Qt 5.2.1 exactly the same code started working as expected.

Hope this may help someone.

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    QGLFormat glFormat;
    glFormat.setVersion(3, 1);
    glFormat.setProfile(QGLFormat::NoProfile);
    glFormat.setSampleBuffers(true);
    glFormat.setDefaultFormat(glFormat);
    glFormat.setSwapInterval(1);
    QGLWidget widget(glFormat);
    widget.makeCurrent();

    const QGLContext *context = widget.context();

    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK) {
        qWarning("Failed to initialize GLEW\n");
    }
    qDebug() << "Context valid: " << context->isValid();
    qDebug() << "Really used OpenGl: " << context->format().majorVersion() << "." << context->format().minorVersion();
    qDebug() << "OpenGl information: VENDOR:       " << (const char*)glGetString(GL_VENDOR);
    qDebug() << "                    RENDERDER:    " << (const char*)glGetString(GL_RENDERER);
    qDebug() << "                    VERSION:      " << (const char*)glGetString(GL_VERSION);
    qDebug() << "                    GLSL VERSION: " << (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
    qDebug() << "endstuff\n";

    return a.exec();
}
Hereld answered 19/7, 2015 at 21:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.