Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [Allegro 5.0.10] Lightning with blenders

This thread is locked; no one can reply to it. rss feed Print
[Allegro 5.0.10] Lightning with blenders
RemmyDZ
Member #15,971
May 2015

Hello everyone,

A while ago I started with Allegro, and thus far, it's one of the greatest libraries I ever worked with, simply amazing!
Currently I'm working on a game where lightning is a very important factor, and so I wanted to create one or more sources of lightning to illuminate the area.
This video perfectly illustrates what I'm looking for exactly:

https://www.youtube.com/watch?v=_YVTOaUKO0Q

Now, when it comes to alpha values, transparency, blenders and what not, I am a complete newbie.
I did some research on blenders in Allegro, tried to make some code of my own, but so far without any promising result.
The point is, I don't really know where to start with this.
I hope you guys can help me out!

Thanks in advance!

Greetings,
RemmyDZ :D

RPG Hacker
Member #12,492
January 2011
avatar

I think what you want for this effect is something like this:

  • In any graphics tool that supports alpha channel, create a black texture and set the alpha values on that texture to resemble your light circle. Alpha = 1.0: No light. Alpha = 0.0: Full lighting. Just create a circle with high alpha values on the border and low alpha values near the center.

  • Load the texture you just created as an ALLEGRO_BITMAP into Allegro.

  • Create an ALLEGRO_BITMAP the size of your window/viewport.

  • At the beginning of your frame, set the target bitmap to the window-sized bitmap you just created.

  • Clear this bitmap to color 0.0f/0.0f/0.0f/1.0f (don't forget the alpha channel, it's the most important).

  • Enable copy blender.*

  • Now draw your light circle bitmap onto this bitmap with the correct position (like your cursor position or whatever you want).

  • Set the target bitmap to the regular backbuffer again.

  • Now render your scene as normal.

  • Enable transparency blending.**

  • Finally draw the bitmap, on which you have previously drawn the light circle, onto the backbuffer.

That should do the trick.

*To enable copy blending, use:
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO)

**To enable transparency blending/alpha blending, use:
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

I took these directly from the documentation.

beoran
Member #12,636
March 2011

To learn more about using blenders in Allegro, take a look at the examples ex_blend and ex_blend2.

Also these threads have some useful examples:
https://www.allegro.cc/forums/thread/615242
https://www.allegro.cc/forums/thread/613960

Polybios
Member #12,293
October 2010

In any graphics tool that supports alpha channel ...

Of course you could also easily create a circle with such properties using Allegro5's primitives addon. For example, you could use something similar to the following function and leave interpolation to the GPU. The vertices could be cached, of course, and blenders need to be set appropriately. This is more or less ripped out of A5's source.

#SelectExpand
1void draw_special_circle(float cx, float cy, float r, 2 ALLEGRO_COLOR outer_color, ALLEGRO_COLOR center_color) 3{ 4 ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE]; 5 int num_segments, ii; 6 7 assert(r >= 0); 8 9 num_segments = ALLEGRO_PRIM_QUALITY * sqrtf(r); 10 11 if (num_segments < 2) 12 return; 13 14 if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { 15 num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; 16 } 17 18 al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r, r, 0, ALLEGRO_PI * 2, 0, num_segments); 19 vertex_cache[0].x = cx; vertex_cache[0].y = cy; 20 21 for (ii = 0; ii < num_segments + 1; ii++) { 22 vertex_cache[ii].color = outer_color; 23 vertex_cache[ii].z = 0; 24 } 25 vertex_cache[0].color = color_center; 26 27 al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN); 28}

Quote:

Enable copy blender.*
Enable transparency blending.**

I'd like to point out that another option would be to use
al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO);
for overlaying the lights. That should be equivalent to Allegro 4's old multiply-blender. It isn't in allegro.cc's version of the manual, but available since 5.0.10.

RemmyDZ
Member #15,971
May 2015

Thank you guys so much for the fast and clear replies, really helpful! :D

