Basically what's happening is that when the SDL determines how much of each color to display, it looks at which bits are set in the mask to determine which bits to pay attention to in the color. It's not quite as simple as a bitwise AND
because the values are shifted over. For example,
color = 0x00800000 = 00000000 10000000 00000000 00000000
and you've set your masks to be
Rmask = 0xFF000000 = 11111111 00000000 00000000 00000000
Gmask = 0x00FF0000 = 00000000 11111111 00000000 00000000
Bmask = 0x0000FF00 = 00000000 00000000 11111111 00000000
Amask = 0x000000FF = 00000000 00000000 00000000 11111111
then the color will be green {R=0, G=128, B=0}. The bits of color
specified by Rmask
are 0, the bits specified by Gmask
are 0x80 == 128
, and the bits specified by Bmask
are 0. If you were to reverse the masks for the same color:
Rmask = 0x000000FF
Gmask = 0x0000FF00
Bmask = 0x00FF0000
Amask = 0xFF000000
now the color will be blue {R=0, G=0, B=128}. It appears that the example you're looking at uses 16 bit color without an alpha channel. Since 16 bits do not divide evenly by 3 color channels, green gets an extra bit (as the human eye is believed to be more sensitive to green).
Example:
color = 0x1234 = 00010 010001 10100
Rmask = 0xF800 = 11111 000000 00000
Gmask = 0x07E0 = 00000 111111 00000
Bmask = 0x001F = 00000 000000 11111
Amask = 0
The color will be {R=2, G=17/2=8.5, B=20}. (the extra bit for green means the value needs to be halved to normalize it).
I'm not sure of how exactly SDL does it, or what types of crazy masks you can use with SDL, but I would imagine the actual algorithm is along the lines of a bitwise AND
, then right-shift as many bits as are cleared in the least significant portion of the mask? Or else working from most significant to least significant bit, for each bit that's set in the mask, shift the total left and add 1 if the corresponding bit of the color is set.