Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QtQuick2 : OpenGL Stencil issues



  • Hi,
    I have been trying to use integrate Qt 5.1.2 with OSG3.2.0/OSGEarth2.5 by doing OSG rendering on beforeRendering() signal of QQuickItem. This works fine, however, if i use use stencil buffer in my code, i could only see a full screen quad drawn with stencilClearColor. To rectify this I created a sample custom QuickView class that with OpenGL calss on beforeRendering() signal.
    QuickGLView.h

    @
    #pragma once

    #include <QtQuick/QQuickView>
    #include <QOpenGLContext>
    #include <QOpenGLPaintDevice>

    class QuickGLView: public QQuickView
    {
    Q_OBJECT

    public:
    QuickGLView();
    ~QuickGLView();

    public slots:
        void drawBackground();
    

    protected:
    void timerEvent(QTimerEvent *);

    };
    @

    QuickGLView.cpp

    @
    #include "QuickGLView.h"
    #include <math.h>
    #include <QTimer>

    QuickGLView::QuickGLView()
    {
    setClearBeforeRendering(false);
    setWidth(1920);
    setHeight(1080);
    glClearColor(0.0, 0.0, 1.0, 0.5);
    connect(this, SIGNAL(beforeRendering()), this, SLOT(drawBackground()), Qt::DirectConnection);
    startTimer(16);
    }
    void QuickGLView::timerEvent(QTimerEvent*)
    { update();}

    void QuickGLView::drawBackground()
    {
    static GLfloat theta = 0;
    GLfloat x = 0.7cos(theta);
    GLfloat y = 0.8
    sin(theta);
    GLfloat rsize = 0.3;

    theta+=0.01;
    
    GLdouble dRadius = 0.1;
    GLdouble dAngle;
    
    //Use 0 for clear stencil, enable stencil test
    glClearStencil(0);
    glEnable(GL_STENCIL_TEST);
    
    QOpenGLContext* ctx = QOpenGLContext::currentContext();
    int stencilSize = ctx->format().stencilBufferSize();
    int depthSize = ctx->format().depthBufferSize();
    
    // Clear color and stencil buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    // All drawing commands fail the stencil test, and are not
    // drawn, but increment the value in the stencil buffer.
    glStencilFunc(GL_NEVER, 0x0, 0x0);
    glStencilOp(GL_INCR, GL_INCR, GL_INCR);
    
    // Spiral pattern will create stencil pattern
    // Draw the spiral pattern with white lines. We
    // make the lines  white to demonstrate that the
    // stencil function prevents them from being drawn
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_LINE_STRIP);
        for(dAngle = 0; dAngle < 400.0; dAngle += 0.1)
            {
            glVertex2d(dRadius * cos(dAngle), dRadius * sin(dAngle));
            dRadius *= 1.002;
            }
    glEnd();
    
    // Now, allow drawing, except where the stencil pattern is 0x1
    // and do not make any further changes to the stencil buffer
    glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        
    glColor3f(0.0f, 1.0f, 0.0f);
    glRectf(x, y, x + rsize, y - rsize);
    
    // All done, do the buffer swap
    //glutSwapBuffers();
    

    }
    @

    main.cpp

    @
    #include <QtWidgets/QApplication>
    #include "QuickGLView.h"

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

    QuickGLView view;
    
    
    QSurfaceFormat surfaceFormat(QSurfaceFormat::StereoBuffers);
    
    surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
    surfaceFormat.setStereo(true);
    surfaceFormat.setStencilBufferSize(8);
    surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
    //surfaceFormat.
    surfaceFormat.setDepthBufferSize(24);
    
    view.setFormat(surfaceFormat);
    view.setSurfaceType(QSurface::OpenGLSurface);
    
    view.setSource(QString::fromStdString("main.qml"));
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.show();
    
    return a.exec&#40;&#41;;
    

    }
    @

    main.qml

    @
    import QtQuick 2.1

    Rectangle{
    id: root
    color: "transparent"
    height: 1080
    width: 1920
    Rectangle{
    id: rect2
    NumberAnimation on x{from: 0; to: 100; duration: 800; loops: Animation.Infinite; running: true}
    color: "transparent"
    opacity: 0.5
    width: 10
    height: 10
    }
    }
    @

    Here, i can see the correct results, with stencil being implemented correctly as the qml has no drawable contents.
    However, when i changed rect2 color to "red" . I can not see my OpenGL results.
    Does anyone know what could be the issue here.?

    Moreover, I tried to use AMD gDebugger to check the stencil buffer.If i use a simple glut application, i can see the values in stencil buffer properly, However, while trying to use the same with Qt, i could not see any values in stencil buffer.

    Thanks,
    Nitish Puri



  • Try calling resetOpenGLState() at the end of drawBackground. Right now you leave the context in a dubious state (for example stencil testing is enabled).
    The function is new in 5.2. In 5.1 just try disabling GL_STENCIL_TEST.



  • Thanks for your reply,.
    I tried both of your solutions resetOpenGLState() in 5.2, and tried disabling GL_STENCIL_TEST at the end of paint, either of them did no help.


Log in to reply