青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

OpenGL Frame Buffer Object 101

OpenGL Frame Buffer Object 101
by Rob 'phantom' Jones

Introduction

The Frame Buffer Object (FBO) extension was introduced to make Render to Texture objects much more efficient and much easier to perform when compared with the copying or pbuffer alternatives.

In this little article I抦 going to give you a quick over view of how to use this extension and some things to keep in mind when using it so you can add faster Render to Texture functionality to your OpenGL programs.

Setting Up

As with the other objects in OpenGL (texture object, pixel buffer objects and vertex buffer object) before you can use a FBO you have to create a valid handle to it:

GLuint fbo;
glGenFramebuffersEXT(1, &fbo);

To perform any operations on a FBO you need to bind it, much like you would a VBO or texture, so that the operations can be performed on it, this is done via the following code

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

The first parameter is the 憈arget?you wish to bind the framebuffer to, right now the only target you can use is the one indicated above however it is possible future extensions might allow you to bind it somewhere else. The fbo variable holds the handle to the FBO we requested earlier. To perform any FBO related operations you need to have a FBO bound or the calls will fail.

Adding a Depth Buffer

A FBO on its own isn抰 of much use, for it to be usable you have to attach some renderable objects to it; these can be textures or the newly introduced renderbuffers.

A renderbuffer are just objects which are used to support offscreen rendering, often for sections of the framebuffer which don抰 have a texture format associated with them such as the stencil or depth buffer.

In this case we are going to use a renderbuffer to give our FBO a depth buffer to use while rendering.

Like the FBO we first of all have to get a handle to a valid renderbuffer:

GLuint depthbuffer;
glGenRenderbuffersEXT(1, &depthbuffer);

Having successfully done this we need to bind the renderbuffer so that it is the current renderbuffer for the following operations:

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);

As with a FBO bind the first parameter is the 憈arget?you wish to bind to, which right now can only be the indicated target. The depthbuffer variable holds the handle to the renderbuffer we抣l be working with after this.

At this point the renderbuffer doesn抰 have any storage space associated with it, so we need to tell OpenGL how we want to use it and what size we抎 like. In this case we are asking for a depth buffer of a certain size:

glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);

Upon successful completion of the above code OpenGL will have allocated space for the renderbuffer to be used as a depth buffer with a given width and height. Note that renderbuffers can be used for normal RGB/RGBA storage and could be used to store stencil information.

Having reserved the space for the depth buffer the next job is to attach it to the FBO we created earlier.

glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer);

While it might look a bit imposing the function is pretty easy to understand; all it is doing is attaching the depthbuffer we created earlier to the currently bound FBO to its depth buffer attachment point.

Adding a Texture To Render To

At this point we still don抰 have a way of writing colour information to the FBO, so that is what we are going to add now. There are two ways of going about it:

  1. Attach a colour Renderbuffer to the FBO
  2. Attach a texture to the FBO

The former does have some uses; however it is the latter we will be covering here.

Before you can attach a texture you need to create one, this hasn抰 changed from the normal way of using textures as you抣l see:

GLuint img;
glGenTextures(1, &img);
glBindTexture(GL_TEXTURE_2D, img);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

In this instance we are creating a normal RGBA image of the same width and height as the renderbuffer we created earlier; this is important as ALL attachments to a FBO have to be the same width and height. Note that we don抰 upload any data, the space is just reserved by OpenGL so we can use it later.

Having created our texture the next job is to attach it to the FBO so we can render to it:

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0);

Again this might look imposing but it isn抰 that bad, the GL_COLOR_ATTACHMENT0_EXT tells OpenGL to attach it to the relevent attachment point (FBOs can have more than one colour buffer attached at any given time, each one to a different point), the GL_TEXTURE_2D tells OpenGL the format of the texture we are going to be attaching, img is the texture we抣l be attaching and the ??refers to the mipmap level of the texture you want to attach to, which you will generally want to leave as 0.

The final job to do in setup is to check that the FBO is 慶omplete? Completeness refers to the state of the FBO being one which, given the current OpenGL state and its attachments, all is correct for you to render to it.

This test is done via a single function which returns the status of the currently bound FBO

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

If all has gone well then status will equal GL_FRAMEBUFFER_COMPLETE_EXT and your FBO is ready to be rendered to. Other error codes, as found in the spec, indicate other problems which might well have occurred when you tried to setup the FBO.

Rendering to Texture

With all the hard work setting things up done the usage of the FBO from here on out is in fact pretty simple and relies on just one function call: glBindFramebufferEXT().

To render to a FBO you bind it and to stop rendering to it you call the above again with ??as the final parameter:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0,0,width, height);
// Render as normal here
// output goes to the FBO and it抯 attached buffers
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

Three lines which probably jumped out at you right away are the glPushAttrib/glPopAttrib pair and the glViewport call. The glViewport call is needed so that we don抰 try to render into an area bigger than, or even smaller than, the FBO is setup for. The glPushAtrrib and glPopAttrib are used as a quick way to save the old viewport information, this is needed because the FBO shares all of its states with the main context and as such any changes made affect both the FBO and the main context you would be normally rendering to.

An important point to make here is that you抣l notice that we only bound and then unbound the FBO to draw to it, we didn抰 reattach any textures or renderbuffers, this because they stay attached until you detach them yourself or the FBO is destroyed.

Using The Rendered To Texture

At this point our scene has been rendered to the texture and is now ready for us to use it and this operation itself is easy; we just bind the attached texture like any other texture.

glBindTexture(GL_TEXTURE_2D, img);

Having carried that out the texture is now ready to read from as normal.

Depending on the texture抯 filtering setup you might also want to generate mipmap information for it. Many people are used to using the gluBuild2DMipmaps() function to build mipmap information at load time and some of you might also be aware of the automatic mipmap generation extension; the FBO extension adds a third way with the GenerateMipmapEXT() function.

This function lets OpenGL build the mipmap information for you, the way it抯 done depends on the hardware you are running on, and is the correct way to do so for textures you have rendered to (you shouldn抰 use the automatic mipmap generation on a texture you are going to render to for various reasons which are covered in the spec).

To use the function all you have to do is bind a texture as above and then call:

glGenerateMipmapEXT(GL_TEXTURE_2D);

OpenGL will then generate all the required mipmap data for you so that your texture is ready to be used.

It抯 important to note that if you intend on using any of the mipmap filters (GL_LINEAR_MIPMAP_LINEAR for example) then you must call glGenerateMipmapEXT() before checking the framebuffer is complete or attempting to render to it.

At setup time you can just do it as follows:

glGenTextures(1, &img);
glBindTexture(GL_TEXTURE_2D, img);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmapEXT(GL_TEXTURE_2D);

At this point your texture is complete and can be rendered to like normal.

Cleaning Up

Finally, when you are done with your FBO you need to clean things up and delete it. This, like textures, is done via a single function:

glDeleteFramebuffersEXT(1, &fbo);

You also have to clean up any renderbuffers you might have allocated, in this case the depthbuffer renderbuffer needs to deleted, which again works the same way as cleaning up a texture:

glDeleteRenderbuffersEXT(1, &depthbuffer);

At this point both the FBO and the renderbuffer have been freed and your clean up is completed.

Final Thoughts

Hopefully this quick tour of the FBO extension will be enough to get you up and running with it. For a more detailed over view you'll want to check out the FBO spec or the section on the extension in the book More OpenGL Game Programming

In way of closing, before you go and check out the example program which shows a basic usage of the FBO extension I抎 like to leave you with the following tips and notes on FBO usage.

  1. Currently you can抰 have a stencil attachment. There is an extension in the works to allow for a texture format which would allow depth-stencil textures and thus render to stencil, however as of yet there is a lack of support for it.
  2. Don抰 constantly make the destroy FBOs, instead generate what you need at load/setup time and reuse them during the program as required.
  3. Avoid modifying the texture you have rendered to via any glTexImage and related calls. Doing so can and most probably will hurt your performance.

Notes on the example program

While this article talks about adding a depth renderbuffer and then a texture to the FBO in that order it was discovered that currently ATI抯 drivers appear to have a bug whereby adding the depth renderbuffer and then a texture causes the application to crash. This should be kept in mind when doing any FBO related work and tested for as it is possible it could be fixed in a future driver revision thus rendering the problem non-existent.

I抎 also like to put out a big thanks to Rick Appleton for helping me test out and debug the code on NVIDA hardware, couldn抰 have done it without you mate :)

The example program requires some form of GLUT to be compiled and run (I used FreeGLUT)

References

More OpenGL Game Programming
Framebuffer Object Spec
GDC 2005 Framebuffer Object pdf

