From: Shawn Hargreaves Newsgroups: comp.os.msdos.djgpp Subject: Re: Lighting Techniques Date: Wed, 5 Mar 1997 20:35:55 +0000 Organization: None Distribution: world Message-ID: <8zQ8rTArkdHzEwYp@talula.demon.co.uk> References: <01bc2853$aa224320$4cddf4cc AT imag DOT net DOT imag DOT net> <01bc290e$ccc6e8c0$8a081ecb AT sly> NNTP-Posting-Host: talula.demon.co.uk MIME-Version: 1.0 Lines: 130 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp 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 #include #include 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; }