OpenGL(九)使用 FrameBufferObject
来源:互联网 发布:苹果电脑看图软件 编辑:程序博客网 时间:2024/06/18 17:21
在OpenGL中所有的图形,都会绘制到 FrameBufferObject 上。如果想使用界面的做分屏渲染,或需要屏幕图像制成贴图以备后期处理,就需要用到 FrameBufferObject 技术,这种方式也被称为 RTT (Render to Texture)。
原理
通过
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,colorBuffer,0);
可以将ColorBuffer绑定到一张Texture上。当然也可以绑定到多张贴图中。另外使用这个函数也可以取出深度贴图。
当生成了自己的fbo之后,即可将图元绘制到贴图上面,可以理解为是一个预渲染的过程。
glBindFramebuffer(GL_FRAMEBUFFER,fbo);glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);draw();glBindFramebuffer(GL_FRAMEBUFFER,0);
然后在实际渲染时使用fbo中的贴图进行绘制。
实现
创建一个产生fbo的函数,并返回ColorBuffer与depthBuffer
GLuint CreateFrameBufferObject(GLuint &colorBuffer,int width,int height){ GLuint fbo; glGenFramebuffers(1,&fbo); glBindFramebuffer(GL_FRAMEBUFFER,fbo); //color buffer glGenTextures(1,&colorBuffer); glBindTexture(GL_TEXTURE_2D,colorBuffer); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,nullptr); glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,colorBuffer,0); glBindTexture(GL_TEXTURE_2D,0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if(status != GL_FRAMEBUFFER_COMPLETE) { printf("FBO Create Fail\n"); } glBindFramebuffer(GL_FRAMEBUFFER,0); return fbo;}
接着创建另一个program来做平面承接fbo中的texture。
//create fboGLuint colorBuffer;GLuint fbo = CreateFramebufferObject(colorBuffer, width, height);//main drawglBindFramebuffer(GL_FRAMEBUFFER, fbo);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);draw();glBindFramebuffer(GL_FRAMEBUFFER, 0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);RenderFullScreenQuad();glFlush();auto draw = [&]()->void{ //draw work}auto RenderFullScreenQuad = [&]()->void{ glUseProgram(fsqprogram); glBindTexture(GL_TEXTURE_2D, colorBuffer); glUniform1i(fsqtextureLocation, 0); glBindVertexArray(fsqvao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fsqibo); glDrawElements(GL_TRIANGLES, fsqindexCount, GL_UNSIGNED_INT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindVertexArray(0); glUseProgram(0);};
最后在shader中做一个全屏的面片,如果是标准的0.5为模型空间坐标的Quad可以简单的使用:
attribute vec3 pos;attribute vec2 texcoord;attribute vec3 normal;uniform mat4 M;uniform mat4 V;uniform mat4 P;varying vec2 V_Texcoord;void main(){ vec4 position=vec4(pos.x*2,pos.y*2,pos.z,1.0); V_Texcoord=texcoord; gl_Position=position;}
来制作一个全屏的面片,最终将贴图贴到面片上即可。这部分的实现可以参考之前的文章:OpenGL(三) 加载贴图。
总结
通过 FrameBufferObject (或称为RTT) 可以将画面抓到一张贴图中,有了这张图,我们就可以做很多后期处理的效果。
关注我的微信公众号,获取更多优质内容
0 0
- OpenGL(九)使用 FrameBufferObject
- OpenGL FrameBufferObject 基础 (1)
- Android OpenGL ES 2.0 (七) FramebufferObject(FBO)
- 在BlackBerry上使用OpenGL绘图(九):投影变换
- FrameBufferObject.cpp
- NeHe OpenGL教程 (九)
- OpenGL入门笔记(九)
- OpenGL入门学习(九)
- OpenGL入门学习(九)
- OPENGL学习视频(九)
- OpenGL学习笔记(九)
- 学习OpenGL(九)MFC与OpenGL编程
- openGL之光照1---openGL学习笔记(九)
- OpenGL基础图形编程(九)OpenGL颜色
- OpenGL---GLUT教程(九) GLUT鼠标
- OpenGL入门学习(九) 【转】
- OpenGL---GLUT教程(九) GLUT鼠标
- OpenGL---GLUT教程(九) GLUT鼠标
- Django中在template中使用静态文件
- linux虚拟机磁盘容量扩增
- Android nfc读卡模式流程
- Linux服务器的安装配置流程
- ActionContext,ServletContext和ServletActionContext有什么区别?
- OpenGL(九)使用 FrameBufferObject
- static和final的区别
- babel-polyfill的作用
- Volley和Ksoap框架整合
- Java 反射机制
- 使用TortoiseGit pull时,提示因为冲突导致拉取失败,怎么办?
- 彩票号码生成器
- Matlab studying~ 运算
- 苹果审核ipv6到底有多坑?看了你会少走很多路。