Framebuffer Object - OpenGL Wiki
文章推薦指數: 80 %
Framebuffer Objects are OpenGL Objects, which allow for the creation of user-defined Framebuffers. With them, one can render to non-Default Framebuffer ...
FramebufferObject
FromOpenGLWiki
Jumptonavigation
Jumptosearch
FramebufferObject
Coreinversion
4.6
Coresinceversion
3.0
CoreARBextension
GL_ARB_framebuffer_object
EXTextension
GL_EXT_framebuffer_object,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_packed_depth_stencil
FramebufferObjectsareOpenGLObjects,whichallowforthecreationofuser-definedFramebuffers.Withthem,onecanrendertonon-DefaultFramebufferlocations,andthusrenderwithoutdisturbingthemainscreen.
Contents
1Semantics
2FramebufferObjectStructure
3AttachingImages
3.1LayeredImages
4Emptyframebuffers
5FramebufferCompleteness
5.1AttachmentCompleteness
5.2CompletenessRules
6FeedbackLoops
7PseudoImplementation
8EXT_Framebuffer_object
9SeeAlso
10Reference
Semantics
Framebufferobjectsareacollectionofattachments.Tohelpexplainletsexplicitlydefinecertainterminology.
Image
Forthepurposesofthisarticle,animageisasingle2Darrayofpixels.Ithasaspecificformatforthesepixels.
LayeredImage
Forthepurposesofthisarticle,alayeredimageisasequenceofimagesofaparticularsizeandformat.LayeredimagescomefromsinglemipmaplevelsofcertainTexturetypes.
Texture
Forthepurposesofthisarticle,atextureisanobjectthatcontainssomenumberofimages,asdefinedabove.Alloftheimageshavethesameformat,buttheydonothavetohavethesamesize(differentmip-maps,forexample).TexturescanbeaccessedfromShadersviavariousmethods.
Renderbuffer
Arenderbufferisanobjectthatcontainsasingleimage.RenderbufferscannotbeaccessedbyShadersinanyway.Theonlywaytoworkwitharenderbuffer,besidescreatingit,istoputitintoanFBO.
Attach
Toconnectoneobjecttoanother.ThistermisusedacrossallofOpenGL,butFBOsmakethemostuseoftheconcept.Attachmentisdifferentfrombinding.Objectsareboundtothecontext;objectsareattachedtooneanother.
Attachmentpoint
Anamedlocationwithinaframebufferobjectthataframebuffer-attachableimageorlayeredimagecanbeattachedto.AttachmentpointsrestrictthegeneralkindofImageFormatforimagesattachedtothem.
Framebuffer-attachableimage
Anyimage,aspreviouslydescribed,thatcanbeattachedtoaframebufferobject.
Framebuffer-attachablelayeredimage
Anylayeredimage,aspreviouslydescribed,thatcanbeattachedtoaframebufferobject.
FramebufferObjectStructure
AsstandardOpenGLObjects,FBOshavetheusualglGenFramebuffersandglDeleteFramebuffersfunctions.Asexpected,italsohastheusualglBindFramebufferfunction,tobindanFBOtothecontext.
Thetargetparameterforthisobjectcantakeoneof3values:GL_FRAMEBUFFER,GL_READ_FRAMEBUFFER,orGL_DRAW_FRAMEBUFFER.ThelasttwoallowyoutobindanFBOsothatreadingcommands(glReadPixels,etc)andwritingcommands(allrenderingcommands)canhappentotwodifferentframebuffers.TheGL_FRAMEBUFFERbindingtargetsimplysetsboththereadandthewritetothesameFBO.
ThedefaultframebufferhasbuffernameslikeGL_FRONT,GL_BACK,GL_AUXi,GL_ACCUM,andsoforth.FBOsdonotusethese.
Instead,FBOshaveadifferentsetofimagenames.EachFBOimagerepresentsanattachmentpoint,alocationintheFBOwhereanimagecanbeattached.FBOshavethefollowingattachmentpoints:
GL_COLOR_ATTACHMENTi:Theseareanimplementation-dependentnumberofattachmentpoints.YoucanqueryGL_MAX_COLOR_ATTACHMENTStodeterminethenumberofcolorattachmentsthatanimplementationwillallow.Theminimumvalueforthisis8,soyouareguaranteedtobeabletohaveatleastcolorattachments0-7.Theseattachmentpointscanonlyhaveimagesboundtothemwithcolor-renderableformats.Allcompressedimageformatsarenotcolor-renderable,andthuscannotbeattachedtoanFBO.
GL_DEPTH_ATTACHMENT:Thisattachmentpointcanonlyhaveimageswithdepthformatsboundtoit.TheimageattachedbecomestheDepthBufferfortheFBO.Notethatifnodepthimageisattached,DepthTestingwillbedisabledwhenrenderingtothisFBO.
GL_STENCIL_ATTACHMENT:Thisattachmentpointcanonlyhaveimageswithstencilformatsboundtoit.TheimageattachedbecomesthestencilbufferfortheFBO.
GL_DEPTH_STENCIL_ATTACHMENT:Thisisshorthandfor"bothdepthandstencil".Theimageattachedbecomesboththedepthandstencilbuffers.
Note:IfyouuseGL_DEPTH_STENCIL_ATTACHMENT,youshoulduseapackeddepth-stencilinternalformatforthetextureorrenderbufferyouareattaching.
AttachingImages
NowthatweknowwhereimagescanbeattachedtoFBOs,wecanstarttalkingabouthowtoactuallyattachimagestothese.InordertoattachimagestoanFBO,wemustfirstbindtheFBOtothecontextwithglBindFramebuffer.
Youcanattachimagesfrommosttexturetypestotheframebufferobject.However,framebuffersaredesignedfor2Drendering.Sothereisaneedtoconsiderhowdifferenttexturetypesmaptoframebufferimages.Rememberthattexturesareasetofimages.Texturescanhavemipmaps,andindividualmipmaplevelscouldcontainoneormoreimages.
Thewaydifferenttexturetypesmaptoframebufferimagesisasfollows:
Imagesina1Dtextureareconsidered2Dimageswithaverticalheightof1.Eachindividualimagecanbeuniquelyidentifiedbyamipmaplevel.
Imagesina2Dtexturearetakenasnormal.Eachindividualimagecanbeuniquelyidentifiedbyamipmaplevel.
Amipmaplevelofa3Dtextureisconsideredtobeasetof2Dimages,withthenumberoftheseimagesbeingtheextentoftheZcoordinateforthatmipmaplevel.EachintegervaluefortheZofa3Dtexturemipmaplevelisaseparate2Dlayer.Soeachimageina3Dtextureisuniquelyidentifiedbyalayerandamipmaplevel.Recallthatdifferentmipmaplevelsina3DtexturewillhavedifferentcountsofZcoordinates.
RectangleTexturescontainasingle2Dimage,whichisidentifiedbyalevelof0.
CubemapTexturescontain62Dimagespermipmap.Thus,eachimageinacubemaptexturecanbeuniquelyidentifiedbyafacetargetandamipmaplevel.However,insomeAPIfunctions,individualfacesinamipmaplevelareidentifiedbyalayerindexinsteadofatarget.
Eachmipmaplevelof1Dor2DArrayTexturescontainsanumberofimages,equaltothecountimagesinthearray.Thus,eachindividualimageisuniquelyidentifiedbyalayer(thearrayindex)andamipmaplevel.For1Darraytextures,eachimagehasaheightof1.Unlike3Dtextures,thelayerdoesn'tchangewhengoingdownthemipmaphierarchy.
CubemapArrayTexturesworklike2Darraytextures,onlywithanimagecount6timesthenumberofitslayers.A2Dimageinthecubemaparrayisidentifiedbythelayer-faceindexlayerandamipmaplevel.
BufferTexturescannotbeattachedtoframebuffers.
Thewordslevel,layer,andtargetabovearesignificant,astheymatchtheparametersofthefollowingfunctionsusedforattachingtextures:
voidglFramebufferTexture1D(GLenumtarget,GLenumattachment,GLenumtextarget,GLuinttexture,GLintlevel);
voidglFramebufferTexture2D(GLenumtarget,GLenumattachment,GLenumtextarget,GLuinttexture,GLintlevel);
voidglFramebufferTextureLayer(GLenumtarget,GLenumattachment,GLuinttexture,GLintlevel,GLintlayer);
Thetargetparameterhereisthesameastheoneforbind.However,GL_FRAMEBUFFERdoesn'tmeanbothreadanddraw(asthatwouldmakenosense);instead,itisthesameasGL_DRAW_FRAMEBUFFER.Theattachmentparameterisoneoftheaboveattachmentpoints.
Thetextureargumentisthetextureobjectnameyouwanttoattachfrom.Ifyoupasszeroastexture,thishastheeffectofclearingtheattachmentforthisattachment,regardlessofwhatkindofimagewasattachedthere.
Becausetextureobjectscanholdmultipleimages,youmustspecifyexactlywhichimagetoattachtothisattachmentpoint.Theparametersmatchtheirabovedefinitions,withtheexceptionoftextarget.
Whenattachinganon-cubemap,textargetshouldbethepropertexturetype:GL_TEXTURE_1D,GL_TEXTURE_2D_MULTISAMPLE,etc.Whenattachinga(non-array)cubemap,youmustusetheTexture2Dfunction,andthetextargetmustbeoneofthe6targetsforcubemapbinding.Whenattachinganimagefromacubemaparray,youmustuseTextureLayer,withthelayerbeingalayer-face.
Note:IfOpenGL4.5orARB_direct_state_accessisavailable,thenglFramebufferTextureLayermaytakenon-arraycubemaptextures.Theyaretreatedasthoughtheywereanarraycubemapwithonelayer(so6layer-faces).ThismeansthatyouneverneedtousetheTexture2DorTexture1Dfunctionsforanything.
LegacyNote:Thereisafunction,glFramebufferTexture3D,specificallyfor3Dtextures.However,youshouldn'tbotherwithit,astheTextureLayerfunctioncandoeverythingitcanandmore.
RenderbufferscanalsobeattachedtoFBOs.Indeed,thisistheonlywaytousethembesidesjustcreatingthestorageforthem.
Onceyouhavecreatedarenderbufferobjectandmadestorageforit(givenasizeandformat),youcanattachittoanFBOwiththisfunction:
voidglFramebufferRenderbuffer(GLenumtarget,GLenumattachment,GLenumrenderbuffertarget,GLuintrenderbuffer);
Theparametersworkmostlythesameaswithtextureattachment.TherenderbuffertargetparammustbeGL_RENDERBUFFER.Therenderbufferparameteristherenderbufferobject'sname.
LayeredImages
Alayeredimage,aspreviouslydefined,isanorderedsequenceofimagesofaparticularsize.Anumberofdifferentkindsoftexturescanbeconsideredlayered.
Asinglemipmaplevelofa1Dor2DArrayTexturecanbeattachedasalayeredimage,wherethenumberoflayersisthearraysize.Asinglemipmaplevelofa3Dtexturelikewisecanbeattachedasalayeredimage,wherethenumberoflayersisthedepthofthatparticularmipmaplevel.Also,amipmaplevelofaCubemapTexturecanbeattachedasalayeredimage.Forcubemaps,yougetexactly6layers,oneforeachface.Andtheorderofthefacesisthesameastheorderoftheenumerators:
Layernumber
Cubemapface
0
GL_TEXTURE_CUBE_MAP_POSITIVE_X
1
GL_TEXTURE_CUBE_MAP_NEGATIVE_X
2
GL_TEXTURE_CUBE_MAP_POSITIVE_Y
3
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
4
GL_TEXTURE_CUBE_MAP_POSITIVE_Z
5
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
Forcubemaparrays,thevaluethatgl_Layerrepresentsisthelayer-faceindex.Thusitisthefacewithinalayer,orderedasabove.Soifyouwanttorendertothe3rdlayer,+zface,youwouldsetgl_Layerto(2*6)+4,or16.
Eachmipmaplevel,whencanbeattachedasalayeredimage,hasaspecificnumberoflayers.For1Dand2Darraytextures,itisthenumberoflayersinthetextureasawhole.For3Dtextures,thisisthedepthofthatparticularmipmaplevel.Forcubemaps,thisisalwaysexactly6layers:oneperface.Cubemaparrayshave6*thenumberoflayers,whichisthenumberoflayer-faces.
Toattachamipmaplevelofatextureasalayeredimage,usethefollowingcommand:
voidglFramebufferTexture(GLenumtarget,GLenumattachment,GLuinttexture,GLintlevel);
Theparametershavethesamemeaningasabove.Indeed,thisfunctioncanreplacemanyoftheusesforglFramebufferTexture1D,2D,orLayer,aslongasyoudonotintendtoattachspecificlayersofarraytextures,cubemaps,or3Dtexturesasregular,non-layeredimages.Ifthetextureisoneofthesekindsoftextures,thenthegivenmipmaplevelwillbeattachedasalayeredimagewiththenumberoflayersthatthegiventexturehas.
LayeredimagesareusedwithLayeredRendering,whichsendsdifferentprimitivestodifferentlayerswithintheframebuffer.
Emptyframebuffers
EmptyFramebuffers
Coreinversion
4.6
Coresinceversion
4.3
CoreARBextension
ARB_framebuffer_no_attachments
Itispossibletorendertoaframebufferobjectthathasnoattachments.Obviouslynoneofthefragmentshaderoutputswillbewrittentoanywhereinthiscase,butrenderingcanotherwiseproceedasnormal.Thisisusefulforusingarbitraryreadingandwritingofimagedatafromshaders,ratherthanwritingtoaboundframebuffer.
However,therasterizationofprimitivesisalwaysbasedontheareaandcharacteristicsoftheboundframebuffer.Thesecharacteristics(size,numberofsamplesformultisamplerendering,etc)wouldnormallybedefinedbytheattachedimages.Ifnoimagesareattached,thesecharacteristicsmustbedefinedinsomeotherfashion.
ThecharacteristicsforanFBOwithnoattachmentscanbesetwiththisfunction:
voidglFramebufferParameteri(GLenumtarget,GLenumpname,GLintparam);
targetisthelocationwheretheframebufferobjectisbound.Tosetthewidth,setpnametoGL_FRAMEBUFFER_DEFAULT_WIDTH;tosettheheight,useGL_FRAMEBUFFER_DEFAULT_HEIGHT.
LayeredframebufferscanbesimulatedbysettingGL_FRAMEBUFFER_DEFAULT_LAYERStoalayercountotherthan0.MultisampleframebufferscanbesimulatedbysettingGL_FRAMEBUFFER_DEFAULT_SAMPLEStoanumberofsamplesotherthan0.FixedmultisamplelocationcansimilarlybesimulatedbysettingGL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONStoanon-zerovalue.
NotethatrenderingisonlylimitedtotheseparametersifnoimagesareattachedtotheFBO.Ifimagesareattached,thentheseparametersareignored.YoushouldonlysetthesevaluesifyouintendtousetheFBOwithoutimages.
FramebufferCompleteness
EachattachmentpointinaFBOhasspecificrestrictionsontheformatofimagesthatcanbeattachedtoit.However,itisnotanimmediateGLerrortoattachanimagetoanattachmentpointthatdoesn'tsupportthatformat.ItisanerrortotrytouseanFBOthathasbeenimproperlysetup.TherearealsoanumberofotherissueswithregardtosizesofimagesandsoforththatmustbedetectedinordertobeabletosafelyusetheFBO.
AnFBOthatisvalidforuseissaidtobe"framebuffercomplete".Totestframebuffercompleteness,callthisfunction:
GLenumglCheckFramebufferStatus(GLenumtarget);
Youarenotrequiredtocallthismanually.However,usinganincompleteFBOisanerror,soit'salwaysagoodideatocheck.
ThereturnvalueisGL_FRAMEBUFFER_COMPLETEiftheFBOcanbeused.Ifitissomethingelse,thenthereisaproblem.Belowaretherulesforcompletenessandtheassociatedreturnvaluesyouwillreceiveiftheyarenotfollowed.
AttachmentCompleteness
Eachattachmentpointitselfmustbecompleteaccordingtotheserules.Emptyattachments(attachmentswithnoimageattached)arecompletebydefault.Ifanimageisattached,itmustadheretothefollowingrules:
Thesourceobjectfortheimagestillexistsandhasthesametypeitwasattachedwith.
Theimagehasanon-zerowidthandheight(theheightofa1Dimageisassumedtobe1).Thewidth/heightmustalsobelessthanGL_MAX_FRAMEBUFFER_WIDTHandGL_MAX_FRAMEBUFFER_HEIGHTrespectively(ifGL4.3/ARB_framebuffer_no_attachments).
Thelayerfor3Dorarraytexturesattachmentsislessthanthedepthofthetexture.ItmustalsobelessthanGL_MAX_FRAMEBUFFER_LAYERS(ifGL4.3/ARB_framebuffer_no_attachments).
ThenumberofsamplesmustbelessthanGL_MAX_FRAMEBUFFER_SAMPLES(ifGL4.3/ARB_framebuffer_no_attachments).
Theimage'sformatmustmatchtheattachmentpoint'srequirements,asdefinedabove.Color-renderableformatsforcolorattachments,etc.
CompletenessRules
Thesearetherulesforframebuffercompleteness.Theorderoftheserulesmatters.
IfthetargetofglCheckFramebufferStatusreferencestheDefaultFramebuffer(ie:FBOobjectnumber0isbound),andthedefaultframebufferdoesnotexist,thenyouwillgetGL_FRAMEBUFFER_UNDEFINED.Ifthedefaultframebufferexists,thenyoualwaysgetGL_FRAMEBUFFER_COMPLETE.TherestoftherulesapplywhenanFBOisbound.
Allattachmentsmustbeattachmentcomplete.(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENTwhenfalse).
TheremustbeatleastoneimageattachedtotheFBO,orifOpenGL4.3orARB_framebuffer_no_attachmentsisavailable,theGL_FRAMEBUFFER_DEFAULT_WIDTHandGL_FRAMEBUFFER_DEFAULT_HEIGHTparametersoftheframebuffermustbothbenon-zero.(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENTwhenfalse).
EachdrawbuffermusteitherspecifycolorattachmentpointsthathaveimagesattachedormustbeGL_NONE.(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFERwhenfalse).NotethatthistestisnotperformedifOpenGL4.1orARB_ES2_compatibilityisavailable.
Ifthereadbufferisset,thenitmustspecifyanattachmentpointthathasanimageattached.(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFERwhenfalse).NotethatthistestisnotperformedifOpenGL4.1orARB_ES2_compatibilityisavailable.
Allimagesmusthavethesamenumberofmultisamplesamples.Allimagesmustalsousethesamefixedsamplelayoutsetting.(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLEwhenfalse).
Ifalayeredimageisattachedtooneattachment,thenallattachmentsmustbelayeredattachments.Theattachedlayersdonothavetohavethesamenumberoflayers,nordothelayershavetocomefromthesamekindoftexture(acubemapcolortexturecanbepairedwithanarraydepthtexture)(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETSwhenfalse).
Noticethatthereisnorestrictionbasedonsize.TheeffectivesizeoftheFBOistheintersectionofallofthesizesoftheboundimages(ie:thesmallestineachdimension).
Theserulesareallcode-based.IfyouevergetanyofthesevaluesfromglCheckFramebufferStatus,itisbecauseyourprogramhasdonesomethingwronginsettinguptheFBO.Eachonehasaspecificremedyforit.
There'sonemorerulethatcantripyouup:
Theimplementationlikesyourcombinationofattachedimageformats.(GL_FRAMEBUFFER_UNSUPPORTEDwhenfalse).
OpenGLallowsimplementationstostatethattheydonotsupportsomecombinationofimageformatsfortheattachedimages;theydothisbyreturningGL_FRAMEBUFFER_UNSUPPORTEDwhenyouattempttouseanunsupportedformatcombination.
However,theOpenGLspecificationalsorequiresthatimplementationssupportcertainformatcombinations;ifyouusethese,implementationsareforbiddentoreturnGL_FRAMEBUFFER_UNSUPPORTED.Implementationsmustallowanycombinationofcolorformats,solongasallofthosecolorformatscomefromtherequiredsetofcolorformats.
Thesecolorformatscanbecombinedwithadepthattachmentwithanyoftherequireddepthformats.Stencilattachmentscanalsobeused,againwiththerequiredstencilformats,aswellasthecombineddepth/stencilformats.However,implementationsareonlyrequiredtosupportbothadepthandstencilattachmentsimultaneouslyifbothattachmentsrefertothesameimage.
Thismeansthatifyouwantstencilwithnodepth,youcanuseoneoftherequiredstencilformats.Ifyouwantdepthwithnostencil,youcanuseoneoftherequireddepthformats.Butifyouwantdepthandstencil,youmustuseadepth/stencilformatandthesameimageinthattexturemustbeattachedtoboththedepthandstencilattachments.
Stayingwithintheselimitsmeansyouwon'tseeGL_FRAMEBUFFER_UNSUPPORTED.Goingoutsideoftheselimitsmakesitentirelypossibletogetthisincompleteness.
LegacyNote:GL_FRAMEBUFFER_UNSUPPORTEDwas,inthedaysofEXT_framebuffer_object,muchlessforgiving.Thespecificationdidn'thavealistofrequiredimageformats.Indeed,theonlyguaranteethattheEXT_FBOspecmadewasthattherewasatleastonecombinationofformatsthatimplementationssupported;itprovidednohintsastowhatthatcombinationmightbe.ThecoreextensionARB_framebuffer_objectdoesdifferfromthecorespecificationinonecrucialway:itusestheEXTwordingforGL_FRAMEBUFFER_UNSUPPORTED.Soifyou'reusing3.0,justusetherequiredformatsasabove.Ifyou'reusingARB_framebuffer_object,thenyoushouldbeconcernedanddoappropriatetesting.
FeedbackLoops
Mainarticle:MemoryModel#Framebufferobjects
ItispossibletobindatexturetoanFBO,bindthatsametexturetoashader,andthentrytorenderwithitatthesametime.
ItisperfectlyvalidtobindoneimagefromatexturetoanFBOandthenrenderwiththattexture,aslongasyoupreventyourselffromsamplingfromthatimage.Ifyoudotrytoreadandwritetothesameimage,yougetundefinedresults.Meaningitmaydowhatyouwant,thesamplermaygetolddata,thesamplermaygethalfoldandhalfnewdata,oritmaygetgarbagedata.Anyofthesearepossibleoutcomes.
Note:"image"hererefersessentiallytoamipmaplevel.Soseparate"images"withinasinglemipmaplevelofanarraytexturedonotcountasseparate,soyouwillgetUBifyoutrytowritetoonewhilereadingfromanother.Viewtexturescanhelpresolvethis,asyoucangetanarraylayertocountasaseparateimage.
Donotdothis.Whatyouwillgetisundefinedbehavior.
OpenGLOpenGL4.5orARB_texture_barrierreducesthecasesoffeedbackloopstojustreading/writingfromthesamepixels,andevenallowsalimitedabilitytoread/writethesamepixels.
PseudoImplementation
Apseudoimplementationwillmakeframebuffersmucheasiertounderstand.
structFramebuffer{
map
延伸文章資訊
- 1OpenGL學習腳印: 幀緩沖對象(Frame Buffer Object) - IT閱讀
FBO中包含兩種類型的附加圖像(framebuffer-attachable): 紋理圖像和RenderBuffer圖像(texture images and renderbuffer imag...
- 2帧缓冲 - LearnOpenGL-CN
把这几种缓冲结合起来叫做帧缓冲(Framebuffer),它被储存于内存中。OpenGL给了我们自己定义帧缓冲的自由,我们可以选择性的定义自己的颜色缓冲、深度和模板缓冲。
- 3Framebuffer Object - OpenGL Wiki
Framebuffer Objects are OpenGL Objects, which allow for the creation of user-defined Framebuffers...
- 4OpenGL Frame Buffer Object (FBO) - Song Ho Ahn
Framebuffer is a collection of 2D arrays or storages utilized by OpenGL; colour buffers, depth bu...
- 5Framebuffers - LearnOpenGL
Renderbuffer objects were introduced to OpenGL after textures as a possible type of framebuffer a...