В основном происходит то, что, когда SDL определяет, сколько каждого цвета отображать, он смотрит, какие биты установлены в маске, чтобы определить, какие биты следует обратить внимание в цвете.Это не так просто, как побитовое AND
, потому что значения смещены.Например,
color = 0x00800000 = 00000000 10000000 00000000 00000000
и вы установили свои маски на
Rmask = 0xFF000000 = 11111111 00000000 00000000 00000000
Gmask = 0x00FF0000 = 00000000 11111111 00000000 00000000
Bmask = 0x0000FF00 = 00000000 00000000 11111111 00000000
Amask = 0x000000FF = 00000000 00000000 00000000 11111111
, тогда цвет будет зеленым {R = 0, G = 128, B = 0}.Биты color
, заданные Rmask
, равны 0, биты, заданные Gmask
, равны 0x80 == 128
, а биты, заданные Bmask
, равны 0. Если вам нужно изменить маски для того же цвета:
Rmask = 0x000000FF
Gmask = 0x0000FF00
Bmask = 0x00FF0000
Amask = 0xFF000000
теперь цвет будет синим {R = 0, G = 0, B = 128}.Похоже, что рассматриваемый вами пример использует 16-битный цвет без альфа-канала.Поскольку 16 битов не делятся равномерно на 3 цветовых канала, зеленый получает дополнительный бит (поскольку человеческий глаз считается более чувствительным к зеленому).
Пример:
color = 0x1234 = 00010 010001 10100
Rmask = 0xF800 = 11111 000000 00000
Gmask = 0x07E0 = 00000 111111 00000
Bmask = 0x001F = 00000 000000 11111
Amask = 0
цвет будет {R = 2, G = 17/2 = 8,5, B = 20}.(дополнительный бит для зеленого означает, что значение должно быть уменьшено вдвое, чтобы его нормализовать).
Я не уверен, как именно SDL это делает, или какие типы сумасшедших масок вы можете использовать с SDL, но яМожно ли предположить, что фактический алгоритм выполняется в соответствии с побитовой AND
, а затем сдвиг вправо на столько битов, сколько очищено в наименее значимой части маски?Или же, работая от старшего значащего до наименее значимого бита, для каждого бита, установленного в маске, сдвиньте итоговое значение влево и добавьте 1, если установлен соответствующий бит цвета.