title: Postprocessing problems using OpenGL / LibGDX - black screen (FBO, shaders, quad)
body: <p>I'm having some problems rendering the post-processed stage to the screen. I wrote some code that was rendering OK to the screen, then decided I needed some postprocessing (sepia an bloom effect, but that comes afterwards) so I decided to render everything to a FrameBuffer object, and then use its color texture to render a textured, full screen quad. The problem is, even using some trivial shaders, I either get a black screen (or whatever the color I use to clear the color buffer) having the depth test disabled, or some garbage pixels occupying the lower left quarter of the screen, when enabling the depth test (that was just blind testing, I'm not sure if I need the depth test in a 2D game, but my OpenGL understading is poor).</p>
  
  <p>So, what am I doing wrong? Here's the code:</p>
  
  <p>TRIVIAL VERTEX SHADER:</p>
  
  <pre><code>attribute vec4 a_position;
  attribute vec4 a_color;
  attribute vec2 a_texCoord0;
  
  varying vec4 vColor;
  varying vec2 vTexCoord;
  
  void main() {
      vColor = a_color;
      vTexCoord = a_texCoord0;
      gl_Position = a_position;
  }
  </code></pre>
  
  <p>TRIVIAL FRAGMENT SHADER:</p>
  
  <pre><code>#ifdef GL_ES
  precision mediump float;
  #endif
  
  varying vec4 vColor;
  varying vec2 vTexCoord;
  
  uniform sampler2D u_texture;
  
  void main() {
      vec4 texColor = texture2D(u_texture, vTexCoord);
      gl_FragColor = vColor.rgba * vec4(texColor.rgb, 1.0);
  }
  </code></pre>
  
  <p>INITIALIZATION:</p>
  
  <pre><code>FrambeBuffer fbo;
  ShaderProgram focusShader;
  Mesh focusQuad;
  
  @Override
  public void show() {
  
      camera1 = new OrthographicCamera();
      camera1.setToOrtho(false);
      camera1.zoom = 0.8f;
      viewport = new ExtendViewport(Globals.VIEWPORT_WIDTH, Globals.VIEWPORT_HEIGHT, camera1);
      batch = new SpriteBatch();
      moveCamera(camera1, player.getX(), player.getY());
      fbo = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
      ShaderProgram.pedantic = false;
      focusShader = new ShaderProgram(Gdx.files.internal("shaders/trivial_vshader"), Gdx.files.internal("shaders/trivial_fshader"));
      focusQuad = createFullScreenQuad(); //TAKEN FROM https://github.com/manuelbua/libgdx-contribs/blob/master/postprocessing/src/main/java/com/bitfire/postprocessing/utils/FullscreenQuad.java
      // Other game initialization...
  }
  </code></pre>
  
  <p>RENDER LOOP:</p>
  
  <pre><code>@Override
  public void render(float delta) {
      // (UPDATE PHYSICS)...
      fbo.begin();
      {
      /* DRAW THE PLAYER */
          batch.setProjectionMatrix(camera1.combined);
          batch.begin();
          player.drawTrail(batch, delta);
          player.draw(batch, delta);
          batch.end();
  
          Gdx.gl.glEnable(GL20.GL_BLEND);
          Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
          shapeRenderer.setProjectionMatrix(camera1.combined);
          shapeRenderer.begin(ShapeType.Filled);
          map.drawEffects(camera1, shapeRenderer);
          //(OTHER GAME STUFF AND EFFECTS...)
          shapeRenderer.end();
          Gdx.gl.glDisable(GL20.GL_BLEND);
      }
      fbo.end();
  
      //NOW THE PROBLEM
      Gdx.gl.glClearColor(0, 0.4f, 0.3f, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      //Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
      Gdx.gl.glEnable(GL20.GL_BLEND);
      Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
      fbo.getColorBufferTexture().bind();
      focusShader.begin();
      focusShader.setUniformi("u_texture", 0);
      focusQuad.render(focusShader, GL20.GL_TRIANGLE_FAN, 0, 4);
      focusShader.end();
  }
  </code></pre>