Короткий ответ:
В большинстве платформ, состояние вашего BackBuffer является неопределенной после выполнения буфера подкачки. Вы можете найти более подробную информацию here. Следовательно, вы не можете полагаться на поведение вашего буфера, оставив его перед операциями свопинга. Затем, чтобы ваша программа была кросс-платформенной, у вас нет другого выбора, чем позвонить glClear()
на каждом рисунке.
На практике:
Вполне возможно, что ваша платформа/конфигурация которых гарантирует, что ваш буфер остается неизменным, или не гарантируют, но она все еще имеет место на практике. Если вы знаете, что находитесь в этих случаях после экспериментов (см. Ниже), но все же ваш экран стал черным, это значит, что каким-то образом в вашем коде вы сделали что-то «неправильное», что делает Qt явно называть glClear()
со своим собственным glClearColor()
.
Этот код можно использовать, чтобы проверить, остается ли буфер после изменения swapBuffers(). Это на самом деле происходит в моей конфигурации: Qt 4.8 на 64bits Linux:
// -------- 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()
не вызывается.
Таким образом, в отношении вашей проблемы:
Либо ваша конфигурация отличается от шахты (реализация SwapBuffers обеспечивается Qt и отличается в зависимости от основной оконной системы)
Или ваш код сломан.
Простой способ проверить: скомпилировать мой код и посмотреть, продолжает ли он воспроизводить проблему. Если это так, то вы на случай 1., и вы ничего не можете с этим поделать (это можно считать ошибкой Qt, а скорее несогласованностью, поскольку правильное поведение не указано нигде в документации). В противном случае вы находитесь в случае 2., а затем вы должны предоставить больше своего кода, чтобы мы могли определить, в чем проблема.
Хорошее предложение, но, к сожалению, неверно. Я попробовал, но это не имеет значения. – Yellow
А что если вы попробуете 'setAutofillBackground (false)' в конструкторе вашего 'QGLWidget'? Если это не сработает, у вас нет другого выбора, кроме как очистить буфер на каждом 'paintGL'. Обратите внимание, что поражение производительности не должно быть проблемой, это то, что делает любая оптимизированная игра в любом случае. ;-) – Boris
И это не работает, я боюсь. Я знаю, что даже в оптимизированных играх функция glClear вызывается, но у меня есть сильное моделирование, работающее в фоновом режиме, поэтому любое небольшое сокращение накладных расходов стоит того. – Yellow