Difference between revisions of "Framebuffer Object Extension Examples"

From OpenGL Wiki
Jump to: navigation, search
(Quick example, render_to_texture (2D Depth texture ONLY))
(Concatenating from the "More about FBOs" page.)
Line 353: Line 353:
 
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 
   glDeleteFramebuffersEXT(1, &fb);
 
   glDeleteFramebuffersEXT(1, &fb);
 +
 +
=== Limitations of GL_EXT_framebuffer_object ===
 +
One of the limitations of GL_EXT_framebuffer_object is that when you bind a color buffer and then you bind a depth buffer, both must have the same
 +
width and height or else the state of the FBO is considered invalid (incomplete).
 +
This means if you have 1 FBO that is 64x64, another which is 512x64, another that is 1024x1024, for each of those you have to allocate a separate depth buffer (if you need depth testing of course). This obviously wastes memory.<br>
 +
In GL 3.0, FBO became core and that limitation was removed.<br>
 +
You can create 1 depth buffer that is 1024x1024 and bind them to all 3 FBOs. Notice that the depth buffer is large enough for even the smaller textures like 64x64.<br>
 +
<br>
 +
=== 1 FBO or more ===
 +
Is it better to make 1 FBO and bind your texture to it each time you need to render to the texture?<br>
 +
An FBO itself doesn't use much memory. It is a state vector object. In terms of performance, each time you bind, the driver needs to validate the state which costs CPU time. Logically, it would be better to have 1 FBO per Render_To_Texture (RTT).<br>
 +
However, it has been found that you get a speed boost if your textures is the same size and you use 1 FBO for them.<br>
 +
If you have 10 textures that are 64x64 and 10 textures that are 512x64, make 2 FBOs. One FBO for each group.<br>
 +
<br>
 +
=== The main framebuffer ===
 +
Can you bind the main framebuffers depth buffer as a depth buffer for your FBO?<br>
 +
No.<br>
 +
Does GL 3.0 allow using the main depth buffer? Unknown.<br>
 +
<br>
 +
=== MSAA ===
 +
Are multisample Render_To_Texture (RTT) supported?<br>
 +
Not directly. You need GL_EXT_framebuffer_multisample and you would have to copy the contents of the AA-FBO to a standard RTT.<br>
 +
Note that GL_EXT_framebuffer_multisample also became core in GL 3.0<br>
 +
See also http://www.opengl.org/wiki/GL_EXT_framebuffer_multisample<br>
 +
<br>
 +
=== Color texture, Depth texture ===
 +
  //RGBA8 2D texture, 24 bit depth texture, 256x256
 +
  glGenTextures(1, &color_tex);
 +
  glBindTexture(GL_TEXTURE_2D, color_tex);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 +
  //NULL means reserve texture memory, but texels are undefined
 +
  //GL_BGRA and GL_UNSIGNED_BYTE are ignored since last param is NULL
 +
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 +
  glGenTextures(1, &depth_tex);
 +
  glBindTexture(GL_TEXTURE_2D, depth_tex);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
 +
  //NULL means reserve texture memory, but texels are undefined
 +
  //GL_BGRA and GL_UNSIGNED_BYTE are ignored since last param is NULL
 +
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 +
  //-------------------------
 +
  glGenFramebuffersEXT(1, &fb);
 +
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
 +
  //Attach 2D texture to this FBO
 +
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0/*mipmap level*/);
 +
  //-------------------------
 +
  //Attach depth texture to FBO
 +
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0/*mipmap level*/);
 +
  //-------------------------
 +
  //Does the GPU support current FBO configuration?
 +
  GLenum status;
 +
  status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 +
  switch(status)
 +
  {
 +
    case GL_FRAMEBUFFER_COMPLETE_EXT:
 +
    cout<<"good";
 +
  default:
 +
    HANDLE_THE_ERROR;
 +
  }
 +
 +
And in the end, cleanup
 +
 +
  //Delete resources
 +
  glDeleteTextures(1, &color_tex);
 +
  glDeleteTextures(1, &depth_tex);
 +
  //Bind 0, which means render to back buffer, as a result, fb is unbound
 +
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 +
  glDeleteFramebuffersEXT(1, &fb);
 +
 +
