title: OpenGL ES 2.0 texture showing up black
body: <p>I've seen a few questions like this on SO, but nothing which has helped me so far. I've made GLTriangle, and GLRectangle classes. I can draw these two shapes no problem, with colors. I'm trying to implement textures into them, and I'm having trouble getting it to work (and debugging).</p>
  
  <p>I'll try to post the relevant code of what I have so far, if you need to see more, let me know.</p>
  
  <p>EDIT: Ok, so after fixing the mistake with the texcoord handlers, I'm still getting a black square. The only time glGetError reports anything is after calling GLES20.glEnable(GLES20.GL_TEXTURE_2D);</p>
  
  <p>GLRectangle relevant code:</p>
  
  <pre><code>@Override
  public void onSurfaceCreated() {
      ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
      vertexByteBuffer.order(ByteOrder.nativeOrder());
      vertexBuffer = vertexByteBuffer.asFloatBuffer();
      vertexBuffer.put(vertices);
      vertexBuffer.position(0);
  
      vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
      fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
  
      mProgram = createAndLinkProgram(VertexShaderHandle(), FragmentShaderHandle(), new String[] { "uMVPMatrix", "vPosition", "a_TexCoordinate" });
      muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
      maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
      loadTexture(context, imageId);
      ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
  ibb.order(ByteOrder.nativeOrder());
  indexBuffer = ibb.asShortBuffer();
  indexBuffer.put(indices);
  indexBuffer.position(0);
  
  ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
  tbb.order(ByteOrder.nativeOrder());
  textureCoordBuffer = tbb.asFloatBuffer();
  textureCoordBuffer.put(texCoords).position(0);
  }
  </code></pre>
  
  <p>And in onDrawFrame:</p>
  
  <pre><code>GLES20.glUseProgram(mProgram);
  GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer);
  GLES20.glEnableVertexAttribArray(maPositionHandle);
  Matrix.multiplyMM(mMVPMatrix, 0, projMatrix, 0, mvMatrix, 0);
  GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
  mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture");
          mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");
  
  GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
  GLES20.glUniform1i(mTextureUniformHandle, 0);
  GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
  </code></pre>
  
  <p>I know, or at least I'm fairly certain that the bitmap is being loaded, as I get the int handle returned when loading it (it will cause a runtime error if the int is 0).</p>
  
  <p>I'm guessing it has something to do with the texture coordinates.</p>
  
  <p>Here's what I have for my tex coords:</p>
  
  <pre><code>texCoords = new float[] { 
      0, 0,
      0, 1,
      1, 1,
      1, 0
  };  
  </code></pre>
  
  <p>Just in case it IS something with the texture loader, here it is:</p>
  
  <pre><code>int[] textureHandle  = new int[1];
  
              GLES20.glGenTextures(1, textureHandle, 0);
  
              if (textureHandle[0] != 0) {
                  final BitmapFactory.Options options = new BitmapFactory.Options();
                  options.inScaled = false;
  
                  final Bitmap bitmap = BitmapFactory.decodeResource(view.getContext().getResources(), resourceId, options);
  
  
  
                  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);                   
  
                  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
                  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
  
  
                  GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
  
  
                  bitmap.recycle();
  
              }
  
              if (textureHandle[0] == 0) {
                  throw new RuntimeException("Unable to load texture!");
              }
              mTextureDataHandle = textureHandle[0];
  </code></pre>
  
  <p>EDIT: Forgot to add my shaders, I'm just setting the string through code right now:</p>
  
  <pre><code>setVertexShader( 
                  "uniform mat4 uMVPMatrix;   \n" +
                  "uniform mat4 MVMatrix;     \n" +
                  "attribute vec4 vPosition;  \n" +
                  "attribute vec2 a_TexCoordinate;    \n" +                   
                  "varying vec2 v_TexCoordinate;  \n" +
  
                  "void main() {      \n" +
  
                  "v_TexCoordinate = a_TexCoordinate; \n" +
                  "gl_Position = uMVPMatrix * vPosition;  \n" +
                  "}  \n");                   
  
          setFragmentShader("precision mediump float;  \n" +
                  "uniform sampler2D u_Texture;   \n" +                   
                  "varying vec2 v_TexCoordinate;  \n" +
                  "void main() {              \n" +
                  "gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n" +
                  "}                         \n");
  </code></pre>