2

I'm programming a game in Allegro 5 and I'm currently working on my drawing algorithm. After calculation I end up with two ALLEGRO_BITMAP*-objects where one of them is my "scene" with the terrain drawn on it and the other one is a shadow-map.

The scene are simply textures of game-elements drawn on the bitmap. The shadow-map is a bitmap using black colors for light and white colors for shadows rendered previously.

For drawing those bitmaps on the screen I use al_draw_scaled_bitmap(...) and al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ONE, ALLEGRO_ONE) to substract the white elements of the shadow-map from the scene to make those visible.

The problem I have is that I want to have all pixels that are white on the shadows-map to be tinted in a world-color, which has been calculated in every frame before, and all black elements simply not modified (gray means partially tinted).

The final color could be calculated like p.r * c.r + 1 - p.r with p = the pixel-color on the scene and c = the world-color for red, green and blue channels in rgb.

Is there any way to achieve a partial tinting effect in Allegro 5 (possibly without massive overdraw)?

I thought of using shaders, but I haven't found a solution to implement these with my ALLEGRO_BITMAP*-objects.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
0liCom
  • 35
  • 8
  • You could divide your bitmaps into sub bitmaps, but I think that is not what you want. Could you include some pictures? Two will work, what you currently have and what you want to have. – rlam12 Jun 14 '16 at 19:26

1 Answers1

3

Allegro's blenders are fairly simple, so you would need a shader for this. Simply write a shader, and when you're drawing your shadow map al_use_shader the shader and then al_use_shader(NULL) when you're done. The shader can use the default vertex source which you can get with al_get_default_shader_source. So you only have to write the fragment shader. Your fragment shader should have a uniform vec4 which is the tint colour. You would also have x, y floats which respresent the x and y values of the destination. It would also have a sampler which is the scene bitmap (which should be the target, since you're drawing to it). You'd sample from the sampler at x, y (x and y should be from 0 to 1, you can get these by using xpixel / width (same with y)) and then do your calculation with the input colour, and then store the result in gl_FragColor (this text assume you're using GLSL (OpenGL). The same principle applies to Direct3D.) Check out the default shaders in src/shader_source.inc in the Allegro source code for more info on writing shaders.

goobliata
  • 340
  • 1
  • 7
  • Thanks, I'll give it a try! – 0liCom Jun 15 '16 at 13:21
  • +1 Works fine even if I have changed it up a bit and used a backbuffer bitmap where everything has been drawn on to calculate shadows and draw this to the display-backbuffer. Can still be improved, but it works and that's everything I want in the moment, performance is good enough – 0liCom Jun 16 '16 at 18:50