OpenGL之FBO(Frame Buffer Object)和多次离屏渲染

194 篇文章 41 订阅
文章介绍了离屏渲染的概念,特别是通过FBO(帧缓冲对象)实现这一过程。首先,详细讲述了如何创建和绑定FBO,以及如何使用它来保存渲染结果。接着,通过示例代码展示了如何进行多次离屏渲染,实现多个处理步骤。作者强调了理解代码的重要性,并鼓励读者提问。
摘要由CSDN通过智能技术生成

第一次听到离屏渲染的时候觉得很高级,遥不可及,直到后来做高斯模糊的时候,需要通过两次处理来节省性能,一直玩一次渲染处理的我这时候才认识FBO,继而明白了离屏渲染,今天抽个空做个记录。

一、FBO怎么用

由于我玩纹理比较多,所以就通过纹理来介绍FBO的用法吧,对纹理不熟可以看看我之前文章。至于FBO是什么这种概念,可以百度下,到处都是,我就不写了。

FBO其实就是帧缓存对象,有时候渲染一次结束,需要保存处理的结果,当作下一次处理的输入时,我们就可以把上一次的处理纹理保存到帧缓存中,给下一个着色器输入即可。

1.FBO的创建和绑定

先上代码:

glGenFramebuffers(1, &FBO[0]); //和其他buffer类似的创建
	glGenTextures(1, &uTexture[2]); //再创建个纹理对象
	glBindTexture(GL_TEXTURE_2D, uTexture[2]); //绑定纹理,接下来设置纹理的默认参数
	//    为当前绑定的纹理对象设置环绕、过滤方式
	//    将纹理包装设置为GL_REPEAT(默认包装方法)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//    设置纹理过滤参数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); //此处尺寸设置要是窗口大小,很重要,也可以自己尝试别的尺寸,看效果
 
	glBindFramebuffer(GL_FRAMEBUFFER, FBO[0]); //绑定FBO
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uTexture[2], 0);//将纹理绑到FBO上
 
	glBindTexture(GL_TEXTURE_2D, 0);//解绑纹理对象
	glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑FBO

从上面可以看到我们为FBO绑定了一张空有尺寸无内容的纹理,为什么呢?因为我们用帧缓存是去存处理后的纹理的,所以绑定个啥样的都不重要,但尺寸要对!

2.FBO的使用

同样还是代码,在渲染时这么写:

glUseProgram(programObject[3]); // 使用着色器,假设我这里是第3号着色器
        glBindVertexArray(VAOId[0]); // 使用VAO信息
		glActiveTexture(GL_TEXTURE1); //激活纹理单元
		glBindTexture(GL_TEXTURE_2D, uTexture[0]);//设定纹理对象,0号纹理
		glUniform1i(glGetUniformLocation(programObject[3], "uTexture1"), 1);//将0号纹理绑定到shader中的纹理变量
		glBindFramebuffer(GL_FRAMEBUFFER, FBO[0]); //绑定FBO开始操作
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//绘制
        glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑FBO

从上述可以看出,跟普通使用着色器绘制相比就多了两行代码,绑定FBO和解绑,有了这两行代码,着色器处理后的结果将不会显示在窗口了,而是保存到FBO绑定的纹理对象上,比如上面绑定的2号纹理对象。离屏渲染也就是这么回事。

那么怎么使用这个FBO保存的纹理呢?怎么多次离屏渲染呢?看接下来的代码:

glUseProgram(programObject[1]); // 使用着色器
		glActiveTexture(GL_TEXTURE0); //激活纹理单元
		glBindTexture(GL_TEXTURE_2D, uTexture[2]);//绑定FBO[0]绑定的纹理对象
        glUniform1i(glGetUniformLocation(programObject[1], "uTexture1"), 0);//将纹理绑定到shader中的纹理变量
        glBindFramebuffer(GL_FRAMEBUFFER, FBO[1]); //绑定第二个FBO对象
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑
 
		glUseProgram(programObject[0]); // 使用着色器
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, uTexture[1]); //绑定FBO[1]绑定的纹理对象,假设为1号
		glUniform1i(glGetUniformLocation(programObject[0], "uTexture1"), 1);//将0号纹理绑定到shader中的纹理变量
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

上面代码先是使用了第一个FBO绑定的纹理,再是用第二个FBO对象去保存第二步着色器处理的纹理,再给第三步着色器使用,这样就利用两次离屏渲染实现了3次处理,当然我们还可以进行三次,四次的离屏渲染,以此类推。

二、总结

前期我也遇到了很多不知名问题,很是崩溃,但是逐行去理解代码之后,问题一一解决,沉下气静下心来理解代码很容易就通畅了。希望有问题可以提出来,非常感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值