繁体   English   中英

使用OpenGL渲染QImage

[英]Render QImage with OpenGL

与我的其他问题相关 ,我认为更重要的问题是,如何使用OpenGL渲染QImage

我认为代码必须看起来像这样,但我不确定我还需要什么,除了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());

但无论哪种方式,我都看不到图像,只是一个白色正方形的大小。 我在这里遗漏了一些东西。

我设法绘制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错误。

如今,使用Qt 5.11,最简单的方法是使用QOpenGLWidget并覆盖其paintEvent方法。

在下面的代码中, OpenGLWidget继承自QOpenGLWidget,而display(const QImage& img)是每当我需要更新图像时触发的插槽。

无论在两个OpenGL渲染之间调用display()多少次, update()调用都不直接触发渲染,它只是将widget标记为脏,以便在下一个循环中重绘。

这种方法实际上非常快,我用它以240fps显示相机帧(虽然并非所有帧都显示在屏幕上)。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM