Визуализация QImage с OpenGL

Связанный с моим другой вопрос, Я думаю, что более центральный вопрос будет, как вы делаете QImage с OpenGL?

Я думаю, что код должен выглядеть примерно так, но я не уверен, что еще мне нужно, кроме, возможно, convertToGLFormat(img),

glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glGenTextures(1, &offscreenBufferTexture);
glBindTexture(GL_TEXTURE_2D, offscreenBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgGL.width(),
imgGL.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
imgGL.bits());

glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2d(0, 0);
glTexCoord2d(1,0); glVertex2d(windowSize.width(), 0);
glTexCoord2d(1,1); glVertex2d(windowSize.width(), windowSize.height());
glTexCoord2d(0,1); glVertex2d(0, windowSize.height());
glEnd();
glDisable(GL_TEXTURE_2D);

Кроме того, я думал, что быстро и грязно вы можете использовать glDrawPixels() (хотя вы не должны), как

glDrawPixels(imgGL.width(), imgGL.height(), GL_RGBA,
GL_UNSIGNED_BYTE, imgGL.bits());

Но в любом случае я не могу видеть изображение, просто белый квадрат с размером его. Я что-то здесь упускаю.

5

Решение

Мне удалось нарисовать QImage с OpenGL из источника изображения, но не из SoOffscreenRenderer как описано Вот.

void init(){
loadTexture2("kitten.png", backgroundimage);
}

QImage loadTexture2(char *filename, GLuint &textureID){
glEnable(GL_TEXTURE_2D); // Enable texturing

glGenTextures(1, &textureID); // Obtain an id for the texture
glBindTexture(GL_TEXTURE_2D, textureID); // Set as the current texture

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

QImage im(filename);
QImage tex = QGLWidget::convertToGLFormat(im);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glDisable(GL_TEXTURE_2D);

return tex;
}

void renderSceneGL2(){
glClearColor(0.4f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, backgroundimage);

glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(-1, -1, -1);
glTexCoord2f(1,0); glVertex3f(1, -1, -1);
glTexCoord2f(1,1); glVertex3f(1, 1, -1);
glTexCoord2f(0,1); glVertex3f(-1, 1, -1);

glEnd();

glDisable(GL_TEXTURE_2D);
}

Также QGLWidget::convertToGLFormat выбрасывает случайным образом Access violation время от времени ошибки.

3

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

В наше время с Qt 5.11 проще всего использовать QOpenGLWidget и переопределить его paintEvent метод.

В следующем коде OpenGLWidget наследовать от QOpenGLWidget и display(const QImage& img) слот срабатывает всякий раз, когда мне нужно обновить изображение.

Независимо от того, сколько раз вызывается display () между двумя рендерингами OpenGL, update() call не запускает рендеринг напрямую, он просто помечает виджет как грязный для перерисовки в следующем цикле.

Этот метод на самом деле довольно быстрый, я использую его для отображения кадров камеры со скоростью 240 кадров в секунду (хотя не все кадры отображаются на экране).

void OpenGLWidget::display(const QImage& img)
{
image = img;
this->update();
}

void OpenGLWidget::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.drawImage(this->rect(),image);
}
1

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