Графика для Windows средствами DirectDraw
Шрифт:
В этой главе мы рассмотрели две демонстрационные программы и воспользовались такими возможностями DirectDraw, как переключение видеорежимов и частот смены кадров, а также применили цветовые ключи. Для переключения видеорежимов и частот использовалась функция EnumDisplayModes интерфейса DirectDraw в сочетании с функцией SetDisplayMode, а для работы с цветовыми ключами — функции SetColorKey и BltFast интерфейса DirectDrawSurface. Вывод текста в программах осуществлялся с помощью функции GetDC интерфейса DirectDrawSurface и текстовых функций Win32.
В
Глава 5. Поверхности и форматы пикселей
Наверное, это самая важная глава во всей книге. Она посвящена поверхностям, а поверхности — главное, для чего создавалась библиотека DirectDraw. Поверхности DirectDraw позволяют хранить изображения, копировать и изменять их, переключать кадры и выводить графическую информацию на экран. Все интерфейсы DirectDraw в первую очередь ориентированы на работу с поверхностями. Интерфейс DirectDrawPalette облегчает интерпретацию палитровых поверхностей; интерфейс DirectDrawClipper определяет, какая часть (или части) поверхности будут копироваться при блиттинге; наконец, сам интерфейс DirectDraw обеспечивает основные средства для работы с поверхностями.
Поверхности
Поверхностью называется интерфейс, представляющий область памяти. Интерфейс DirectDrawSurface выполняет различные операции с этой памятью — размещение, копирование, переключение и освобождение. Интерфейс поверхностей позволяет написать практически любое графическое приложение.
Тем не менее следует заметить, что доступ к памяти поверхности должен предоставляться интерфейсом DirectDrawSurface; вы не сможете обратиться к поверхности никаким другим способом. Если учесть это обстоятельство, становится ясно, что интерфейс DirectDrawSurface должен быть быстрым и универсальным. К счастью, дело обстоит именно так.
Интерфейс DirectDrawSurface обеспечивает прямой доступ к памяти поверхности. Он предоставляет самые быстрые и гибкие средства для работы с поверхностями, потому что вы можете делать с памятью все, что захотите, и работа не замедляется никакими интерфейсами-посредниками. Более того, данные поверхности всегда организованы линейно, независимо от способа их хранения в видеоустройстве.
Несмотря на все преимущества прямого линейного доступа, при манипуляциях с поверхностями программист должен соблюдать осторожность. Например, чтобы получить указатель на память поверхности, ее необходимо предварительно заблокировать. Чаще всего такая блокировка заставляет DirectDraw временно отключать основные механизмы Windows. Если вы забудете разблокировать поверхность или ваша программа «зависнет» при заблокированной поверхности, скорее всего, придется перезагружать компьютер. Кроме того, для проверки правильности работы кода между вызовами Lock и Unlock нельзя пользоваться отладчиками.
Новые возможности DirectX 5
DirectX 5 позволяет указать DirectDraw, что во время блокировки поверхностей можно обойтись без остановки механизмов Windows. DirectDraw постарается заблокировать поверхность, но при этом обойтись без обычных проблем.
Эта новая возможность обеспечивается функцией Lock интерфейса DirectDrawSurface3, которой можно передать новый флаг DDLOCK_NOSYSLOCK.
Для прямого доступа к поверхности нужно знать формат ее пикселей. Этот формат определяет способ хранения цветовых данных каждого пикселя. Он может изменяться в зависимости от видеоустройства и даже от видеорежима. Форматы пикселей особенно сильно различаются для поверхностей High Color (16-битных).
При прямом доступе к памяти поверхности необходимо также знать значение шага поверхности (surface stride). Шагом называется объем памяти, необходимый для представления горизонтальной строки пикселей. С первого взгляда кажется, что шаг поверхности совпадает с ее шириной, но на самом деле это разные параметры. Шаг поверхности, как и формат пикселей, зависит от конкретного видеоустройства.
В этой главе мы рассмотрим и решим все эти проблемы. Мы начнем с изучения форматов пикселей, а затем посмотрим, как написать код для работы с любыми типами поверхностей, независимо от глубины и формата пикселей. Затем мы изучим формат 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, на котором наглядно изображены глубины всех четырех вариантов пикселей.