A question of transparency
I'm struggling with transparency. I'm trying to draw a bitmap (that I do not load from a file), called fog, onto the screen, but it's not working! What I have is something like this:
//Create the fog
//Now randomly place a few circles for the fog
//Now draw the scene to the screen with out fog
What I would like to happen is for the areas that are covered by the white circles to show completely, with a circle of color makecol(128,128,128) greying the pixels underneath, and the black areas of the fog to completely blot out whatever is under them, so you only see black. So far, I only get the fog covering everything on the screen. Any suggestions on how to do this?
Draw the circles with makecol(255,0,255) so they dont occlude whats beneath them. Then I guess you would have to set the alpha value of the grey circles to less than 255 so that they are translucent.
It seems to work well; thank you for a solution. However, I'm still confused: what is special about the color makecol(255,0,255) that fixed it so that the circles worked? Also, if I wanted to have a translucent part of the fog, say, have the center of the circle be completely transparent and the other rims increasingly dimmer, how could I do that? And how do I set the alpha value of a pixel in a bitmap (right now I'm using 16 bit color)?
It is called "magic pink." It is defined in allegro as invisible.
Oh, sorry. I should have thought of that.
Does anyone know how to do the fog effect, but with not 100% transparent fog, but with the center all the way clear and the edges less clear?
I'm not sure how to use alpha blending with Allegro. I think what I need is a 32-bit bitmap called fog, so I could do something like:
After that, I need some way of setting the alpha part of each pixel in the image, which I was unable to find in the Allegro manual (so please don't tell me to rtfm!). Then, I need to just blit the fog onto the image like normal, right? Or am I missing something here?
blit() does not take into account any alpha channel!
You basically need look into the manual and try to write your own. I made my own translucent sprite drawing function, here:
|1||int color_shift(int col1, int col2, int percent)|
|3|| int ipercent = 100 - percent;|
|4|| int n_col, rn, gn, bn;|
|5|| int r1, g1, b1, r2, g2, b2;|
|6|| //get colors|
|7|| r1 = getr(col1);|
|8|| r2 = getr(col2);|
|9|| g1 = getg(col1);|
|10|| g2 = getg(col2);|
|11|| b1 = getb(col1);|
|12|| b2 = getb(col2);|
|14|| rn = ((r1*percent)/100)+((r2*ipercent)/100);|
|15|| gn = ((g1*percent)/100)+((g2*ipercent)/100);|
|16|| bn = ((b1*percent)/100)+((b2*ipercent)/100);|
|18|| n_col = makecol(rn, gn, bn);|
|20|| return n_col;|
|1||void trans_draw(BITMAP *dest, BITMAP *source, int x, int y, int percent)|
|3|| int w = source -> w;|
|4|| int h = source -> h;|
|5|| int w2 = dest -> w;|
|6|| int h2 = dest -> h;|
|7|| for (int sx = 0; sx < w; sx++)|
|9|| if ((x + sx >= w2)||(x + w < 0))|
|11|| while (x + sx < 0)|
|13|| for(int sy = 0; sy < h; sy++)|
|15|| if ((y + sy >= h2)||(y + h < 0))|
|17|| while (y + sy < 0)|
|19|| int col1 = _getpixel32(source, sx, sy);|
|20|| if (col1 != MASK_COLOR_32)|
|22|| int col2 = _getpixel32(dest, sx+x, sy+y);|
|23|| int col3 = merge(col1, col2, percent);|
|24|| _putpixel32(dest, x+sx, y+sy, col3);|
You can use it as you want. Basically, just use it like draw_sprite(), only give it the last parameter to tell it how much to blend the image into the background.
Almost forgot! This function only works with 32-bit color depth.
Thanks! The code you posted is great, but as you said, it requires 32-bit color depth. I wrote my own just now, which accepts an 8-bit bitmap which contains the alpha part and anouther bitmap, as well as the position (x,y) of where to place the alpha part on the other (truecolor) bitmap; so far, it works. Here is my alpha-blending function:
|1||void drawAlpha(BITMAP *alpha,BITMAP *destination,int x,int y)|
|3|| int r,g,b;|
|4|| float alphaPart;|
|5|| int rx,ry;|
|6|| int color;|
|7|| //Out of bounds?|
|8|| if(x>=destination->w || y>=destination->h || x+alpha->w<0 || y+alpha->h<0)|
|11|| for(rx=0;rx<alpha->w;rx++) //rx for relative x|
|12|| for(ry=0;ry<alpha->h;ry++) //See above|
Now the fog of war really does look like fog!
Thread #589235. Printed from Allegro.cc
I wrote a whole header of cool functions, and I will probably release it sometime. Good that you solved you problem!