QPainter changes the rendering of OpenGLWidget



  • Hello everyone! I have encountered a strange problem with a QOpenGLWidget when trying to paint some rectangle box with text over it with QPainter. I have the following code to draw the opengl geometry:

    void GLWidgetGeometry::initializeGL()
    {

    initializeOpenGLFunctions();
    glClearColor(0.0, 0.0, 0.0, 1.0);
    
    // connect shader to the source files
    if (!shaderProgram_.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vshader.glsl"))
        close();
    if (!shaderProgram_.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fshader.glsl"))
        close();
    if (!shaderProgram_.link())
        close();
    
    glEnable(GL_DEPTH_TEST); // important to keep for realistic output of rays on the foreground of the texture
    //glDisable(GL_DEPTH_TEST);
    // to see transparent back faces
    glDisable(GL_CULL_FACE);
    //glShadeModel(GL_SMOOTH); // not available in windows qt version
    //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    // transparency
    glEnable(GL_BLEND);
    // blending of alpha-colors of surfaces in the system with the background
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //glBlendFunc(GL_ONE, GL_ONE);
    
    // initial position
    rotation_ = QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), -90) * rotation_;
    rotation_ = QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0), 30) * rotation_;
    

    }

    void GLWidgetGeometry::paintGL()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // Calculate model view transformation (camera moves, but not object itself)

    QMatrix4x4 matrix, viewMatrix;
    
    viewMatrix.lookAt(QVector3D(0, 0, 1.0), QVector3D(0, 0, 0), QVector3D(0, 1, 0));
    viewMatrix.translate(translation_);
    viewMatrix.rotate(rotation_);
    // in the future use scaling factor provided by ray tracer
    viewMatrix(2, 3) -= 5.0f * exp(distanceExp_ / 1200.0f); // scaling the view
    
    //double scaling = rayTracer_->scalingFactor();
    viewMatrix.scale(rayTracer_->scalingFactor());
    
    shaderProgram_.bind();
    // Set modelview-projection matrix
    shaderProgram_.setUniformValue("mvp_matrix", projection_*viewMatrix*matrix);
    shaderProgram_.setUniformValue("mv_matrix", viewMatrix*matrix);
    shaderProgram_.setUniformValue("normal_matrix", (viewMatrix*matrix).normalMatrix());
    
    shaderProgram_.setUniformValue("lightPosition", QMatrix4x4((viewMatrix*matrix).normalMatrix())*QVector3D(1.0, 1.0, 1.0).normalized());
    shaderProgram_.setUniformValue("lightIntensity", QVector3D(5.0, 5.0, 5.0));
    
    rayTracer_->draw(shaderProgram_);
    shaderProgram_.release();
    
    drawLegend(title_) ; // without this everything works perfect!
    

    }

    So when I am just draw geometry with opengl and shader call everything looks great, once I call drawLegend function with QPainter everything becomes ugly.

    void GLWidgetGeometry::drawLegend(const QString& text)
    {
    QPainter painter; // to draw a legend

    painter.begin(this);
    painter.setRenderHint(QPainter::TextAntialiasing);
    
    QFont font = painter.font(); // enlarged the text
    font.setPixelSize(14);
    font.setBold(true);
    painter.setFont(font);
    
    QFontMetrics metrics = QFontMetrics(font);
    int border = qMax(4, metrics.leading());
    
    QRect rect = metrics.boundingRect(0, 0, width() - 2*border, height()/4,
                                      Qt::AlignLeft | Qt::TextWordWrap, text);
    painter.setRenderHint(QPainter::TextAntialiasing);
    
    QPen pen = painter.pen();
    pen.setWidth(2);
    pen.setColor(QColor(255, 255, 255, 200));
    painter.setPen(pen);
    
    QRect rectText(0, 0, rect.width() + 4*border, rect.height() + 4*border);
    
    painter.setBrush(QColor(38, 181, 242, 120));
    painter.drawRect(rectText);
    painter.drawText(rectText.x() + 2*border, rectText.y(), rectText.width(), rectText.height(),
                     Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, text);
    painter.end();
    

    }
    Picture before adding QPainter draw
    Picture after adding QPainter draw



  • The solution of the problem was, that after using QPainter the OPenGL state was lost, so all the glEnable() were ignored and therefore the depth test as well, so I put again all the glEnable calls after QPainter call and it works well.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    IIRC when you want to mix both, you need to enclose your OpenGL primitives call between painter-> beginNativePainting() and painter->endNativePainting()

    Hope it helps



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