Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QPainter changes the rendering of OpenGLWidget
Forum Updated to NodeBB v4.3 + New Features

QPainter changes the rendering of OpenGLWidget

Scheduled Pinned Locked Moved Unsolved General and Desktop
qpainterqopenglwidgetrenderingpainting
3 Posts 2 Posters 3.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BlondXXX
    wrote on last edited by
    #1

    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

    1 Reply Last reply
    0
    • B Offline
      B Offline
      BlondXXX
      wrote on last edited by
      #2

      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.

      1 Reply Last reply
      1
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        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

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved