与我的other question相关,我认为更重要的问题是,如何使用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());
但无论哪种方式,我都看不到图像,只是一个白色的正方形。我在这里错过了一些东西。
答案 0 :(得分:3)
我设法从图片来源中使用OpenGL绘制QImage
,但不是如here所描述的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
错误。
答案 1 :(得分:1)
如今,在Qt 5.11中,最简单的方法是使用QOpenGLWidget
并覆盖其paintEvent
方法。
在下面的代码中,OpenGLWidget
继承自QOpenGLWidget,display(const QImage& img)
是一个在我需要更新图像时触发的插槽。
无论在两个OpenGL渲染之间调用了display()多少次,update()
调用都不会直接触发渲染,它只是将小部件标记为脏,以便在下一个循环中重画。
这种方法实际上非常快,我正在使用它以240fps的速度显示摄像机帧(尽管并非所有帧都显示在屏幕上)。
void OpenGLWidget::display(const QImage& img)
{
image = img;
this->update();
}
void OpenGLWidget::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.drawImage(this->rect(),image);
}