title: Android OpenGL2.0 showing black textures
body: <p>I am trying to draw textures onto quads in OpenGL2.0. So far I got the quads to show up and everything, but the textures are not there - the quads are all black.  </p>
  
  <p>My main suspicion is that i'm not mapping the textures correctly - my textures are <strong><em>not powers of 2, nor are they square</em></strong> - their width is in the field mWidth and their height in mRowHeight.</p>
  
  <p>The quads are drawn in a vertical list, which is done with a translate matrix.</p>
  
  <p>I'll be very grateful if anyone can go over this cause I'm desperate!</p>
  
  <p>Here's related code:</p>
  
  <p>Initializing the buffers:  </p>
  
  <pre><code>    void initBuffers() {
          float r = (float) mRowHeight / (mHeight / 2f);
          ByteBuffer bb;
  
          float[] bounds = { // X Y Z
          /* 0 - TL */-1f, 1f,    0f, 
          /* 1 - BL */-1f, 1 - r, 0f, 
          /* 2 - BR */ 1f, 1 - r, 0f,
          /* 3 - TR */ 1f, 1f,    0f };
          bb = ByteBuffer.allocateDirect(bounds.length * 4);
          bb.order(ByteOrder.nativeOrder());
          mVertBuffer = bb.asFloatBuffer();
          mVertBuffer.put(bounds).position(0);
  
          short[] indices = { 0, 1, 2, 0, 2, 3 };
          bb = ByteBuffer.allocateDirect(indices.length * 2);
          bb.order(ByteOrder.nativeOrder());
          mIndBuffer = bb.asShortBuffer();
          mIndBuffer.put(indices).position(0);
  
          float[] texture = { 
                  /* 0 - BL */-1f, 1f, 
                  /* 1 - TL */-1f, 1 - r, 
                  /* 2 - BR */1f, 1 - r, 
                  /* 3 - TR */1f, 1f };
          bb = ByteBuffer.allocateDirect(texture.length * 4);
          bb.order(ByteOrder.nativeOrder());
          mTexBuffer = bb.asFloatBuffer();
          mTexBuffer.put(texture).position(0);
  
      }
  </code></pre>
  
  <p>Drawing the frame:</p>
  
  <pre><code>    @Override
      public void drawFrame() {
          long startTime = System.currentTimeMillis();
          if (!mLayoutComplete) {
              return;
          }
          final float halfw = mHeight / 2f;
          final int rowHeight = mRowHeight;
          final float r = (float) rowHeight / halfw;
  
          int i = mFirstRow;
  
          final float initial = (float) ((i * rowHeight) - mScroll) / halfw;
  
          Matrix.setIdentityM(mTMatrix, 0);
          Matrix.translateM(mTMatrix, 0, 0, -initial, 0);
  
          GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
                  false, 0, mVertBuffer);
          GLES20.glEnableVertexAttribArray(maPositionHandle);
  
          final int l = mLastRow;
          for (; i &lt;= l; i++) {
  
              ThumbRow thr = mCache.get(i);
              if (thr != null) {
                  GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
                  if (thr.mDirty) {
                      thr.loadTexture(null, null);
                      thr.mDirty = false;
                  } else {
                      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, thr.mRow + 1);
                  }
                  GLES20.glUniform1i(msTextureHandle, 0);
  
                  GLES20.glVertexAttribPointer(maTextureHandle, 2,
                          GLES20.GL_FLOAT, false, 0, mTexBuffer);
                  GLES20.glEnableVertexAttribArray(maTextureHandle);
  
                  GLES20.glUniformMatrix4fv(muTMatrixHandle, 1, false,
                          mTMatrix, 0);
                  GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6,
                          GLES20.GL_UNSIGNED_SHORT, mIndBuffer);
                  Log.i(TAG, GLES20.glGetProgramInfoLog(mProgram));
              }
  
              Matrix.translateM(mTMatrix, 0, 0, -r, 0); // Shift drawing
                                                          // window to next
                                                          // row.
          }
  
          GLES20.glDisableVertexAttribArray(maPositionHandle);
          GLES20.glDisableVertexAttribArray(maTextureHandle);
  
          Log.d(TAG, "onDrawFrame(): "
                  + (System.currentTimeMillis() - startTime));
      }
  </code></pre>
  
  <p>Loading the textures:</p>
  
  <pre><code>        public void loadTexture(GL10 gl, Context c) {
              GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mRow + 1);
  
              // Create Nearest Filtered Texture
              GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                      GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
              GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                      GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
  
              // Different possible texture parameters, e.g.
              // GLES20.GL_CLAMP_TO_EDGE
              GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                      GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
              GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
                      GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
  
              Bitmap bitmap = mBitmap;
              if (bitmap == null) {
                  bitmap = mEmptyBitmap;
              }
              GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
          }
  </code></pre>
  
  <p>Vertex Shader:</p>
  
  <pre><code>uniform mat4 uTMatrix;
  uniform mat4 uMVPMatrix;
  attribute vec4 aPosition;
  attribute vec2 aTextureCoord;
  varying vec2 vTextureCoord;
  
  void main() {
      gl_Position = uMVPMatrix * uTMatrix * aPosition;
      vTextureCoord = aTextureCoord;
  }
  </code></pre>
  
  <p>Fragment Shader:</p>
  
  <pre><code>precision mediump float;
  varying vec2 vTextureCoord;
  uniform sampler2D sTexture;
  void main() {
      gl_FragColor = texture2D(sTexture, vTextureCoord);
  }
  </code></pre>
  
  <p>Any help will be much appreciated.</p>