c++ - 使用 glClearColor 初始化 QGLWidget

标签 c++ qt qt4.8 qglwidget

我有一个QMainWindow,里面有一个QGLWidget。我希望小部件显示我自己选择的“清晰”颜色,而不是默认的黑屏。

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 再次将我的屏幕涂黑?更重要的是,我如何才能确保屏幕是我自己的默认颜色,而不是在每个时间步骤都将其重新绘制为空白?

最佳答案

简答:

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

实践中:

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

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

// -------- 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() 或不调用它。屏幕保持红色,即永远不会变黑(或显示 unicorn ),即使未调用 glClear() 也是如此。

因此,关于您的问题:

  1. 要么你的配置和我的不一样(swapBuffers的实现是Qt提供的,根据底层window系统不同)

  2. 或者您的代码已损坏。

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

关于c++ - 使用 glClearColor 初始化 QGLWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17295963/

相关文章:

c++ - Qt - 事物如何协同工作?

qt - 更改对话框窗口大小时使 QTableWidget 展开

qt - QTreeView 中的 QModelIndexList 提供调试断言

c++ - 基本的 C++ 继承

c++ - OpenCL 结构数组中的动态数组

c++ - 使用指向对象的指针初始化不可复制的第三方基类

linux - QFileIconProvider 总是使用 "gnome"主题?

c++ - 错误 C2059 : 'constant' when trying to create a Qt container in a header file with known size

C++ Game Started terminate 在抛出 'std::out_of_range' 实例后调用

c++ - 如何让cin只接受数字