【OpenGL】OpenGL帧缓存对象(FBO:Frame Buffer Object)

文章推薦指數: 80 %
投票人數:10人

OpenGL管线的最终渲染目的地被称作帧缓存(framebuffer)。

帧缓冲是一些二维数组和OpenG所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。

【OpenGL】OpenGL帧缓存对象(FBO:FrameBufferObject) 编程学习指南 于 2012-02-2216:36:02 发布 56039 收藏 38 文章标签: object buffer image ext generation parameters 翻译的,如果不正确,敬请谅解和指正。

OpenGLFrameBufferObject(FBO) Overview:    在OpenGL渲染管线中,几何数据和纹理经过多次转化和多次测试,最后以二维像素的形式显示在屏幕上。

OpenGL管线的最终渲染目的地被称作帧缓存(framebuffer)。

帧缓冲是一些二维数组和OpenG所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。

一般情况下,帧缓存完全由window系统生成和管理,由OpenGL使用。

这个默认的帧缓存被称作“window系统生成”(window-system-provided)的帧缓存。

在OpenGL扩展中,GL_EXT_framebuffer_object提供了一种创建额外的不能显示的帧缓存对象的接口。

为了和默认的“window系统生成”的帧缓存区别,这种帧缓冲成为应用程序帧缓存(application-createdframebuffer)。

通过使用帧缓存对象(FBO),OpenGL可以将显示输出到引用程序帧缓存对象,而不是传统的“window系统生成”帧缓存。

而且,它完全受OpenGL控制。

相似于window系统提供的帧缓存,一个FBO也包含一些存储颜色、深度和模板数据的区域。

(注意:没有累积缓存)我们把FBO中这些逻辑缓存称之为“帧缓存关联图像”,它们是一些能够和一个帧缓存对象关联起来的二维数组像素。

有两种类型的“帧缓存关联图像”:纹理图像(textureimages)和渲染缓存图像(renderbufferimages)。

如果纹理对象的图像数据关联到帧缓存,OpenGL执行的是“渲染到纹理”(rendertotexture)操作。

如果渲染缓存的图像数据关联到帧缓存,OpenGL执行的是离线渲染(offscreenrendering)。

这里要提到的是,渲染缓存对象是在GL_EXT_framebuffer_object扩展中定义的一种新的存储类型。

在渲染过程中它被用作存储单幅二维图像。

下面这幅图显示了帧缓存对象、纹理对象和渲染缓存对象之间的联系。

多多个纹理对象或者渲染缓存对象能够通过关联点关联到一个帧缓存对象上。

在一个帧缓存对象中有多个颜色关联点(GL_COLOR_ATTACHMENT0_EXT,...,GL_COLOR_ATTACHMENTn_EXT),一个深度关联点(GL_DEPTH_ATTACHMENT_EXT),和一个模板关联点(GL_STENCIL_ATTACHMENT_EXT)。

每个FBO中至少有一个颜色关联点,其数目与实体显卡相关。

可以通过GL_MAX_COLOR_ATTACHMENTS_EXT来查询颜色关联点的最大数目。

FBO有多个颜色关联点的原因是这样可以同时将颜色而换成渲染到多个FBO关联区。

这种“多渲染目标”(multiplerendertargets,MRT)可以通过GL_ARB_draw_buffers扩展实现。

需要注意的是:FBO本身并没有任何图像存储区,只有多个关联点。

FBO提供了一种高效的切换机制;将前面的帧缓存关联图像从FBO分离,然后把新的帧缓存关联图像关联到FBO。

在帧缓存关联图像之间切换比在FBO之间切换要快得多。

FBO提供了glFramebufferTexture2DEXT()来切换2D纹理对象和glFramebufferRenderbufferEXT()来切换渲染缓存对象。

  创建FBO 创建FBO和产生VBO类似。

glGenFramebuffersEXT() VoidgelGenFramebuffersEXT(GLsizein,GLuint*ids); voidglDeleteFramebuffersEXT(GLsizein,constGLuint*ids); glGenFramebuffersEXT()需要两个参数:第一个是要创建的帧缓存的数目,第二个是指向存储一个或者多个ID的变量或数组的指针。

它返回未使用的FBO的ID。

ID为0表示默认帧缓存,即window系统提供的帧缓存。

当FBO不再被使用时,FBO可以通过调用glDeleteFrameBuffersEXT()来删除。

glBindFramebufferEXT() 一旦一个FBO被创建,在使用它之前必须绑定。

voidglBindFramebufferEXT(GLenumtarget,GLuintid) 第一个参数target应该是GL_FRAMEBUFFER_EXT,第二个参数是FBO的ID号。

一旦FBO被绑定,之后的所有的OpenGL操作都会对当前所绑定的FBO造成影响。

ID号为0表示缺省帧缓存,即默认的window提供的帧缓存。

因此,在glBindFramebufferEXT()中将ID号设置为0可以解绑定当前FBO。

  渲染缓存对象(RenderbufferObject) 另外,渲染缓存是为离线渲染而新引进的。

它允许将一个场景直接渲染到一个渲染缓存对象中,而不是渲染到纹理对象中。

渲染缓存对象是用于存储单幅图像的数据存储区域。

该图像按照一种可渲染的内部格式存储。

它用于存储没有相关纹理格式的OpenGL逻辑缓存,比如模板缓存或者深度缓存。

glGenRenderbuffersEXT() voidglGenRenderbuffersEXT(GLsizein,GLuint*ids) voidglDeleteRenderbuffersEXT(GLsizein,constGluint*ids) 一旦一个渲染缓存被创建,它返回一个非零的正整数。

ID为0是OpenGL保留值。

glBindRenderbufferEXT() voidglBindRenderbufferEXT(GLenumtarget,GLuintid) 和OpenGL中其他对象一样,在引用渲染缓存之前必须绑定当前渲染缓存对象。

