QGLWidget:用QPainter重绘

时间:2013-02-21 07:26:13

标签: c++ qt opengl qpainter

我想在我的图像查看器上绘制一些叠加图:图像周围的虚线矩形,表示边界框。 以下是我在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函数中的代码移动到另一个非虚拟但没有改变任何东西的函数。

1 个答案:

答案 0 :(得分:4)

首先应执行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