title: FBOs render to texture and glReadPixels
body: <p>I have set up FBOs (GL_FRAMEBUFFER_EXT, color and depth buffers) and my app is rendering a simple OpenGL 3D object (a rotating teapot) to texture with a NULL image. I am trying to capture pixel data using glReadPixels. I see the 3D object correctly on the screen. But glReadPixels gives junk data. I wonder where I am going wrong. Any help/pointers is appreciated.</p>
  
  <pre><code>   Code is given below (in brief) -
  
      glEnable(GL_TEXTURE_2D); // Enable texturing so we can bind our frame buffer texture
      glEnable(GL_DEPTH_TEST); // Enable depth testing
  
      // Initialize the FBO
      int WIDTH=window_width;
      int HEIGHT=window_height;
  
      glGenTextures(1, &amp;fbo_texture); // Generate one texture
      glBindTexture(GL_TEXTURE_2D, fbo_texture); // Bind the texture fbo_texture
  
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard texture with the width and height of our window
  
          // Setup the basic texture parameters
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  
     ......
     ......
     // setup depth buffer
     glGenRenderbuffersEXT(1, &amp;fbo_depth); // Generate one render buffer and store the ID in fbo_depth
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_depth); // Bind the fbo_depth render buffer
  
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, window_width, window_height); // Set the render buffer storage to be a depth component, with a width and height of the window
  
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth); // Set the render buffer of this buffer to the depth buffer
  
     ....
     .....
    //set up FBO
    glGenFramebuffersEXT(1, &amp;fbo); // Generate one frame buffer and store the ID in fbo
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer
  
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_texture, 0); // Attach the texture fbo_texture to the color buffer in our frame buffer
  
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth); // Attach the depth buffer fbo_depth to our frame buffer
  
  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Check that status of our generated frame buffer
  
  if (status != GL_FRAMEBUFFER_COMPLETE_EXT) // If the frame buffer does not report back as complete
  {
      std::cout &lt;&lt; "Couldn't create frame buffer" &lt;&lt; std::endl; // Output an error to the console
      exit(0); // Exit the application
  }
  
  
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer for rendering
      glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
      glViewport(0, 0, window_width, window_height); // Set the size of the frame buffer view port
  
      glClearColor (0.0f, 0.0f, 1.0f, 1.0f); // Set the clear colour
      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and colour buffers
      glLoadIdentity(); // Reset the modelview matrix
  
      glTranslatef(0.0f, 0.0f, -5.0f); // Translate back 5 units
  
      glRotatef(rotation_degree, 1.0f, 1.0f, 0.0f); // Rotate according to our rotation_degree value
  
      glutSolidTeapot(1.0f); // Render a teapot
      glPopAttrib(); // Restore our glEnable and glViewport states
  
      glReadPixels(0, 0, window_width, window_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels[i]);
  
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture
  
      //now display
  
      ....
      ....
  
      glutSwapBuffers();
      }
  </code></pre>