他target参数应该是GL_RENDERBUFFER_EXT。

glRenderbufferStorageEXT() voidglRenderbufferStorageEXT(GLenumtarget,GLenuminternalFormat,                              GLsizeiwidth,GLsizeiheight) 当一个渲染缓存被创建,它没有任何数据存储区域,所以我们还要为他分配空间。

这可以通过用glRenderbufferStorageEXT()实现。

第一个参数必须是GL_RENDERBUFFER_EXT。

第二个参数可以是用于颜色的(GL_RGB,GL_RGBA,etc.),用于深度的(GL_DEPTH_COMPONENT),或者是用于模板的格式(GL_STENCIL_INDEX)。

Width和height是渲染缓存图像的像素维度。

width和height必须比GL_MAX_RENDERBUFFER_SIZE_EXT小,否则将会产生GL_UNVALID_VALUE错误。

glGetRenderbufferParameterivEXT() voidglGetRenderbufferParameterivEXT(GLenumtarget,GLenumparam,GLint*value); 我们也可以得到当前绑定的渲染缓存对象的一些参数。

Target应该是GL_RENDERBUFFER_EXT,第二个参数是所要得到的参数名字。

最后一个是指向存储返回值的整型量的指针。

渲染缓存的变量名有如下: GL_RENDERBUFFER_WIDTH_EXT GL_RENDERBUFFER_HEIGHT_EXT GL_RENDERBUFFER_INTERNAL_FORMAT_EXT GL_RENDERBUFFER_RED_SIZE_EXT GL_RENDERBUFFER_GREEN_SIZE_EXT GL_RENDERBUFFER_BLUE_SIZE_EXT GL_RENDERBUFFER_ALPHA_SIZE_EXT GL_RENDERBUFFER_DEPTH_SIZE_EXT GL_RENDERBUFFER_STENCIL_SIZE_EXT 将图像和FBO关联 FBO本身没有图像存储区。

我们必须帧缓存关联图像(纹理或渲染对象)关联到FBO。

这种机制允许FBO快速地切换(分离和关联)帧缓存关联图像。

切换帧缓存关联图像比在FBO之间切换要快得多。

而且,它节省了不必要的数据拷贝和内存消耗。

比如,一个纹理可以被关联到多个FBO上,图像存储区可以被多个FBO共享。

把2D纹理图像关联到FBO glFramebufferTexture2DEXT(GLenumtarget,                          GLenumattachmentPoint,                          GLenumtextureTarget,                          GLuinttextureId,                          GLint level) glFramebufferTexture2DEXT()把一幅纹理图像关联到一个FBO。

第一个参数一定是GL_FRAMEBUFFER_EXT,第二个参数是关联纹理图像的关联点。

第三个参数textureTarget在多数情况下是GL_TEXTURE_2D。

第四个参数是纹理对象的ID号。

最后一个参数是要被关联的纹理的mipmap等级 如果参数textureId被设置为0,那么纹理图像将会被从FBO分离。

如果纹理对象在依然关联在FBO上时被删除,那么纹理对象将会自动从当前帮的FBO上分离。

然而,如果它被关联到多个FBO上然后被删除,那么它将只被从绑定的FBO上分离,而不会被从其他非绑定的FBO上分离。

把渲染缓存对象关联到FBO voidglFramebufferRenderbufferEXT(GLenumtarget,                                  GLenumattachmentPoint,                                  GLenumrenderbufferTarget,                                  GLuintrenderbufferId) 通过调用glFramebufferRenderbufferEXT()可以关联渲染缓存图像。

前两个参数和glFramebufferTexture2DEXT()一样。

第三个参数只能是GL_RENDERBUFFER_EXT,最后一个参数是渲染缓存对象的ID号。

如果参数renderbufferId被设置为0,渲染缓存图像将会从FBO的关联点分离。

如果渲染缓存图像在依然关联在FBO上时被删除,那么纹理对象将会自动从当前绑定的FBO上分离,而不会从其他非绑定的FBO上分离。

检查FBO状态 一旦关联图像(纹理和渲染缓存)被关联到FBO上,在执行FBO的操作之前,你必须检查FBO的状态,这可以通过调用glCheckFramebufferStatusEXT()实现。

如果这个FBObuilding完整,那么任何绘制和读取命令(glBegin(),glCopyTexImage2D(),etc)都会失败。

GLenumglCheckFramebufferStatusEXT(GLenumtarget) glCheckFramebufferStatusEXT()检查当前帧缓存的关联图像和帧缓存参数。

这个函数不能在glBegin()/glEnd()之间调用。

Target参数必须为GL_FRAMEBUFFER_EXT。

它返回一个非零值。

如果所有要求和准则都满足,它返回GL_FRAMEBUFFER_COMPLETE_EXT。

否则,返回一个相关错误代码告诉我们哪条准则没有满足。

FBO完整性准则有: (1)帧缓存关联图像的宽度和高度必须非零。

(2)如果一幅图像被关联到一个颜色关联点,那么这幅图像必须有颜色可渲染的内部格式(GL_RGBA,GL_DEPTH_COMPONENT,GL_LUMINANCE,etc)。

(3)如果一幅被图像关联到GL_DEPTH_ATTACHMENT_EXT,那么这幅图像必须有深度可渲染的内部格式(GL_DEPTH_COMPONENT,GL_DEPTH_COMPONENT24_EXT,etc)。

(4)如果一幅被图像关联到GL_STENCIL_ATTACHMENT_EXT,那么这幅图像必须有模板可渲染的内部格式(GL_STENCIL_INDEX,GL_STENCIL_INDEX8_EXT,etc)。

(5)FBO至少有一幅图像关联。

(6)被关联到FBO的缩影图像必须有相同的宽度和高度。

(7)被关联到颜色关联点上的所有图像必须有相同的内部格式。

