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 remain valid trough that 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 most if not 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 is 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 FBO’s come into the picture, an FBO is a custom memory area in where you could render stuff to, and not only that it’s main purpose is to 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 bit’s, the stuff i am gonna ignore this tut is the drawBox() func, the IsExtensionSupported() func, the checkfbo() func and all the extention 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.

Ok, the first thing we have to do is to initialize the frame buffer, and the associated textures and render buffers, fb, color_tex and depth_rb are just unsigned ints, nothing complicated,


// 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);

//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)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, color_tex, 0);

// create a render buffer as our depthbuffer 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);

We have now managed to create it, now in order for you to be able to render to this frame buffer you need to do two things, make sure the color buffer texture is no bound at the moment and switch to FBO rendering.

glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

Simple, and to render the texture you do the reverse.

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

And thats all there is to it, of cause the render loop is a bit more complicated and i am gonna include the tut’s 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 one frame buffer at once not all of them, you also need to set the viewport to the fbo size or things will look odd.


// 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 ();

That’s all for this time make sure you download the tut 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