[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] 8bit surfaces and palettes

> 2) i use 8bit bitmaps. i would like to replace a specific color with a given
> color value (to recolor the dress of a player - just direct color/color
> replacement). what possibilities do i have to do that? manipulating the
> palette of a surface (after convert())? directly manipulating the bitmap
> after loading? using surfarray? i would appreciate any suggestions.

you may want to peek at my little palette shifting example in the
pygame code repository http://www.pygame.org/pcr/submissions/04192001a.html

here's a quick overview of how SDL (and hence, pygame) handle 8bit
surfaces. first, each 8bit image obviously has its own palette.
you can access the palette as a list of 3 element lists in python.
this makes it fairly easy to work with.
(and easy to convert to a Numeric array if you desire)

when blitting a non-8bit image to an 8bit image, or blitting an
8bit image to non-8bit image, SDL will correctly map the image
palette between the two images.

when blitting an 8bit image to an 8bit image, SDL will not use
the palette at all, only copy the color index values from one
image to the other.

when converting an image to match the display format, the new
surface will have a duplicate version of the same palette and its
colors will be remapped to match the display palette. (this happens
for 8bit and non-8bit surfaces)

when creating an 8bit display surface, you almost always want to
pass the HWPALETTE flag in the display flags. without the HWPALETTE
your display won't get the full 256 palette entires, and instead
have to share the palette with other running applications.
(that is only for windows, nonfullscreen displays, i believe)

when you have your 8bit display surface, there are always 2 separate
palettes. mainly these two palettes remain exactly the same. One
palette is the "logical" palette, and this is the palette SDL uses
when blitting and mapping images to the display colormap. The other
palette is the "physical" palette. this is the actualy palette SDL
uses to display the surface on the monitor.

in pygame, setting the display surface palette (Surface.set_palette)
sets both the logical and physical palettes to the same thing.
new in pygame-1.1 you can call pygame.display.set_palette(), which
will only change the physical (display) palette, and not the one used
for blitting.

there's a lot of things to know about 8bit surfaces. i never found a
single place that explained it all for SDL, i just kind of learned these
"rules" as i went along.

using the surfarray module you can quickly interact with your image
as a raw set of 8bit integers. for example, if you have an 8bit image
in your game, you can create a Numeric array that directly references
the pixel data of the surface.

i think in a standard 8bit game, you have all your image data already
set to a 'universal' palette. then any effects you do are done by just
changing the palette for the display. this is the way SDL is set up to
do its blitting, so i'd recommend this approach.

another thing to remember is you can perform some palette shifting
tricks on an offscreen 8bit surface, then blit them to a 32bit
display surface and see the effects.

pygame mailing list