Sign in to follow this  

palette mapping?

This topic is 3596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

A common feature in many older games and still prevelent in some newer games. Palette mapping is perhaps most commonly used to allow the remapping of colors in a given image for 'customization'. Sadly, I don't know where to start with this. I've looked around for libs and can't find anything usable in my language of choice (C++) then I started writing my own and quickly found the way I'd chosen to do this was extremely bloated in comparison to most other implementations. I'd chosen to declare the entire palette as integer arrays of 3 elements which of course would be the rgb values. I wrote a quick script to write out the declarations for all 256 arrays so all I had to do was plug in the palette values. However doing so results in a 400k file just with the arrays declared and no actual functionality. It has a 8000k memory footprint while similar applications written in C++ as well take 200k have full remapping capablities file io and other additions and of course have a larger memory footprint. Obviously I'm going about this all wrong. My original intention was to load an image from a file into a buffer, figure out functions similar to getpixel() and putpixel() and use a while loop until eof() replacing indexed values where needed then write the output to a different buffer and close the original buffer only to reopen that buffer for the next image. This doesn't seem to be an efficent or standardized way of doing this, and declaring all 256 palette entries as an array was obviously not the way it's been acheived by others. Some guidance in palette mapping and any resources/code/guides/libraries/etc. would be greatly appreciated. Thanks in advance.

Share this post


Link to post
Share on other sites
Do you want to display images while remapping some of their colors? Similar to how several strategy games use the same image for a unit, but replace certain colors to show the owners color (red tank, blue tank, etc.)?

If that's what you're looking for, then forget about palettes. They're used to compress files. Remapping colors just happens to be easy with them because you can swap palettes, that's all. Since modern systems hardly ever use palettes anymore, it's probably more hassle than it's worth. Some file formats use palettes for compression, but they're not usually loaded into memory as such. You may want to use a color replacement table and while blitting an image, look up each pixel in that table to find the replacement color, to use that color instead of the original. It might not be the most efficient way, but it's probably a lot easier to implement.

Or, if memory isn't much of a constraint, you can create multiple versions of the same image, utilizing the above process to create the remapped versions. You can then draw these images as usual.


Anyway, it seems that you're hard-coding this palette or color replacement table. That's a bad idea. Load it from an (image) file (or files) instead. This not only cuts down on filesize and memory usage, but also makes your program a lot more flexible: need different replacement colors? Just modify the image, no need to recompile. :)

Share this post


Link to post
Share on other sites
As Captain P alludes, the palette acts as the level of indirection necessary to implement proper palette mapping. I also sounds as if you are using one of the modern, non-paletted color modes (15bpp, 16bpp, 24bpp, 32bpp, etc) which is the problem.

There are a few basic solutions:

If the resource can be represented by 256 colors or fewer, create the resource in 256 color (8bit paletted mode) and alter it's palette at run-time as needed. However, there will likely be some performance penalty for using paletted resources in a mostly non-paletted application.

If the color is constant and can be determined when the resources are loaded, designate some color value in the resources native color format to indicate that this color is to be replaced by a color value specified at run-time. Choose as many of these indicators as is necessary. This is similar to color-keyed transparency.

If the color is dynamic and the resource contains more than 256 colors, then you may be able to use vertex color values and blending modes to get the desired effect. If this is not flexible enough, create a duplicate texture and "mask" the portions that you want to be effected, leaving the rest transparent. At run-time, apply this texture over the top of the standard texture and apply the vertex-lighting and blending to it. Only the parts you masked will be affected by the color parameter. You can use different blending modes and different values for the masked pixels to create gradient and other effects.

Share this post


Link to post
Share on other sites
If you're looking for that retro feel of 8-bit era games, a good choice would probably be the Allegro library. It has palette manipulation like you mentioned, as well as a wide variety of other graphic, input and sound functions. Allegro is designed primarily as a C library- or was, to be honest I haven't used it in some time -but with minimal effort it works just fine in an object oriented program. Just watch out for destructors as mentioned in the Allegro documentation.

If the whole library is too bloated for your purposes, you might be able to use the Allegro source as a starting point to write your own code. (Or even use the Allegro code, I believe the license allows for that)

Share this post


Link to post
Share on other sites
Quote:
Do you want to display images while remapping some of their colors? Similar to how several strategy games use the same image for a unit, but replace certain colors to show the owners color (red tank, blue tank, etc.)?


Indeed.

Quote:
Or, if memory isn't much of a constraint, you can create multiple versions of the same image, utilizing the above process to create the remapped versions. You can then draw these images as usual.


Given that each image has a number of remappable areas that will map to different colors, this would be an extreme waste of my time, energy and system space. Remapping is a much more efficent solution.

Quote:
Anyway, it seems that you're hard-coding this palette or color replacement table. That's a bad idea. Load it from an (image) file (or files) instead. This not only cuts down on filesize and memory usage, but also makes your program a lot more flexible: need different replacement colors? Just modify the image, no need to recompile. :)


While currently hard coded into 256 arrays, I don't foresee changing the palette in the future. I may however decide to use fstream to import the values from an external file to the arrays.

Quote:
If you're looking for that retro feel of 8-bit era games, a good choice would probably be the Allegro library. It has palette manipulation like you mentioned, as well as a wide variety of other graphic, input and sound functions. Allegro is designed primarily as a C library- or was, to be honest I haven't used it in some time -but with minimal effort it works just fine in an object oriented program. Just watch out for destructors as mentioned in the Allegro documentation.

If the whole library is too bloated for your purposes, you might be able to use the Allegro source as a starting point to write your own code. (Or even use the Allegro code, I believe the license allows for that)


This seems like the most viable solution. Thank you all for your assistance. Especially you puck. I'll go download the allegro lib as it seems to be exactly what I'm looking for. I'll probably wind up using it as a basis more so than just including it. It'll be a good learning experiance. Again, thank you all for your help.

Due to the lack of readily available documentation, I think once I've finished this project of mine, or atleast acheived the desired goals for palette mapping, I'll make a tutorial and post it on gamedev among other resources I often use so in the future others in this situation have less work to do.

Share this post


Link to post
Share on other sites

This topic is 3596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this