I know very little about OpenGL so please be gentle.
The app needs to load a bitmap (from resources), resize it, and use it in an OpenGL texture. I have an implementation that works, but there was a bad banding issue on the Wildfire S. So I changed the implementation and fixed the banding issue (by switching to ARGB_8888) but that then broke the functionality on the Galaxy Nexus and the Nexus One.
I am seeing three visual presentations:
-
The bitmap (a smooth 24-bit gradient) shows correctly, with no banding.
-
The gradient shows, but with obvious banding
-
The texture shows as flat white, no bitmap (or issues in logcat)
Here are two versions of the method to load the bitmap, and notes on the results seen with each:
// White on Galaxy Nexus. White on Nexus One. Renders correct image (no banding) on Wildfire S
private Bitmap getBitmap1() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.outWidth = getTextureSize();
options.outHeight = getTextureSize();
final Bitmap bmp;
bmp = BitmapFactory.decodeResource(getResources(), bitmapResourceId, options);
return bmp;
}
// Renders correctly (no banding) on Galaxy Nexus. Renders on Nexus One and Wildfire S but with obvious banding.
private Bitmap getBitmap2() {
int textureSize = getTextureSize();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.outWidth = getTextureSize();
options.outHeight = getTextureSize();
final Bitmap bmp;
bmp = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), bitmapResourceId, options), textureSize, textureSize, true);
return bmp;
}
getTextureSize() returns 1024.
How do I build a single method that shows the bitmap without banding on all devices, and without any devices show a big white box?
getBitmap1
outHeight and outWidth are used in conjunction with inJustDecodeBounds. You cannot use them to load a scaled bitmap. So the reason you are seeing a white texture is that the bitmap is not a power of two.
getBitmap2
you should keep a reference to the bitmap returned by decodeResource so that you can recycle it later.
also use
options.inScaled = false;to load an unscaled version of the bitmap. Also take note that createScaledBitmap may change the depth of the bitmap to RGB_565 if the original bitmap contains no alpha channel (Source);Questions:
is the original Bitmap Resource square? If not your scaling code will change the aspect ratio which could result in artifacts.
EDIT:
so how do you scale a bitmap and preserve the bit depths?
Easiest solution is to pass a bitmap with alpha channel into createScaledBitmap.
You can also scale yourself like so:
ANOTHER EDIT:
take a look at this Question for pointers on how to deal with that.