OpenGL 3.2+ and Qt Quick2



  • Is it possible to overlay a Qt Quick2 GUI on rendering done with an OpenGL 3.2+ context? I'd like to use Qt Quick for my GUI but I don't want to be limited to OpenGL 2.1. I've tried creating a 3.2 context and using the beforeRendering signal to make it current against the QQuickView window to do my rendering, but haven't had much success yet. I'd like to avoid rendering to FBOs if possible.



  • Yup. Create your window, set the gl format to 3.2 and make sure it is a compatibility profile. Have a look at this http://www.youtube.com/watch?v=GYa5DLV6ADQ



  • Thanks for the reply! I'm watching the video now. However unfortunately on OS X, you can't create an opengl 3.2 context with the compatibility profile, only core. If you don't specify the core profile you'll end up with a 2.1 context.



  • Ah, then the alternative is to create your own context and do a context switch twice each frame. In my code it looks like this
    @
    QOpenGLContext* current = QOpenGLContext::currentContext();
    Context* context = _item->context();
    context->makeCurrent();

    {
        AutoFrameSwitch fs(context);
        _frame->render(context, [&]() { _item->render(); });
    }
    
    current->makeCurrent(_item->window());
    

    @
    I do the FBO thing but I highly don't recommend doing what I do if you can avoid it. I'm actually in the process of moving my engines rendering out into another thread and getting rid of those context switches.



  • That looks a lot like what I've been trying to do, except I haven't been using FBOs. I let the QQuickView create the window, then use its beforeRendering signal to try to render to its QSurface using my own gl 3.2 context. It looks something like this:

    @myQuickView->setClearBeforeRendering(false);
    QObject::connect(myQuickView, &QQuickWindow::beforeRendering, testrender, Qt::DirectConnection);

    void testrender()
    {
    QOpenGLContext* savedContext = QOpenGLContext::currentContext();
    myGL32Context->makeCurrent(myQuickView);
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    savedContext->makeCurrent();
    }@

    The above leaves garbage in the framebuffer though, indicating the glClear isn't having an effect. I'm don't know if having two contexts render into the same QSurface like this is unsupported, or if I'm doing something else wrong.



  • Just out of interest, what happens if you leave out your context and just continue with the default one?



  • It works fine with the default one, I'll get a cleared red screen with my QML gui on top. I saw the part of the talk you linked where he inherits QQuickView and sets the surface format to a gl 3.3. compatibility profile. Unfortunately this wouldn't work on OS X -- otherwise it's exactly what I'd like to achieve.



  • That shouldn't matter since you're switching to your own context though. I am wondering if the context you're requesting is valid. Can you put up the code where you're creating your context?



  • The context appears to be created successfully. glGetString(GL_VERSION) returns "3.2 ATI-7.32.12". I create it in a class derived from QQuickView, on the render thread. This is the actual code:

    @GLWindow::GLWindow(QWindow *parent)
    : QQuickView(parent)
    , mCustomContext(0)
    {
    resize(QSize(800, 600));
    connect(this, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection);
    }

    void GLWindow::createContext()
    {
    QSurfaceFormat fmt = format();
    fmt.setMajorVersion(3);
    fmt.setMinorVersion(2);
    fmt.setProfile(QSurfaceFormat::CoreProfile);
    mCustomContext = new QOpenGLContext();
    mCustomContext->setFormat(fmt);
    qDebug() << "create context" << mCustomContext->create();
    }

    void GLWindow::render()
    {
    if (mCustomContext == 0) createContext();
    QOpenGLContext* savedContext = QOpenGLContext::currentContext();
    mCustomContext->makeCurrent(this);

    glViewport(0, 0, width(), height());
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    savedContext->makeCurrent(this);
    

    }
    @



  • Try adding
    @
    setFormat(fmt);
    @
    after you create the context



  • No change unfortunately. It looks like this (I used the openglunderqml example as a starting point). The glClear is doing something, as it will occasionally flash a (corrupted) red buffer.

    https://dl.dropboxusercontent.com/u/25115714/qml_gl.png



  • I'm afraid I'm running out of ideas. For reference mine is
    @
    _context->setScreen(QGuiApplication::primaryScreen());
    QSurfaceFormat format;
    format.setMajorVersion(4);
    format.setMinorVersion(3);
    format.setSamples(4);
    // format.setProfile(QSurfaceFormat::CoreProfile);
    _context->setFormat(format);
    _context->setShareContext(share);
    _context->create();

    _window->setFormat(_context->format());
    

    @
    I really don't remember why I commented out the setProfile line. Suddenly seems suspicious. If I uncomment it my app crashes at glGenSamplers indicating it isn't giving me a useful context. Probably because I'm trying to share it.



  • I just compiled and ran the exact same code on windows on the same machine and it worked perfectly. It seems it's an OS X issue :/


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.