![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
Lighting and Allegro 5 |
Myrdos
Member #1,772
December 2001
|
I was looking at the Allegro 5 examples, some of which are very sexy, and I thought it would be cool to add a 'headlights' effect to my game like so: {"name":"one_headlight.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/4\/343d78b66f23dbb6f3ccf7e52c2c93cd.png","w":641,"h":364,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/4\/343d78b66f23dbb6f3ccf7e52c2c93cd"} Can it be done with Allegro, or would it require OpenGL? I'd like the light to be as realistic as possible. Also, would it be possible to use Allegro for the drawing, and OpenGL only for the lighting? Or, once you use OpenGL, do you have to use it for everything? __________________________________________________ |
Trent Gamblin
Member #261
April 2000
![]() |
If you just want to do what's in the screenshot, you can do that easily with primitives and blending. I don't know how realistic you want to go though... you can mix opengl and allegro calls no problem as long as you don't mess up opengl state and you know how allegro is affecting opengl state as well.
|
Myrdos
Member #1,772
December 2001
|
Trent Gamblin said: I don't know how realistic you want to go though... Well, I'd like to have the light fade with distance. The only blending function I see is "al_set_blender". Would I have to set the blending function for every pixel in software, depending on how far the pixel is from light source(s)? Quote: as long as you don't mess up opengl state and you know how allegro is affecting opengl state as well Sounds tricky, but doable. __________________________________________________ |
Trent Gamblin
Member #261
April 2000
![]() |
Fading with distance shouldn't be a big problem if the light is a constant shape. You could have a bitmap that is a white triangle/trapezoid that fade from full alpha (or whatever you want) down to no alpha to the end. Then draw that with additive blending, maybe draw it more than once for a better effect. al_set_blender is all you need. You can achieve an additive blender with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE).
|
Myrdos
Member #1,772
December 2001
|
Trent Gamblin said: You could have a bitmap that is a white triangle/trapezoid that fade from full alpha (or whatever you want) down to no alpha to the end. I like that! I think it might even be possible to add shadowing by blitting the terrain in front of the car onto the 'light triangle', such that the terrain areas have zero alpha. Hmm... I could even pre-process my terrain so that the edges of the terrain are illuminated, but the interior remains dark. {"name":"another_headlight.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/a\/fa2c531a2279ea9733927c783005c6cf.png","w":530,"h":322,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/a\/fa2c531a2279ea9733927c783005c6cf"} [EDIT] Oops, forgot to ask: Why would applying the light triangle multiple times improve the results? __________________________________________________ |
Trent Gamblin
Member #261
April 2000
![]() |
The only reason it might help is to make it brighter. You could also draw it with less or more alpha, even modifying them in real time so that it looks like it's "glowing". I don't recall what sort of transparency you'll see if you have say full alpha and draw additively... that's why I suggested drawing more than once. If it's 100% white at that point then drawing again wouldn't help but if was 50% you could get a brighter light by drawing more than once.
|
Myrdos
Member #1,772
December 2001
|
I guess I'll experiment with it and see what it looks like. Thanks for all the help! [EDIT] Hmmm... no way to give cookies. __________________________________________________ |
Trent Gamblin
Member #261
April 2000
![]() |
That's ok, I need to watch my weight anyway
|
Matthew Leverton
Supreme Loser
January 1999
![]() |
It shouldn't brighten the area behind the hill as dramatically as your screenshot shows, although it may not really matter much in the context of the game. |
Trent Gamblin
Member #261
April 2000
![]() |
See the last image in the thread. He plans to draw the "scenery" back over top of the light except for an edge which I think will work ok.
|
Myrdos
Member #1,772
December 2001
|
Matthew Leverton said: It shouldn't brighten the area behind the hill as dramatically as your screenshot shows, although it may not really matter much in the context of the game. I know, if you can think of a way to add shadows I'd be interested... My attempt at a light so far has been of limited success: {"name":"light1.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/f\/5f1f05301f61f01d14e87401ebf8faf2.png","w":648,"h":485,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/f\/5f1f05301f61f01d14e87401ebf8faf2"} It's creating a kind of 'fog' effect, rather than illuminating anything. I'm drawing it like so: al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); al_draw_scaled_bitmap(spotlight, 0, 0, al_get_bitmap_width(spotlight), al_get_bitmap_height(spotlight), 50, 60, al_get_bitmap_width(spotlight) * 2, al_get_bitmap_height(spotlight) * 2, 0); The spotlight bitmap is made of white pixels with varying amounts of alpha. Any ideas on how to improve this? __________________________________________________ |
Trent Gamblin
Member #261
April 2000
![]() |
What would really improve it is if you can somehow get the background image into a trapezoid and draw that with additive blending... I'm not sure how you'd do that without shaders except using the stencil buffer. Both are kind of "exotic". To do it with the stencil buffer you'd have a stencil the shape of the trapezoid and a translucent->black version of the trapezoid. You would draw from the display (or if that turns out to be too slow, you could have an intermediate buffer) to a bitmap with the stencil on so only the trapezoid gets drawn (the rest would be pure alpha or black) and then draw the black/alpha bitmap over that before drawing it with additive blending. EDIT:
|
gnolam
Member #2,030
March 2002
![]() |
Hint: Lightmaps don't actually lighten pixels, they darken them. -- |
Myrdos
Member #1,772
December 2001
|
gnolam said: Hint: Lightmaps don't actually lighten pixels, they darken them. So... I should selectively darken the terrain, except where the light is. Makes sense... Trent Gamblin said: Scratch that, you could use have extra black in the black/alpha image wherever the trapezoid doesn't touch. So no need for stencil or anything exotic. I not sure if I completely follow you here, but is that similar to what I have now? The parts of the spotlight that aren't 'light' are black with 0 alpha. Let me run this past you: 1) I fill the back buffer with black. 2) I draw my terrain to a bitmap, using 80% transparency. 3) I draw the light to the bitmap, but use blending such that the alpha value of the light pixels are added to the terrain, but not the colors. 4) I blit the result to the back buffer Is that type of blending possible? __________________________________________________ |
Trent Gamblin
Member #261
April 2000
![]() |
{"name":"604620","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/4\/842ef10cbe84998c0a06ce138a69313f.png","w":646,"h":430,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/4\/842ef10cbe84998c0a06ce138a69313f"} That's what I got with what I said above. Easier for me to post code than to describe it. The image I used is also attached. 1#include <allegro5/allegro.h>
2#include <allegro5/allegro_image.h>
3
4int main(void)
5{
6 al_init();
7 al_init_image_addon();
8
9 ALLEGRO_DISPLAY *display = al_create_display(640, 400);
10 al_clear_to_color(al_map_rgb_f(0, 0, 0));
11
12 ALLEGRO_BITMAP *allegro = al_load_bitmap("allegro.pcx");
13 ALLEGRO_BITMAP *trap = al_load_bitmap("trap.png");
14 ALLEGRO_BITMAP *buf = al_create_bitmap(640, 400);
15 ALLEGRO_BITMAP *tmp = al_create_bitmap(320, 200);
16
17 al_set_target_bitmap(buf);
18 al_clear_to_color(al_map_rgba_f(0, 0, 0, 0));
19 al_draw_tinted_bitmap(allegro, al_map_rgba_f(0.2, 0.2, 0.2, 1.0), 0, 0, 0);
20 al_draw_tinted_bitmap(allegro, al_map_rgba_f(0.2, 0.2, 0.2, 1.0), 320, 0, 0);
21 al_draw_tinted_bitmap(allegro, al_map_rgba_f(0.2, 0.2, 0.2, 1.0), 0, 200, 0);
22 al_draw_tinted_bitmap(allegro, al_map_rgba_f(0.2, 0.2, 0.2, 1.0), 320, 200, 0);
23
24 al_set_target_bitmap(tmp);
25 al_clear_to_color(al_map_rgba_f(0, 0, 0, 0));
26 al_draw_bitmap_region(buf, 160, 100, 320, 200, 0, 0, 0);
27 al_draw_bitmap(trap, 0, 0, 0);
28
29 al_set_target_bitmap(buf);
30 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
31 al_draw_bitmap(tmp, 160, 100, 0);
32 al_draw_bitmap(tmp, 160, 100, 0);
33
34 al_set_target_backbuffer(display);
35 al_draw_bitmap(buf, 0, 0, 0);
36 al_flip_display();
37
38 al_rest(10);
39
40 return 0;
41}
EDIT: I'm going to explain what the code does so I can use it as a blog post or wiki article. The key thing happening here is you have a completely rendered scene, except for the light(s), and you can quickly draw parts of that scene to a different destination bitmap. You need an image defining the shape and cutoff of the light as well. In this example, our "scene" is just the allegro.pcx image drawn 4 times to fit a 640x400 window, at 20% brightness. That's what the first lines of code after loading bitmaps does. After that's done, the area that will be lit is drawn to a "temporary"/work bitmap. Then the light-shape-definition bitmap is drawn over top of that, which gives us a bitmap with the colors we want (color directly from the scene) and the shape (due to drawing the trapezoid over top). The last thing that needs to be done is to set the target back to your scene and draw the "temporary" image we made back over top of the scene at the same point we copied from earlier. We use additive blending to draw it, and draw it as many times as needed to give the desired brightness.
|
Mark Oates
Member #1,146
March 2001
![]() |
I'm confused. 1) draw scene -- |
Trent Gamblin
Member #261
April 2000
![]() |
1) subtractive blending is not supported on all chips
|
Mark Oates
Member #1,146
March 2001
![]() |
The multiply blender would work, but it doesn't appear that that's available until 5.1. Until then, I would then do it as thus: al_draw_bitmap(af_get_image("scene.png"), 0, 0, NULL); // < draw scene af_push_state(ALLEGRO_STATE_BLENDER); // < obvious what this does, I guess al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ONE, ALLEGRO_ONE); // < makeshift subtractive blender al_draw_bitmap(shadow_layer, 0, 0, NULL); // < draw scene af_pop_state(); The work-around being that you'll have to draw your shadow layer inverted. Black is white and white is black - because the blender is subtracting more when the value is white. scene: [edit] er... is ALLEGRO_DEST_MINUS_SRC the part that's not supported on all chips? Which chips are affected? -- |
Elias
Member #358
May 2000
|
Well, in DirectX you have to query a flag and in OpenGL it's an extension you check for. So there at least were chips at one point which did not support it. I'd say all GPUs with shader support support it as it's now just a matter of shipping the right shader in the drivers for emulating the old fixed pipeline blending. -- |
Trent Gamblin
Member #261
April 2000
![]() |
Ok, now how do you move the light? You have to recreate the shadow layer each time it moves, and it will be constantly moving, so like I said, basically the same thing I posted but inverted, or am I still missing something?
|
Mark Oates
Member #1,146
March 2001
![]() |
Trent Gamblin said: Ok, now how do you move the light? You just draw the light in a different place. Quote: basically the same thing I posted but inverted
I guess mine has less code?... I dunno. Right now I'm brain-mush confus from trying to learn shaders. -- |
Trent Gamblin
Member #261
April 2000
![]() |
You can't just draw it in a different place. In your example is has to be drawn over the whole scene and thus fill the whole screen so moving it would make gaps in places. This is for a car. Imagine the car driving along then going up a hill. Now imagine there are 5 cars all with headlights on.
|
Myrdos
Member #1,772
December 2001
|
Trent: I've got your example working. \o/ I've got some code that draws a spotlight onto a bitmap, with a variable angle, beam length, brightness and aperture size. Do you think it would be worth submitting it to the Allegro dev team? It requires math.h. __________________________________________________ |
Trent Gamblin
Member #261
April 2000
![]() |
I don't personally think it fits in Allegro... seems too high level. You could post it on the wiki. I'm sure that would be useful for someone.
|
Mark Oates
Member #1,146
March 2001
![]() |
Trent Gamblin said: You can't just draw it in a different place. In your example is has to be drawn over the whole scene and thus fill the whole screen so moving it would make gaps in places. The shadow layer is a second buffer, just like the the display backbuffer. In the normal backbuffer you draw your scene, the sprites, trees, enemies and whatnot. As you draw their sprites (or in a separate process), you draw their shadows to that "shadowbuffer." Here's your light triangle (thumbnail doesn't render correctly because it has alpha: Once all that's done you put the two together. This is basically how I would do it, except I would try to see how many more features I could work in (except I would probably get frustrated and quit after I couldn't get them all in.)
Most of these require shaders. The end might look something like this (photoshop): {"name":"604637","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/5\/25aca9c4603800a22883474df0ba7228.png","w":958,"h":660,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/5\/25aca9c4603800a22883474df0ba7228"} -- |
|
1
2
|