posted on 2007-05-24 16:27 zmj 閱讀(1539) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            性一交一乱一区二区洋洋av| 伊甸园精品99久久久久久| 亚洲精一区二区三区| 亚洲电影第三页| 亚洲欧美日韩视频一区| 亚洲男人的天堂在线观看| 午夜精品久久久久久99热软件| 亚洲欧洲精品一区二区| 夜夜嗨网站十八久久| 亚洲视频电影图片偷拍一区| 欧美一区二区在线免费观看| 欧美一区二区精品在线| 久久久夜夜夜| 国产精品国产亚洲精品看不卡15| 亚洲综合日韩在线| 91久久香蕉国产日韩欧美9色 | 亚洲国产经典视频| 亚洲国语精品自产拍在线观看| 亚洲精品乱码久久久久久按摩观 | 国产综合自拍| 在线日韩成人| 亚洲免费观看视频| 亚洲欧美另类综合偷拍| 美女任你摸久久| 小辣椒精品导航| 欧美 日韩 国产在线| 亚洲欧洲一级| 欧美一区二区精品在线| 老司机午夜精品视频| 国产精品v欧美精品v日韩| 精品成人在线观看| 亚洲一区二区在线| 免费成人高清视频| 亚洲午夜精品一区二区| 欧美不卡在线| 国模吧视频一区| 99国产欧美久久久精品| 久久一二三四| 亚洲一区二区三区在线看| 鲁大师影院一区二区三区| 国产日韩欧美在线播放| 在线视频精品一区| 麻豆精品精华液| 亚洲图片在线| 欧美日韩成人在线| 亚洲国产欧美不卡在线观看| 亚洲欧美日韩一区二区三区在线| 欧美不卡高清| 久久成人免费日本黄色| 国产麻豆视频精品| 亚洲麻豆av| 牛夜精品久久久久久久99黑人| 午夜在线电影亚洲一区| 欧美视频网址| 亚洲一区日韩在线| 亚洲国产精品综合| 久久久天天操| **性色生活片久久毛片| 蜜臀va亚洲va欧美va天堂| 欧美伊人久久久久久久久影院| 国产欧亚日韩视频| 午夜精品久久久久久久久久久久| 9l视频自拍蝌蚪9l视频成人 | 欧美日韩视频一区二区| 亚洲日本久久| 亚洲欧洲一区二区天堂久久| 欧美日韩aaaaa| 亚洲一区在线观看视频 | 欧美一二三区在线观看| 亚洲欧美另类中文字幕| 国产视频亚洲| 免费黄网站欧美| 老司机午夜精品视频| 日韩一区二区免费看| 一区二区三区四区五区精品视频| 国产精品国产三级国产aⅴ浪潮 | 欧美三级在线播放| 亚洲日本成人网| 亚洲日韩成人| 国产精品不卡在线| 欧美一区二区女人| 久久福利一区| 最新日韩在线| 9人人澡人人爽人人精品| 国产精品一级久久久| 久久久精品2019中文字幕神马| 久久精品一区二区三区中文字幕| 亚洲承认在线| 一区二区黄色| 亚洲国产成人tv| 久久免费精品日本久久中文字幕| 国产精品毛片a∨一区二区三区| 午夜视频精品| 久久久久久久一区二区| 一本色道久久综合狠狠躁篇怎么玩 | 亚洲欧美激情一区| 午夜亚洲性色福利视频| 亚洲三级毛片| 性做久久久久久久久| 亚洲经典在线| 亚洲一区二区三区国产| 亚洲韩国青草视频| 亚洲欧美精品伊人久久| 亚洲精品在线观| 久久成年人视频| 午夜精品久久| 欧美激情在线观看| 欧美精品99| 免播放器亚洲一区| 亚洲精品女av网站| 亚洲性线免费观看视频成熟| 国产一区二区激情| 99国产精品久久久久久久久久 | 欧美成人国产| 国产精品成人v| 欧美国产日韩一区二区在线观看| 国产精品剧情在线亚洲| 免费成人激情视频| 国产亚洲综合性久久久影院| 亚洲国产精品成人综合| 99精品热视频| 久久岛国电影| 久久精品综合一区| 亚洲一卡二卡三卡四卡五卡| 久久经典综合| 性欧美超级视频| 欧美日韩一卡二卡| 免费人成精品欧美精品| 国产日韩精品在线播放| 99ri日韩精品视频| 亚洲欧洲午夜| 理论片一区二区在线| 久久久久在线观看| 国产精品免费在线| av成人福利| 夜夜嗨网站十八久久| 欧美日韩第一页| 亚洲激情视频| 亚洲国产精品福利| 久久国产66| 久久人人爽国产| 久久久夜色精品亚洲| 国产视频亚洲精品| 亚洲欧美成人网| 午夜视频精品| 国产视频丨精品|在线观看| 亚洲在线一区二区| 香蕉av福利精品导航| 国产精品视频福利| 亚洲视频1区2区| 欧美在线看片a免费观看| 国产精品久久国产三级国电话系列| 91久久在线| 亚洲影视在线播放| 国产精品豆花视频| 性视频1819p久久| 久久综合九色| 91久久精品国产91性色| 欧美激情91| 夜色激情一区二区| 亚洲欧美激情四射在线日| 国产日韩一区| 久久精品免视看| 亚洲精品日韩欧美| 午夜久久电影网| 在线观看久久av| 欧美日韩精选| 亚洲欧美三级在线| 嫩草伊人久久精品少妇av杨幂| 亚洲精品一区二区网址| 欧美精品一区在线发布| 亚洲欧美高清| 老巨人导航500精品| 亚洲国产天堂久久国产91| 欧美金8天国| 亚洲一区激情| 欧美成人综合一区| 先锋影院在线亚洲| 亚洲第一视频| 国产精品红桃| 美腿丝袜亚洲色图| 亚洲一级片在线看| 欧美激情在线有限公司| 欧美在线观看一二区| 亚洲第一精品久久忘忧草社区| 欧美日韩激情小视频| 久久久久久成人| 亚洲午夜黄色| 亚洲精品国产精品久久清纯直播| 亚洲欧美色婷婷| 亚洲一区二区三区在线| 日韩西西人体444www| 国产自产2019最新不卡| 欧美伦理在线观看| 久久久综合精品| 午夜在线一区二区| 最新日韩在线视频| 免费欧美在线| 久久综合久久美利坚合众国| 亚洲一区二区在线|