When setting up the FBO for the g-buffer, we use textures with the internal format GL_RGB32F for the position and normal components. As we are storing geometry information, rather than simply color information, there is a need to use a higher resolution (that is more bits per pixel). The buffer for the diffuse reflectivity just uses GL_RGB8 since we don't need the extra resolution for these values.
The three textures are then attached to the framebuffer at color attachments 0, 1, and 2 using glFramebufferTexture2D. They are then connected to the fragment shader's output variables with the call to glDrawBuffers:
glDrawBuffers(4, drawBuffers);
The array drawBuffers indicates the relationship between the framebuffer's components and the fragment shader's output variable locations. The ith item in the array corresponds to the ith output variable location. This call sets color attachments 0, 1, and 2 to output variable locations 1, 2, and 3, respectively. (Note that the fragment shader's corresponding variables are PositionData, NormalData, and ColorData.)
In the fragment shader, the functionality depends on the value of the variable Pass. It will either call pass1 or pass2, depending on its value. In the pass1 function, we store the values of Position, Normal, and Material.Kd in the appropriate output variables, effectively storing them in the textures that we just talked about.
In the pass2 function, the values of the position, normal, and color are retrieved from the textures, and used to evaluate the diffuse lighting model. The result is then stored in the output variable FragColor. In this pass, FragColor should be bound to the default framebuffer, so the results of this pass will appear on the screen.