24- и 32-битные пиксели, как и 16-битные, делятся на две разновидности: RGB и BGR. Следовательно, код для работы с пикселями True Color должен использовать сведения о формате, полученные от DirectDraw, и не делать никаких безусловных предположений.
Напоминаю, что альфа-байт в 32-битных пикселях часто остается неиспользованным. Если ваша программа не работает с альфа-данными, вы можете выбирать между 24- и 32-битным видеорежимами. Работа в 24-битном режиме экономит память.
Рис. 5.6. Типичные форматы пикселей True Color
Получение данных о формате пикселей
Сведения о формате пикселей поверхности можно получить функцией GetPixelFormat()интерфейса DirectDrawSurface, в которой для передачи данных используется структура DDPIXELFORMAT. Функция GetPixelFormat()применяется так:
DDPIXELFORMAT format;
ZeroMemory(&format, sizeof(format));
format.dwSize=sizeof(format);
surf->GetPixelFormat(&format);
Структура DDPIXELFORMATсодержит четыре поля, представляющих для нас интерес:
• dwRGBBitCount
• dwRBitMask
• dwGBitMask
• dwBBitMask
Поле dwRGBBitCountпоказывает глубину пикселей поверхности. Три оставшихся поля являются масками, определяющими, в каких битах пикселя хранятся данные красной, зеленой и синей составляющих. Например, типичные значения полей для поверхности High Color формата 5-6-5 приведены в табл. 5.1.
Три маски показывают, в каких позициях пикселя хранятся данные отдельных цветовых составляющих. С помощью этих масок можно корректно читать и записывать данные пикселя независимо от его формата.
Таблица 5.1. Типичные данные формата для 16-битных пикселей
Поле |
Значение |
Двоичное значение |
dwRGBBitCount |
16 |
(неважно) |
dwRBitMask |
63488 |
1111100000000000 |
dwGBitMask |
2016 |
0000011111100000 |
dwBBitMask |
31 |
0000000000011111 |
В приведенном ниже коде маски используются для вычисления двух величин: начальной позиции каждой цветовой составляющей внутри пикселя (бит, с которого начинается составляющая, или стартовый бит ), и количества бит для представления каждой цветовой составляющей. Значения этих величин приведены в табл. 5.2. Обратите внимание на то, что стартовый бит отсчитывается справа налево (старшие биты в двоичных величинах находятся слева).
Рассчитанные значения облегчают операции с пикселями. Стартовый бит показывает, на сколько позиций сдвигаются данные цветовой составляющей, а количество — сколько бит занимает составляющая в двоичной величине.
Таблица 5.2. Типичные данные формата для 16-битных пикселей
Поле |
Значение |
Двоичное значение |
Стартовый бит |
Количество бит |
dwRBitMask |
63488 |
1111100000000000 |
11 |
5 |
dwGBitMask |
2016 |
0000011111100000 |
5 |
6 |
dwBBitMask |
31 |
0000000000011111 |
0 |
5 |
Однако до сих пор мы рассматривали лишь 16-битные пиксели. 8-битные пиксели нас не интересуют, но перед тем, как идти дальше, необходимо уделить внимание пикселям формата True Color. В табл. 5.3 приведены данные формата пикселей (в том числе две вычисленные величины для каждой цветовой составляющей) для типичного 24-битного формата.
Таблица 5.3. Типичные данные формата для 24-битных пикселей
Поле |
Значение |
Двоичное значение |
Стартовый бит |
Количество бит |
dwRBitMask |
16711680 |
111111110000000000000000 |
16 |
8 |
dwGBitMask |
65280 |
000000001111111110000000 |
8 |
8 |
dwBBitMask |
255 |
000000000000000011111111 |
0 |
8 |
Помните — данные в этих таблицах относятся к конкретной аппаратуре. Они представлены лишь для примера того, как могут выглядеть такие данные, а не как исчерпывающее руководство по форматам пикселей.
Переменные формата пикселей в классе DirectDrawWin
При описании класса DirectDrawWinв главе 3 мы видели, что функция DirectDrawWin::ActivateDisplayMode()после активизации нового видеорежима, но до создания вспомогательных поверхностей приложения, вызывает функцию StorePixelFormatData(). Описание этой функции было отложено до настоящего момента.
Функция StorePixelFormatData()присваивает значения шести переменным класса DirectDrawWinв соответствии с форматом пикселей текущего активного видеорежима; эти переменные определяют стартовый бит и количество бит для каждой цветовой составляющей пикселя. В следующем разделе мы увидим, как эти переменные используются при манипуляциях с памятью поверхности. Функция StorePixelFormatData()выглядит так:
Читать дальше