Инициализируйте QGLWidget с помощью glClearColor

у меня есть 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 снова закрашивает мой экран в черный цвет? И что еще более важно, как я могу убедиться, что мой собственный цвет экрана по умолчанию, не перекрашивая его пустым на каждом шаге по времени?

3

Решение

Короткий ответ:

На большинстве платформ состояние вашего резервного буфера не определено после выполнения замены буфера. Вы можете найти более подробную информацию Вот. Следовательно, вы не можете полагаться на поведение вашего буфера, оставляемого до операций подкачки. Затем, чтобы убедиться, что ваша программа кроссплатформенная, вы другого выбора нет чем звонить glClear() на каждом розыгрыше.

На практике:

Вполне возможно, что ваша платформа / конфигурация гарантируют, что ваш буфер неизменен, или не гарантируют это, но это все еще имеет место на практике. Если вы знаете, что находитесь в этих случаях после экспериментов (см. Ниже), но ваш экран по-прежнему становится черным, это означает, что каким-то образом в вашем коде вы сделали что-то «не так», что заставляет Qt явно вызывать glClear() со своим glClearColor(),

Вы можете использовать этот код, чтобы увидеть, остается ли буфер неизменным после swapBuffers (). Это действительно так в моей конфигурации: Qt 4.8 на Linux 64bit:

// -------- 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тогда я звоню только glClearColor() раз и навсегда в initializeGL(), Затем в paintGLЯ чередую звонить glClear() или не называть это. Экран остается красным, то есть никогда не становится черным (или отображает единорога), даже когда glClear() не называется.

Следовательно, относительно вашей проблемы:

  1. Либо ваша конфигурация отличается от моей (реализация swapBuffers предоставляется Qt и отличается в зависимости от базовой оконной системы)

  2. Или ваш код не работает.

Простой способ проверить это: скомпилировать мой код и посмотреть, воспроизводит ли он проблему по-прежнему. Если это так, то вы в случае 1., и вы ничего не можете с этим поделать (это можно считать ошибкой Qt, скорее несоответствия, так как правильное поведение не указано нигде в документации). В противном случае вы находитесь в случае 2., а затем вам следует предоставить больше кода, чтобы мы могли определить, в чем проблема.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]