QGLWidget:使用QPainter进行复涂

QGLWidget: overpainting with QPainter

本文关键字:QPainter 使用 QGLWidget      更新时间:2023-10-16

我想在我的图像查看器上绘制一些覆盖:在图像周围绘制一个虚线矩形,指示边界框。以下是我在paintEvent函数中所做的操作:

void ViewerGL::paintEvent(QPaintEvent* event){
    makeCurrent();
    QPainter p(this);
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT); // << If I don't do this it clears out my viewer white
// and I want it black
    p.setBackgroundMode(Qt::TransparentMode); // < was a test, doesn't seem to do anything
    p.setBackground(QColor(0,0,0,0));
     //loading the appropriate shader before texture mapping
    if(rgbMode() && _shaderLoaded){
        shaderRGB->bind();
    }else if(!rgbMode() && _shaderLoaded){
        shaderLC->bind();
    }
    paintGL(); // render function (texture mapping)
    //drawing a rect around the texture on the viewer
    QPen pen(Qt::DashLine); 
    pen.setColor(QColor(233,233,233));
    p.setPen(pen);
    QPoint btmRight=mousePosFromOpenGL(dataWindow().w(),dataWindow().h() +transY*2 + ( zoomY-dataWindow().h()/2)*2);
    QPoint btmLeft=mousePosFromOpenGL(0,dataWindow().h() +transY*2 + ( zoomY-dataWindow().h()/2)*2);
    QPoint topLeft=mousePosFromOpenGL(0,0 +transY*2 + ( zoomY-dataWindow().h()/2)*2);
    QPoint topRight=mousePosFromOpenGL(dataWindow().w(), 0+ +transY*2 + ( zoomY-dataWindow().h()/2)*2);
    p.drawLine(topLeft,topRight);
    p.drawLine(topRight,btmRight);
    p.drawLine(btmRight,btmLeft);
    p.drawLine(btmLeft,topLeft);
    QPoint pos = mousePosFromOpenGL( (dataWindow().w()) + 10  ,
                                    (dataWindow().h()) +transY*2 + ( zoomY-dataWindow().h()/2)*2  +10); // bottom right of the texture +10
    p.drawText(pos, _resolutionOverlay);
    p.end();
}

这是我在paintGL函数中所做的:

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
... my drawing code
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glPopAttrib();

以及initializeGL函数:

    initAndCheckGlExtensions();
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glGenTextures (1, texId);
    glGenTextures (1, texBlack);
    glGenBuffersARB(1, &texBuffer);
    shaderBlack=new QGLShaderProgram(context());
    shaderBlack=new QGLShaderProgram(context());
    if(!shaderBlack->addShaderFromSourceCode(QGLShader::Vertex,vertRGB))
        cout << shaderBlack->log().toStdString().c_str() << endl;
    if(!shaderBlack->addShaderFromSourceCode(QGLShader::Fragment,blackFrag))
        cout << shaderBlack->log().toStdString().c_str() << endl;
    if(!shaderBlack->link()){
        cout << shaderBlack->log().toStdString().c_str() << endl;
    }

到目前为止,它是有效的,我有我想要的,但我的程序在退出时充斥着stderr:'QGLContext::makeCurrent:无法将无效上下文设为当前上下文'我知道这是来自QPainter,而不是来自我程序中的其他内容。

我试图将paintGL函数中的代码移动到另一个非虚拟函数,但这并没有改变任何内容。

您应该首先执行OpenGL调用,清除OpenGL状态,然后在QPainter::begin(QGLWidget *)QPainter::end(QGLWidget *)之间封装所有QPainter绘制调用。

您的程序很可能会导致问题,因为您交错了QPainter和OpenGL绘图调用。当您使用QPainter(QPaintDevice *)实例化QPainter对象时,您会告诉QPainter使用QGLWidget的本地绘图工具来执行QPainter操作。所以…QPainter使用OpenGL固定函数调用来执行2D绘图,当您的状态尚未清除时,它可能会干扰OpenGL渲染调用。

我建议遵循以下指南:

https://doc.qt.io/archives/qt-4.8/qt-opengl-overpainting-example.html