我有一个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再次将我的屏幕涂成黑色?更重要的是,如何确保屏幕是我自己的默认颜色,而不是在每个时间步骤重新绘制它?
答案 0 :(得分:2)
简答:
在大多数平台上,执行缓冲区交换后,后备缓冲区的状态为 undefined 。您可以找到更多详细信息here。因此,在交换操作之前,您不能依赖缓冲区保留的行为。然后,为了确保您的程序是跨平台的,您别无选择,而不是在每张图纸上调用glClear()
。
在实践中:
您的平台/配置可能确保您的缓冲区保持不变,或者不保证它,但实际情况仍然如此。如果你在实验后知道你处于这种情况下(见下文),但仍然让你的屏幕变黑,这意味着在你的代码中,你做了一些“错误”的事情,使Qt明确地用自己的glClear()
调用glClearColor()
。
您可以使用此代码查看swapBuffers()后缓冲区是否保持不变。在我的配置中实际情况如此:Linux 64位上的Qt 4.8:
// -------- 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;
};
如果test == true
,那么我总是拨打glClearColor()
,然后是glClear()
,但每秒都会在红色和绿色之间交替。我确实看到颜色在红色和绿色之间来回切换。
如果test == false
,那么我只会在glClearColor()
中一次性致电initializeGL()
。然后在paintGL
中,我在调用glClear()
或不调用它之间交替。屏幕保持红色,即使未调用glClear()
,也不会变黑(或显示独角兽)。
因此,关于你的问题:
您的配置与我的配置不同(交换缓冲区的实现由Qt提供,并根据底层窗口系统而有所不同)
或者您的代码已损坏。
简单的检查方法:编译我的代码,看它是否仍然能够重现问题。如果确实如此,那么你就是1,并且你无能为力(可以认为是Qt的一个错误,而不是一个不一致,因为在文档中没有指定正确的行为)。否则,你是2,然后你应该提供更多的代码,以便我们确定问题的位置。