缓冲区有很多用途:可以保存顶点数据,像素数据,纹理数据,着色器处理的输入,不同着色器阶段的输出。

缓冲区保存在GPU内存中,提供高速有效的访问。
 
像素缓冲区对象:
GLuint pixBufferObjs[1];
glGenBuffers(1,pixBuffObjs);
glBindBuffer(GL_PIXEL_PACK_BUFFER,pixBuffObjs[0]);
glBufferData(GL_PIXEL_PACK_BUFFER,pixelDataSize,pixelData,GL_DYNAMIC_COPY);//分配像素缓冲区对象的大小
glDeleteBuffers(1,pixBuffObjs);
 
void glBufferSubData(GLenum target,intptr offset,sizeiptr size,const void *data);
 
当一个像素缓冲区对象被绑定到这个目标上GL_PIXEL_PACK_BUFFER,任何读取像素的OpenGL操作都会从像素缓冲区对象中获取它们的数据。
 
 
纹理缓冲区对象:
纹理缓冲区能够用来提供对片段着色器和顶点着色器中的顶点数组的访问。常常需要将texBO(纹理缓冲区对象的名称)大小作为一个统一值传递到着色器中。
纹理缓冲区是作为普通的缓冲区来创建的,当它被绑定到一个纹理或者GL_TEXTURE_BUFFER绑定点时会成为真正的纹理缓冲区。
 
GLuint texBO[1];
glGenBuffers(1,texBO);
glBindBuffer(GL_TEXTURE_BUFFER,texBO[0]);
glBufferData(GL_TEXTURE_BUFFER,sizeof((float)*count),fileData,GL_STATIC_DRAW);
 
但是texBO必须绑定到一个纹理单元上才能变得真正有用。要将一个texBO绑定到一个纹理单元上,得调用glTexBuffer,但首先得确定使用的纹理已经进行了绑定。
glActiveTexture(GL_TEXTURER1);
glBindTexture(GL_TEXTURE_BUFFER,texBOTexture);//纹理对象
glTexBuffer(GL_TEXTURE_BUFFER,GL_R32F,texBO[0]);//将texBO纹理缓冲区对象绑定到texBOTexture纹理单元上
 
纹理缓冲区对象不能在着色器中使用普通的采样器(sampler1D和sampler2D)进行访问,得使用samplerBuffer采样器,采样函数也不同,得使用texelFetch从纹理缓冲区中进行读取。
当着色器在一个纹理缓冲区中进行查询时,必须使用基于整数的非标准化索引,texelFetch函数接受从0到缓冲区大小值的整数索引。
 
帧缓冲区对象:
默认的帧缓冲区对象是与创建的OpenGL窗口相关联的,并且在一个新的环境被绑定时自动进行绑定。我们可以创建多个帧缓冲区对象,即FBO,并且直接渲染到一个FBO而不是窗口中。
帧缓冲区对象不受窗口大小的限制,它可以包含多个颜色缓冲区。甚至可以直接将一个纹理绑定到一个FBO上,也即可以直接渲染到一个纹理中。
并不存在与一个帧缓冲区对象相关联的真正内存存储空间。帧缓冲区对象只是一个容器,它可以保存其他确实有内存存储并且可以进行渲染的对象,如纹理或者渲染缓冲区。
 
GLuint fboName;
glGenFramebuffers(1,&fboName);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,fboName);//同一时间只有一个FBO可以绑定用来进行绘制,并且同一时间只有一个FBO可以绑定来进行读取。
                                                                                 //第一个参数既可以是GL_DRAW_FRAMEBUFFER,也可以是GL_READ_FRAMEBUFFER
 
glDeleteFrameBuffers(1,&fboName);
 
渲染缓冲区对象:
RBO是一种图像表面,专门为绑定到FBO而设计。
一个渲染缓冲区对象可以是一个颜色表面,模板表面或者深度/模板组合表面。可以给给定的FBO挑选任意的RBO组合。可以一次性绘制多个颜色缓冲区。
 
