Mail Archives: djgpp/1997/03/05/21:26:49
Sly writes:
>> both directions, you could (a bit more work) use the
>> create_color_table() function to build a lookup table which will treat
>> light level 128 as the original color, 0 as black, and 255 as white.
>
>When I read this, I started thinking how this would be achieved (the lookup
>table to treat light level 128 as the original colour, 0 as black, and 255
>as white). But I can't think of how it would be done. Any tips?
You have to write a custom color blender, and then pass it to the
create_color_table() function. This will call your routine 65536 times,
once for every possible combination of two colors X and Y (for lighting,
X is the light level). You return the RGB value that you want as the
result of this combination, and the map builder will use the closest
color it can find in the palette (how well it works depends on if there
is such a color available or not).
Here's a little example program. Pass it the name of a PCX file, and it
will display the image at various light levels, first with regular table
and then with a black -> color -> white one. It will work best if the
PCX is quite small, eg. 32x32 :-)
There are a lot of refinements you could use on this basic idea, eg. you
might prefer to use additive color blending rather than interpolation,
or do the adjustments in HSV color space. Also, you could divide the 256
light levels into several ranges, and use eg. 0-31 to tint the sprite
red, 32-63 to make it grey out, etc...
<--- snip: lighting.c --->
#include <stdlib.h>
#include <stdio.h>
#include <allegro.h>
COLOR_MAP map;
RGB blender(PALETTE pal, int x, int y)
{
RGB ret;
if (x < 128) {
/* blend towards black */
ret.r = (int)pal[y].r * x / 128;
ret.g = (int)pal[y].g * x / 128;
ret.b = (int)pal[y].b * x / 128;
}
else if (x > 128) {
/* blend towards white */
ret.r = 63 - (63 - (int)pal[y].r) * (255 - x) / 128;
ret.g = 63 - (63 - (int)pal[y].g) * (255 - x) / 128;
ret.b = 63 - (63 - (int)pal[y].b) * (255 - x) / 128;
}
else {
/* light = 128, so use the exact color from the sprite */
ret = pal[y];
}
return ret;
}
int main(int argc, char *argv[])
{
BITMAP *bmp;
PALETTE pal;
int x, y;
if (argc != 2) {
printf("No bitmap filename specified!\n");
return 1;
}
/* read in the test bitmap */
bmp = load_bitmap(argv[1], pal);
if (!bmp) {
printf("Error reading '%s'\n", argv[1]);
return 1;
}
color_map = ↦
allegro_init();
install_keyboard();
set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
/* make a normal lighting table */
clear(screen);
set_palette(desktop_palette);
textout(screen, font, "Normal lighting table...", 32, 32, 255);
create_light_table(&map, pal, 0, 0, 0, NULL);
clear(screen);
set_palette(pal);
/* show the image with it */
for (x=0; x<8; x++)
for (y=0; y<8; y++)
draw_lit_sprite(screen, bmp, x*48, y*48, (y*8+x)*4);
readkey();
/* make a custom lighting table */
clear(screen);
set_palette(desktop_palette);
textout(screen, font, "Custom lighting table...", 32, 32, 255);
create_color_table(&map, pal, blender, NULL);
clear(screen);
set_palette(pal);
/* show the image with it */
for (x=0; x<8; x++)
for (y=0; y<8; y++)
draw_lit_sprite(screen, bmp, x*48, y*48, (y*8+x)*4);
readkey();
destroy_bitmap(bmp);
return 0;
}
- Raw text -