|OpenGL Offscreen Rendering Demo
This Windows OpenGL application demonstrates offscreen rendering to a texture and then applying that texture to a screen aligned full screen quad.
In this demo we use offscreen rendering to render our scene to a texture with the same dimensions as the screen. Once the scene is rendered to this offscreen texture the intention is to then apply some kind of post processing filter to it. Some examples of post processing filters include full scene motion blur, tone mapping (for HDR rendering), and specular bloom. After the post processing is applied the offscreen texture is then applied to a full screen quad and displayed on the screen. We don't actually perform any kind of post processing in this demo. This demo simply sets up the required infrastructure for offscreen rendering and post processing.
This demo uses the GL_EXT_framebuffer_object (FBO) extension to handle rendering to a texture. This is preferred to the older PBuffer extension since FBOs share the same OpenGL context as the one used by the window of your application. PBuffers require their own context.
Until recently FBOs did not support multisampling. Two new extensions - GL_EXT_framebuffer_multisample and GL_EXT_framebuffer_blit - extend the existing FBO framework by providing support for multisample rendering. The GL_EXT_framebuffer_multisample extension allows the allocation of render buffer images that can be used as a multisample buffer. However no mechanism is provided for creating multisample texture images. What this means is that to have FBOs that support multisampling we need to use two FBOs. The first FBO will have 2 multisample render buffer images: one for the color buffer and the other for the depth buffer. This is the FBO that the scene will be rendered to. The rendered scene will be multisampled. The second FBO contains no multisample render buffer images. It just has the offscreen texture directly attached to one of the FBO's color attachment points. To transfer the pixels in the multisample color render buffer image to the offscreen texture we use the GL_EXT_framebuffer_blit extension. The GL_EXT_framebuffer_blit extensions modifies FBOs by splitting their binding points into separate DRAW and READ bindings. This allows the direct copying of the contents of one FBO to another. Once the copy operation is complete the offscreen texture will contain a copy of the pixel data from the first FBO's multisample color render buffer image.
Screen resolutions are usually not powers of two. As a result this demo uses the OpenGL texture rectangle extension for non power of two texture support. We opted to use GL_ARB_texture_rectangle rather than the newer GL_ARB_texture_non_power_of_two extension since the former is more likely to be supported on older hardware. The latter is now part of the OpenGL 2.0 specification. One of the limitations of the GL_ARB_texture_rectangle extension is that is does not support mipmaps. This is not a problem for this demo since we are only ever going to use the offscreen texture on a screen aligned full screen quad. This demo contains code paths for both extensions. By default it uses the texture rectangle path since it is more likely to be supported on older hardware. The GL_ARB_texture_non_power_of_two code path can be enabled by uncommenting a defined constant.
This demo uses the following OpenGL extensions:
The multisample extensions to FBOs are quite new and the best reference on how to use these new extensions is the NVIDIA OpenGL SDK 10 Simple Framebuffer Object Sample.
This demo requires the Visual C++ 2010 Library Runtimes. Download instructions can be found here.
Download executable, source, and Visual C++ 2010 solution files.
10 July 2010.
Added missing .vcxproj.filters file to the project.
13 June 2010.
Updated solution to Microsoft Visual Studio 2010.
26 April 2008.
main.cpp: In the DrawFrame() function updated comments and removed redundant calls to load the projection and modelview matrices with the identity matrix. This is already done in the DrawFullScreenQuad() function. In the DrawFullScreenQuad() function the projection matrix is now loaded with the identity matrix. The drawn quad is now specified in normalized device coordinates. Mip maps are no longer generated for the offscreen texture in the USE_GL_ARB_TEXTURE_NON_POWER_OF_TWO code path. In the InitFBO() function the USE_GL_ARB_TEXTURE_NON_POWER_OF_TWO code path no longer uses mip maps and the texture wrap mode has been changed to clamp. This improves compatibility with older AMD ATI cards. In the InitFBOWithMultiSampling() function the USE_GL_ARB_TEXTURE_NON_POWER_OF_TWO code path no longer uses mip maps and the texture wrap mode has been changed to clamp. This improves compatibility with older AMD ATI cards.
2 February 2008.
Updated solution to Microsoft Visual Studio 2008.
22 December 2007.
GL_EXT_framebuffer_object.h: Added missing extern "C" declaration.
gl_font.h: Fixed incorrect include statement. Updated code sample in the class description.
gl_font.cpp: Modified the begin() method to reduce the amount of state saving prior to beginning font rendering. Modified the end() method to reduce the amount of state restore after font rendering.
19 December 2007.
main.cpp: Fixed a bug in the InitFBO() and InitFBOWithMultiSampling() functions where GL_TEXTURE_2D was being used as the target instead of GL_TEXTURE_RECTANGLE_ARB in the calls to create the offscreen texture image.