<br>
 +
 +
=== Depth only ===
 +
This is similar to the case above (Color texture, Depth texture) except that since there is no color buffer, call glDrawBuffer(GL_NONE) before or after calling glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb) and then render. When you are done, call glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) to render to the main framebuffer. This is <b>important</b>, call glDrawBuffer(GL_BACK) after. If you call before glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0), a GL error will be raised.<br>
 +
<br>
 +
=== Color only ===
 +
Simply disable depth testing (glDisable(GL_DEPTH_TEST) and set the depth mask to FALSE (glDepthMask(GL_FALSE)) before you render to your RTT.
 +
<br>
 +
=== Stencil ===
 +
Talk about stencil buffer.<br>
 +
<br>
 +
=== MRT ===
 +
MRT<br>
 +
<br>
 +
=== MRT and cubemaps ===
 +
MRT and cubemaps<br>
 +
<br>
 +
=== Mode change ===
 +
On Windows, when a display mode change occurs, resources in VRAM are lost. Resources would be display lists, VBOs, shaders, FBOs. This is why drivers keep a backup in RAM so that when a change occurs, the driver receives a notification from Windows that "poof, all is gone", and the driver can reupload all the resources.<br>
 +
In the case of FBOs (or should we call it render to texture), when it gets lossed, will the driver reupload it?<br>
 +
This is unknown and not explained in the GL_EXT_framebuffer_object extension.<br>
 +
It is presumed that preserving would not be beneficial to performance therefore it is not preserved. In other words, you should update your render to texture (RTT) once in a while or at every frame render.<br>

Revision as of 19:10, 3 September 2009

RTT = render_to_texture
This page shows a few examples on how to setup a RTT and how to cleanup.
The extension specification is at http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt
Note that this extension became core in GL 3.0 and at the same time they released the ARB version of the extension
http://www.opengl.org/registry/specs/ARB/framebuffer_object.txt
GL_ARB_framebuffer_object brings together GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, GL_EXT_packed_depth_stencil which are all folded into the core of GL 3.0.

Quick example, render_to_texture (2D)

  //RGBA8 2D texture, 24 bit depth texture, 256x256
  glGenTextures(1, &color_tex);
  glBindTexture(GL_TEXTURE_2D, color_tex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  //NULL means reserve texture memory, but texels are undefined
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
  //-------------------------
  glGenFramebuffersEXT(1, &fb);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
  //Attach 2D texture to this FBO
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0);
  //-------------------------
  glGenRenderbuffersEXT(1, &depth_rb);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 256, 256);
  //-------------------------
  //Attach depth buffer to FBO
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
  //-------------------------
  //Does the GPU support current FBO configuration?
  GLenum status;
  status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  switch(status)
  {
     case GL_FRAMEBUFFER_COMPLETE_EXT:
     cout<<"good";
  default:
     HANDLE_THE_ERROR;
  }
  //-------------------------
  //and now you can render to GL_TEXTURE_2D
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  //-------------------------
  glViewport(0, 0, 256, 256);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0.0, 256.0, 0.0, 256.0, -1.0, 1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  //-------------------------
  glDisable(GL_TEXTURE_2D);
  glDisable(GL_BLEND);
  glEnable(GL_DEPTH_TEST);
  //-------------------------
  //**************************
  //RenderATriangle, {0.0, 0.0}, {256.0, 0.0}, {256.0, 256.0}
  //Read http://www.opengl.org/wiki/VBO_-_just_examples
  RenderATriangle();
  //-------------------------
  GLubyte pixels[4*4*4];
  glReadPixels(0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
  //pixels 0, 1, 2 should be white
  //pixel 4 should be black
  //----------------
  //Bind 0, which means render to back buffer
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

And in the end, cleanup

  //Delete resources
  glDeleteTextures(1, &color_tex);
  glDeleteRenderbuffersEXT(1, &depth_rb);
  //Bind 0, which means render to back buffer, as a result, fb is unbound
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glDeleteFramebuffersEXT(1, &fb);

Quick example, render_to_texture (2D), mipmaps

  //RGBA8 2D texture, 24 bit depth texture, 256x256
  glGenTextures(1, &color_tex);
  glBindTexture(GL_TEXTURE_2D, color_tex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  //NULL means reserve texture memory, but texels are undefined
  //**** Tell OpenGL to reserve level 0
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
  //You must reserve memory for other mipmaps levels as well either by making a series of calls to
  //glTexImage2D or use glGenerateMipmapEXT(GL_TEXTURE_2D).
  //Here, we'll use :
  glGenerateMipmapEXT(GL_TEXTURE_2D)
  //-------------------------
  glGenFramebuffersEXT(1, &fb);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
  //Attach 2D texture to this FBO
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0);
  //-------------------------
  glGenRenderbuffersEXT(1, &depth_rb);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 256, 256);
  //-------------------------
  //Attach depth buffer to FBO
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
  //-------------------------
  //Does the GPU support current FBO configuration?
  GLenum status;
  status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  switch(status)
  {
     case GL_FRAMEBUFFER_COMPLETE_EXT:
     cout<<"good";
  default:
     HANDLE_THE_ERROR;
  }
  //-------------------------
  //and now you can render to GL_TEXTURE_2D
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  //-------------------------
  glViewport(0, 0, 256, 256);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0.0, 256.0, 0.0, 256.0, -1.0, 1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  //-------------------------
  glDisable(GL_TEXTURE_2D);
  glDisable(GL_BLEND);
  glEnable(GL_DEPTH_TEST);
  //-------------------------
  //**************************
  //RenderATriangle, {0.0, 0.0}, {256.0, 0.0}, {256.0, 256.0}
  //Read http://www.opengl.org/wiki/VBO_-_just_examples
  RenderATriangle();
  //-------------------------
  GLubyte pixels[4*4*4];
  glReadPixels(0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
  //pixels 0, 1, 2 should be white
  //pixel 4 should be black
  //----------------
  //Bind 0, which means render to back buffer
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  //----------------
  //**** Now that we rendered to level 0 of the texture, we must generate the mipmaps.
  //This should be quick since it is done on the GPU.
  glBindTexture(GL_TEXTURE_2D, color_tex);
  glGenerateMipmapEXT(GL_TEXTURE_2D)

And in the end, cleanup

  //Delete resources
  glDeleteTextures(1, &color_tex);
  glDeleteRenderbuffersEXT(1, &depth_rb);
  //Bind 0, which means render to back buffer, as a result, fb is unbound
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glDeleteFramebuffersEXT(1, &fb);

Quick example, render_to_texture (Cubemap)

//RGBA8 Cubemap texture, 24 bit depth texture, 256x256

 glGenTextures(1, &color_tex);
 glBindTexture(GL_TEXTURE_CUBE_MAP, color_tex);
 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 //NULL means reserve texture memory, but texels are undefined
 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+0, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+1, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+2, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+3, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+4, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+5, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 //-------------------------
 glGenFramebuffersEXT(1, &fb);
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
 //Attach one of the faces of the Cubemap texture to this FBO
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, color_tex, 0);
 //-------------------------
 glGenRenderbuffersEXT(1, &depth_rb);
 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 256, 256);
 //-------------------------
 //Attach depth buffer to FBO
 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
 //-------------------------
 //Does the GPU support current FBO configuration?
 GLenum status;
 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 switch(status)
 {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
    cout<<"good";
 default:
    HANDLE_THE_ERROR;
 }
 //-------------------------
 //and now you can render to GL_TEXTURE_CUBE_MAP_POSITIVE_X
 //In order to render to the other faces, do this :
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, color_tex, 0);
 //... now render
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, color_tex, 0);
 //... now render
 //... and so on


