Skip to main content

Thanks for your help,

Ash

Here is the code: -

Thanks for your help,

Ash

Here is the code: -

Here is the code: -

Source Link
Ash McConnell
  • 375
  • 2
  • 3
  • 11

Loading PNG textures for use in Android OpenGL ES1

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?

Thanks for your help,

Ash

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;

}