title: Loading compressed textures in Android OpenglES 2.0
body: <p>I'm trying to optimize my app by having compressed textures. Since a lot of my textures require alpha I can't use ETC1.</p>
  
  <p>I've successfully compressed textures to other formats using hints from this post. <a href="https://stackoverflow.com/questions/9148795/android-opengl-texture-compression">Android OpenGL Texture Compression</a></p>
  
  <p>Problem is I can't seem to adapt my code, to read this textures. The only thing I get with this code is black (colour, instead of texture).</p>
  
  <p>Here is the method, that loads textures:</p>
  
  <pre><code>public static int loadCompressedTexture(Context context, int resourceId){
      final int[] textureObjectIds = new int[1];
  
      glGenTextures(1, textureObjectIds, 0);
  
      if(textureObjectIds[0] == 0){
          logTextureHelper(Log.WARN, "Could not generate a new OpenGL texture object");
          return 0;
      }
  
      final InputStream bitmap = context.getResources().openRawResource(resourceId);
      byte[] buffer;
      ByteBuffer bf;
  
      try {
          buffer = new byte[bitmap.available()];
          bitmap.read(buffer);
          bf  = ByteBuffer.wrap(buffer);
  
          glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]);//binds texture to texture object
  
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);//minimization filter
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
          //texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);//send texture data to OpenGL to the CURRENTLY BOUND object
          GLES20.glCompressedTexImage2D(GLES20.GL_TEXTURE_2D, 0, GL10.GL_PALETTE4_RGBA8_OES, 512, 512, 0, bf.capacity(), bf);
  
  
          //glGenerateMipmap(GL_TEXTURE_2D);
          glBindTexture(GL_TEXTURE_2D, 0); //unbind texture
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
  
      return textureObjectIds[0];
  }
  </code></pre>
  
  <p>I currently trying to load resource that is 512x512px, compressed with PvrTexTool, using PVRTC 4bpp RGBA encoding.</p>
  
  <p>Can anyone see what the problem is? Or better yet, point me to an example that works? From what I found I could only find examples for ETC1, who use some ETCUtil to load textures.</p>
  
  <p>EDIT2: Ok I've solved it.
  There were 2 problems. First you need to use these texture filters.     </p>
  
  <blockquote>
    <p>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);</p>
  </blockquote>
  
  <p>Secondly I was not aware that pvrtc had a seperate header. The correct offset is thus 67 bytes.
  <a href="http://ksstoolkit.googlecode.com/svn/branches/monogame/ThirdParty/Libs/PVRTexLib/Documentation/PVR%20File%20Format.Specification.REL_2.10@863105.External.pdf" rel="nofollow noreferrer">PVRTC format specification</a></p>
  
  <p>This code now works correctly:</p>
  
  <pre><code>            buffer = new byte[bitmap.available()];
              bitmap.read(buffer);
  
              int offset = 67; // 52 bit = header, 15 bit = metadata
              bf = ByteBuffer.wrap(buffer, offset, buffer.length-offset);
              bf.order(ByteOrder.LITTLE_ENDIAN);
  
              long version     = bf.getInt(0) &amp; 0xFFFFFFFFL;
              long flags       = bf.getInt(4);
              long pixelFormat = bf.getLong(8);
              long colorF      = bf.getInt(16);
              long chanel      = bf.getInt(20);
              int height       = bf.getInt(24);
              int width        = bf.getInt(28);
              long depth       = bf.getInt(32);
              long nsurf       = bf.getInt(36);
              long nface       = bf.getInt(40);
              long mipC        = bf.getInt(44);
              long mSize       = bf.getInt(48);
              long fourCC      = bf.getInt(52)&amp; 0xFFFFFFFFL;
              long key         = bf.getInt(56)&amp; 0xFFFFFFFFL;
              long dataSize    = bf.getInt(60)&amp; 0xFFFFFFFFL;
  
  
  
  //              Log.d("TextureHelper","Buffer size: "+version+" "+flags+" "+pixelFormat+" "+colorF+" "+chanel+" "+height+" w: "+width+" h: "+height+" "+depth+" "+nsurf+" "+nface+" "+mipC+" "+mSize);
  //              Log.d("TextureHelper","Buffer size: "+fourCC+" "+key+" "+dataSize);
  
  
              glBindTexture(GL_TEXTURE_2D, textureObjectIds[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);
              glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
              glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
  
  
              GLES20.glCompressedTexImage2D(GL_TEXTURE_2D, 0,GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, width, height, 0, bf.capacity()-offset, bf);
              Log.d("TextureHelper","Buffer size: "+bf.capacity()+"   : "+buffer.length+" error:"+GLES20.glGetError());
  
              glBindTexture(GL_TEXTURE_2D, 0); //unbind texture
  </code></pre>