And in the end, cleanup

  //Delete resources
  glDeleteTextures(1, &color_tex);
  glDeleteRenderbuffersEXT(1, &depth_rb);
  //Bind 0, which means render to back buffer, as a result, fb is unbound
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glDeleteFramebuffersEXT(1, &fb);

Quick example, render_to_texture (2D Depth texture ONLY)

 //32 bit depth texture, 256x256
 glGenTextures(1, &depth_tex);
 glBindTexture(GL_TEXTURE_2D, depth_tex);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
 //NULL means reserve texture memory, but texels are undefined
 //You can also try GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24 for the internal format.
 //If GL_DEPTH24_STENCIL8_EXT, go ahead and use it (GL_EXT_packed_depth_stencil)
 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, 256, 256, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
 //-------------------------
 glGenFramebuffersEXT(1, &fb);
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
 //Attach
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0);
 //-------------------------
 //Does the GPU support current FBO configuration?
 //Before checking the configuration, you should call these 2 according to the spec.
 //At the very least, you need to call glDrawBuffer(GL_NONE)
 glDrawBuffer(GL_NONE);
 glReadBuffer(GL_NONE);
 GLenum status;
 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 switch(status)
 {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
    cout<<"good";
 default:
    HANDLE_THE_ERROR;
 }
 //-------------------------
 //----and to render to it, don't forget to call
 //At the very least, you need to call glDrawBuffer(GL_NONE)
 glDrawBuffer(GL_NONE);
 glReadBuffer(GL_NONE);
 //-------------------------
 //If you want to render to the back buffer again, you must bind 0 AND THEN CALL glDrawBuffer(GL_BACK)
 //else GL_INVALID_OPERATION will be raised
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 glDrawBuffer(GL_BACK);
 glReadBuffer(GL_BACK);

