SDLСтатьи

SDL: alpha канал и все о нем

Автор:

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 все тоже самое.

sdl_aplha_test_16 | SDL: alpha канал и все о нем

16 бит

sdl_aplha_test_24 | SDL: alpha канал и все о нем

24 бит

sdl_aplha_test_32 | SDL: alpha канал и все о нем

32 бит

Мне же нужен был корректный 16 бит, и в итоге, пришлось напрячься и родить тест, в котором также есть и реализация альтернативного SDL_Blit, который корректно отрабатывает 16 и 24 бит.

sdl_aplha_test

На дворе уже SDL-2.0 что там пока не знаю.

#sdl

4 мая 2012