Apparently the cause of the premultiplied alpha lies in GLUtils, or perhaps the way GLUtils works with the Bitmap class. We can get the correct non-premultiplied alpha behaviour by replacing GLUtils.texImage2D with the opengl method gl.glTexImage2D which takes a pixel component array as a parameter. Thus we can avoid the premultiplied alpha behaviour, which means we can use the blend function gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
Note for uninitiated confused opengl android developers: I posted a question on opengl.org discussion forum, where I described the symptoms of the problem: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=281526&#Post281526 Here's how I loaded the image in Android: private int loadTexture(GL10 gl, int resourceId) { int[] textureNameWorkspace = new int[1]; gl.glGenTextures(1, textureNameWorkspace, 0); int textureName = textureNameWorkspace[0]; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName); 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); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT); gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE); Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId); myTexImage2D(gl, bitmap); // Set the crop parameter because I use drawtexture extension ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, new int[] { 0, bitmap.getHeight(), bitmap.getWidth(), - bitmap.getHeight() }, 0); return textureName; } private void myTexImage2D(GL10 gl, Bitmap bitmap) { // Don't loading using GLUtils, load using gl-method directly // GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); int[] pixels = extractPixels(bitmap); byte[] pixelComponents = new byte[pixels.length*4]; int byteIndex = 0; for (int i = 0; i < pixels.length; i++) { int p = pixels[i]; // Convert to byte representation RGBA required by gl.glTexImage2D. // We don't use intbuffer, because then we // would be relying on the intbuffer wrapping to write the ints in // big-endian format, which means it would work for the wrong // reasons, and it might brake on some hardware. pixelComponents[byteIndex++] = (byte) ((p >> 16) & 0xFF); // red pixelComponents[byteIndex++] = (byte) ((p >> 8) & 0xFF); // green pixelComponents[byteIndex++] = (byte) ((p) & 0xFF); // blue pixelComponents[byteIndex++] = (byte) (p >> 24); // alpha } ByteBuffer pixelBuffer = ByteBuffer.wrap(pixelComponents); gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuffer); } public static int[] extractPixels(Bitmap src) { int x = 0; int y = 0; int w = src.getWidth(); int h = src.getHeight(); int[] colors = new int[w * h]; src.getPixels(colors, 0, w, x, y, w, h); return colors; } Since the above implementation does not use native code to convert the bitmap and since it also allocates the bitmap array twice besides loading the bitmap (thus taking three times the memory space) its not quite optimal. It would be quite reasonable that Android supplied a native method for doing this. Certainly the documenation for GLUtils should state that it loads a premultiplied alpha texture. Does anyone know if there is a bugreport/feature request on this on Android? I cant seem to find any mentioning of it in the issue list: http://code.google.com/p/android/issues/list Alex. -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

