Jump to content
  • Advertisement
Sign in to follow this  
darenking

c++ ALLEGRO, how can I write to the alpha layer of a 32 bit RGBA bitmap?

This topic is 4835 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hmm. I need help changing the alpha layer of RGBA bitmaps in Allegro, if anyone is up to the challange. I'm constructing sprites by creating new, blank bitmaps then loading in 8 bit black/white/grey bitmaps and using these bitmaps to 'cut out' a shape from the blank bitmap. To put it another way, imagine if you had a piece of paper and you placed a stencil on the piece of paper and drew a shape and cut it out with scissors. The first, blank bitmap, created with "create_bitmap(width, height)" is the piece of paper. The second bitmap, loaded from an 8 bit greyscale .bmp file, is the stencil. What's the point? Well, I can fill the first bitmap with whatever colour I like, and make lots of different coloured (or textured) sprites using the same 'stencil' by reading the greyscale stencil bitmap and writing these values to the alpha layer of the 'piece of paper' bitmap. I know how to read pixels from the 8 bit 'stencil' bitmap: alpha = getpixel(stencil, 0, 0); alpha = getr(alpha); This gives me a value between 0 and 255, I can't remember which is solid and which is translucent but values between will be shades of grey, signifying a blended pixel. The 'sheet of paper' bitmap is a 32 bit bitmap. Regardless of whatever colour each pixel is, I need to just change the alpha layer of each pixel. Let's say I have a bright red pixel in the top left corner, 0,0, and let's say I've read the top left pixel of the 'stencil' bitmap and found a sort of mid grey pixel, value 127. How do I change the top left pixel of the 'sheet of paper' bitmap so that it retains its value of red, but becomes translucent to the value 127? (So if drawn on a white screen it would look mid pink instead of bright red.) Presumably I use this: drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0); putpixel(paperBitmap, x, y, ??????);

Share this post


Link to post
Share on other sites
Advertisement
It seems tricky to use. You don't seem to be able to use it to put a pixel in the way that you would exepect, ie creating the colour, eg 127, 127, 127, 127 you would expect to create a mid grey 50% translucency, but it doesn't seem to, when you put pixel with it, it just puts a grey pixel with zero translucency.

