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

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>
            久久精品一区二区国产| 久久国产精品亚洲va麻豆| 日韩一级黄色av| 激情欧美一区二区三区| 国产精品丝袜91| 国产一区在线看| 在线观看亚洲| 亚洲综合导航| 午夜精品久久| 久久久精品午夜少妇| 久久综合久久久| 欧美成人午夜激情| 欧美日韩亚洲国产一区| 国产乱子伦一区二区三区国色天香| 国产精品久久久久国产精品日日| 国产欧美日本| 亚洲日本激情| 午夜视频一区在线观看| 欧美成人精精品一区二区频| 亚洲黄色免费电影| 一二三区精品| 免费在线成人av| 欧美特黄一区| 亚洲日本va午夜在线电影 | 欧美激情无毛| 久久精品人人做人人爽电影蜜月| 久久午夜羞羞影院免费观看| 99国产精品久久久久久久成人热| 久久久久久91香蕉国产| 欧美福利一区| 亚洲国产精品va| 欧美一区二区三区四区视频| 亚洲国产清纯| 欧美一区二区视频网站| 欧美激情第3页| 狠狠干成人综合网| 一区二区三区精品视频在线观看| 久久日韩精品| 亚洲一区二区日本| 欧美日本国产视频| 国产一区二区三区的电影 | 一区二区在线观看视频| 亚洲欧洲一区二区在线播放| 久久激五月天综合精品| 亚洲级视频在线观看免费1级| 久久爱91午夜羞羞| 欧美日韩国产天堂| 亚洲欧洲视频| 亚洲国产精品热久久| 久久精品亚洲国产奇米99| 亚洲精品资源美女情侣酒店| 另类成人小视频在线| 亚洲精品你懂的| 久热爱精品视频线路一| 伊人久久综合97精品| 久久精品盗摄| 久久精品女人天堂| 影音先锋中文字幕一区| 久久精品最新地址| 久久久国产成人精品| 国产欧美在线观看| 久久国产欧美日韩精品| 亚洲永久免费av| 国产精品家庭影院| 性8sex亚洲区入口| 亚洲一区视频在线观看视频| 国产精品爽爽爽| 香蕉久久a毛片| 亚洲欧美日韩在线| 国产欧美日韩91| 久久99伊人| 久久久久国内| 亚洲国产一二三| 最新高清无码专区| 欧美日韩成人一区二区| 中日韩美女免费视频网址在线观看 | 亚洲视频一区| 国产精品黄页免费高清在线观看| 亚洲欧美日韩在线一区| 亚洲一区二区在线观看视频| 国产欧美在线播放| 蜜桃久久av一区| 免费看亚洲片| 国模一区二区三区| 欧美成人午夜剧场免费观看| 欧美美女bbbb| 亚洲自拍偷拍福利| 欧美一级片在线播放| 亚洲国产日韩欧美综合久久 | 欧美激情一区在线观看| 欧美日韩免费高清一区色橹橹| 一区二区三区四区五区视频| 亚洲欧美日韩精品久久奇米色影视| 国产精品欧美一区喷水| 久久精品免视看| 欧美电影在线观看| 亚洲综合丁香| 另类欧美日韩国产在线| 亚洲在线观看视频| 久久婷婷国产麻豆91天堂| 亚洲欧美国产高清va在线播| 欧美在线国产| 亚洲欧美日韩国产成人| 久久青草欧美一区二区三区| 一本色道**综合亚洲精品蜜桃冫 | 精品99视频| 欧美激情一区二区三级高清视频| 欧美激情视频网站| 久久亚洲二区| 99xxxx成人网| 久久久久久穴| 一区二区三区你懂的| 狠狠色综合色区| 中日韩美女免费视频网站在线观看| 国内久久精品视频| 一个色综合导航| 亚洲片在线观看| 午夜精品视频网站| 亚洲欧美另类国产| 欧美a级理论片| 久久久在线视频| 国产欧美一区在线| 在线亚洲精品| 亚洲视频在线看| 欧美www在线| 欧美福利影院| 在线成人免费观看| 欧美一区二区三区视频免费播放| 亚洲欧美日韩精品久久久| 欧美激情一区| 亚洲激情专区| 亚洲欧洲日产国产综合网| 亚洲毛片在线免费观看| 奶水喷射视频一区| 美女爽到呻吟久久久久| 曰韩精品一区二区| 久久精品视频在线看| 久久视频在线看| 国产主播在线一区| 欧美亚洲三区| 久久综合久久综合久久| 国产一区激情| 久久夜色精品亚洲噜噜国产mv| 久久精品一区二区三区四区| 国产在线精品一区二区中文| 久久成人资源| 女女同性精品视频| 91久久精品久久国产性色也91| 久久漫画官网| 欧美激情精品久久久久久黑人| 在线观看视频亚洲| 欧美成人四级电影| 亚洲精品自在在线观看| 亚洲视频在线看| 国产精品亚洲аv天堂网| 亚洲免费在线观看视频| 久久综合久久美利坚合众国| 亚洲国产精品嫩草影院| 欧美日韩xxxxx| 亚洲综合不卡| 国产日韩在线看| 久久免费国产精品| 欧美国产视频一区二区| 这里只有精品在线播放| 国产精品久久久一区二区三区| 香蕉成人久久| 欧美多人爱爱视频网站| 在线亚洲电影| 国产日韩欧美一区二区三区四区| 久久国产精品第一页| 亚洲人成网站色ww在线| 亚洲欧美日韩国产中文| 亚洲黄一区二区| 久久久久久久一区二区| 国语自产精品视频在线看| 欧美—级在线免费片| 亚洲一二三区视频在线观看| 免费成人黄色av| 亚洲午夜精品17c| 在线观看一区欧美| 国产精品久久网站| 免费国产自线拍一欧美视频| 亚洲女同同性videoxma| 美女国产精品| 亚洲——在线| 日韩午夜在线电影| 国产欧美日韩一区| 欧美精品乱人伦久久久久久| 午夜国产精品视频| 日韩亚洲视频在线| 牛牛国产精品| 亚洲女同精品视频| 亚洲日韩欧美视频| 国产视频在线观看一区| 欧美视频三区在线播放| 免费欧美在线视频| 久久成人av少妇免费| 午夜日韩在线观看| 亚洲一区二区在| 亚洲神马久久|