Быстрое рисование / рендеринг 2d текстуры изображения
Я волнуюсь, чтобы решить мерцание моего программного обеспечения во время работы / обработки изображений.
Сначала я представлю свою проблему, объясню, что я сделал, затем в конце я оставлю свои вопросы / потребности:
Моя программа обрабатывает изображения и сразу показывает их на экране, действуя как сканер. Пиксели изображения строятся с использованием фотодатчиков изображения, обрабатываются с использованием OpenCV и рисуются на экране как можно быстрее, чтобы обеспечить плавное движение во время генерирования изображения.
На практике у меня сначала получается белое сплошное изображение размером 1000x808, пиксели которого заменяются соответствующими фотосенсорными встроенными изображениями и отображаются на экране так, что изображение перетекает слева направо на экране. Весь процесс генерации каждого кадра длится около 10 ~ 12 мс.
Тем не менее, кадры не течет, как ожидалось, на экране. Много мигает. Поскольку я понятия не имею, как измерить FPS в OpenGL, я предполагаю, что мой код OpenGL (который я вообще ничего не знаю о OpenGL) вызывает мерцание.
Я использую следующий код в моем GLWidget, который я приложил все усилия, чтобы написать, но я совершенно уверен, что он написан не с лучшей производительностью OpenGL.
У меня почти ничего нет в моем конструкторе GLWidget, но я играю с этими функциями, без существенного эффекта:
QGLFormat glFormat;
glFormat.setSwapInterval(0);
glFormat.setDoubleBuffer(true);
glFormat.setSampleBuffers(true);
glFormat.setDirectRendering(true);
glFormat.setSamples(4);
setFormat(glFormat);
Мой initializeGL показан следующим образом:
initializeGL()
{
glClearColor(255.0f,255.0f,255.0f,0.1f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,this->width(), this->height(), 0.0f,0.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glGenTextures(3, &this->texture);
glBindTexture(GL_TEXTURE_2D, this->texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, this->width(), this->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glDisable(GL_TEXTURE_2D);
this->original = cv::Mat(this->height(), this->width(), CV_8UC4);
memset(this->original.data, 0xff, this->original.rows * this->original.step);
this->repaint = true;
}
Как вы можете видеть, в этот момент при инициализации отображается пустое изображение размером 1000x808 (размер экрана) (поскольку изображения еще не созданы)
Когда изображения начинают строиться (через каждые 5 столбцов), я отправляю изображение (через setImage) на экран, затем оно рендерится с OpenGL на переопределенную функцию paintGL:
setImage(cv::Mat imageRGBA)
{
this->original = imageRGBA;
this->repaint = true;
update();
}
paintGL()
{
if (this->repaint) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, this->texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, this->original.cols, this->original.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->original.data );
glBegin(GL_QUADS);
glTexCoord2f(0,1); glVertex2f(0,this->height());
glTexCoord2f(0,0); glVertex2f(0,0);
glTexCoord2f(1,0); glVertex2f(this->width(),0);
glTexCoord2f(1,1); glVertex2f(this->width(),this->height());
glEnd();
glDisable(GL_TEXTURE_2D);
this->repaint = false;
}
}
Соображения: Как вы можете видеть, я работаю только с 2D-изображениями размером 1000x808 (исправлено), и для рендеринга не требуется слишком много энергии. В настоящее время я пишу код для работы на компьютере Intel Core i3 Haswell (со встроенной Intel HD Graphics). Вверху Linux Ubuntu 14.04 x64 OS с установленными последними драйверами Intel.
Ожидание: я ожидаю визуализировать / нарисовать изображения как можно скорее, без мерцания. У меня есть около 150 1000x808 изображений для рендеринга подряд (с ~ 12 мс между процессами сборки изображений). Я бы хотел, чтобы на экране отображались плавные изображения с частотой ~60 Гц.
Вопросы:
- Основываясь на моем коде, что мне нужно сделать для повышения производительности и прекращения мерцания?
- Действительно ли необходимо перейти на QOpenGLWidget, отличный от текущего QGLWidget (устарело?)?
- Поскольку мне был написан код OpenGL "немедленный режим", стоит ли мне переходить на VBO/PBO/VAO? И какой из них лучше всего подходит для меня?
- Нужны ли в Linux настройки для улучшения производительности? Если да, то что?
- Любая помощь очень приветствуется!