Anyway, I've solved the above problem in a different way (painting the whole sprite using draw_sprite or whatever it's called), but still need to know how to change the translucency of a pixel without affecting the colour, as before I need to be able to create a blank BITMAP (could be all black or all white, not sure and I think it doesn't matter at this stage) with 100% translucency. A completely see thru BITMAP that I can draw my alpha BITMAPS onto.

So to recap, forgetting all the other stuff above (if anyone doesn't feel like reading it), all I need to know now, is how to create a blank (black of white) BITMAP that is 100% translucent, or in other words has 255 on the alpha layer for each pixel.

Share this post


Link to post
Share on other sites
Are you sure you have used set_color_depth(32) before writing to an alpha-bitmap? Using makeacol32(127, 127, 127, 127) and putpixel(), I managed to display a grey 50% translucent bitmap without any problems.

If it still doesn't work, try the following code:


#include <allegro.h>

// Globals

BITMAP *Buffer;
const int ScreenWidth = 800;
const int ScreenHeight = 600;
int Ticks = 0;
const int FPS = 50;


// Ticker

void Ticker()
{
Ticks++;
}
END_OF_FUNCTION(ticker);


// MAIN

int main()
{
// Allegro init

allegro_init();
install_keyboard();
install_timer();
install_mouse();

// GFX-stuff

set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, ScreenWidth, ScreenHeight, 0, 0);
Buffer = create_system_bitmap(ScreenWidth, ScreenHeight);

// Create bitmap with alpha channel

BITMAP *Alpha = create_bitmap(100, 100);
clear_bitmap(Alpha);

// Fill it with a mid-grey tone of 50% translucency

int colourAlpha = makeacol32(127, 127, 127, 32);
rectfill(Alpha, 0, 0, 100, 100, colourAlpha);

// Init alpha blending

drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
set_alpha_blender();


// Init timers

int Frames = Ticks;

LOCK_FUNCTION(Ticker);
LOCK_VARIABLE(Ticks);

install_int_ex(Ticker, BPS_TO_TIMER(FPS));


// Main loop

while(!key[KEY_ESC])
{
if (Frames < Ticks)
{
clear_bitmap(Buffer);

// Draw trans sprite

draw_trans_sprite(Buffer, Alpha, 200, 200);

textprintf_ex(Buffer, font, 2, 2, makecol(255, 255, 255), 0, "FPS: %f", FPS * (static_cast<float>(Frames) / static_cast<float>(Ticks)));

blit(Buffer, screen, 0, 0, 0, 0, ScreenWidth, ScreenHeight);
Frames++;
}
}

// Exit

remove_int(Ticker);
destroy_bitmap(Buffer);
}
END_OF_MAIN()




[Edited by - Harry de Man on August 14, 2005 5:57:02 PM]

Share this post


Link to post
Share on other sites
Thanks for those examples. In konForce's example, there's this:

// the mask needs to stay 8-bit, so we must disable color conversion
set_color_conversion(COLORCONV_NONE);

I don't do that in my program, and yet I'm able to load in a 32 bit image, a texture picture eg wood grain, and draw an 8 bit grayscale mask over the top, "cutting out" a shape with smooth edges.

I wonder why I didn't have to do the above?

Will post my example later.

Share this post


Link to post
Share on other sites
The example loads an 8-bit BMP from disk that serves as the alpha channel. Color Index 0 is 0 and Color Index 255 is 100%. The color conversion is disabled in the example, because otherwise the image would be loaded as a 32-bit image (the current depth of the screen).

I just tried it out without the color conversion disabled, and it did still work. I'm surprised that it did, because the manual specifically says, "After enabling this mode [write_alpha_blender]] you can also use draw_trans_sprite() to superimpose an 8-bit alpha mask over the top of an existing 32-bit sprite. "

Quote:
I don't do that in my program, and yet I'm able to load in a 32 bit image, a texture picture eg wood grain, and draw an 8 bit grayscale mask over the top, "cutting out" a shape with smooth edges.

In the example, 8-bit mask is being loaded from disk after disabling color conversion. However, the 32-bit image is loaded before it is disabled - just like your program. You generally want to keep color conversion on when loading a high/true color image in a high/true color screen.

If you are creating your 8-bit mask within your program, there is no need to mess with the color conversions.

Share this post


Link to post
Share on other sites
Quote:
Original post by Harry de Man

If it still doesn't work, try the following code:



I got your code to run fine on its own, but when I try to implement it into my program the bitmap doesn't have the translucency.

I know it's not the way I'm drawing the bitmaps to the screen, as if I load a RGBA sprite instead of try to create one, the translucency works fine.

Here's my code:


//in main.cpp
allegro_init();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, bufferWidth, bufferHeight, 0, 0);
set_alpha_blender();
install_keyboard();

//in world.cpp, which stores bitmaps and data for game world
bitmaps.push_back(create_bitmap(width, height));
clear_bitmap( bitmaps.back() );
int colourAlpha = makeacol32(255, 0, 0, 127); //try red with 50% alpha
drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
rectfill(bitmaps.back(), 0, 0, 100, 100, colourAlpha);

//in method that updates screen, draws each bitmap in different part of screen
draw_trans_sprite(buffer, bitmaps[count], x, y);




The bitmap seems to have 100% translucency, whereas it should have 50% (127).

If I leave out the rectfill, it still has 100% translucency.

If I clear to colour red:

clear_to_color( bitmaps.back(), makecol32(255, 0, 0) );

... again, it still has 100% translucency when I draw it with draw_trans_sprite. (When I draw it with blit or draw_sprite it draws the red box as it should.)

Help me before I tear my hair out!

Share this post


Link to post
Share on other sites
Quote:
Original post by konForce
If you are creating your 8-bit mask within your program, there is no need to mess with the color conversions.


I have different types of masks. Will it save memory to force it to load in 8 bit masks as 8 bit?

Share this post


Link to post
Share on other sites
Or, can anyone tell me how to do one simple (theoretically) thing? You can read the value of a pixel in the alpha layer, a value between 0 and 255, all I really want to do is change it as well as read it!

Let's say for example you wanted to increase or decrease the transparancy of just ONE pixel by 1/256, eg from 127 to 126.

Surely there must be a direct, simple way to do that?

A simple thing, and yet I can't do it. Surely it can be done?


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!