|
|
(2 intermediate revisions by one other user not shown) |
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, /*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>
| |