title: OpenGL multiple Framebuffer chaining and post processing
body: <p>I have three different framebuffer objects for three different steps:</p>
  
  <pre><code>GLuint fbo1;   // Step1: draw initial scene
  GLuint fbo2;   // Step2: apply lens effect shader
  GLuint fbo3;   // Step3: final smoothing
  </code></pre>
  
  <p>I want to draw my initial scene as a texture attached to fbo1. 
  Then apply a lens-shader on that and save it as a texture in fbo2.
  Then apply a smoothing-shader on fbo2 and save it to fbo3. </p>
  
  <p>The code in my main render function, uses a few helper functions, and is as follows:</p>
  
  <pre><code>// Step1    
  useFrameBuffer(fbo1, fbo1);   // src , dest
  DrawInitialScene();
  
  // Step2    
  LensShader.use();             // a glsl shader program class 
  useFrameBuffer(fbo1, fbo2);   // src , dest
  drawQuadOnFbo(fbo2Texture);
  
  // Step3    
  SmoothingShader.use();         // a glsl shader program class
  useFrameBuffer(fbo2, fbo3);    // src , dest
  drawQuadOnFbo(fbo3Texture);
  
  // Final Copy Step to OpenGL default FBO
  int width = self.frame.size.width;
  int height = self.frame.size.height;
  glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo3);
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //destination
  glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
  </code></pre>
  
  <p>The helper function useFrameBuffer(src, dest), simply sets the source framebuffer to read from and destination write framebuffer:</p>
  
  <pre><code>void useFrameBuffer (GLuint fboSrc , GLuint fboDest)
  {
      glBindFramebuffer(GL_READ_FRAMEBUFFER, fboSrc);
      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboDest);
  
      GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0};
      glDrawBuffers(1, drawbufs);
      glReadBuffer(GL_COLOR_ATTACHMENT0);
  
      glViewport(0, 0, width, height);  // width, height are private to class
  }
  </code></pre>
  
  <p>To apply the shader on the output of fbo1 and fbo2, I am drawing a quad with a texture associated to the respective frame-buffers:</p>
  
  <pre><code>void drawQuadOnFbo(GLuint fboTexture) {
      glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We're not using stencil buffer now
      glBlendFunc(GL_ONE, GL_ONE);
  
      glBindVertexArray(quadVAO);
      glDisable(GL_DEPTH_TEST);
      glBindTexture(GL_TEXTURE_2D, fboTexture);
      glDrawArrays(GL_TRIANGLES, 0, 6);
      glBindVertexArray(0);
  }
  </code></pre>
  
  <p><strong>The Problem:</strong></p>
  
  <p>The problem is that output appears to be a combination of Step1 and Step3 only. Looks like the Step2 is completely missed out. You can see in the final copy step, I am copying the contents of fbo3 to the final OpenGL default fbo using:</p>
  
  <blockquote>
    <p>glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo3);</p>
  </blockquote>
  
  <p>If I change this to fbo2, then I do see the results of applying Step2 (but then I don't have Step3). </p>
  
  <p>So it looks like that both fbo2 and fbo3 are connected directly to the output of fbo1, but not connected to each other. </p>
  
  <p>How can I fix that ?? </p>
  
  <p><strong>Other Helper Functions:</strong></p>
  
  <p>I initialised my Framebuffers at the start of the application, outside the main render function using the method below:</p>
  
  <pre><code>GLuint initFrameBuffer( int width, int height, GLenum textureTarget) {
  
  
      // 1. Create FBO
      GLuint fbo;
      glGenFramebuffers(1, &amp;fbo);
  
      // 2. Bind it
      glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  
      // FrameBuffer Requirements
      //   (i). atleast 1 buffer (color, depth, stencil)
      //  (ii). atleast 1 color-attachment
      // (iii). all attachments should be complete
      //  (iv). same no. of samples for each buffer
  
      // 3. Texture Attachment
      GLuint quadTex;  // texture to be associated to this FBO
      glActiveTexture(textureTarget);
      glGenTextures(1, &amp;quadTex);
      glBindTexture(GL_TEXTURE_2D, quadTex);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  
      // attach it as COLOR-ATTACHMENT 0
      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, quadTex, 0);
  
  
      // 4. RenderBuffer attachement
      GLuint rbo;
      glGenRenderbuffers(1, &amp;rbo);
      glBindRenderbuffer(GL_RENDERBUFFER, rbo);
      glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
      glBindRenderbuffer(GL_RENDERBUFFER, 0);
      // attach it
      glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
  
  
      // 5. Set Targets for fragment shader output
      GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0};
      glDrawBuffers(1, drawbufs);
  
      // 6. Check that the FrameBuffer is complete
      if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
          NSLog(@"ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
          return fboObj;
      }
  
      // 7. revert to Default
      glBindFramebuffer(GL_FRAMEBUFFER, 0);
  
      return fbo;
  }
  </code></pre>