使用glClearColor初始化QGLWidget

Initialise a QGLWidget with a glClearColor

本文关键字:QGLWidget 初始化 glClearColor 使用      更新时间:2023-10-16

我有一个带有QGLWidgetQMainWindow。我希望小部件显示我自己选择的"清晰"颜色,而不是默认的黑屏。

void MyQGLWidget::initializeGL(void) {
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
}
void MyQGLWidget::paintGL(void) {       
     qDebug("Painting grey-ness");
     glClear(GL_COLOR_BUFFER_BIT);
     // ... Do more stuff, but only after a certain event has happened ...
}

这是有效的,我注意到该方法在启动过程中被调用了4次。然而,我只想在paintGL()方法中把它涂成空白,因为这个方法在启动后经常被调用,如果每次调用都清除缓冲区,实际上会有很小但显著的性能损失。

所以我把代码改成了这个:

void MyQGLWidget::paintGL(void) {
    static bool screenOnBlank = false;
    if (!screenOnBlank) {
         qDebug("Painting grey-ness");
         glClear(GL_COLOR_BUFFER_BIT);
         screenOnBlank = true;
     }
    // ... Do more stuff, but only after a certain event has happened ...
}

现在只清理了一次,但我留下了一个黑色屏幕,而不是glClearColor的灰色屏幕。为什么会这样?为什么QGLWidget再次将我的屏幕涂成黑色?更重要的是,我如何确保屏幕是我自己的默认颜色,而不在每个时间步骤都将其重新涂成空白?

简短回答:

在大多数平台中,执行缓冲区交换后,后台缓冲区的状态为未定义。您可以在此处找到更多详细信息。因此,您不能依赖于在交换操作之前离开缓冲区时所保留的行为。然后,为了确保您的程序是跨平台的,您别无选择,只能在每次绘图时调用glClear()

实践中:

您的平台/配置可能确实保证了缓冲区不变,或者不保证,但在实践中仍然如此。如果你在实验后知道自己处于这种情况(见下文),但屏幕仍然变黑,这意味着在你的代码中,你做了一些"错误"的事情,使Qt用自己的glClearColor()显式调用glClear()

您可以使用此代码查看swapBuffers()之后缓冲区是否保持不变。事实上,我的配置是这样的:Linux上的Qt 4.8 64位:

// -------- main.cpp --------
#include <QApplication>
#include "GLWidget.h"
int main(int argc, char ** argv)
{
    QApplication app(argc, argv);
    GLWidget * w = new GLWidget();
    w->show();
    return app.exec();
}

// -------- GLWidget.h --------
#include <QGLWidget>
#include <QTimer>

class GLWidget: public QGLWidget
{
    Q_OBJECT
public:
    GLWidget() : i(0), N(60)
    {
        timer.setInterval(16);
        connect(&timer, SIGNAL(timeout()), 
              this, SLOT(animationLoop()));
        timer.start();
    }

protected:
     void initializeGL()
     {
         glClearColor(1.0, 0.0, 0.0, 1.0);
     }
     void resizeGL(int w, int h)
     {
         glViewport(0, 0, (GLint)w, (GLint)h);
     }
     void paintGL()
     {
         bool test = false;
         if(i<N)
         {
             if(test)
                 glClearColor(1.0, 0.0, 0.0, 1.0);
             glClear(GL_COLOR_BUFFER_BIT);
         }
         else
         {
             if(test)
             {
                 glClearColor(0.0, 1.0, 0.0, 1.0);
                 glClear(GL_COLOR_BUFFER_BIT);
             }
         }
     }
private slots:
    void animationLoop() 
    {
         i++;
         if(i>2*N) i=0;
         updateGL();
    }
private:
    int i, N;
    QTimer timer;
};
  1. 如果是test == true,那么我总是调用glClearColor(),然后是glClear(),但每秒在红色和绿色之间交替。我确实看到颜色在红色和绿色之间来回切换。

  2. 如果是test == false,那么我在initializeGL()中只调用glClearColor()一次。然后在paintGL中,我在调用glClear()和不调用它之间交替。屏幕保持红色,即即使不调用glClear(),也不会变黑(或显示独角兽)。

因此,关于您的问题:

  1. 要么你的配置与我的不同(swapBuffers的实现由Qt提供,根据底层窗口系统的不同而不同)

  2. 或者你的代码坏了。

简单的检查方法:编译我的代码,看看它是否还能重现问题。如果是这样,那么您处于情况1.,对此您无能为力(可以认为是Qt的一个错误,而不是不一致性,因为文档中没有指定正确的行为)。否则,您将处于情况2.,然后您应该提供更多的代码,以便我们可以确定问题所在。