在运行/处理图像时,我很害怕解决我的软件闪烁问题 .

首先,我将介绍我的问题,解释我做了什么,然后最后我会留下我的问题/需求:

我的软件处理图像并在屏幕上显示它,就像扫描仪一样 . 图像像素使用图像光电传感器构建,使用OpenCV处理,并在屏幕上尽快绘制,以在生成图像时提供平滑的移动 .

实际上,我首先使用白色固体1000x808空白图像,其像素被相应的光照内置图像替换,并显示在屏幕上,以便图像在屏幕上从左向右流动 . 每帧生成的整个过程持续大约10~12ms .

但是,帧不会按预期在屏幕上流动 . 它闪烁了很多 . 由于我不知道如何在OpenGL上测量FPS,我想我的OpenGL代码(我对OpenGL一无所知)导致了闪烁 .

我在我的GLWidget上使用以下代码,我尽力编写,但我确信它不是OpenGL性能最好的 .

我的GLWidget构造函数几乎没有任何东西,但我已经玩了这些函数,没有显着的影响:

QGLFormat glFormat;
    glFormat.setSwapInterval(0);
    glFormat.setDoubleBuffer(true);
    glFormat.setSampleBuffers(true);
    glFormat.setDirectRendering(true);
    glFormat.setSamples(4);
    setFormat(glFormat);

我的initializeGL如下所示:

initializeGL()
{    
    glClearColor(255.0f,255.0f,255.0f,0.1f);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glDisable(GL_DEPTH_TEST);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,this->width(), this->height(), 0.0f,0.0f,1.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_TEXTURE_2D);
    glGenTextures(3, &this->texture);
    glBindTexture(GL_TEXTURE_2D, this->texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, 3, this->width(), this->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glDisable(GL_TEXTURE_2D);

    this->original = cv::Mat(this->height(), this->width(), CV_8UC4);
    memset(this->original.data, 0xff, this->original.rows * this->original.step);

    this->repaint = true;
}

如您所见,此时初始化时会显示大小为1000x808(屏幕大小)的空白图像(因为图像尚未构建)

当图像开始构建时(每5列)我将图像(通过setImage)发送到屏幕,然后在覆盖paintGL函数上使用OpenGL渲染:

setImage(cv::Mat imageRGBA)
{
    this->original = imageRGBA;
    this->repaint = true;
    update();
}
paintGL()
{
    if (this->repaint) {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glEnable(GL_TEXTURE_2D);

        glBindTexture(GL_TEXTURE_2D, this->texture);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, this->original.cols, this->original.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->original.data );

        glBegin(GL_QUADS);
        glTexCoord2f(0,1); glVertex2f(0,this->height());
        glTexCoord2f(0,0); glVertex2f(0,0);
        glTexCoord2f(1,0); glVertex2f(this->width(),0);
        glTexCoord2f(1,1); glVertex2f(this->width(),this->height());
        glEnd();

        glDisable(GL_TEXTURE_2D);

        this->repaint = false;
    }
}

Considerations: 正如您所看到的,我只使用尺寸为1000x808(固定)的2D图像,并且它不需要太多的渲染能力 . 我目前正在编写此代码以使用英特尔酷睿i3 Haswell机器(集成了英特尔高清显卡) . 最重要的是Linux Ubuntu 14.04 x64操作系统,安装了最新的intel驱动程序 .

Expectation: 我希望尽快渲染/绘制图像,而不会闪烁 . 我有大约150个1000x808图像连续渲染(图像构建过程之间约12毫秒) . 我希望在屏幕上呈现平滑的~60Hz平滑图像

Questions:

  • 根据我的代码,我需要做些什么才能提高性能并停止闪烁?

  • 除了当前的QGLWidget之外,是否真的有必要转移到QOpenGLWidget(不建议使用?)?

  • 由于我编写了OpenGL "immediate mode"代码,我是否应考虑转向VBO / PBO / VAO?哪一个最适合我?

  • 我是否因为提高性能而需要进行Linux调整?如果是这样,那是什么样的?

  • 非常欢迎任何形式的帮助!