GLSL使用FBO实现MRT(Multiple Render Targets)绘制到多张纹理 【转】
项目的程序里设计需要将某一帧渲染出来的画面拆成三通道单色图像存到三张纹理里面。要绘制到纹理里,自然就想到FBO了。但是一次要输出多张纹理,这个还没接触过。一阵网上搜索过后,终于了解到了MRT(多重渲染目标)。但是网上的教程大部分都使用到了Fragment Shader里的一个预置变量:gl_FragData[]。但是实际使用当中,glsl却报告说这个gl_FragData变量是不建议使用了。于是再经过多方搜索,知道了建议的操作方法是如何实现的。
首先自然是新建一个FBO,然后绑定缓存。一般的FBO我们会绑定一个颜色缓存和一个深度缓存。如果是渲染到纹理,我们就会把一个同样尺寸的纹理绑到颜色缓存中去,比如以下代码:
- //新建FBO
- GLuint fboId;
- glGenFramebuffersEXT(1, &fboId);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
- //绑定纹理
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, textureId, 0);
- //绑定深度缓存
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT, rboId);
当然深度缓存也是要预先建好的。那么现在我需要绑定三个纹理,该如何绑定呢?
FBO是提供了不止一个颜色挂接点的。因此,我们可以将第i张纹理绑定到第i个颜色挂接点上。具体一个FBO能有多少个颜色挂接点,可以使用GL_MAX_COLOR_ATTACHMENTS_EXT参数来查询。
因此绑定纹理的代码就变成了:
- for(i=0; i<3; ++i)
- {
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i,
- GL_TEXTURE_2D, textureId[i], 0);
- }
当然纹理数量不能超过颜色挂接点的最大值。
准备工作完成之后,就是实际FBO渲染时的操作。在绑定多个纹理之后,绘制之前还要告诉FBO输出到哪些缓存。使用以下语句:
- GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
- glDrawBuffers(3, mrt);
以上语句先枚举要输出的挂接点,然后使用glDrawBuffers语句来指定。此处绘制3个纹理。这些信息将被传入GLSL当中。
在Fragment Shader里还需要加一些语句:
- //此处3个location应当与FBO的GL_COLOR_ATTACHMENTi_EXT对应
- layout(location = 0) out vec4 Frag0;
- layout(location = 1) out vec4 Frag1;
- layout(location = 2) out vec4 Frag2;
这里就不用原来的gl_FragColor或者gl_FragData[]变量了,而是用自己指定位置的输出值。然后在Fragment的主循环里可以针对三个输出值做自己需要的处理。
于是绘制完成后,FBO就会将渲染结果存入三张纹理当中,可以进行后续的使用。
参考:
http://blog.csdn.net/xiajun07061225/article/details/7283929
http://blog.csdn.net/yangdelong/article/details/1668673
http://www.cnblogs.com/vertexshader/articles/3022981.html
GLSL使用FBO实现MRT(Multiple Render Targets)绘制到多张纹理 【转】的更多相关文章
- 认识多渲染目标(Multiple Render Targets)技术 【转】
认识多渲染目标(Multiple Render Targets)技术 首先,渲染到纹理是D3D中的一项高级技术.一方面,它很简单,另一方面它很强大并能产生很多特殊效果. 比如说发光效果,环境映射,阴影 ...
- framebufferfetch in mali multiple render targets mrt
gl_LastFragColorARM https://www.khronos.org/registry/OpenGL/extensions/ARM/ARM_shader_framebuffer_fe ...
- 认识多渲染目标(Multiple Render Targets)技术【转】
http://www.cnblogs.com/hellohuan/archive/2008/12/01/1345359.html 首先,渲染到纹理是D3D中的一项高级技术.一方面,它很简单,另一方面它 ...
- GLSL实现Simple Displace Mapping 水仿真流体绘制 【转】
http://blog.csdn.net/a3070173/archive/2008/11/20/3342062.aspx Dislace Mapping其实就是在顶点着色器中 对顶点进行置换偏移,经 ...
- 渲染、render与绘制
渲染是抽象到具体的过程: 抽象:图片信息的描述(比如一条线:两个端点的位置.线粗.颜色等特征): 具体:依据抽象信息得到的可视图片(绘制过程). 渲染是中文翻译的问题,有种添油加醋的感觉.直意就是交与 ...
- OpenGL中FBO的概念及其应用 [转]
http://www.cppblog.com/kongque/archive/2010/08/26/124754.html FBO一个最常见的应用就是:渲染到纹理(render to texture) ...
- [OSG]OSG例子程序简介
1.example_osganimate一)演示了路径动画的使用(AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera.CameraView.M ...
- OSG中的示例程序简介
OSG中的示例程序简介 转自:http://www.cnblogs.com/indif/archive/2011/05/13/2045136.html 1.example_osganimate一)演示 ...
- OSG中的示例程序简介(转)
OSG中的示例程序简介 1.example_osganimate一)演示了路径动画的使用 (AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera ...
随机推荐
- 精确解释Unicode
来自:http://blog.csdn.net/gqqnb/article/details/6266542 ---------------------------------------------- ...
- docker从零开始网络(三) overly(覆盖)网络
使用overly网络 该overlay网络驱动程序会创建多个docker进程主机之间的分布式网络.该网络位于(覆盖)特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信.Dock ...
- python tips:列表推导
看一个代码: a=[1,2,3,4,5,6,7,8,9] b=[5 if (i >3) else 1 for i in a] print(b) 这就是列表推导. 列表推导一般用在通过一个list ...
- AC日记——逆序对 洛谷 P1908
逆序对 思路: 线段树水过: 代码: #include <cstdio> #include <cstring> #include <iostream> #inclu ...
- ajaxfileupload异步上传文件
ajaxfileupload插件可以以异步方式上传文件(其实现:iframe),不像传统那样需要刷新,下面就介绍下其使用 1.HTML部分(先引入jquery): <!DOCTYPE html& ...
- [centos6.5] 把xampp的htdocs改为其他目录
vim /opt/lampp/etc/httpd.conf DocumentRoot "/opt/lampp/htdocs" 改为 DocumentRoot "/var/ ...
- UVA 11636.Hello World!-水题
Hello World! Time limit: 1.000 seconds When you first made the computer to print the sentence “Hello ...
- ANDROID NFC读M1卡
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.Cons ...
- gcc与gdb的使用
1.gcc/g++编译过程: gcc/g++的编译格式: gcc [option][filename]... g++ [option][filename]... 1)processing:预处理过程, ...
- golang笔记:net/smtp
跟go语言的net/smtp斗争了一天,记录下历程. 先用最标准的例子 host := net.JoinHostPort(hostname, port) auth := smtp.PlainAut ...