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

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>
            国产精品视频最多的网站| 亚洲国产91精品在线观看| 国产精品久久久久久久第一福利| 欧美成年人网| 欧美日韩综合久久| 国产精品久久一级| 狠狠久久亚洲欧美| 亚洲欧洲综合| 亚洲天堂网在线观看| 亚洲免费综合| 久久精品亚洲一区| 你懂的成人av| 一本大道久久a久久综合婷婷| 亚洲一级免费视频| 久久精品视频va| 欧美日韩国产一区精品一区| 国产精品伦一区| 伊人色综合久久天天| 99精品热视频只有精品10| 午夜国产精品视频| 欧美成人有码| 亚洲欧美精品在线观看| 久久婷婷激情| 在线亚洲免费| 国产日韩欧美精品在线| 亚洲国产精品一区二区第一页| 一本久久综合亚洲鲁鲁| 久久狠狠久久综合桃花| 欧美成人情趣视频| 亚洲免费视频观看| 久久久综合激的五月天| 一本色道婷婷久久欧美| 久久国产一二区| 亚洲七七久久综合桃花剧情介绍| 亚洲图色在线| 欧美成人在线影院| 国产一区二区中文字幕免费看| 亚洲精品一区在线观看| 久久九九精品99国产精品| 亚洲久久一区二区| 久久伊人精品天天| 国内精品久久久久国产盗摄免费观看完整版| 日韩视频一区二区三区在线播放| 久久精品国产91精品亚洲| 一区二区久久| 欧美日韩一区二区三区在线看 | 国产亚洲免费的视频看| 一区二区精品| 亚洲国产精品久久| 欧美制服丝袜| 国产精品一区二区女厕厕| 亚洲少妇中出一区| 亚洲精品网址在线观看| 欧美成人一品| 亚洲精美视频| 亚洲福利视频在线| 欧美成人免费网| 日韩午夜三级在线| 亚洲人精品午夜| 欧美精品成人一区二区在线观看 | 国产精品高清在线| 亚洲免费在线观看视频| 一区二区av在线| 国产精品免费看| 欧美一区成人| 午夜在线观看欧美| 国产日本亚洲高清| 久久久夜精品| 麻豆成人av| 亚洲精品一区二区三区蜜桃久 | 亚洲免费观看高清完整版在线观看| 久久免费视频在线观看| 亚洲高清视频一区| 亚洲精品久久久久久久久久久| 亚洲最黄网站| 国产精品99久久久久久久女警| 美女成人午夜| 99精品欧美一区二区三区综合在线 | 欧美午夜精品久久久| 亚洲欧美日韩国产一区| 亚洲男人的天堂在线aⅴ视频| 国产欧美一级| 免费成年人欧美视频| 欧美成人日韩| 午夜日韩av| 久久人人爽国产| 制服诱惑一区二区| 欧美在线free| 夜夜爽99久久国产综合精品女不卡| 99国产精品私拍| 国内精品久久久久影院薰衣草| 欧美成人精品h版在线观看| 欧美日韩mp4| 久久女同互慰一区二区三区| 欧美精品乱码久久久久久按摩| 亚洲一区日本| 鲁大师影院一区二区三区| 亚洲午夜电影| 久久精品人人做人人综合| 亚洲视频电影图片偷拍一区| 欧美亚洲午夜视频在线观看| 91久久精品一区| 亚洲欧美国产77777| 亚洲福利专区| 午夜在线精品| 日韩一级网站| 久久精品在线| 先锋影音网一区二区| 欧美激情1区2区3区| 久久―日本道色综合久久| 欧美天堂在线观看| 欧美国产三级| 国产在线拍揄自揄视频不卡99| av成人毛片| 亚洲国产成人精品久久| 亚洲字幕一区二区| 这里只有精品在线播放| 蜜臀av一级做a爰片久久| 欧美在线播放视频| 欧美日韩精品综合| 亚洲国产精品久久久久| 国产美女精品一区二区三区| 亚洲精品国产精品乱码不99按摩| 国产日韩欧美一区在线 | 永久免费视频成人| 亚洲新中文字幕| 日韩手机在线导航| 久久久久免费视频| 久久亚洲一区| 国产精品自拍在线| 99re热精品| 久久综合图片| 在线观看精品视频| 久久精品日产第一区二区| 午夜精品免费在线| 欧美三日本三级少妇三2023| 亚洲日本免费| 亚洲精品一区在线观看香蕉| 久久精品亚洲乱码伦伦中文 | 欧美在线观看一二区| 午夜在线精品偷拍| 国产精品美女久久| 亚洲性图久久| 欧美在线播放一区| 国产偷国产偷精品高清尤物| 欧美亚洲网站| 久久久91精品| 曰韩精品一区二区| 久久久www成人免费精品| 久久久久久久成人| 国产一区二区av| 久久国产欧美精品| 欧美www视频| 亚洲精品视频免费观看| 农村妇女精品| 亚洲精品视频免费| 亚洲女女做受ⅹxx高潮| 国产欧美1区2区3区| 欧美在线播放一区二区| 美女精品在线观看| 亚洲精品美女久久久久| 欧美日韩一区二区在线| 亚洲影院高清在线| 老牛国产精品一区的观看方式| 亚洲国产日韩一级| 欧美午夜精品久久久久久久 | 欧美亚洲成人免费| 性欧美大战久久久久久久久| 久久久久女教师免费一区| 在线观看亚洲视频啊啊啊啊| 美女黄毛**国产精品啪啪| 亚洲美女一区| 久久精品视频在线看| 亚洲国产精彩中文乱码av在线播放 | 欧美在线视频a| 亚洲国产专区| 国产精品成人在线| 欧美中文字幕第一页| 欧美大片免费观看在线观看网站推荐| 亚洲福利久久| 国产伦精品一区二区三区视频孕妇| 久久蜜桃精品| 夜夜嗨av一区二区三区网页| 久久九九久精品国产免费直播| 亚洲电影免费观看高清完整版在线观看 | 亚洲一线二线三线久久久| 麻豆国产精品777777在线| 99re视频这里只有精品| 国产美女一区| 欧美一级一区| 亚洲一区二区三区激情| 久久久久久亚洲精品不卡4k岛国| 亚洲激情偷拍| 国产视频在线一区二区| 欧美精品一区二区三| 久久久精品久久久久| 亚洲一区二区视频| 99re成人精品视频| 亚洲黄色成人| 欧美aaa级|