glGenRenderBuffers(3,renderBufferNames);
glBindRenderbuffer(GL_RENDERBUFFER,renderBufferNames[0]);//和FBO一样,RBO需要先进行绑定才能修改
RBO绑定后,需要分配支持RBO的内存空间。RBO在创建时是没有初始存储的,没有存储就没有任何东西可以渲染。
glBindRenderbuffer(GL_RENDERBUFFER,renderBufferNames[0]);
glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA8,screenWidth,screenHeight);
glBindRenderbuffer(GL_RENDERBUFFER,depthBufferName);
glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT32,screenWidth,screenHeight);
 
一个帧缓冲区可以有多个绑定点:一个深度绑定点,一个模板绑定点,多个颜色绑定点。
//将渲染缓冲区对象绑定到帧缓冲区对象
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,fboName);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,depthRenderName);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_RENDERBUFFER,renderBufferNames[0]);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT1,GL_RENDERBUFFER,renderBufferNames[1]);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT2,GL_RENDERBUFFER,renderBufferNames[2]);
 
要获得对渲染缓冲区的访问,第一,确保片段着色器设置正确,第二,确保输出被引导到正确的位置。
 
着色器输出:
为了将颜色输出到多个缓冲区,着色器必须配置为写入多重颜色输出。从着色器写入颜色输出的一种方法是写入到名为gl_FragData[n]的内建输出中,n的值是着色器的输出索引。
 
缓冲区映射:
OpenGL允许一个应用程序通过为每个缓冲区指定颜色绑定来将着色器输出映射到不同的FBO缓冲区。默认的行为是一个单独的颜色输出将被发送到颜色绑定0。
通过调用glDrawBuffers来对着色器输出进行路由。将覆盖之前所有的映射,即使现在指定的映射数量比上一次的少。
 
GLenum fboBuffers[]={
                                   GL_COLOR_ATTACHMENT0,
                                   GL_COLOR_ATTACHMENT1,
                                   GL_COLOR_ATTACHMENT2
                                   };
glDrawBuffers(3,fboBuffers);
在调用glDrawBuffers之前,要确保FBO已经被绑定。如果由一个在用户创建的FBO被绑定的情况下使用glDrawBuffers,那么合法的缓冲区目标为从GL_COLOR_ATTACHMENT0到“1减去最大值”,或者为GL_NONE。除了GL_NONE之外,其他的值都可以且只可以使用一次。
如果默认的FBO被绑定,那么可以使用与窗口相关联的颜色缓冲区名称,一般为GL_BACK_LEFT。
如果默认的FBO被绑定,或者着色器程序被写入到gl_FragColor,那么我们传递到glDrawBuffers的所有缓冲区都会获得相同的颜色。
不要忘记在使用FBO之后恢复绘制缓冲区的设置,否则将会产生错误。

GLenum windowBuff[]={GL_FRONT_LEFT};
glDrawBuffers(1,windowBuff);
 
帧缓冲区完整性:
绑定完整性、整个缓冲区的完整性
检查完整性函数:
GLenum fboStatus=glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
 
在帧缓冲区中复制数据:
使用blit命令可以将像素数据从一点移动到另外一个点。
void glBlitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter);
复制的源是通过调用glReadBuffer指定的读取缓冲区,复制的目标是通过调用glDrawBuffer指定的当前绘制缓冲区。
如果我们将读取和绘制缓冲区设置为同一个FBO,并将同一个FBO绑定到了GL_DRAW_FRAMEBUFFER和GL_READ_FRAMEBUFFER,那么我们甚至可以将数据从一个缓冲区的一部分复制到缓冲区的另一部分。

