using Bitmap with alpha channel: weird behaviour? (+NDK)

Problems with Canvas, OpenGL, etc...

using Bitmap with alpha channel: weird behaviour? (+NDK)

Postby gardiol » Tue Nov 08, 2011 9:38 am

Hi guys! I come from the Qt world and i am porting an application to Android. I am bit confused, i am banging my head for a few days now on something that must be so trivial that i cannot find why it's not working.

Some background: i have a C++ engine which i use trough NDK and JNI. This engine creates some bitmaps and passes them to the Java side, the Java side must display them on a View and let the user interact with them (drag and such).

The engine works properly, because i use it under Qt with full success. This is the workflow:

1- Java loads a big Bitmap from a custom data file (the C++ engine expects it to be in ARGB format, but it's compressed JPG data)

Code: Select all
        Bitmap.Config fmt = Bitmap.Config.ARGB_8888;
        Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, size).copy( fmt , false);

2- initialize the C++ engine passing the bitmap. The C++ engine "breaks" the bitmap in smaller tiles. For tile it builds a rather complex alpha mask and stores it into the first byte of the bitmap (the "a" byte). This alpha mask only uses two values: 0xFF for opaque and 0x00 for transparent.

Code: Select all
        init_C_engine( this.fullImage );

3- The Java side then allocates all the tiles bitmaps, i do in two steps because before init i dont know which size will the tiles be. The engine will populate the tile_width and tile_height arrays:

Code: Select all
        Bitmap.Config fmt = Bitmap.Config.ARGB_8888;
        for (int t = 0; t < this.puzzle_size; t++ ){
            tile_data[ t ] = Bitmap.createBitmap(  tile_width[t],  tile_height[t],   fmt);

4- Last step,inside the C++ engine, all the tiles bitmaps are filled:

Code: Select all
    for ( int n = 0; n < nBitmaps; n++ )
    {
            jobject bitmap = env->GetObjectArrayElement( bitmaps, n );
            AndroidBitmap_getInfo(env, bitmap, &info);
            AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void **>(&pixels));
            game->getTileBitmap( n, (unsigned char*)pixels );
            AndroidBitmap_unlockPixels(env, bitmap);
            env->SetObjectArrayElement( bitmaps, n, bitmap );
        }   
    }

Now, in my custom View:

Code: Select all
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);
        for ( int t = 0; t < board.nTiles; t++ ){
                canvas.drawBitmap( tile_data[tile],
                                   tile_x[tile],
                                   tile_y[tile], paint);
            }
    }

What i expect is that on my View i see my tiles with transparent areas. what i get instead is a weird behaviour so that on the black background i see the ENTIRE tile like the alpha bytes are all set to opaque, but when i move the tiles one of top of the other, the "transparent" areas get combined in some strange way, like colors are "xor"ed or multiplied in some way! When i move one tile on the other i can see the areas where the alpha bytes are set to transparent but colors gets mangled instead of being transparend!

Basically i expect that pixels having alpha set to 0 are drawn as transparent... i looked on internet but i could not find anything usefull to help me out....

Does somebody have ideas? Anything will be appreciated!
thanks.
gardiol
Once Poster
Once Poster
 
Posts: 1
Joined: Tue Nov 08, 2011 9:28 am

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 3 guests