title: Android OpenGL ES 2.0 textures from png file are black
body: <p>Im facing a problem with my OpenGL implementation I don't understand.
  I'm displaying a Sprite with three textures combined in FragmentShader. If I use bitmaps from android ressource as texture all works fine, but if I'm using the downloaded png equivalents and load them from file system my texture is displayed only black.</p>
  
  <p>The textures are not power of 2 and not square, but as I said the implementation works if I copy the images to android ressource but in real world I need to download them.</p>
  
  <p>This is my Code:
  Sprite Constructor:</p>
  
  <pre><code>final float[] spriteTextureCoordinates =
  {                                               
          1f,  0f,
          1f, 1f,
           0f, 1f,
           0f,  0f
  };
  
  mCubeTextureCoordinates = ByteBuffer.allocateDirect(spriteTextureCoordinates.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
  mCubeTextureCoordinates.put(spriteTextureCoordinates).position(0);
  
  ByteBuffer dlb = ByteBuffer.allocateDirect(spriteCoords.length * 2);
  dlb.order(ByteOrder.nativeOrder());
  drawListBuffer = dlb.asShortBuffer();
  drawListBuffer.put(drawOrder);
  drawListBuffer.position(0);
  
  int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
  int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
  
  shaderProgram = GLES20.glCreateProgram();
  GLES20.glAttachShader(shaderProgram, vertexShader);
  GLES20.glAttachShader(shaderProgram, fragmentShader);
  
  GLES20.glBindAttribLocation(shaderProgram, 0, "a_TexCoordinate");
  
  GLES20.glLinkProgram(shaderProgram);
  mTextureManager.loadDefaultTextures(mActivityContext, true);
  </code></pre>
  
  <p>onDraw:</p>
  
  <pre><code>GLES20.glUseProgram(shaderProgram);
  
  mPositionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
  
  GLES20.glEnableVertexAttribArray(mPositionHandle);
  
  GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
  
  mTextureUniformHandle0 = GLES20.glGetUniformLocation(shaderProgram, "u_Texture0");
  mTextureUniformHandle1 = GLES20.glGetUniformLocation(shaderProgram, "u_Texture1");
  mTextureUniformHandle2 = GLES20.glGetUniformLocation(shaderProgram, "u_Texture2");
  mTextureCoordinateHandle = GLES20.glGetAttribLocation(shaderProgram, "a_TexCoordinate");
  
  GLES20.glUniform1i(mTextureUniformHandle0, 0);
  GLES20.glUniform1i(mTextureUniformHandle1, 2);
  GLES20.glUniform1i(mTextureUniformHandle2, 4);
  
  GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + 0);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureManager.getMapLayerTexture());
  
  GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + 2);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureManager.getRadarTexture(currentImageIndex));
  
  GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + 4);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureManager.getGeoLayerTextureForZoomLevel(zoomStep));
  
  mCubeTextureCoordinates.position(0);
  GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0, mCubeTextureCoordinates);
  GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
  
  mMVPMatrixHandle = GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix");
  
  GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
  
  GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
  
  GLES20.glDisableVertexAttribArray(mPositionHandle);
  </code></pre>
  
  <p>Shader:</p>
  
  <pre><code>private final String vertexShaderCode =
  "attribute vec2 a_TexCoordinate;" +
  "varying vec2 v_TexCoordinate;" +
  "uniform mat4 uMVPMatrix;" +
  "attribute vec4 vPosition;" +
  "void main() {" +
  "  gl_Position = uMVPMatrix * vPosition;" +
      "v_TexCoordinate = a_TexCoordinate;" +
  "}";
  
  private final String fragmentShaderCode =
  "precision mediump float;" +
  "uniform sampler2D u_Texture0;" +
  "uniform sampler2D u_Texture1;" +
  "uniform sampler2D u_Texture2;" +
  "varying vec2 v_TexCoordinate;" +
  "void main() {" +
  "vec4 texel0 = texture2D(u_Texture0, v_TexCoordinate);" +
  "vec4 texel1 = texture2D(u_Texture1, v_TexCoordinate);" +
  "vec4 texel2 = texture2D(u_Texture2, v_TexCoordinate);" +
  "gl_FragColor = mix(mix(texel0, texel1, texel1.a),texel2,texel2.a);"+
  "}";
  </code></pre>
  
  <p>Working texture loading:</p>
  
  <pre><code> public  int[] loadTextures(final Context context, int... resIDs)
  {
      final int[] textureHandle = new int[resIDs.length];
  
      GLES20.glGenTextures(resIDs.length, textureHandle, 0);
  
      for(int i=0; i&lt;textureHandle.length; i++){
          if (textureHandle[i] != 0)
          {
              final BitmapFactory.Options options = new BitmapFactory.Options();
              options.inScaled = false;   // No pre-scaling
  
              final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resIDs[i], options);
  
              GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[i]);
  
              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_NEAREST);
              GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
  
              bitmap.recycle();
          }
          if (textureHandle[i] == 0)
          {
              throw new RuntimeException("Error loading texture.");
          }
      }
  
  
      return textureHandle;
  }
  </code></pre>
  
  <p>an the not working one:</p>
  
  <pre><code>public synchronized int loadNewRadarLayerTexture(Context context, ImageData data) throws IOException {
      int textureID = data.getTextureID();
      if(textureID == 0) {
          final int[] textureHandle = new int[1];
          GLES20.glGenTextures(textureHandle.length, textureHandle, 0);
          textureID = textureHandle[0];
          if (textureID != 0) {
              final BitmapFactory.Options options = new BitmapFactory.Options();
              options.inScaled = false; // No pre-scaling
  
              File directory = context.getDir(RRD.DIR,
                      Context.MODE_PRIVATE);
              File image = new File(directory, data.getFile());
  
              Bitmap bitmap = BitmapFactory.decodeFile(image.getPath(),options);
  
              // Bind to the texture in OpenGL
              GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
  
              // Set filtering
              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_NEAREST);
              GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
              Log.d("OpenGL","Error:"+GLES20.glGetError());
              bitmap.recycle();
          }
          if(textureID == 0){
              throw new RuntimeException("Error loading texture.");
          }
  
          data.setTextureID(textureID);
  
      }
      return textureID;
  }
  </code></pre>
  
  <p>if I use the texture generated by the first method, all works fine. if i use the second method my whole texture seems to be black</p>