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

From OpenGL Wiki
Jump to navigation Jump to search
 
m
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>
 
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/
+
GL 3.0 makes FBO a core feature. http://www.opengl.org/documentation/specs/<br>
 +
RTT = render to texture<br>
  
1. 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
+
=== 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).
 
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>
 
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>
Line 8: Line 10:
 
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>
 
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>
 
<br>
2. Is it better to make 1 FBO and bind your texture to it each time you need to render to the texture?<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>
 
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>
 
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>
 
If you have 10 textures that are 64x64 and 10 textures that are 512x64, make 2 FBOs. One FBO for each group.<br>
 
<br>
 
<br>
3. Can you bind the main framebuffers depth buffer as a depth buffer for your FBO?<br>
+
=== The main framebuffer ===
 +
Can you bind the main framebuffers depth buffer as a depth buffer for your FBO?<br>
 
No.<br>
 
No.<br>
 
Does GL 3.0 allow using the main depth buffer? Unknown.<br>
 
Does GL 3.0 allow using the main depth buffer? Unknown.<br>
 
<br>
 
<br>
4. Are multisample Render_To_Texture (RTT) supported?<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>
 
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>
 
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>
 
<br>
5. Talk about render to depth only. No color buffer.<br>
+
=== Color texture, Depth texture ===
6. Talk about render to color only.<br>
+
  //RGBA8 2D texture, 24 bit depth texture, 256x256
7. Talk about stencil buffer.<br>
+
  glGenTextures(1, &color_tex);
8. MRT<br>
+
  glBindTexture(GL_TEXTURE_2D, color_tex);
9. MRT and cubemaps<br>
+
  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, /*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;
 +
  }
 +
<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 17:07, 5 February 2009

Feel free to have a look at http://www.opengl.org/registry and have a look at the GL_EXT_framebuffer_object spec.
GL 3.0 makes FBO a core feature. http://www.opengl.org/documentation/specs/
RTT = render to texture

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, /*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;
 }


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.