В этой главе мы рассмотрим и решим все эти проблемы. Мы начнем с изучения форматов пикселей, а затем посмотрим, как написать код для работы с любыми типами поверхностей, независимо от глубины и формата пикселей. Затем мы изучим формат BMP-файлов, при этом основное внимание будет уделяться загрузке BMP-файла на поверхность. Главу завершает программа BmpView, предназначенная для просмотра графических файлов формата BMP (если вас интересует только процесс загрузки растровых изображений на поверхности, обращайтесь к заключительному разделу этой главы).
Глубина пикселей
Глубина пикселей показывает, сколько разных цветов может быть представлено одним пикселем поверхности. Глубина пикселей также влияет на объем памяти, необходимой для представления поверхности. В DirectDraw предусмотрена поддержка четырех глубин пикселей: 8-битных (палитровых), 16-битных (High Color), 24-битных и 32-битных (объединяемых термином True Color).
Для организации наиболее эффективного доступа к памяти поверхности необходимо знать глубину ее пикселей. Если вы собираетесь заблокировать поверхность и обратиться к ее памяти, нужно знать, как добраться до каждого отдельного пикселя, как назначить ему нужный цвет и как интерпретировать существующие цветовые данные. Начнем с 8-битных поверхностей.
Наверное, с 8-битными, или палитровыми, поверхностями работать проще всего, потому что каждый пиксель в них представляется одним байтом. Как вы вскоре убедитесь, это особенно упрощает интерпретацию BMP-файлов. Кроме того, каждый пиксель 8-битной поверхности просто соответствует целочисленному индексу палитры, а не закодированному цветовому значению. Впрочем, это достоинство отчасти компенсируется хлопотами по работе с палитрой.
Пиксели High Color (16-битные) выглядят несколько сложнее, однако результат часто оправдывает усилия. Простота использования, характерная для беспалитровых поверхностей, сочетается в них с умеренным расходом памяти (по сравнению с пикселями глубины True Color). Каждый пиксель High Color содержит не индекс, а цвет. Цвета выражаются в виде комбинации трех цветовых составляющих: красной, зеленой и синей (RGB).
Пиксели True Color делятся на две категории (24- и 32-битные), но в обоих случаях используются только 24 бита данных RGB. Лишние 8 бит 32-битных пикселей иногда используются для хранения альфа-канала (то есть данных о прозрачности пикселя). К сожалению, в DirectDraw все еще отсутствует возможность эмуляции альфа-наложения, так что лишние биты 32-битного пикселя часто пропадают впустую.
Разумеется, достоинства поверхностей True Color отчасти снижаются увеличенным расходом памяти. Сказанное поясняет рис. 5.1, на котором наглядно изображены глубины всех четырех вариантов пикселей.
Хотя рис. 5.1 не содержит никаких особых откровений, он позволяет понять, как представление пикселя в памяти зависит от его глубины. Кроме того, его общая структура будет использоваться в других рисунках данного раздела.
Рис. 5.1. Зависимость требований к памяти от глубины пикселей
Шаг поверхности Шагом поверхности называется объем памяти (в байтах), необходимой для представления горизонтальной строки пикселей. Шаг поверхности может совпадать с объемом памяти, необходимой для хранения горизонтальной строки пикселей, но часто оказывается больше.
Для примера возьмем 8-битную поверхность (поскольку один пиксель в таких поверхностях представляется одним байтом, что упрощает вычисления). Предположим, ваше видеоустройство требует, чтобы во внутреннем (для DirectDraw) представлении ширина поверхности была выровнена по границам параграфов (то есть была кратна 4 байтам). В этом случае поверхность с шириной в 10 пикселей будет иметь внутреннюю ширину в 12 байт. Если мы заблокируем эту поверхность и назначим значения пикселей, предполагая, что развертка одной горизонтальной строки занимает 10 байт, изображение получится перекошенным. Проблему можно легко решить, если вместо ширины при развертке поверхностей будет использоваться шаг. При этом независимо от внутренней ширины поверхностей, используемой DirectDraw, вычисление адресов пикселей будет давать правильный результат. Ситуация поясняется на рис. 5.2.
Рис. 5.2. Небольшая 8-битная поверхность с разными значениями шага и ширины
Читать дальше