SDL: alpha канал и все о нем
Автор: Andrey Barmaley
SDL поддерживает два типа surface:
1. RGB surface: альфа канал на всю поверхность, создается при amask = 0, альфа хранится в SDL_Surface->format->alpha, изменяется через SDL_SetAlpha
2. RGBA surface: альфа канал на пиксел, создается при валидной amask, значение хранится естественно в пикселях, функция SDL_SetAlpha манипулирует только флагом SDL_SRCSLPHA.
Чем они отличаются?
Например: у нас есть картинка с тенью, это возможно реализовать через две surface первого типа (в одной картинка во второй тень), либо просто реализовать через одну surface второго типа.
Так вот давайте поговорим о втором типе.
RGBA surface создается при значении amask, отличной от нуля. Совокупность rmask, gmask, bmask, amask представляет пиксел, разрядность которого определяется параметром BitsPerPixel при создании SDL_CreateRGBSurface.
Подробнее о битности цвета. Для RGBA surface, возможны значения 16, 24, 32 (другие пропустим ;).
От этого параметра, так же, в первую очередь зависит размер используемой памяти картинки. И для сегмента всяких embeded устройств это очень важный параметр!
В SDL-1.2 рекомендуется использовать только 32 битный, (почему? для меня это было всегда загадкой, пока сам не столкнулся) отмазка там одна типа тормоза и все такое (куча багов, которая действительно присутствует и об этом ниже), а нам пофигу ;) И вообще, например, в windows для рабочего стола возможно выставлять 16, 32 бита, В linux возможно выставить 16, 24 бита цвета, у меня есть железка с WinCE там 16 бит... Это я к тому что рынок разнообразен, и желательна поддержка в минимуме всех трех вариантов 16, 24, 32 бита для обоих типов поверхности.
Переходим напрямую к маскам, man SDL_CreateRGBSurface, для 32 бит для LITTLE_ENDIAN платформы,
определяет rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000;
точно так же по аналогии можно определить для оставшихся два варианта:
RGBA32: rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; RGBA24: rmask = 0x0000003f; gmask = 0x00000fс0; bmask = 0x0003f000; amask = 0x00fc0000; RGBA16: rmask = 0x0000000f; gmask = 0x000000f0; bmask = 0x00000f00; amask = 0x0000f000;
Кому не совсем понятно (особенно для 24 бит) просто переведите в двоичную систему.
Простой вариант операций SDL_Blit, для surface: RGB -> RGB, RGBA -> RGBA работает без нареканий.
Более сложный вариант SDL_Blit, для surface: RGB -> RGBA, RGBA -> RGB работает корректно, только для 32 бит цветности.
Для 16 бит, и 24 бита результат не предсказуем, тестировал и SDL-1.3 все тоже самое.