title: Color Picking on Android in OpenGL ES 2.0
body: <p>I have implemented a color picking method and it also works; sometimes. The problem is when I call my method in the <code>onSurfaceChanged</code> method, it does read back the correct pixels. But when I call my method in the <code>onTouchevent</code> of the GLSurfaceView, it reads back only zeros. In my method I create a <code>framebuffer object</code> and attach two <code>renderbuffer objects</code> to it. My renderer is set to <code>RENDERMODE_WHEN_DIRTY</code> and <code>glGetError()</code> returns 0. Where exactly is the problem? I'm not sure whether it is my method, or if I simply cannot do this in an <code>onTouchevent</code>. Here is the sourcecode of my picking method in my renderer:</p>
  
  <pre><code>public int pick(int x, int y) {
      int result = -2;
  
      int[]  view = new int[4];
      GLES20.glGetIntegerv(GLES20.GL_VIEWPORT, view, 0);
  
      y = view[3] - y;
  
      int[] fbo = new int[1];
      GLES20.glGenFramebuffers(1, fbo, 0);
      GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
  
      int[] rbo = new int[2];
      GLES20.glGenRenderbuffers(2, rbo, 0);
  
      GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, rbo[0]);
      GLES20.glRenderbufferStorage(
              GLES20.GL_RENDERBUFFER, 
              GLES20.GL_RGBA4, view[2], view[3]);
  
      GLES20.glFramebufferRenderbuffer(
              GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, 
              GLES20.GL_RENDERBUFFER, rbo[0]);
  
      GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, rbo[1]);
      GLES20.glRenderbufferStorage(
              GLES20.GL_RENDERBUFFER, 
              GLES20.GL_DEPTH_COMPONENT16, 
              view[2], view[3]);
  
      GLES20.glFramebufferRenderbuffer(
              GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, 
              GLES20.GL_RENDERBUFFER, rbo[1]);
  
      int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
      if (status == GLES20.GL_FRAMEBUFFER_COMPLETE) {
          result = -1;
          GLES20.glClear(
                  GLES20.GL_COLOR_BUFFER_BIT | 
                  GLES20.GL_DEPTH_BUFFER_BIT);
  
          for (int i = 0; i &lt; mObjects.size(); i++)
              mObjects.get(i).render(mProgram, mMatrixMVP, true);
  
          ByteBuffer pixels = ByteBuffer.allocate(view[2] * view[3] * 4);
          pixels.order(ByteOrder.nativeOrder());
  
          GLES20.glReadPixels( // I read every pixel just for debugging
                  0, 0, view[2], view[3], GLES20.GL_RGBA, 
                  GLES20.GL_UNSIGNED_BYTE, pixels);
  
          int e = GLES20.glGetError(); // always returns 0
          byte[] tmp = pixels.array(); // only zeros when called in onTouch
  
          for (int i = 0; i &lt; mObjects.size(); i++)
              if ((Math.abs(r - mObjects.get(i).CODE_R) &lt; 8) &amp;&amp;
                  (Math.abs(g - mObjects.get(i).CODE_G) &lt; 8) &amp;&amp;
                  (Math.abs(b - mObjects.get(i).CODE_B) &lt; 8)) {
  
                  result = i;
                  break;
              }
      } 
  
      GLES20.glDeleteRenderbuffers(2, rbo, 0);
      GLES20.glDeleteFramebuffers(1, fbo, 0);
      GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
  
      return result;
  }
  </code></pre>
  
  <p>And since it might be relevent, here is my <code>onDrawFrame</code> method:</p>
  
  <pre><code>@Override
  public void onDrawFrame(GL10 gl) {
      GLES20.glClear(
              GLES20.GL_COLOR_BUFFER_BIT | 
              GLES20.GL_DEPTH_BUFFER_BIT);
  
      for (int i = 0; i &lt; mObjects.size(); i++)
          mObjects.get(i).render(mProgram, mMatrixMVP, false);
  }
  </code></pre>
  
  <p>I have read that the onDrawFrame Method runs in a seperate thread, but I don't think that this is the problem, since I am in <code>RENDERMODE_WHEN_DIRTY</code>...</p>