注意:即使以上所有条件都满足,你的OpenGL驱动也可能不支持某些格式和参数的组合。

如果一种特别的实现不被OpenGL驱动支持,那么glCheckFramebufferStatusEXT()返回GL_FRAMEBUFFER_UNSUPPORTED_EXT。

示例:渲染到纹理 源代码下载:http://www.songho.ca/opengl/gl_fbo.html 包括渲染到纹理、只渲染到深度缓存和使用模板缓存渲染对象的轮廓。

有时候,你需要产生动态纹理。

比较常见的例子是产生镜面反射效果、动态环境贴图和阴影等效果。

动态纹理可以通过把场景渲染到纹理来实现。

渲染到纹理的一种传统方式是将场景绘制到普通的帧缓存上,然后调用glCopyTexSubImage2D()拷贝帧缓存图像至纹理。

使用FBO,我们能够将场景直接渲染到纹理,所以我们不必使用window系统提供的帧缓存。

并且,我们能够去除额外的数据拷贝(从帧缓存到纹理);。

这个demo实现了使用FBO和不使用FBO两种情况下渲染到纹理的操作,并且比较了性能差异。

除了能够获得性能上的提升,使用FBO的还有另外一个优点。

在传统的渲染到纹理的模式中(不使用FBO),如果纹理分辨率比渲染窗口的尺寸大,超出窗口区域的部分将被剪切掉。

然后,使用FBO就不会有这个问题。

你可以产生比显示窗口大的帧缓存渲染图像。

以下代码在渲染循环开始之前,对FBO和帧缓存关联图像进行了初始化。

注意只有一幅纹理图像被关联到FBO,但是,一个深度渲染图像被关联到FBO的深度关联点。

实际上我们并没有使用这个深度缓存,但是FBO本身需要它进行深度测试。

如果我们不把这个深度可渲染的图像关联到FBO,那么由于缺少深度测试渲染输出结果是不正确的。

如果在FBO渲染期间模板测试也是必要的,那么也需要把额外的渲染图像和GL_STENCIL_ATTACHMENT_EXT关联起来。

//createatextureobject GLuinttextureId; glGenTextures(1,&textureId); glBindTexture(GL_TEXTURE_2D,textureId); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,GL_TRUE);//automaticmipmap glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,TEXTURE_WIDTH,TEXTURE_HEIGHT,0, GL_RGBA,GL_UNSIGNED_BYTE,0); glBindTexture(GL_TEXTURE_2D,0); //createarenderbufferobjecttostoredepthinfo GLuintrboId; glGenRenderbuffersEXT(1,&rboId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,rboId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT, TEXTURE_WIDTH,TEXTURE_HEIGHT); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,0); //createaframebufferobject GLuintfboId; glGenFramebuffersEXT(1,&fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId); //attachthetexturetoFBOcolorattachmentpoint glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,textureId,0); //attachtherenderbuffertodepthattachmentpoint glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,rboId); //checkFBOstatus GLenumstatus=glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if(status!=GL_FRAMEBUFFER_COMPLETE_EXT) fboUsed=false; //switchbacktowindow-system-providedframebuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); ... 渲染到纹理的过程和普通的绘制过程基本一样。

我们只需要把渲染的目的地由window系统提供的帧缓存改成不可显示的应用程序创建的帧缓存(FBO)就可以了。

... //setrenderingdestinationtoFBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId); //clearbuffers glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //drawascenetoatexturedirectly draw(); //unbindFBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //triggermipmapsgenerationexplicitly //NOTE:IfGL_GENERATE_MIPMAPissettoGL_TRUE,thenglCopyTexSubImage2D() //triggersmipmapgenerationautomatically.However,thetextureattached //ontoaFBOshouldgeneratemipmapsmanuallyviaglGenerateMipmapEXT(). glBindTexture(GL_TEXTURE_2D,textureId); glGenerateMipmapEXT(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,0); ... 注意到,glGenerateMipmapEXT()也是作为FBO扩展的一部分,用来在改变了纹理图像的基级之后显式生成mipmap的。

如果GL_GENERATE_MIPMAP被设置为GL_TRUE,那么glTex{Sub}Image2D()和glCopyTex{Sub}Image2D()将会启用自动mipmap生成(在OpenGL版本1.4或者更高版本中)。

然后,当纹理基级被改变时,FBO操作不会自动产生mipmaps。

因为FBO不会调用glCopyTex{Sub}Image2D()来修改纹理。

因此,要产生mipmap,glGenerateMipmapEXT()必须被显示调用。

  原网址:http://www.songho.ca/opengl/gl_fbo.html 英文原文: In OpenGLrenderingpipeline,thegeometrydataandtexturesaretransformedandpassedseveraltests,andthenfinallyrenderedontoascreenas2Dpixels.ThefinalrenderingdestinationoftheOpenGLpipelineiscalled framebuffer.Framebufferisacollectionof2DarraysorstoragesutilizedbyOpenGL;colourbuffers,depthbuffer,stencilbufferandaccumulationbuffer.Bydefault,OpenGLusestheframebufferasarenderingdestinationthatiscreatedandmanagedentirelybythewindowsystem.Thisdefaultframebufferiscalled window-system-provided framebuffer. TheOpenGLextension, GL_EXT_framebuffer_object providesaninterfacetocreateadditionalnon-displayableframebufferobjects(FBO).Thisframebufferiscalled application-createdframebufferinordertodistinguishfromthedefault window-system-provided framebuffer.Byusingframebufferobject(FBO),anOpenGLapplicationcanredirecttherenderingoutputtotheapplication-created framebufferobject(FBO)otherthanthetraditional window-system-providedframebuffer.And,itisfullycontrolledbyOpenGL. Similarto window-system-provided framebuffer,aFBOcontainsacollectionofrenderingdestinations;color,depthandstencilbuffer. (NotethataccumulationbufferisnotdefinedinFBO.)TheselogicalbuffersinaFBOarecalled framebuffer-attachableimages,whichare2Darraysofpixelsthatcanbeattachedtoaframebufferobject. Therearetwotypesofframebuffer-attachableimages;textureimagesandrenderbufferimages.Ifanimageofatextureobjectisattachedtoaframebuffer,OpenGLperforms "rendertotexture".Andifanimageofarenderbufferobjectisattachedtoaframebuffer,thenOpenGLperforms "offscreenrendering". Bytheway, renderbufferobject isanewtypeofstorageobjectdefinedinGL_EXT_framebuffer_objectextension.Itisusedasarenderingdestinationforasingle2Dimageduringrenderingprocess. Thefollowingdiagramshowstheconnectivityamongtheframebufferobject,textureobjectandrenderbufferobject.Multipletextureobjectsorrenderbufferobjectscanbeattachedtoaframebufferobjectthroughtheattachmentpoints。

