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
QtWS25 Last Chance

QPainter changes the rendering of OpenGLWidget

Scheduled Pinned Locked Moved Unsolved General and Desktop
qpainterqopenglwidgetrenderingpainting
3 Posts 2 Posters 3.1k Views
  • 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 18 Nov 2015, 11:09 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 20 Nov 2015, 13:19 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
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 20 Nov 2015, 23:01 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

        2/3

        20 Nov 2015, 13:19

        • Login

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