QT下OpenGL的离屏渲染(Offscreen rendering)

本文介绍了在Qt环境下使用OpenGL的帧缓冲对象(FBO)进行离屏渲染的过程,包括FBO的初始化和纹理渲染。重点强调了在将FBO中的纹理渲染到默认帧缓冲时,必须正确获取并绑定Qt的默认Framebuffer对象,否则会导致渲染失败。提供了一个完整的Qt FBO使用示例,并给出了问题解决方法。
摘要由CSDN通过智能技术生成

        最近学习了一下OpenGL的相关知识,在此记录一下FBO的使用和Qt下离屏渲染的注意事项。

有关FBO的介绍在很多博客中都有介绍,本文就不再赘述了,FBO初始化代码:

glGenFramebuffers(1, &m_frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);

glGenTextures(1, &m_textureFBO);
glBindTexture(GL_TEXTURE_2D, m_textureFBO);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);//TODO
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureFBO, 0);

glGenRenderbuffers(1, &m_RBO);
glBindRenderbuffer(GL_RENDERBUFFER, m_RBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_width, m_height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RBO);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	qDebug() << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" ;
glBindFramebuffer(GL_FRAMEBUFFER, 0);

        成功将图像绘制到自己创建的FBO中的纹理后,如何将此纹理再渲染到默认的FBO中显示出来,有一个地方需要注意,否则会渲染失败。paintGL()函数如下:

glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);
glEnable(GL_DEPTH_TEST);

glClearColor(0.5f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

m_shaderProgram->bind();
glBindVertexArray(m_VAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_texture);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
m_shaderProgram->release();

/********** 关键之处 ***********/
//通过api获取qt绘制时默认的framebuffer编号,此编号不一定为0
//但是glfw或glut中framebuffer默认编号是0
GLuint fb = context()->defaultFramebufferObject();
glBindFramebuffer(GL_FRAMEBUFFER, fb);

glDisable(GL_DEPTH_TEST);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, m_width, m_height);

m_programScreen->bind();
glBindVertexArray(m_fVAO);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_textureFBO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
m_programScreen->release();

如果是用glfw或glut,绑定默认Framebuffer时,通常是用:

glBindFramebuffer(GL_FRAMEBUFFER, 0);

        但在Qt中,当前Framebuffer的id不一定是0,而很多博客或代码中都是直接绑定0,往往就是因为绑定的id不对,导致渲染失败。楼主就是在这里耽误了好久,以为是FBO初始化过程有错误,于是不停的改,但就是不能解决问题。

正确的方法是:

GLuint fb = context()->defaultFramebufferObject();
glBindFramebuffer(GL_FRAMEBUFFER, fb);


        在paintGL()中,通过context()->defaultFramebufferObject()获取当前Framebuffer的id,然后glBindFramebuffer()这个ID号。

完整的demo:https://github.com/986247404/Qt-OpenGL-FBO

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值