Difference between revisions of "GL EXT framebuffer object More about FBOs"

From OpenGL Wiki
Jump to navigation Jump to search
(This material has been copied to the main article.)
 
Line 1: Line 1:
Feel free to have a look at http://www.opengl.org/registry and have a look at the GL_EXT_framebuffer_object spec.<br>
 
GL 3.0 makes FBO a core feature. http://www.opengl.org/documentation/specs/<br>
 
RTT = render to texture<br>
 
  
=== 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>
 

Latest revision as of 19:10, 3 September 2009