Now, I have a few questions.
First of all, thanks to RPG Hacker for the very nice steps you made for me, I understand most of them.
As for a few, I need some extra help there, if possible.
What do you exactly mean with "At the beginning of your frame .... you just created"?
I honestly can't figure out what you mean with targeting a bitmap.
Do you mean like I have to draw it first?
Next, how do I clear a bitmap to color?
I assumed I have to use al_draw_tinted_bitmap(...), but I'm not exactly sure.
And last but not least, how do I set a target bitmap to the regular backbuffer, and how do I draw the bitmap on the backbuffer?
Or is drawing the bitmap on the backbuffer just al_draw_bitmap(...) and then al_flip_display()?

Also, after many attempts of Paint.NET and GIMP, I was very happy with your post, Polybios, this function creates the perfect circle in terms of transition from full alpha to none!
Could you maybe explain your code a bit, because I don't quite know how it works, and I don't plan on simply copy-pasting it without knowing how it works.

Thank you guys so much!

Greetings,
RemmyDZ

RPG Hacker
Member #12,492
January 2011
avatar

RemmyDZ said:

What do you exactly mean with "At the beginning of your frame .... you just created"?
I honestly can't figure out what you mean with targeting a bitmap.

I mean that, at the beginning of the rendering code of your game loop, you have to set the target bitmap to the black bitmap you created before. In Allegro (and in most somewhat up-to-date graphics APIs) you can not only render graphics to the window/screen, but also onto another texture. In the case of Allegro, this is represented with the bitmaps. You can render things onto bitmaps and then use these bitmaps for further rendering or whatever. You can set the target bitmap with

al_set_target_bitmap(bitmap);

Just pass your black bitmap to this function.

Quote:

Next, how do I clear a bitmap to color?

After calling the function I mentioned above, just call

al_clear_to_color(al_map_rgba_f(0.0f, 0.0f, 0.0f, 1.0f));

This function always clears the bitmap which is currently the target bitmap.

Quote:

And last but not least, how do I set a target bitmap to the regular backbuffer, and how do I draw the bitmap on the backbuffer?

There are two ways to reset the target bitmap to the backbuffer. You can either do

al_set_target_bitmap(al_get_backbuffer(display));

or, as a simplified version,

al_set_target_backbuffer(display);

Just pass your display to whatever method you prefer. After calling one of those two functions, just call any draw function to render the bitmap onto the backbufer. For example:

void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags);

Polybios
Member #12,293
October 2010

RemmyDZ said:

I don't quite know how it works

Because of ALLEGRO_TRIANGLE_FAN, it draws a triangle fan, i. e. all triangles share one vertex, which is the first in the array that is passed to al_draw_prim. This first vertex is initialised to be the center of the circle. The other points are generated to be evenly distributed on the circle (the circular line) by al_calculate_arc. That's it basically. The other stuff deals just with estimating how many vertices to take for the circle given the radius and initialising the colors accordingly. Like I said, it's mostly copied from Allegro's source.

RemmyDZ
Member #15,971
May 2015

Allright, thank you guys so much!
It's working right now, and I'm really thankful for that!
I also learned alot of this, since I never used blenders and vertices before, still working on comprehending everything, but I'll probably manage, and if not, I can post my question(s) on this amazing forum.

Once again guys, thank you all so much for the fast and perfect replies! ;D

Greetings,
RemmyDZ :D

Edgar Reynaldo
Member #8,592
May 2007
avatar

There was an accidental typo in the thread title that led me to believe you were going to be doing 'lightning' with shaders, which I thought would be really cool. G-Force, a WMP visualizer, does something similar I would bet.

beoran
Member #12,636
March 2011

Hmm, drawing a beam of lightening shouldn't be too hard with al_draw_ribbon or a few al_draw_line statements? No need for shaders, it seems?

Polybios
Member #12,293
October 2010

But lightning would involve some lighting. >:(

Go to: