第一次听到离屏渲染的时候觉得很高级,遥不可及,直到后来做高斯模糊的时候,需要通过两次处理来节省性能,一直玩一次渲染处理的我这时候才认识FBO,继而明白了离屏渲染,今天抽个空做个记录。
一、FBO怎么用
由于我玩纹理比较多,所以就通过纹理来介绍FBO的用法吧,对纹理不熟可以看看我之前文章。至于FBO是什么这种概念,可以百度下,到处都是,我就不写了。
FBO其实就是帧缓存对象,有时候渲染一次结束,需要保存处理的结果,当作下一次处理的输入时,我们就可以把上一次的处理纹理保存到帧缓存中,给下一个着色器输入即可。
1.FBO的创建和绑定
先上代码:
glGenFramebuffers(1, &FBO[0]);
glGenTextures(1, &uTexture[2]);
glBindTexture(GL_TEXTURE_2D, uTexture[2]);
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]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uTexture[2], 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
从上面可以看到我们为FBO绑定了一张空有尺寸无内容的纹理,为什么呢?因为我们用帧缓存是去存处理后的纹理的,所以绑定个啥样的都不重要,但尺寸要对!
2.FBO的使用
同样还是代码,在渲染时这么写:
glUseProgram(programObject[3]);
glBindVertexArray(VAOId[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, uTexture[0]);
glUniform1i(glGetUniformLocation(programObject[3], "uTexture1"), 1);
glBindFramebuffer(GL_FRAMEBUFFER, FBO[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
从上述可以看出,跟普通使用着色器绘制相比就多了两行代码,绑定FBO和解绑,有了这两行代码,着色器处理后的结果将不会显示在窗口了,而是保存到FBO绑定的纹理对象上,比如上面绑定的2号纹理对象。离屏渲染也就是这么回事。
那么怎么使用这个FBO保存的纹理呢?怎么多次离屏渲染呢?看接下来的代码:
glUseProgram(programObject[1]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, uTexture[2]);
glUniform1i(glGetUniformLocation(programObject[1], "uTexture1"), 0);
glBindFramebuffer(GL_FRAMEBUFFER, FBO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(programObject[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, uTexture[1]);
glUniform1i(glGetUniformLocation(programObject[0], "uTexture1"), 1);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
上面代码先是使用了第一个FBO绑定的纹理,再是用第二个FBO对象去保存第二步着色器处理的纹理,再给第三步着色器使用,这样就利用两次离屏渲染实现了3次处理,当然我们还可以进行三次,四次的离屏渲染,以此类推。
二、总结
前期我也遇到了很多不知名问题,很是崩溃,但是逐行去理解代码之后,问题一一解决,沉下气静下心来理解代码很容易就通畅了。希望有问题可以提出来,非常感谢!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)