And in the end, cleanup

  //Delete resources
  glDeleteTextures(1, &depth_tex);
  //Bind 0, which means render to back buffer, as a result, fb is unbound
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glDeleteFramebuffersEXT(1, &fb);

Quick example, render_to_texture (2D), mipmaps, depth_stencil

If GL_EXT_packed_depth_stencil is present, use it. Also called a D24S8 format. All common GPUs support this format.
http://www.opengl.org/registry/specs/EXT/packed_depth_stencil.txt

 //RGBA8 2D texture, D24S8 depth/stencil texture, 256x256
 glGenTextures(1, &color_tex);
 glBindTexture(GL_TEXTURE_2D, color_tex);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 //NULL means reserve texture memory, but texels are undefined
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 //You must reserve memory for other mipmaps levels as well either by making a series of calls to
 //glTexImage2D or use glGenerateMipmapEXT(GL_TEXTURE_2D).
 //Here, we'll use :
 glGenerateMipmapEXT(GL_TEXTURE_2D);
 //-------------------------
 glGenFramebuffersEXT(1, &fb);
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
 //Attach 2D texture to this FBO
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0);
 //-------------------------
 glGenRenderbuffersEXT(1, &depth_stencil_rb);
 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_rb);
 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 256, 256);
 //-------------------------
 //Attach depth buffer to FBO
 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_rb);
 //Also attach as a stencil
 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_rb);
 //-------------------------
 //Does the GPU support current FBO configuration?
 GLenum status;
 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 switch(status)
 {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
    cout<<"good";
 default:
    HANDLE_THE_ERROR;
 }
 //-------------------------
 //and now you can render to GL_TEXTURE_2D
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
 glClearColor(0.0, 0.0, 0.0, 0.0);
 //It's always a good idea to clear the stencil at the same time as the depth when the format is D24S8.
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |  GL_STENCIL_BUFFER_BIT);
 //-------------------------
 glViewport(0, 0, 256, 256);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho(0.0, 256.0, 0.0, 256.0, -1.0, 1.0); 
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 //-------------------------
 glDisable(GL_TEXTURE_2D);
 glDisable(GL_BLEND);
 glEnable(GL_DEPTH_TEST);
 //-------------------------
 //**************************
 //RenderATriangle, {0.0, 0.0}, {256.0, 0.0}, {256.0, 256.0}
 //Read http://www.opengl.org/wiki/VBO_-_just_examples
 RenderATriangle();
 //-------------------------
 GLubyte pixels[4*4*4];
 glReadPixels(0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
 //pixels 0, 1, 2 should be white
 //pixel 4 should be black
 //----------------
 //Bind 0, which means render to back buffer
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

And in the end, cleanup

 //Delete resources
 glDeleteTextures(1, &color_tex);
 glDeleteRenderbuffersEXT(1, &depth_stencil_rb);
 //Bind 0, which means render to back buffer, as a result, fb is unbound
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 glDeleteFramebuffersEXT(1, &fb);

Limitations of GL_EXT_framebuffer_object

One of the limitations of GL_EXT_framebuffer_object is that when you bind a color buffer and then you bind a depth buffer, both must have the same width and height or else the state of the FBO is considered invalid (incomplete). This means if you have 1 FBO that is 64x64, another which is 512x64, another that is 1024x1024, for each of those you have to allocate a separate depth buffer (if you need depth testing of course). This obviously wastes memory.
In GL 3.0, FBO became core and that limitation was removed.
You can create 1 depth buffer that is 1024x1024 and bind them to all 3 FBOs. Notice that the depth buffer is large enough for even the smaller textures like 64x64.

1 FBO or more

Is it better to make 1 FBO and bind your texture to it each time you need to render to the texture?
An FBO itself doesn't use much memory. It is a state vector object. In terms of performance, each time you bind, the driver needs to validate the state which costs CPU time. Logically, it would be better to have 1 FBO per Render_To_Texture (RTT).
However, it has been found that you get a speed boost if your textures is the same size and you use 1 FBO for them.
If you have 10 textures that are 64x64 and 10 textures that are 512x64, make 2 FBOs. One FBO for each group.

The main framebuffer

Can you bind the main framebuffers depth buffer as a depth buffer for your FBO?
No.
Does GL 3.0 allow using the main depth buffer? Unknown.

MSAA

Are multisample Render_To_Texture (RTT) supported?
Not directly. You need GL_EXT_framebuffer_multisample and you would have to copy the contents of the AA-FBO to a standard RTT.
Note that GL_EXT_framebuffer_multisample also became core in GL 3.0
See also http://www.opengl.org/wiki/GL_EXT_framebuffer_multisample

Color texture, Depth texture

 //RGBA8 2D texture, 24 bit depth texture, 256x256
 glGenTextures(1, &color_tex);
 glBindTexture(GL_TEXTURE_2D, color_tex);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 //NULL means reserve texture memory, but texels are undefined
 //GL_BGRA and GL_UNSIGNED_BYTE are ignored since last param is NULL
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 glGenTextures(1, &depth_tex);
 glBindTexture(GL_TEXTURE_2D, depth_tex);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
 //NULL means reserve texture memory, but texels are undefined
 //GL_BGRA and GL_UNSIGNED_BYTE are ignored since last param is NULL
 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 //-------------------------
 glGenFramebuffersEXT(1, &fb);
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
 //Attach 2D texture to this FBO
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0/*mipmap level*/);
 //-------------------------
 //Attach depth texture to FBO
 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0/*mipmap level*/);
 //-------------------------
 //Does the GPU support current FBO configuration?
 GLenum status;
 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 switch(status)
 {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
    cout<<"good";
 default:
    HANDLE_THE_ERROR;
 }