Therearemultiplecolorattachmentpoints(GL_COLOR_ATTACHMENT0_EXT,...,GL_COLOR_ATTACHMENTn_EXT),onedepthattachmentpoint(GL_DEPTH_ATTACHMENT_EXT),andonestencilattachmentpoint(GL_STENCIL_ATTACHMENT_EXT)inaframebufferobject.Thenumberofcolorattachmentpointsisimplementationdependent,buteachFBOmusthaveatleastonecolorattachementpoint.YoucanquerythemaximumnumberofcolorattachementpointswithGL_MAX_COLOR_ATTACHMENTS_EXT,whicharesupportedbyagraphicscard.ThereasonthataFBOhasmultiplecolorattachementpointsistoallowtorenderthecolorbuffertomultipledestinationsatthesametime.This "multiplerendertargets" (MRT)canbeaccomplishedbyGL_ARB_draw_buffers extension.Noticethattheframebufferobjectitselfdoesnothaveanyimagestorage(array)init,but,ithasonlymultipleattachmentpoints.Thefollowingdiagramshowstheconnectivityamongtheframebufferobject,textureobjectandrenderbufferobject.Multipletextureobjectsorrenderbufferobjectscanbeattachedtoaframebufferobjectthroughtheattachmentpoints. Framebufferobject(FBO)providesanefficientswitchingmechanism;detachthepreviousframebuffer-attachableimagefromaFBO,andattachanewframebuffer-attachableimagetotheFBO.Switchingframebuffer-attachableimagesismuchfasterthanswitchingbetweenFBOs.FBOprovides glFramebufferTexture2DEXT() toswitch2Dtextureobjects,andglFramebufferRenderbufferEXT() toswitchrenderbufferobjects. CreatingFrameBufferObject(FBO) Creatingframebufferobjectsissimilartogenerating vertexbufferobjects(VBO). glGenFramebuffersEXT() voidglGenFramebuffersEXT(GLsizein,GLuint*ids)voidglDeleteFramebuffersEXT(GLsizein,constGLuint*ids) glGenFramebuffersEXT()requires2parameters;thefirstoneisthenumberofframebufferstocreate,andthesecondparameteristhepointertoaGLuintvariableoranarraytostoreasingleIDormultipleIDs.ItreturnstheIDsofunusedframebufferobjects.ID0meansthedefaultframebuffer,whichisthewindow-system-providedframebuffer. And,FBOmaybedeletedbycalling glDeleteFramebuffersEXT() whenitisnotusedanymore. glBindFramebufferEXT() OnceaFBOiscreated,ithastobeboundbeforeusingit. voidglBindFramebufferEXT(GLenumtarget,GLuintid) Thefirstparameter,target,shouldbeGL_FRAMEBUFFER_EXT,andthesecondparameteristheIDofaframebufferobject.OnceaFBOisbound,allOpenGLoperationsaffectontothecurrentboundframebufferobject.TheobjectID0isreservedforthedefaultwindow-systemprovidedframebuffer.Therefore,inordertounbindthecurrentframebuffer(FBO),useID0inglBindFramebufferEXT(). RenderbufferObject Inaddition,renderbufferobjectisnewlyintroducedforoffscreenrendering.Itallowstorenderascenedirectlytoarenderbufferobject,insteadofrenderingtoatextureobject.Renderbufferissimplyadatastorageobjectcontainingasingleimageofarenderableinternalformat.ItisusedtostoreOpenGLlogicalbuffersthatdonothavecorrespondingtextureformat,suchasstencilordepthbuffer. glGenRenderbuffersEXT() voidglGenRenderbuffersEXT(GLsizein,GLuint*ids)voidglDeleteRenderbuffersEXT(GLsizein,constGluint*ids) Oncearenderbufferiscreated,itreturnsnon-zeropositiveinteger.ID0isreservedforOpenGL. glBindRenderbufferEXT() voidglBindRenderbufferEXT(GLenumtarget,GLuintid) SameasotherOpenGLobjects,youhavetobindthecurrentrenderbufferobjectbeforereferencingit.ThetargetparametershouldbeGL_RENDERBUFFER_EXTforrenderbufferobject. glRenderbufferStorageEXT() voidglRenderbufferStorageEXT(GLenumtarget,GLenuminternalFormat,GLsizeiwidth,GLsizeiheight) Whenarenderbufferobjectiscreated,itdoesnothaveanydatastorage,sowehavetoallocateamemoryspaceforit.ThiscanbedonebyusingglRenderbufferStorageEXT().ThefirstparametermustbeGL_RENDERBUFFER_EXT.Thesecondparameterwouldbecolor-renderable(GL_RGB,GL_RGBA,etc.),depth-renderable(GL_DEPTH_COMPONENT),orstencil-renderableformats(GL_STENCIL_INDEX).Thewidthandheightarethedimensionoftherenderbufferimageinpixels. ThewidthandheightshouldbelessthanGL_MAX_RENDERBUFFER_SIZE_EXT,otherwise,itgeneratesGL_INVALID_VALUEerror. glGetRenderbufferParameterivEXT() voidglGetRenderbufferParameterivEXT(GLenumtarget,GLenumparam,GLint*value); Youalsogetvariousparametersofthecurrentlyboundrenderbufferobject. target shouldbeGL_RENDERBUFFER_EXT,andthesecondparameteristhenameofparameter.Thelastisthepointertoanintegervariabletostorethereturnedvalue.Theavailablenamesoftherenderbufferparametersare; GL_RENDERBUFFER_WIDTH_EXTGL_RENDERBUFFER_HEIGHT_EXTGL_RENDERBUFFER_INTERNAL_FORMAT_EXTGL_RENDERBUFFER_RED_SIZE_EXTGL_RENDERBUFFER_GREEN_SIZE_EXTGL_RENDERBUFFER_BLUE_SIZE_EXTGL_RENDERBUFFER_ALPHA_SIZE_EXTGL_RENDERBUFFER_DEPTH_SIZE_EXTGL_RENDERBUFFER_STENCIL_SIZE_EXT AttachingimagestoFBO FBOitselfdoesnothaveanyimagestorage(buffer)init.Instead,wemustattachframebuffer-attachableimages(textureorrenderbufferobjects)totheFBO.ThismechanismallowsthatFBOquicklyswitch(detachandattach)theframebuffer-attachableimagesinaFBO.Itismuchfastertoswitchframebuffer-attachableimagesthantoswitchbetweenFBOs.And,itsavesunnecessarydatacopiesandmemoryconsumption.Forexample,atexturecanbeattachedtomultipleFBOs,anditsimagestoragecanbesharedbymultipleFBOs. Attachinga2DtextureimagetoFBO glFramebufferTexture2DEXT(GLenumtarget,GLenumattachmentPoint,GLenumtextureTarget,GLuinttextureId,GLintlevel) glFramebufferTexture2DEXT()istoattacha2DtextureimagetoaFBO.ThefirstparametermustbeGL_FRAMEBUFFER_EXT,andthesecondparameteristheattachmentpointwheretoconnectthetextureimage.AFBOhasmultiplecolorattachmentpoints(GL_COLOR_ATTACHMENT0_EXT,...,GL_COLOR_ATTACHMENTn_EXT),GL_DEPTH_ATTACHMENT_EXT,andGL_STENCIL_ATTACHMENT_EXT.Thethirdparameter,"textureTarget" isGL_TEXTURE_2Dinmostcases.Thefourthparameteristheidentifierofthetextureobject.Thelastparameteristhemipmaplevelofthetexturetobeattached. Ifthe textureId parameterissetto0,then,thetextureimagewillbedetachedfromtheFBO.IfatextureobjectisdeletedwhileitisstillattachedtoaFBO,then,thetextureimagewillbeautomaticallydetachedfromthecurrentlyboundFBO.However,ifitisattachedtomultipleFBOsanddeleted,thenitwillbedetachedfromonlytheboundFBO,butwillnotbedetachedfromanyotherun-boundFBOs. AttachingaRenderbufferimagetoFBO voidglFramebufferRenderbufferEXT(GLenumtarget,GLenumattachmentPoint,GLenumrenderbufferTarget,GLuintrenderbufferId) ArenderbufferimagecanbeattachedbycallingglFramebufferRenderbufferEXT().ThefirstandsecondparametersaresameasglFramebufferTexture2DEXT().ThethirdparametermustbeGL_RENDERBUFFER_EXT,andthelastparameteristheIDoftherenderbufferobject. If renderbufferId parameterissetto0,therenderbufferimagewillbedetachedfromtheattachmentpointintheFBO.IfarenderbufferobjectisdeletedwhileitisstillattachedinaFBO,thenitwillbeautomaticallydetachedfromtheboundFBO.However,itwillnotbedetachedfromanyothernon-boundFBOs. CheckingFBOStatus Onceattachableimages(texturesandrenderbuffers)areattachedtoaFBOandbeforeperformingFBOoperation,youmustvalidateiftheFBOstatusiscompleteorincompletebyusingglCheckFramebufferStatusEXT().IftheFBOisnotcomplete,thenanydrawingandreadingcommand(glBegin(),glCopyTexImage2D(),etc)willbefailed. GLenumglCheckFramebufferStatusEXT(GLenumtarget) glCheckFramebufferStatusEXT()validatesallitsattachedimagesandframebufferparametersonthecurrentlyboundFBO.And,thisfunctioncannotbecalledwithinglBegin()/glEnd()pair.ThetargetparametershouldbeGL_FRAMEBUFFER_EXT.Itreturnsnon-zerovalueaftercheckingtheFBO.Ifallrequirementsandrulesaresatisfied,thenitreturns GL_FRAMEBUFFER_COMPLETE_EXT.Otherwise,itreturnsarelevanterrorvalue,whichtellswhatruleisviolated. TherulesofFBOcompletenessare: Thewidthandheightofframebuffer-attachableimagemustbenotzero.Ifanimageisattachedtoacolorattachmentpoint,thentheimagemusthaveacolor-renderableinternalformat. (GL_RGBA,GL_DEPTH_COMPONENT,GL_LUMINANCE,etc)IfanimageisattachedtoGL_DEPTH_ATTACHMENT_EXT,thentheimagemusthaveadepth-renderableinternalformat. (GL_DEPTH_COMPONENT,GL_DEPTH_COMPONENT24_EXT,etc)IfanimageisattachedtoGL_STENCIL_ATTACHMENT_EXT,thentheimagemusthaveastencil-renderableinternalformat. (GL_STENCIL_INDEX,GL_STENCIL_INDEX8_EXT,etc)FBOmusthaveatleastoneimageattached.AllimagesattachedaFBOmusthavethesamewidthandheight.Allimagesattachedthecolorattachmentpointsmusthavethesameinternalformat. Notethateventhoughalloftheaboveconditionsaresatisfied,yourOpenGLdrivermaynotsupportsomecombinationsofinternalformatsandparameters.IfaparticularimplementationisnotsupportedbyOpenGLdriver,thenglCheckFramebufferStatusEXT()returnsGL_FRAMEBUFFER_UNSUPPORTED_EXT. Example:RenderToTexture Downloadthesourceandbinary: fbo.zip Extras: -Renderingtothedepthbufferonly: fboDepth.zip -Renderingtheoutlinesofanobjectusingstencilbuffer: fboStencil.zip Sometimes,youneedtogeneratedynamictexturesonthefly.Themostcommonexamplesaregeneratingmirroring/reflectioneffects,dynamiccube/environmentmapsandshadowmaps.Dynamictexturingcanbeaccomplishedbyrenderingthescenetoatexture.Atraditionalwayofrender-to-textureistodrawascenetotheframebufferasnormal,andthencopytheframebufferimagetoatexturebyusingglCopyTexSubImage2D(). UsingFBO,wecanrenderascenedirectlyontoatexture,sowedon'thavetousethewindow-system-providedframebufferatall.Furthermore,wecaneliminateanadditionaldatacopy(fromframebuffertotexture). Thisdemoprogramperforms rendertotexture operationwith/withoutFBO,andcomparestheperformancedifference.Otherthanperformancegain,thereisanotheradvantageofusingFBO.Ifthetextureresolutionislargerthanthesizeoftherenderingwindowintraditionalrender-to-texturemode(withoutFBO),thentheareaoutofthewindowregionwillbeclipped.However,FBOdoesnotsufferfromthisclippingproblem.Youcancreateaframebuffer-renderableimagelargerthanthedisplaywindow. ThefollowingcodesistosetupaFBOandframebuffer-attachableimagesbeforetherenderingloopisstarted.NotethatnotonlyatextureimageisattachedtotheFBO,butalso,arenderbufferimageisattachedtothedepthattachmentpointoftheFBO.Wedonotactuallyusethisdepthbuffer,however,theFBOitselfneedsitfordepthtest.Ifwedon'tattachthisdepthrenderableimagetotheFBO,thentherenderingoutputwillbecorruptedbecauseofmissingdepthtest.IfstenciltestisalsorequiredduringFBOrendering,thenadditionalrenderbufferimageshouldbeattachedtoGL_STENCIL_ATTACHMENT_EXT. ...//createatextureobjectGLuinttextureId;glGenTextures(1,&textureId);glBindTexture(GL_TEXTURE_2D,textureId);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,GL_TRUE);//automaticmipmapglTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,TEXTURE_WIDTH,TEXTURE_HEIGHT,0,GL_RGBA,GL_UNSIGNED_BYTE,0);glBindTexture(GL_TEXTURE_2D,0);//createarenderbufferobjecttostoredepthinfoGLuintrboId;glGenRenderbuffersEXT(1,&rboId);glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,rboId);glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,TEXTURE_WIDTH,TEXTURE_HEIGHT);glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,0);//createaframebufferobjectGLuintfboId;glGenFramebuffersEXT(1,&fboId);glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId);//attachthetexturetoFBOcolorattachmentpointglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,textureId,0);//attachtherenderbuffertodepthattachmentpointglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT,rboId);//checkFBOstatusGLenumstatus=glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);if(status!=GL_FRAMEBUFFER_COMPLETE_EXT)fboUsed=false;//switchbacktowindow-system-providedframebufferglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);... Therenderingprocedureofrender-to-textureisalmostsameasnormaldrawing.Weonlyneedtoswitchtherenderingdestinationfromthewindow-system-providedtothenon-displayable,application-createdframebuffer(FBO). ...//setrenderingdestinationtoFBOglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId);//clearbuffersglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//drawascenetoatexturedirectlydraw();//unbindFBOglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);//triggermipmapsgenerationexplicitly//NOTE:IfGL_GENERATE_MIPMAPissettoGL_TRUE,thenglCopyTexSubImage2D()//triggersmipmapgenerationautomatically.However,thetextureattached//ontoaFBOshouldgeneratemipmapsmanuallyviaglGenerateMipmapEXT().glBindTexture(GL_TEXTURE_2D,textureId);glGenerateMipmapEXT(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D,0);... Notethat glGenerateMipmapEXT() isalsoincludedaspartofFBOextensioninordertogeneratemipmapsexplicitlyaftermodifyingthebaseleveltextureimage.If GL_GENERATE_MIPMAP issettoGL_TRUE,thenglTex{Sub}Image2D()andglCopyTex{Sub}Image2D()triggerautomaticmipmapgeneration(inOpenGLversion1.4orgreater).However,FBOoperationdoesnotgenerateitsmipmapsautomaticallywhenthebaseleveltextureismodifiedbecauseFBOdoesnotcallglCopyTex{Sub}Image2D()tomodifythetexture.Therefore,glGenerateMipmapEXT()mustbeexplicitlycalledformipmapgeneration. Ifyouneedtoapostprocessingofthetexture,itispossibletocombinewith PixelBufferObject(PBO) tomodifythetextureefficiently. 编程学习指南 关注 关注 13 点赞 踩 17 评论 38 收藏 扫一扫,分享内容 点击复制链接 OpenGL缓冲区对象之FBO Frank的专栏 11-15 1万+ FBO OpenGL学习脚印:帧缓冲对象(FrameBufferObject) 热门推荐 王定桥的专栏 09-03 1万+ 写在前面 一直以来,我们在使用OpenGL渲染时,最终的目的地是默认的帧缓冲区,实际上OpenGL也允许我们创建自定义的帧缓冲区。