OpenGL超级宝典第5版&&缓冲区的更多相关文章

  1. OpenGL超级宝典第5版&&基础渲染

    1.OpenGL查询拓展机制是否被支持 gltools函数库: int gltIsExtSupported(const char *extension) { #ifndef OPENGL_ES GLi ...

  2. OpenGL超级宝典第5版&&glProvokingVertex

    翻译:https://www.opengl.org/sdk/docs/man3/xhtml/glProvokingVertex.xml 方法原型:void glProvokingVertex(GLen ...

  3. OpenGL超级宝典第5版&&GLSL法线变换

    在GLSL中,有一些情况需要把局部坐标系下的向量或点转换到视点坐标系下,如光照计算时,需要把法向转化到视点坐标系.如果是模型上一点p 转化到视点坐标系下,直接(model-view matrix )* ...

  4. OpenGL超级宝典第5版&&开发环境搭建

    参考:http://www.zyh1690.org/build-opengl-super-bible-fifth-edition-development-environment/ 环境搭建的测试环境为 ...

  5. 【极简版】OpenGL 超级宝典(第五版)环境配置 VS2010

    事先声明:该教程仅适用于VS2010环境下超级宝典第五版的配置 第一步:下载示例代码和环境包: 链接:https://pan.baidu.com/s/1llRRQ8ymBgMGuXp5M50pJw 提 ...

  6. OpenGL超级宝典visual studio 2013开发环境配置,GLTools

    做三维重建需要用到OpenGL,开始看<OpenGL超级宝典>,新手第一步配置环境就折腾了一天,记录下环境的配置过程. <超级宝典>中的例子使用了GLEW,freeglut以及 ...

  7. 问题解决——OpenGL超级宝典 第四章 4.5.2 关于freeglut.lib问题的解决过程

    看<OpenGL超级宝典(第四版)>的4.5.2节时遇到了一系列问题,经过不懈努力终于解决,现将过程记录在下,以便查找追思. 在第4.5.2节之前,自己写的的代码都没有使用作者的gltoo ...

  8. OpenGL超级宝典笔记----框架搭建

    自从工作后,总是或多或少的会接触到客户端3d图形渲染,正好自己对于3d图形的渲染也很感兴趣,所以最近打算从学习OpenGL的图形API出发,进而了解3d图形的渲染技术.到网上查了一些资料,OpenGL ...

  9. 问题解决——OpenGL超级宝典 关于gltDrawTorus的错误解决

    看OpenGL超级宝典的时候,遇到一个函数 “gltDrawTorus”,在TRANSFORM和SPHEREWORLD中都有用到.但是一开始在自己写示例代码里时却没法使用,而在作者的代码目录结构下却可 ...

随机推荐

  1. *[topcoder]PalindromicSubstringsDiv2

    http://community.topcoder.com/stat?c=problem_statement&pm=12967 计算一个字符串里Palindrome的数量.我的DP方法需要n^ ...

  2. Shell 是个什么玩意

    Shell的定义: 计算机分为软件和硬件,管理计算机硬件的是操作系统,也就是我们说的kernel,而这个核心是需要被保护起来的. 那我们如何通过软件与硬件进行沟通,让硬件执行我们要完成的指令呢? 这个 ...

  3. Uboot 2014.07 makefile分析 - 其他Cortex系列

    uboot的官网可以通过谷歌搜索得到,显示结果第一个链接就是. 官网:: http://www.denx.de/wiki/U-Boot ftp下载: ftp://ftp.denx.de/pub/u-b ...

  4. [转载]浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  5. IOS基础框架

    GameKit 为游戏提供网络功能:点对点互联和游戏中的语音交流 AddressBook 提供访问用户联系人信息的功能 AddressBookUI 提供一个用户界面,用于显示存储在地址簿中的联系人信息 ...

  6. Android通过JNI调用驱动程序(完全解析实例)

    要达到的目的:android系统中,用JAVA写界面程序,调用jni中间库提供的接口,去操作某个驱动节点,实现read,writer ioctl等操作!这对底层驱动开发人员是很重要的一个调试通道,也是 ...

  7. 【HDOJ】4080 Stammering Aliens

    1. 题目描述给定一个长为$n \in [1, 4000]$的字符串,求其中长度最长的子串,并且该子串在原串中出现至少$m$次,并求最右起始位置. 2. 基本思路两种方法:二分+后缀数组,或者二分+哈 ...

  8. Eclipse中Python插件PyDev的安装与配置流程

    安装PyDev插件的两种安装方法: 方法1.下载地址:http://sourceforge.net/projects/pydev/files/,将下载的PyDev解压(目前最新版本 PyDev 4.5 ...

  9. 面试题_48_to_65_Java 集合框架的面试题

    这部分也包含数据结构.算法及数组的面试问题 48) List.Set.Map 和 Queue 之间的区别(答案)List 是一个有序集合,允许元素重复.它的某些实现可以提供基于下标值的常量访问时间,但 ...

  10. iOS开发:本地数据存储-NSUserDefaults

    Getting Default Values arrayForKey(_:) boolForKey(_:) dataForKey(_:) dictionaryForKey(_:) floatForKe ...