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

Reply via email to