title: Android OpenGL ES 2.0 - Black Textures On Some Devices
body: <p><strong>SOLVED:</strong> Turns out, I was passing the OpenGL named texture to the shader instead of the active texture number, fixed it with:</p>
  
  <pre><code>GLES20.glUniform1i(sTextureHandle, 0); // 0 means GLES20.GL_TEXTURE0
  </code></pre>
  
  <p><strong>UPDATE:</strong> glGetError() returns 0, after calling glTexImage2D(). So there are no OpenGL flagged errors...</p>
  
  <p>I've been working on a game using OpenGL 2.0 for the rendering.  </p>
  
  <p>I've been testing it on my Samsung Galaxy Nexus, and haven't had any texturing errors.  All of my textures are powers of 2, in a .png format, and stored in the No -DPI folder.  All textures load, and render perfectly using or not using alpha.  </p>
  
  <p>I tried the game on the Samsung Galaxy S4 and a Droid Bionic, both of which resulted in black textures (with and without alpha blending).  </p>
  
  <p>I have scoured the internet for people with the same problem, but all of their fixes were already reflected in my code.  </p>
  
  <p>I'm thinking it must be something with the way I create the texture, or my OpenGL setup because why else would it only work on the Galaxy Nexus?</p>
  
  <p>OpenGL Setup:</p>
  
  <pre><code>GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);    //Black Background
  GLES20.glClearDepthf(1.0f);                     //Depth Buffer Setup
  GLES20.glEnable(GLES20.GL_DEPTH_TEST);          //Enables Depth Testing
  GLES20.glDepthFunc(GLES20.GL_LEQUAL);           //The Type Of Depth Testing To Do
  GLES20.glDisable(GLES20.GL_BLEND);
  Matrix.orthoM(sProjectionMatrix, 0, 0.0f, width, height, 0.0f, 0.0f, MAX_DEPTH);
  Matrix.setLookAtM(sViewMatrix, 0, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
  
  // Get the texturing handles
  GLES20.glBindAttribLocation(sShaderProgram, 2, "a_tex_coords");
  sTexCoordsHandle = GLES20.glGetAttribLocation(sShaderProgram, "a_tex_coords");
  sTextureHandle = GLES20.glGetUniformLocation(sShaderProgram, "u_texture");
  GLES20.glUseProgram(sShaderProgram);
  
  GLES20.glEnableVertexAttribArray(sPositionHandle);
  GLES20.glEnableVertexAttribArray(sColorHandle);
  GLES20.glEnableVertexAttribArray(sTexCoordsHandle);
  </code></pre>
  
  <p>Texture Loading Code:</p>
  
  <pre><code>Bitmap bitmap = BitmapFactory.decodeStream(sGame.CONTEXT.getResources().openRawResource(R.drawable.circle));
  
  LAST_TEXTURE_INDEX++;
  GLES20.glGenTextures(1, Texture.IDS, LAST_TEXTURE_INDEX);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, IDS[LAST_TEXTURE_INDEX]);
  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_NEAREST); 
  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
  GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
  bitmap.recycle();
  </code></pre>
  
  <p>Other Texture Attempt (In replace of GLUtils.texImage2D and the bitmap):</p>
  
  <pre><code>int width = 128;
  int height = 128;
  ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(width * height * 3).order(ByteOrder.nativeOrder());
  
  for (int y = 0; y &lt; height; y++)
  {
      for (int x = 0; x &lt; width; x++)
      {
          pixelBuffer.put((byte) 0x00);
          pixelBuffer.put((byte) 0xFF);
          pixelBuffer.put((byte) 0xFF);
      }
  }
  
  pixelBuffer.position(0);
  GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, width, height, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, pixelBuffer);
  </code></pre>
  
  <p>Before rendering I call these:</p>
  
  <pre><code>GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, sTextureIndex);
  GLES20.glUniform1i(sTextureHandle, sTextureIndex);
  </code></pre>
  
  <p>Vertex Shader:</p>
  
  <pre><code>attribute vec4 a_position;
  attribute vec4 a_color;
  attribute vec2 a_tex_coords;
  uniform mat4 u_model_view_projection;
  varying vec4 v_color;
  varying vec2 v_tex_coords;
  
  void main() {
      v_color = a_color;
      v_tex_coords = a_tex_coords;
      gl_Position = u_model_view_projection * a_position;
  }
  </code></pre>
  
  <p>Fragment Shader:</p>
  
  <pre><code>varying vec2 v_tex_coords;
  uniform sampler2D u_texture;
  void main() {
      vec4 color = texture2D(u_texture, v_tex_coords);
      gl_FragColor = color;
  }
  </code></pre>
  
  <p>And for the sake of solving the bug, I disabled blending because I know the alpha can often cause a headache aswell.</p>
  
  <p>Both types of texturing (Using an image or using pixel data) works on my Galaxy Nexus, but not on the S4.  I don't know if it's my texturing code that's broken, or some other OpenGL setting, but I'll try to post all relevant code.</p>