title: openGL / GLSL: bloom/blur, rendering to FBO
body: <p>I've reached another impasse I can't seem to resolve on my own. I really hope someone can help me out.</p>
  
  <p>I've been trying to create a nice little bloom effect using GLSL, which worked quite well. When I tried including something moving into my scene I noticed that I forgot to clear my FBOs before rendering into them. </p>
  
  <p>Without clearing it worked for never changing scenes because I was always using the same texture. With the glClear(); command it still works, but for the very first frame only, all I get after that is a black screen. So I guess my issue is that I can't get my FBOs to continuously be updated every frame.</p>
  
  <p>I feel like I'm either missing something very obvious or doing something horribly wrong. </p>
  
  <p>I'd be thankful for any suggestions you might have.</p>
  
  <p>Here's what I get for the first frame:
  <img src="https://i.stack.imgur.com/1UECh.png" alt="enter image description here"></p>
  
  <p><strong>Sources:</strong>
  (using openFrameworks)</p>
  
  <p>setup:</p>
  
  <pre><code>void testApp::setup(){
  
  ofSetVerticalSync(true);
  ofDisableSetupScreen();
  
  width = ofGetWidth();
  height = ofGetHeight();
  
  //complie/link/generate ShaderObjects ....
  horizontalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_horizontal.glsl", GL_FRAGMENT_SHADER);
  verticalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_vertical.glsl", GL_FRAGMENT_SHADER);
  BlurVertex.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/horizontal_blur.glsl", GL_VERTEX_SHADER);
  blendTextures.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/blend_shader.glsl", GL_FRAGMENT_SHADER);
  
  fboOriginal.initialize(width, height);
  fboH800.initialize(width, height);
  fboV800.initialize(width, height);
  fboH400.initialize(width, height);
  fboV400.initialize(width, height);}
  </code></pre>
  
  <p>draw:</p>
  
  <pre><code>void testApp::draw(){
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  
  //set orthographic projection
  glOrtho( -1, 1, -1, 1, 1.0, 40.0 );
  
  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();
  
  glViewport( 0, 0, width, height);
  
  glDisable(GL_TEXTURE_2D);
  
  fboOriginal.bind();
  
      glClearColor(0.0, 0.0, 0.0, 1.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glPushAttrib(GL_VIEWPORT_BIT);
          glViewport(0, 0, width, height);
          glPushMatrix();
              glScalef(0.1f, 0.1f, 1.0f);
  
              //generating values between 0 and 2
              float x = 2 * (sin(time)+1.000001)/2;
  
              //drawSOlidRect(xPos, yPos, width, height, red, green, blue);
              drawSolidRect(-8.0f, 8.0f, x, x, 0.4f, 0.4f, 1.0f);
              drawSolidRect(-5.0f, 8.0f, x, x, 0.4f, 1.0f, 0.4f);
              drawSolidRect(-2.0f, 8.0f, x, x, 0.4f, 1.0f, 1.0f);
              drawSolidRect( 1.0f, 8.0f, x, x, 1.0f, 0.4f, 0.4f);
              drawSolidRect( 4.0f, 8.0f, x, x, 1.0f, 0.4f, 1.0f);
              drawSolidRect( 7.0f, 8.0f, x, x, 1.0f, 1.0f, 0.4f);
          glPopMatrix();
      glPopAttrib();
  fboOriginal.unbind();
  
  glEnable(GL_TEXTURE_2D);
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, fboOriginal.fboTexture);
  
  BlurVertex.enable();
  
  horizontalBlurFrag.enable();
  glUniform1i(glGetUniformLocation(horizontalBlurFrag.program, "RTScene"), 0);
  
  glDisable(GL_TEXTURE_2D);
  
  fboH800.bind();
  
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glPushAttrib(GL_VIEWPORT_BIT);
          glViewport(0, 0, width, height);
          glPushMatrix();
              glBegin(GL_QUADS);
                  glColor3f(1.0f, 1.0f, 1.0f);
  
                  glTexCoord2f(0.0f, 1.0f);
                  glVertex3f(-1.0, 1.0, -1.0);
  
                  glTexCoord2f(1.0f, 1.0f);
                  glVertex3f(1.0, 1.0, -1.0);
  
                  glTexCoord2f(1.0f, 0.0f);
                  glVertex3f(1.0, -1.0, -1.0);
  
                  glTexCoord2f(0.0f, 0.0f);
                  glVertex3f(-1.0, -1.0, -1.0);
              glEnd();
          glPopMatrix();
      glPopAttrib();
  glDisable(GL_TEXTURE_2D);
  fboH800.unbind();
  
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, fboH800.fboTexture);
  
  BlurVertex.enable();
  
  verticalBlurFrag.enable();
  glUniform1i(glGetUniformLocation(verticalBlurFrag.program, "RTBlurH"), 0);
  
  glDisable(GL_TEXTURE_2D);
  
  fboV800.bind();
  
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glPushAttrib(GL_VIEWPORT_BIT);
          glViewport(0, 0, width, height);
          glPushMatrix();
              glBegin(GL_QUADS);
                  glColor3f(1.0f, 1.0f, 1.0f);
  
                  glTexCoord2f(0.0f, 1.0f);
                  glVertex3f(-1.0, 1.0, -1.0);
  
                  glTexCoord2f(1.0f, 1.0f);
                  glVertex3f(1.0, 1.0, -1.0);
  
                  glTexCoord2f(1.0f, 0.0f);
                  glVertex3f(1.0, -1.0, -1.0);
  
                  glTexCoord2f(0.0f, 0.0f);
                  glVertex3f(-1.0, -1.0, -1.0);
              glEnd();
          glPopMatrix();
      glPopAttrib();
  fboV800.unbind();
  
  glEnable(GL_TEXTURE_2D);
  glActiveTexture(GL_TEXTURE1);
  glBindTexture(GL_TEXTURE_2D, fboV800.fboTexture);
  
  BlurVertex.enable();
  
  horizontalBlurFrag.enable();
  glUniform1i(glGetUniformLocation(horizontalBlurFrag.program, "RTScene"), 1);
  
  glDisable(GL_TEXTURE_2D);
  
  fboH400.bind();
  
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glPushAttrib(GL_VIEWPORT_BIT);
          glPushMatrix();
          glViewport(0, 0, width/4, height/4);    //crude downscale
              glBegin(GL_QUADS);
                  glColor3f(1.0f, 1.0f, 1.0f);
  
                  glTexCoord2f(0.0f, 1.0f);
                  glVertex3f(-1.0, 1.0, -1.0);
  
                  glTexCoord2f(1.0f, 1.0f);
                  glVertex3f(1.0, 1.0, -1.0);
  
                  glTexCoord2f(1.0f, 0.0f);
                  glVertex3f(1.0, -1.0, -1.0);
  
                  glTexCoord2f(0.0f, 0.0f);
                  glVertex3f(-1.0, -1.0, -1.0);
              glEnd();
          glPopMatrix();
      glPopAttrib();
  glDisable(GL_TEXTURE_2D);
  fboH400.unbind();
  
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, fboH400.fboTexture);
  
  BlurVertex.enable();
  
  verticalBlurFrag.enable();
  glUniform1i(glGetUniformLocation(verticalBlurFrag.program, "RTBlurH"), 1);
  
  glDisable(GL_TEXTURE_2D);
  
  fboV400.bind();
  
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glPushAttrib(GL_VIEWPORT_BIT);
          glPushMatrix();
          glViewport(0, 0, width*4, height*4);    //crude downscale
              glBegin(GL_QUADS);
  
              glColor3f(1.0f, 1.0f, 1.0f);
              glTexCoord2f(0.0f, 1.0f);
              glVertex3f(-1.0, 1.0, -1.0);
  
              glTexCoord2f(1.0f, 1.0f);
              glVertex3f(1.0, 1.0, -1.0);
  
              glTexCoord2f(1.0f, 0.0f);
              glVertex3f(1.0, -1.0, -1.0);
  
              glTexCoord2f(0.0f, 0.0f);
              glVertex3f(-1.0, -1.0, -1.0);
          glEnd();
      glPopMatrix();
  glPopAttrib();
  glDisable(GL_TEXTURE_2D);
  fboV400.unbind();
  
  glBindTexture(GL_TEXTURE_2D, 0);
  
  glEnable(GL_TEXTURE_2D);
  
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, fboV800.fboTexture);
  
  glActiveTexture(GL_TEXTURE1);
  glBindTexture(GL_TEXTURE_2D, fboV400.fboTexture);
  
  BlurVertex.enable();
  
  blendTextures.enable();
  glUniform1i(glGetUniformLocation(blendTextures.program, "originalSizeTex"), 0);
  glUniform1i(glGetUniformLocation(blendTextures.program, "downscaledTex"), 1);
  
  glDisable(GL_TEXTURE_2D);
  
  glBegin(GL_QUADS);
  
      glColor3f(1.0f, 1.0f, 1.0f);
      glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 1.0f);
      glVertex3f(-1.0, 1.0, -1.0);
  
      glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 1.0f);
      glVertex3f(1.0, 1.0, -1.0);
  
      glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 0.0f);
      glVertex3f(1.0, -1.0, -1.0);
  
      glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 0.0f);
      glVertex3f(-1.0, -1.0, -1.0);
  glEnd();
  
  glDisable(GL_TEXTURE_2D);}
  </code></pre>
  
  <p>FBO:</p>
  
  <pre><code>class FrameBufferObject{
  public:
      //handles
      GLuint fbo, fboTexture, fboDepthbuffer;
  public:
      void initialize(GLuint width, GLuint height){
          // generate namespace for the frame buffer, colorbuffer and depthbuffer
          glGenFramebuffersEXT(1, &amp;fbo);
          glGenTextures(1, &amp;fboTexture);
          glGenRenderbuffersEXT(1, &amp;fboDepthbuffer);
  
          //switch to our fbo so we can bind stuff to it
          glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  
          //create the colorbuffer texture and attach it to the frame buffer
          glEnable(GL_TEXTURE_2D);
          glBindTexture(GL_TEXTURE_2D, fboTexture);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
          glTexParameteri(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);
          glGenerateMipmapEXT(GL_TEXTURE_2D);
  
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
          glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTexture, 0);
  
          // create a render buffer as our depthbuffer and attach it
          glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthbuffer);
          glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,width, height);
          glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fboDepthbuffer);
  
          // Go back to regular frame buffer rendering
          glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  
          glDisable(GL_TEXTURE_2D);
      }
  
      void bind(){
          glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
      }
      void unbind(){
          glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
      }
  
      void clear(){
          glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
          glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
      }};
  </code></pre>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>The alpha value one the glClearColor at least seems to be part of my issue. </p>
  
  <p>I tried messing around with it and what i got is this:
  (with up- and downscaling quads as you'd expect)</p>
  
  <p><img src="https://i.stack.imgur.com/Ac07f.png" alt="enter image description here"></p>
  
  <p>Somehow i seem to be losing all color somewhere along the way.
  Oddly enough i got the best result having (0, 0, 0, 0) for 4 of my FBOs and (0, 0, 0, 1) for one of them. Setting (0, 0, 0, 0) for all FBOs just yields a greyish picture (which i assume is the default window without anything in it).</p>
  
  <p>Here's my "blending-together-shader":</p>
  
  <pre><code>uniform sampler2D originalSizeTex;
  uniform sampler2D downscaledTex;
  
  varying vec2 vTexCoord;
  
  void main(void){
      vec4 colorOriginal = vec4(0.0, 0.0, 0.0, 0.0);
      vec4 colorDownscale = vec4(0.0, 0.0, 0.0, 0.0);
  
      colorOriginal = texture2D(originalSizeTex, vTexCoord.xy);
      colorDownscale = texture2D(downscaledTex, vTexCoord.xy);
  
      gl_FragColor = vec4(colorOriginal + colorDownscale);
  }
  </code></pre>
  
  <p>Any guesses?</p>