Oct 31, 2011

Android OpenGL ES 1.0: How to load non-power of 2 bitmaps

Hi all.
Today I will show my code for loading non-power of 2 bitmaps for textures.
Quite simple.


loadTexture():
   int imageWidth = mBitmap.getWidth();
   int imageHeight = mBitmap.getHeight();
   
   int height = imageHeight;
   int width = imageWidth;
   
   boolean convert = false;
   
   if(!MathUtils.isPowerOfTwo(height)) {
    height = MathUtils.nextPowerOfTwo(height);
    convert = true;
   }
   
   if(!MathUtils.isPowerOfTwo(width)) {
    width = MathUtils.nextPowerOfTwo(width);
    convert = true;
   }
   
   float maxS = imageWidth / (float)width;
   float maxT = imageHeight / (float)height;
   
   setTextureCoordinates(new float[]{ 0f, maxT,
       maxS, maxT,
                0f, 0f,
                maxS, 0f });
   
   ByteBuffer data = ByteBuffer.allocateDirect(width * height * 4);
   data.order(ByteOrder.nativeOrder());
   
   if(convert) {
    Bitmap tmpImage = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(tmpImage);
    canvas.drawBitmap(mBitmap, new Matrix(), null);
      
    mBitmap.recycle();
    
    tmpImage.copyPixelsToBuffer(data);
       
    tmpImage.recycle();
   } else {
    mBitmap.copyPixelsToBuffer(data);
    mBitmap.recycle();
   }
   
   data.position(0);
    
   gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, 
     data);
   data.clear();
   data = null;

MathUtils.java
public class MathUtils {

 static public int nextPowerOfTwo(int value) {
  if (value == 0)
   return 1;
  if ((value & value - 1) == 0)
   return value;
  value |= value >> 1;
  value |= value >> 2;
  value |= value >> 4;
  value |= value >> 8;
  value |= value >> 16;
  return value + 1;
 }

 static public boolean isPowerOfTwo(int value) {
  return value != 0 && (value & value - 1) == 0;
 }
}

So here if we have a non-power of 2, we set the convert falg to true and create a bitmap with closest size.

No comments: