【问题标题】:QGLWidget: overpainting with QPainterQGLWidget:使用 QPainter 进行重绘
【发布时间】:2013-02-21 07:26:13
【问题描述】:

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

【问题讨论】:

  • 向我们展示您定义上下文的位置。
  • QGLContext 对象是使用默认设置自动创建的,但这里是 initialiazeGL 函数(在主帖中)

标签: c++ qt opengl qpainter


【解决方案1】:

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

【讨论】:

  • 谢谢,与此同时,我放弃了所有 QPainter 的东西,并用 openGL 代码编写了所有内容……没有比自己更好的服务了
  • 很高兴它在这里工作! Qt 确实是 openGL 开发的绝佳选择。如果您使用纯固定函数管道调用,我建议学习 QtQuick 2.0(作为 QT 5.0 的一部分)。真是太棒了。
  • 该指南的链接已失效,您知道该文档是如何命名的,以便人们可以尝试用 Google 搜索吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
相关资源
最近更新 更多