And in the end, cleanup

 //Delete resources
 glDeleteTextures(1, &color_tex);
 glDeleteTextures(1, &depth_tex);
 //Bind 0, which means render to back buffer, as a result, fb is unbound
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 glDeleteFramebuffersEXT(1, &fb);


Depth only

This is similar to the case above (Color texture, Depth texture) except that since there is no color buffer, call glDrawBuffer(GL_NONE) before or after calling glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb) and then render. When you are done, call glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) to render to the main framebuffer. This is important, call glDrawBuffer(GL_BACK) after. If you call before glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0), a GL error will be raised.

Color only

Simply disable depth testing (glDisable(GL_DEPTH_TEST) and set the depth mask to FALSE (glDepthMask(GL_FALSE)) before you render to your RTT.

Stencil

Talk about stencil buffer.

MRT

MRT

MRT and cubemaps

MRT and cubemaps

Mode change

On Windows, when a display mode change occurs, resources in VRAM are lost. Resources would be display lists, VBOs, shaders, FBOs. This is why drivers keep a backup in RAM so that when a change occurs, the driver receives a notification from Windows that "poof, all is gone", and the driver can reupload all the resources.
In the case of FBOs (or should we call it render to texture), when it gets lossed, will the driver reupload it?
This is unknown and not explained in the GL_EXT_framebuffer_object extension.
It is presumed that preserving would not be beneficial to performance therefore it is not preserved. In other words, you should update your render to texture (RTT) once in a while or at every frame render.