使用自定义的帧缓冲区,可以实现镜面,离屏渲染,以及很酷的后处理效果。

本节将学习帧缓存的使用,文中示例代码均可以在我的github下载。

本节内容整理自 1.OpenGLFrameBufferObject(FBO) 2.www.learn 评论 17 您还未登录,请先 登录 后发表或查看评论 OpenGL渲染到帧缓存对象(FBO) qq_16555407的博客 11-19 809 窗口系统提供的帧缓存是唯一可以被图形服务器的显示系统所识别的帧缓存。

也就是说,我们要想在屏幕上看到东西,就必须把它画在这个窗口系统提供的帧缓存中。

1.创建n个帧缓存对象id voidglGenFramebuffers(GLsizein,GLuint*ids); 2.创建帧缓存对象并切换到当前帧缓存 voidglBindFramebuffer(GLenumtarget,GLuin... OpenGL帧缓存对象(FBO) 翻肚鱼儿的博客 08-06 319 帧缓存(Framebuffer) 帧缓存是屏幕所显示画面的一个直接映象,又称为位映射图(BitMap)或光栅。

帧缓存的每一存储单元对应屏幕上的一个像素,整个帧缓存对应一帧图像。

图形程序一个重要的目标,就是在屏幕上绘制图像(或者绘制到离屏的一处缓存中)。

帧缓存(通常也就是屏幕)是由矩形的像素数组组成的,每个像素都可以在图像对应的点上显示一小块方形的颜色值。

经过光栅化阶段,也就是执行片元着色器之后,得到的数据还不是真正的像素,只是候选的片元。

每个片元都包含与像素位置对应的坐标数据,以及颜色和深度的 OpenGL帧缓存FrameBuffer 春夜喜雨的专栏 07-25 3384 概念上,FrameBuffer指驱动显示设备显示的位图内存区域,该内存区域包含了完整的帧数据。

在现代的显卡设备核心中集成了相关framebuffer显示电路,该电路把内存中的位图转换成视频信号显示到显示设备上。

OpenGL学习笔记25-Framebuffers wangxingxing321的博客 07-29 435 Framebuffers帧缓冲器 Advanced-OpenGL/Framebuffers 到目前为止,我们已经使用了几种类型的屏幕缓冲区:用于写入颜色值的颜色缓冲区,用于写入和测试深度信息的深度缓冲区,以及允许我们根据某些条件丢弃某些片段的模板缓冲区。

这些缓冲区的组合存储在GPU内存的某处,被称为framebuffer。

OpenGL让我们可以灵活地定义自己的framebuffer,从而定义自己的颜色(以及可选的深度和模板)缓冲区。

到目前为止,我们所做的渲染操作都是在附加到默认framebuff. OpenGLFBO学习 weixin_41623673的博客 06-22 85 OpenGLFrameBufferObject(FBO) Overview 在OpenGL渲染管线中,几何数据和纹理被转换并通过多次测试,然后最终作为2D像素渲染到屏幕上。

OpenGL管线的最终渲染目的地称为帧缓冲区。

帧缓冲区是OpenGL使用的二维数组或存储的集合:颜色缓冲区、深度缓冲区、模板缓冲区和累积缓冲区。

默认情况下,OpenGL使用帧缓冲区作为渲染目标,完全由窗口系统创建和管理。

此默认帧缓冲区称为窗口系统提供的帧缓冲区(window-system-provided-fram fbo OpenGL&game 08-21 1633 原文地址:http://www.cppblog.com/init/archive/2012/02/16/165778.aspx 帧缓冲区对象呢又称为FBO,它允许我们把渲染从窗口的帧缓冲区转移到我们所创建的一个或者多个离屏帧缓冲区。

被推荐用于数据渲染到纹理对象,相对于其他同类技术,如数据拷贝或者交换缓冲区等等,使用FBO技术会更高效且易于实现。

此buffer包含了colorbuffer OpenGL中FrameBuffer使用 weixin_30662539的博客 08-28 760 这边先引用别人写的比较好的文章,以便快速的了解关于framebuffer的一些函数。

http://longzxr.i.sohu.com/blog/view/168909774.htm 《-------------------------------------------------------------------一下内容为引用------------------------------... OpenGL学习之FBO的使用 YuQing_Cat的博客 11-06 7201 概述 帧缓冲对象FBO(FramebufferObject)。

OpenGL默认情况下,在GLSurfaceView中绘制的结果是显示到屏幕上的,但是实际情况中大部分时候都不需要渲染到屏幕中去,这个FBO就是来实现这个需求的,FBO可以让不渲染到屏幕当中去,而是渲染到离屏的buffer中。

关于FBO比较好的资料,这个是英文版的 http://www.songho.ca/opengl/gl_f... 帧缓存对象FrameBufferObject u014767384的博客 08-18 2595 1.概述 2.创建FBO 3.创建帧缓存附加图像(framebuffer-attachableimage) 3.1.创建纹理图像(textureimages) 3.2.创建Renderbuffer图像(Renderbufferimages) 4.绘制到纹理(Rendertotexture) 5.使用后处理效果(postprocessing) ... OpenGL中的FBO深入理解 宁静,忍耐,伟大,坚强! 06-13 2559     FBO技术应该算是OpenGL里很实用的高级技术,如果你没接触过这个技术那么请看这篇文章,你就会大致入门了. OpenGLVBO,PBO与FBO 翻肚鱼儿的博客 08-11 277 VBO,VertexBufferArray 为了加快显示速度,显卡增加了一个扩展,即VBO。

它本质上是存储几何数据的缓存。

它直接把顶点数据放置到显卡中的高速缓存,极大提高了绘制速度。

这个扩展用到ARB_vertex_buffer_object,它可以直接像顶点数组那样使用。

唯一不同的地方在于它需要将数据载入显卡的高效缓存,因此需要占用渲染时间。

[参考文章1]给出了一个使用VBO扩展的例子程序。

[参考文章2]罗列了与VBO操作相关的函数 [参考文章3]归纳出VBO... openGL学习笔记三十九:FBO 哲学天空的博客 05-14 442 PBuffer:   是opengl的扩展,在opengles中称作surface,在一个应用程序中建立多个opengl对象,主要用途:离屏渲染(离开屏幕进行渲染),建立一个PBuffer就是建立一个opengl对象,这个opengl对象是在后台绘制,并不把数据绘制到我们的窗口上。

FrameBufferObject(FBO):   帧缓冲对象,另一种离屏渲染方式,比PBuffer更加高效,opengl2.0以上才有的扩展功能。

用于缓存一帧数据。

  当创建一个fbo对象后,它并不占用显存,它只是一 Opengl中使用Framebuffer要注意的一些问题 vily_lei的专栏 08-13 657 1.Framebuffer身上附加的Textureid要保存好,防止被意外glDeleteTextures(..)删除掉。

如果这个Textureid被删除,则会出现意想不到的错乱。

你在将绘制目标设置为这个Framebuffer的时候,最终得到的结果可能是别的Framebuffer的内容。

2.不要将清理Framebuffer和将Framebuffer身上attachment的text... OpenGL(九)使用FrameBufferObject 阿修罗道 04-19 6952 在OpenGL中所有的图形,都会绘制到FrameBufferObject上。

如果想使用界面的做分屏渲染,或需要屏幕图像制成贴图以备后期处理,就需要用到FrameBufferObject技术,这种方式也被称为RTT(RendertoTexture)。

OpenGLFramebuffersObject:帧缓冲区对象详解 最新发布 aDiligentCigarette的博客 12-04 90 帧缓冲区对象FrameBuffersObject(FBO) 一概念 =============================================================== 迄今为止,我们使用了好几种屏幕缓冲区:颜色缓冲区,深度缓冲区,模板缓冲区。

这些缓冲区存储在GPU的内存中,称为帧缓冲区(framebuffer). OpenGL允许我们创建自己的帧缓冲区。

以前的渲染是这样:在渲染缓冲区顶部有一个默认的帧缓冲区(default framebu... OpenGL:使用FBO为渲染对象并从GPU取出存图 shenyi0_0的博客 10-13 519 OpenGL使用FBO为渲染对象并从GPU取出存图的代码 #include"gl/glew.h" #include"gl/glut.h" #include #defineisize512 constchar*vertexShaderSource="#version460\n" "layout(location=0)invec3aPos;\n" "voidmain()\n" "{\n" "gl_Position=vec4(aPo OpenGL之FBO 时光的博客 12-06 830 ####一:概述 在OpenGLrenderingpipeline中,原始数据和纹理经过处理过后最终会被渲染到屏幕上成为2D像素。

OpenGLpipeline的最终渲染目标就是framebuffer(帧缓存) OpenGL使用作为渲染目标的帧缓存是被window系统生成管理的,这个默认的framebuffer被称为window-system-providedframebuffer. ... “相关推荐”对你有帮助么? 非常没帮助 没帮助 一般 有帮助 非常有帮助 提交 ©️2022CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页 编程学习指南 CSDN认证博客专家 CSDN认证企业博客 码龄13年 阿里巴巴Java技术专家 138 原创 1万+ 周排名 3127 总排名 254万+ 访问 等级 1万+ 积分 4307 粉丝 1209 获赞 1018 评论 1928 收藏 私信 关注 我的公众号:编程学习指南 关注微信公众号【编程学习指南】回复【书单】可获得阿里大神整理的82本计算机高分书籍,CS专业必看!!! 热门文章 【Linux】Vim编辑器-批量注释与反注释 160162 【数字图像处理】直方图均衡化详解及编程实现 155113 【Linux学习】epoll详解 149749 【数字图像处理】C++读取、旋转和保存bmp图像文件编程实现 113403 2014找工作总结-机会往往留给有准备的人 111423 分类专栏 公众号:编程学习指南 11篇 Java 8篇 Spring 2篇 Linux 19篇 设计模式 4篇 Nginx模块开发与原理剖析 14篇 Nginx 12篇 数据结构与算法 19篇 笔试面试题 8篇 C/C++ 36篇 ACM水题 4篇 华科计算机考研复试 12篇 其他 4篇 区块链 dubbo 1篇 分布式 2篇 最新评论 计算机专业大学四年应该怎么过才有意义? BC3500wz: 噢噢,谢谢了 连夜撸了一个简易聊天室 编程学习指南: 一起加油呀 计算机专业大学四年应该怎么过才有意义? 编程学习指南: 想想办法还是可以的哈~ 【数字图像处理】直方图均衡化详解及编程实现 AK4?: 感谢大佬补充,我刚好也遇到了这个错误 聊聊如何才能进大厂实习~ Cessi_lion: 谢谢,很有帮助! 您愿意向朋友推荐“博客详情页”吗? 强烈不推荐 不推荐 一般般 推荐 强烈推荐 提交 最新文章 2022年学C++好比49年入国军? 连夜撸了一个简易聊天室 聊聊如何才能进大厂实习~ 2022年11篇 2021年3篇 2018年2篇 2015年1篇 2014年4篇 2013年47篇 2012年37篇 2011年46篇 2010年7篇 目录 目录 分类专栏 公众号:编程学习指南 11篇 Java 8篇 Spring 2篇 Linux 19篇 设计模式 4篇 Nginx模块开发与原理剖析 14篇 Nginx 12篇 数据结构与算法 19篇 笔试面试题 8篇 C/C++ 36篇 ACM水题 4篇 华科计算机考研复试 12篇 其他 4篇 区块链 dubbo 1篇 分布式 2篇 目录 实付元 使用余额支付 点击重新获取 扫码支付 钱包余额 0 抵扣说明: 1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。

2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值



請為這篇文章評分?