Hedede
Hedede

Reputation: 1173

QOpenGLWidget's makeCurrent does not work?

I am trying to use QOpenGLWidget without subclassing.

When I try to make OpenGL calls outside of QOpenGLWidget's methods or signals, nothing seems to happen. For example, following code clears window black despite me setting glClearColor:

MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
{
    auto glw = new QOpenGLWidget( this );
    glw->makeCurrent();
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glw->doneCurrent();

    connect( glw, &QOpenGLWidget::aboutToCompose, [=] {
        glClear( GL_COLOR_BUFFER_BIT );
    });

    setCentralWidget( glw );
}

However, when I move glClearColor inside the lambda connected to the aboutToCompose signal, widget is cleared with white color.

Upvotes: 1

Views: 2196

Answers (2)

Doug Rogers
Doug Rogers

Reputation: 21

You can call auto *ctx = QOpenGLContext::currentContext(); to check if makeCurrent succeeded.

Upvotes: 1

Louis Langholtz
Louis Langholtz

Reputation: 3123

As essentially explained in the comments section by Fabio and G.M., QOpenGLWidget::makeCurrent won't work if called before things are setup enough.

As of Qt 5.11 and probably other releases, QOpenGLWidget::makeCurrent works by calling the QOpenGLContext::makeCurrent method. That call only happens if the QOpenGLWidget is already in the initialized state however. Additionally, QOpenGLContext::makeCurrent can fail. The latter at least gives some indication of failure via its bool return parameter. Unfortunately, QOpenGLWidget::makeCurrent gives no indication at all. QOpenGLWidget::makeCurrent fails silently.

Besides knowing this & heeding the advice in the comments, one can use the QOpenGLWidget::context method to determine whether the QOpenGLWidget is in the initialized state. According to the linked documentation (and as seen in practice), the context method returns "0 if not yet initialized" or a non-null pointer otherwise. So it's a means to determine whether or not QOpenGLWidget::makeCurrent calls QOpenGLContext::makeCurrent and a means to partially work around QOpenGLWidget::makeCurrent returning void. That's probably not particularly useful in this case, but can be useful in other related contexts so I thought this worth mentioning.

So to get QOpenGLWidget::makeCurrent to actually succeed, QOpenGLWidget::makeCurrent has to be called after the QOpenGLWidget has been initialized in order for it to work.

Reading between the lines of this question, it sounds as if wondering about what was needed to be done in order for GL calls to work. And as the question's author recognizes, delaying the GL calls till the aboutToCompose signal has been fired, works for that (at least in the context of this user's code). Another way, is to make the QOpenGLWidget visible, then call the GL code.

Hope this answers your question completely if not at least helpfully.

Upvotes: 2

Related Questions