I'm very new to Android and OpenGL coding (I have previously used ogre3d). I am trying to find an efficient way to load PNG textures. It is currently taking around 8 secs to load 3 512x512 textures on a fairly fast phone (Motorola Defy)
There seems to be a problem with the texture being upside-down (I used a Matrix to flip it below). Secondly, the order of the colour channels are incompatible, therefore each pixel needs changed. This (I believe) is the cause of the slowness, is there a way to make the BitmapFactory load it in a channel order that is compatible with opengl? Is there a better approach here?
Here is the code: -
// Will load a texture out of a drawable resource file, and return an OpenGL texture ID:
private int loadTexture(GL10 gl, Context context, int resource, boolean loadMipMaps) {
// We need to flip the textures vertically:
Matrix flip = new Matrix();
flip.postScale(1f, -1f);
// This will tell the BitmapFactory to not scale based on the device's pixel density:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = false;
// Load up, and flip the texture:
Bitmap temp = BitmapFactory.decodeResource(context.getResources(), resource, opts);
Bitmap bmp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), flip, true);
temp.recycle();
int id = loadTextureFromBmp(gl,bmp, true);
bmp.recycle();
return id;
}
protected static int loadTextureFromBmp(GL10 gl, Bitmap bmp, boolean reverseRGB) {
ByteBuffer bb = ByteBuffer.allocateDirect(bmp.getHeight()*bmp.getWidth()*4);
bb.order(ByteOrder.nativeOrder());
IntBuffer ib = bb.asIntBuffer();
for (int y=bmp.getHeight()-1;y>-1;y--)
for (int x=0;x<bmp.getWidth();x++) {
if (reverseRGB) {
int px = bmp.getPixel(x,y);
int alpha = (px & 0xFF000000) >> 24;
int red = (px & 0xFF0000)>>16;
int green = (px & 0xFF00)>>8;
int blue = (px & 0xFF);
ib.put((alpha << 24) | (blue << 16) | (green<<8) | (red));
//ib.put(Integer.reverseBytes(bmp.getPixel(x, y)));
}
else {
ib.put(bmp.getPixel(x,y));
}
}
ib.position(0);
bb.position(0);
int[] tmp_tex = new int[1];
gl.glGenTextures(1, tmp_tex, 0);
int tex = tmp_tex[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, bmp.getWidth(), bmp.getHeight(), 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, bb);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
return tex;
}