Realtime pixel manipulation? (Palette shifting)

BlitzMax Forums/BlitzMax Programming/Realtime pixel manipulation? (Palette shifting)

Mineth(Posted 2010) [#1]
Hi,

I'm making a 2d game using small sprites of around 32x48 pixels each. The screen is scaled and zoomed accordingly so you can 'count the pixels' on a 800x600 screen which is really 320x240 pixels, but that's intended of this game and I'm not changing that.

I'm looking for a good way to manipulate pixels on realtime, namely palette shifting. I have a LOT of sprites using only up to 16 colors, and I want to shift colors every few frames. Recreating every sprite with different colors would take up too much memory tbh and shouldn't really be needed.

I can come up with a function like this:

for x until pixmaps.width OR screen.width
- for y until pixmaps.height OR screenheight
- - if readpixel(x,y) = color1a then writepixel(x,y,color1b)
- - if readpixel(x,y) = color2a then writepixel(x,y,color2b)
- - if readpixel(x,y) = color3a then writepixel(x,y,color3b)

But that's manipulating pixmaps (or the whole screen even) directly, and I'm not really sure if that's the fastest and best solution for this with looping that on multiple sprites (50+) every few frames.

Anyone got a nice solution to this? If anything's not clear, don't hesitate to ask.


ImaginaryHuman(Posted 2010) [#2]
One thing you can do is use SetColor to tint the sprite. It's basically like multiplying a value 0..255 by the value of each color component in the sprite. Normally SetColor $FF,$FF,$FF translates to multiplying by 1.0, since internally it gets converted from 0..255 to 0..1 range. But this tints the entire image. If you want to individually tint different parts of the sprite, you could have multiple sprite layers and do each separately. If you have 16-color sprites you could draw 16 layers separately?

There is no simple hardware-accelerated `remap colors` functionality. You can do it in a shader, or in a pixmap which is relatively slow.

How are you doing masking, do you use alphablending or just 1-color masking?

Here's an option. Since you only have 16-colors, copy the color `index` into the alpha channel of the sprite. You'll have alpha values of 0..15. Then use the alpha threshold/test to only draw pixels whose alpha = a given index value. Do 16 draws of the sprite with different alpha tests and color tints.