Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
116 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

OpenGL FrameBuffer Object 201


The Second Example

The second example is a hybrid of the first example and the example from the first article. It performs the same output as the first example from this article but only draws the cube to the FBO once like the original article does; we achieve this by using a shader to control the output.

As with before, the major difference is in the initialisation code. Leaving aside the loading of a GLSL program, which is beyond the scope of this article, the part which is required to make MRT rendering work with an FBO is the following two lines:

GLenum mrt[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }
glDrawBuffers(2, mrt);

These two lines tell OpenGL that we wish to render to two buffers and what those two buffers are. Remember that an FBO remembers the last render target it was told to use, as such by doing this while the FBO is bound we can set this at startup and not have to worry about doing so during the main rendering loop.

The rendering loop should look familiar; the rendering to the FBO is the same as the original code, the only change being the call to bind and unbind the GLSL program which controls the colour output. The lower section is the same as the first example from this article, with the two cubes being rendered one with each texture on it.

The two GLSL shaders themselves require a quick mention as they are somewhat central to how MRT works in this manner.

The vertex shader, which is executed for each vertex you send to the graphics card, simply passes the colour value passed via glColor() to the fragment shader and transforms the vertex so it will be in the right place to draw the cube.

The fragment shader used is as follows:

#version 110

void main(void)
{
	gl_FragData[0] = vec4(gl_Color.r, gl_Color.g,gl_Color.b,1.0);
	gl_FragData[1] = vec4(gl_Color.r/2.0, gl_Color.g/2.0,gl_Color.b/2.0,1.0);
}

The key lines are the two gl_FragData lines, these indicate which buffer we are writing to. In this case gl_FragData[0] is the first texture and it gets a copy of the unmodified colour passed down from the vertex. On the other hand gl_FragData[1] is the second texture and gets the value of the colour passed from the vertex shader but halfed, thus giving the same output as the first example.





Final Thoughts


Contents
  Introduction
  Selecting The Destination
  The first example
  Multiple Render Targets
  The Draw Buffers Extension
  MRT with FBO and GLSL
  The Second Example
  Final Thoughts

  Source code
  Printable version
  Discuss this article

The Series
  OpenGL Frame Buffer Object 101
  OpenGL Frame Buffer Object 201