Simple FBO rendering

Frame buffer objects is something new to openGL, it didn’t make it in time to 2.0 but it will probably be in 2.1 so it’s likely that it will change a little, but this tut should still remain valid for the most part.
Now if you don’t know what frame buffer objects are then i will tell you, the frame buffer is where you do all of your rendering, it is the memory area where the actual pixel data is stored, now previously you had only one (4 actually, but the other ones are rarely used) and if you wanted more then you had to use p-buffers, but p-buffers are something that is definitely problematic, I’m not gonna go into details but my advice it to stay as far away from them as possible.

This is where Frame Buffer Objects come into the picture, an FBO is a custom memory area in where you could render stuff to and provide a quick and easy render to texture solution where you could render directly to a depth texture or use odd formats and sizes.
FBO’s also makes High Dynamic Rendering (HDR) practical as you only have to create a texture that uses this format witch is as easy as typing GL_RGBA16F_ARB.

Now on to the cody bits.
The stuff i am gonna ignore this tutorial is the drawBox() func, the IsExtensionSupported() func, the checkfbo() func and all the extension init code, they are pretty much self explanatory and dull as dry bread, if you want to know what’s in it then you have to download the code and take a look.

So the first thing we have to do is to initialize the frame buffer and the associated textures and render buffers then binding the frame buffer so that we can work with it.
fb, color_tex and depth_rb are just unsigned ints, nothing complicated.

[stextbox id=”grey”]// generate namespace for the frame buffer, colorbuffer and depthbuffer
glGenFramebuffersEXT(1, &fb);
glGenTextures(1, &color_tex);
glGenRenderbuffersEXT(1, &depth_rb);

//switch to our fbo so we can bind stuff to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);[/stextbox]

Then bind and create the texture color_tex, the same way as with regular texturing but with a NULL or 0 instead of the data

[stextbox id=”grey”]//create the colorbuffer texture and attach it to the frame buffer
glBindTexture(GL_TEXTURE_2D, color_tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0,
GL_RGBA, GL_INT, NULL)[/stextbox]

Now attach the texture to the frame buffer to the first color attachment, if you need to in conjunction with MRT it’s possible to have more than one color buffer

[stextbox id=”grey”]glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, color_tex, 0);[/stextbox]

Do the same thing with the render buffer and bind it to the depth attachment.
A render buffer is basically the same as the texture above except that it cant be used anywhere else so it’s primarily used as throwaway depth buffer.
[stextbox id=”grey”]// create a render buffer as our depth buffer and attach it
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
GL_DEPTH_COMPONENT24,512, 512);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depth_rb);

// Go back to regular frame buffer rendering
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);[/stextbox]

And thats it, use the checkfbo() function to see if you where successfull in creating the FBO, if it passes you can now start using it.

So we have now managed to create it, but in order for you to be able to render to this frame buffer you need to do two things, first make sure the color buffer texture or any other texture bound to the fbo is not bound at the moment and then switch to FBO rendering.
[stextbox id=”grey”]glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);[/stextbox]

Simple, and to render the texture you do the reverse.
[stextbox id=”grey”]glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_2D, color_tex);[/stextbox]

And thats all there is to it, naturally the render loop is a bit more complicated and i am gonna include the tutorials full draw func just to show you how it’s done, note that you have to call glClear two times, this is because the clear only works on the currently bound frame buffer and not all of them at once, you also need to set the viewport to the size of the current framebuffer or things will look odd.
[stextbox id=”grey”]// FBO render pass
glViewport (0, 0, 512, 512);
// set The Current Viewport to the fbo size glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
glClearColor (1.0f, 0.0f, 0.0f, 0.5f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
glTranslatef (0.0f, 0.0f, -6.0f);
glRotatef(angle,0.0f,1.0f,0.0f);
glRotatef(angle,1.0f,0.0f,0.0f);
glRotatef(angle,0.0f,0.0f,1.0f);
glColor3f(1,1,0);
drawBox()

// Framebuffer render pass

glEnable(GL_TEXTURE_2D);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_2D, color_tex);

glClearColor (0.0f, 0.0f, 0.0f, 0.5f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glViewport (0, 0, (GLsizei)(g_window->init.width), (GLsizei)(g_window->init.height));
glLoadIdentity ();
glTranslatef (0.0f, 0.0f, -6.0f);
glRotatef(angle,0.0f,1.0f,0.0f);
glRotatef(angle,1.0f,0.0f,0.0f);
glRotatef(angle,0.0f,0.0f,1.0f)
glColor3f(1,1,1);
drawBox();
glDisable(GL_TEXTURE_2D);
glFlush ();[/stextbox]
That’s all for this time make sure you download the tutorial and look at the code to understand the context a bit better.
Download this tutorial for MSVCPP 6.0


1 Comment

  • By Peter Wallström, May 4, 2010 @ 16:57

    -old comments-

    Comment by Kerry on 2008:05:17 00:56
    Thanks for this great tutorial! :)

    Comment by Nedim on 2008:09:24 14:59
    Many thanks!
    Very easy to follow for the first time and to get me motivated to learn more about it.

    Comment by Xing on 2008:12:06 22:24
    Thank you very much!

    Really appreciate your hard work.

    I wish you would add some tut on environment map and bump mapping.

    Comment by Overlord on 2008:12:07 00:13
    Take a look at tutorial 02C, it describes normal mapping which in my mind is far superior to regular bump mapping.

    As for environment mapping, i refer you to http://nehe.gamedev.net/ as it’s an old and simple effect and in the next set of tutorials would likely be a lot more advanced (probably deferred rendering), or at least something new to openGL.
    If i where to do an environment mapping tutorial, it would be a step above and beyond anything you can see today, i do have some ideas for it and i am likely to do a batch of misc effects after the next one, Only the future will tell though.

    Comment by genzy on 2009:03:25 19:01
    Thanks a lot, you have saved my life :)

Other Links to this Post

RSS feed for comments on this post. TrackBack URI

Leave a comment

*


WordPress Themes