How to draw pixels of bitmaps transparently upon collision
Travis Peterson

Making a game and attempting to create a light system with torches on a 2d rpg platformer and want to mask out pixels of a black allegro_bitmap wondering if yall know how its done or a similar method to achieve that effect

maybe changing the alpha channel on specific pixels could work but dont know the syntax to do that also dont know how costly that would be preciate your help

Chris Katko

I'm gonna need some more details on what you're trying to do, and how you're thinking of implementing it.

Can you throw up a screenshot of a game with a similar effect?

- Are you trying for lightmaps (most likely?), or polygonal lighting?

Usually with lightmaps you just set the blending function to the correct one, and (IIRC) draw the light map on top of it. (IIRC) Or start with a full-screen black, draw your lightmaps onto it, and then merge that with the non-lit version at once. (Sorry, it's been years since I had to do this so my mind is a bit hazy.)

And you mention collision, and pixels. Are you making a TILE map game, or a PIXEL/bitmap game?

For lightmaps, you do the above, they're just "lit" bitmaps using known light patterns like a circle.

For polygonal lighting, you again draw to a "shadow buffer" or "light buffer" the size of your screen and merge in, but for "collisions" you're actually sending out rays from your light-sources and marking any spots they cover/hit.

There's tons of lighting tutorials for various game libraries on the internet. Try googling "light maps 2d tutorial." If you can identify the type of lighting you're looking for, we can drill down more into the details of how to implement it. But right now, there's "a thousand ways to skin a cat" so the best/easiest way to implement it depends on what specifically you're looking to implement.

Here's some example quick googles:

http://frankforce.com/?p=2614

http://ncase.me/sight-and-light/

Here's polygonal: (and you can fuzz/blur it to make it look softer)

{"name":"kFJyu.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/1\/f1db1ffbb5a3ce36a75c004de535bb44.jpg","w":1280,"h":720,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/1\/f1db1ffbb5a3ce36a75c004de535bb44"}kFJyu.jpg

Here's a lightmap (just lightmaps):

{"name":"3.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/c\/bc0c03bbd3b14b947881c49b36313914.jpg","w":1021,"h":1025,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/c\/bc0c03bbd3b14b947881c49b36313914"}3.jpg

Here's a lightmap:

{"name":"2JEvm.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/c\/ec6bfd7ba7e526bfa98113ae6c431fd3.jpg","w":1920,"h":1080,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/c\/ec6bfd7ba7e526bfa98113ae6c431fd3"}2JEvm.jpg

Notice how the lights are all "the same." They don't have to be, you can vary size, intensity, etc. But the key here is they're not polygonal. They're not "rays" sent out from a lightsource that collide. Which means you can run into artifacts where they don't get clipped by walls (unless you specifically add that check).

But there are no hard-and-fast rules. Lightmaps can be made more "collision aware" and vertex lighting can be made more like lightmaps. Again, it really depends on what you're looking for.

Travis Peterson

Understand the logistics of what youre saying bout lightmaps and blenders but dont know the code to get started could you post a basic lightmap programs code

Ideally looking to light up circles on a black rectangle dark region with some of the light circles obstructed at certain walls
but just making a circle light system similar to your 3rd pic would be cool for now if thats too much
Btw its really cool how fast and knowledgable you guys are in this community

Edgar Reynaldo

Well in that case what you want to do is draw a shadow map, and you do that by drawing lights on shadow.

Draw a background buffer bitmap of RGBA(0,0,0,255) using a full copy blender.
Draw lights of RGBA(0,0,0,255-light) using an additive alpha blender. See al_set_separate_blender and al_set_blender for details.

Then once you're done drawing your shadow map, you draw the shadows over your screen with an alpha blender.

EDIT
To draw a nice gradient alpha circle like above in Chris' example, you can draw from radius to zero number of circles with varying alpha to make a gradient.

Chris Katko

To get the (lightmap) shadows clipped, the easiest way would be to draw all your solid pieces INTO the shadow buffer and remove the lighting THEN merge the shadow buffer in like normal.

So you have this black buffer. You draw your lights onto it. Then you REMOVE those lights at places where there is a solid wall, by drawing black on those spaces (even just draw the same tile, into the shadow buffer, with a color set to black so transparent pixels don't get drawn.)

Now there's a caveat with that easiest method. If your lights are "bigger" than one tile (or is it 3x3?), the lights will be filled in by those black parts correctly, but beyond them won't be clipped. If your world has large blocks of "filled" tiles, then you'll be fine. If your world has many thin strips of solid walls with very large lights, then the lighting will just shoot passed them.

I can take a moment and draw a diagram if that's helpful...

[edit] Here we go.

{"name":"zLqNXf0.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/a\/cab18b04db3ad7c890a27c37b91500bc.png","w":1382,"h":1824,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/a\/cab18b04db3ad7c890a27c37b91500bc"}zLqNXf0.png

[edit] fixed typo

Travis Peterson

So would the code be:

ALLEGRO_IMAGE *shadebackground;
shadebackground = al_load_bitmap("image.png");
al_set_separate_blender(shadebackground); al_set_blender(shadebackground);

Edgar Reynaldo

Nope. Try reading the manual like I linked to.

If you have a shadow map premade, you can draw it with :

ALLEGRO_BITMAP* shadows = ...;

al_draw_bitmap(background , 0 , 0);

al_set_blender(ALLEGRO_ADD , ALLEGRO_ALHPA , ALLEGRO_INVERSE_ALPHA);

al_draw_bitmap(shadows , 0 , 0);

If you want to draw light on your shadow map :

ALLEGRO_BITMAP* shadows = al_create_bitmap(buffer->W() , buffer->H());
al_clear_to_color(al_map_rgba(0,0,0,0));
al_set_separate_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO , ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO);
al_draw_circle(buffer->W()/2 , buffer->H()/2 , buffer->W()/2 , al_map_rgba(0,0,0,light - 255);

And when you're done, reset the normal blender :

al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_INVERSE_ALPHA);

Thread #617144. Printed from Allegro.cc