Render QImage with OpenGL

拥有回忆 提交于 2019-12-04 09:37:44

问题


Related to my other question, I think the more central question would be, how you render a QImage with OpenGL?

I think the code has to look something like this, but I'm not sure what else I need, besides maybe 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);

Also, I thought quick and dirty you could use glDrawPixels() (although you shouldn't), like

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

But either way I can't see the image, just a white square with the size of it. I'm missing something here.


回答1:


I managed to draw a QImage with OpenGL from a picture source, but not from the SoOffscreenRenderer as described here.

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);
}

Also QGLWidget::convertToGLFormat throws random Access violation errors from time to time.




回答2:


Nowadays, with Qt 5.11, the easiest way is to use QOpenGLWidget and override its paintEvent method.

In the following code OpenGLWidget inherite from QOpenGLWidget, and display(const QImage& img) is a slot triggered whenever I need to update the image.

No matter how many times display() is called between two OpenGL rendering, the update() call doesn't trig rendering directly, it just marks widget dirty for redrawing on next loop.

This method is actually pretty fast, I'm using it to display camera frames at 240fps (although not all frames are displayed on screen).

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

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


来源:https://stackoverflow.com/questions/20245865/render-qimage-with-opengl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!