从5.10.0升级到5.12.1的Qt OpenGL问题

时间:2019-02-22 18:43:56

标签: qt opengl qt5

我有一个旧的C ++ Qt应用程序,该应用程序已通过许多许多版本的Qt进行了升级。我最近将其从Qt 5.10.0升级到5.12.1,现在突然之间,我的两个OpenGL显示器都遇到了问题,我不知道为什么。

问题快速摘要:

第一个显示器绘制3d表面图。它非常旧(包含使用glew的旧式控件),并且使用了现在已过时的QGLWidget。我不能改变这个。

class GLAdapterWidget : public QGLWidget
{
    // ...A whole lot of legacy code which has not changed...
public:
    // How I update the display

    void doUpdate()
    {
        someLegacyGLDrawingFunction();
        updateGL();  // fails if attribute Qt::WA_Mapped not set
    }
};

现在的问题是,一旦加载它,它仍然会变成全黑,直到我实际单击鼠标时在其边界内的某个位置。然后突然之间,它的GL图纸完美地出现了。这在Qt 5.10.0中没有发生。

调试,我至少可以跟踪到小部件属性 Qt :: WA_Mapped 。该属性未在我的窗口小部件上设置,因此Qt在我单击它之前不会绘制它。一旦我在其边界内单击,Qt就会设置该属性,即可正常工作。但是我尝试解决方法(例如调用show()或尝试在软件中设置该属性)无效。

第二个显示更加现代,并使用QOpenGLWidget。它显示了实时更新的实时摄像机图像。

class VideoDisplay : public QOpenGLWidget, 
                     protected QOpenGLFunctions_3_3_Core
{

    virtual void initializeGL() override
    {
        initializeOpenGLFunctions();
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-width()/2, width()/2, height()/2, -height()/2, -1, 1); 
        glClearColor(0.25f,0.25f,0.25f,1.0f);

    }
    virtual void paintGL() override
    {
        // Legacy Code that draws a live image using glDrawPixels and which has not changed.
    }
    virtual void resizeGL(int w, int h) override
    {
        glViewport(0,0,w,h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-w/2, w/2, h/2, -h/2, -1, 1);
    }
};

这似乎起初很好。该图像显示并更新。但是,如果我显示较旧的GLAdapterWidget的实例,然后返回该显示(VideoDisplay),则它突然显示为黑色,没有任何东西可以重绘。调试我看到paintGL仍在被调用,并且它具有有效的图像。所有参数看起来都不错。但是什么也没显示。

我知道这没什么可继续的了。这段代码既旧又庞大,以至于我觉得发布其中的大部分内容并不会做很多事情,但会造成混乱。

我意识到,在这两种情况下,罪魁祸首都可能是基于QGLWidget的较旧显示器。但是当我说我无法抛弃该代码时,我并不是在开玩笑,无论我愿意怎么做

因此,我(非常)关注于以下事实:它在5.10.0中有效,而在5.12.1中不适用。 我希望的是,对Qt有更好了解的人可以识别任何特定的关键体系结构Qt在5.10.0和5.12.1之间变化,这可能是导致我进行调查或尝试变通的途径 的罪魁祸首。

我需要创可贴。我不介意做这项工作,我只是不知道从哪里开始。

1 个答案:

答案 0 :(得分:1)

我在这里向Qt报告了此问题:https://bugreports.qt.io/browse/QTBUG-72668以及一个棘手的解决方法,直到解决为止。

  

解决方法:在设置为特定间隔的父QMainWindow上安装QTimer。暴露窗口之后,子QOpenGLWidget isValid()返回true后,将窗口小部件的大小调整为其他大小(注意:它不能是相同大小,repaint(),update()或update(0,0,宽度,高度)工作)

    QWindow *window = windowHandle();
    if(window && window->isExposed() && glWidget->isValid()) {
        resize(801,601);
        _timer.stop();
    }