OpenGL超级宝典第5版&&缓冲区

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

缓冲区保存在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,那么我们甚至可以将数据从一个缓冲区的一部分复制到缓冲区的另一部分。

时间: 2024-11-05 12:50:17

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

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

1.OpenGL查询拓展机制是否被支持 gltools函数库: int gltIsExtSupported(const char *extension) { #ifndef OPENGL_ES GLint nNumExtensions; glGetIntegerv(GL_NUM_EXTENSIONS, &nNumExtensions); for(GLint i = 0; i < nNumExtensions; i++) if(strcmp(extension, (const char *)g

OpenGL超级宝典第5版&amp;&amp;glProvokingVertex

翻译:https://www.opengl.org/sdk/docs/man3/xhtml/glProvokingVertex.xml 方法原型:void glProvokingVertex(GLenum provokeMode) 作用:指定哪个点的数据作为平面着色的数据源 参数:GL_FIRST_VERTEX_CONVENTION(图元的第一个顶点)和GL_LAST_VERTEX_CONVENTION(图元的最后一个顶点) 解释:对一个顶点着色器的动态输出进行平面着色(Flat shading

OpenGL超级宝典第5版&amp;&amp;开发环境搭建

参考:http://www.zyh1690.org/build-opengl-super-bible-fifth-edition-development-environment/ 环境搭建的测试环境为:VS2010+Windows7 32位 第一步:下载文件 所需文件下载地址:http://yunpan.cn/cAI56sdhc8iIF(提取码:8152) 文件如下: 第二步:库准备 (1)freeglut 1)打开 ~\freeglut-2.8.1\VisualStudio\2010\free

OpenGL超级宝典第5版&amp;&amp;GLSL法线变换

在GLSL中,有一些情况需要把局部坐标系下的向量或点转换到视点坐标系下,如光照计算时,需要把法向转化到视点坐标系.如果是模型上一点p 转化到视点坐标系下,直接(model-view matrix )*p即可,但法线是向量,不是一个点,不能这样做.我们需要用法线矩阵来转换法线. 法线矩阵: 法线矩阵通常是模型视点矩阵(model-view matrix)左上角3x3矩阵的逆转置矩阵(inverse transpose). 但如果我们的model-view 矩阵不包含任何非一致缩放(non-unif

Ubuntu:Codeblocks编译OpenGL超级宝典(第5版)的实例

最近在看OpenGL超级宝典第五版,系统为Ubuntu,想通过Codeblocks运行书中的实例,途中遇到不少问题,均已解决,现分享一下操作步骤如下: 1. 建立基本编译环境 sudo apt-getinstall build-essential 2. 安装OpenGL Library sudo apt-getinstall libgl1-mesa-dev   3.安装OpenGL Utilities sudo apt-getinstall libglu1-mesa-dev 4.安装OpenGL

[转]OpenGL超级宝典 5e 环境配置

OpenGL超级宝典(第五版)环境配置 1.各种库的配置 (1)glew 下载:https://sourceforge.net/projects/glew/files/glew/1.7.0/glew-1.7.0.zip/download 将include文件夹下的.h文件拷贝到C:\Program Files\Microsoft Visual Studio 9.0\VC\include\GL目录中(没有GL目录就自己创建一个,这里的具体路径视电脑上VS2008安装的位置而定) 将lib文件夹下的

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

事先声明:该教程仅适用于VS2010环境下超级宝典第五版的配置 第一步:下载示例代码和环境包: 链接:https://pan.baidu.com/s/1llRRQ8ymBgMGuXp5M50pJw 提取码:7ujk 第二步:新建VS2010空工程一个 第三步:环境配置 在左侧边栏选择右键 源文件 -> 添加 -> 新建筛选器, 命名为 GLTools.再在GLTools上右键 添加->现有项 ,将 Env包 中的 src/GLTools/src 下的文件都添加进去. 在工程名上右击,选择

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

做三维重建需要用到OpenGL,开始看<OpenGL超级宝典>,新手第一步配置环境就折腾了一天,记录下环境的配置过程. <超级宝典>中的例子使用了GLEW,freeglut以及作者自己开发的GLTools这三个库. 1.GLEW The OpenGL Extension Wrangler Library (GLEW) is a cross-platform open-source C/C++ extension loading library. GLEW provides effi

win8+VS2012搭建OpenGL超级宝典的环境

自从公司搬到腾讯附近,每天上班都迟到20分钟左右,迟到会扣钱,两不相欠,迟到就成了心安理得的事情了. 如果你光看我之前的blog,我现在告诉你目前从事游戏开发,你可能会感到惊讶.是啊,我之前从未写过一篇关于游戏的文章.或许因缘巧合吧,正在做手游项目啊,用的是cocos2dx引擎.说来话长,大学的毕业设计是用java写了个小游戏,后来工作了,进了一家做电子教育产品的公司,虽然不是游戏公司,产品里也包含些休闲小游戏,其中有个游戏是我经理开发的,在同行的产品中算是最大型的一款游戏吧,由c语言写成,未使