Приложение MFC D3D: руководство по Direct3D часть I - Класс перечисления
ОГЛАВЛЕНИЕ
Класс перечисления
Давайте взглянем на класс перечисления: он устанавливает ограничения приложения на разрешение, цвет, альфа, форматы отображения, форматы буфера невидимых поверхностей, форматы буфера глубины/трафарета, типы множественной выборки, интервалы воспроизведения, использование буфера глубины и использование смешанной (аппаратной и программной) VP. Слишком страшно? Не беспокойтесь: я тщательно разберу значение каждого из них в умеренном темпе. Сейчас вы должны понять, что класс перечисления хранит требования приложения, относящиеся к устройству D3D.
//----------------------------------------------------------
// класс CXD3DEnum: перечисляет адаптеры, устройства D3D и т.д.
//----------------------------------------------------------
class CXD3DEnum
{
...
// ограничения приложения
bool AppUsesMixedVP; // может ли приложение использовать
// смешанный тип обработки вершин
UINT AppMinFullscreenWidth; // минимальная ширина приложения в полноэкранном режиме
UINT AppMinFullscreenHeight; // минимальная высота приложения в полноэкранном режиме
UINT AppMinRGBBits; // минимальное количество красных, жёлтых, зеленых битов на /
/каждый канал
UINT AppMinAlphaBits; // минимальное количество альфа битов на каждый пиксель
bool AppUsesDepthBuffer; // использует ли приложение буфер глубины
UINT AppMinDepthBits; // минимальное количество битов глубины
UINT AppMinStencilBits; // минимальное количество битов трафарета
// списки допустимых ограничений приложения
DWORDARRAY AppDisplayFormats;
DWORDARRAY AppBackBufferFormats;
DWORDARRAY AppDepthStencilFormats;
DWORDARRAY AppMultiSamplingTypes;
// список перечисленных AdapterInfos
AdapterInfoArray AdapterInfos;
...
};
Помните, что главное в настройке и обеспечении готовности к работе Direct3D - перечислять, перечислять и снова перечислять. Мы начинаем с набора минимальных требований, чтобы все, что ниже их, отфильтровывалось. Это реализуется с помощью серии ограничений приложения, набора переменных с префиксом "App" в CXD3DEnum.
Первое ограничение, AppUsesMixedVP, позволяет среде разработки включать или выключать использование смешанной VP, хотя не во время выполнения. Смешанная VP упоминалась при рассмотрении устройств, поэтому вернитесь назад, если вы пропустили ее. Полноэкранные ширина и высота в пикселях, иначе называемые “разрешением режима дисплея”, ограничены. По умолчанию, минимум установлен в 640x480. Глубина бита цвета или количество битов, используемых для каждого цветового канала, и глубина альфа бита - т.е. уровень непрозрачности или прозрачности – также ограничены AppMinRGBBits и AppMinAlphaBits, соответственно. Каждое из остальных ограничений приложения заслуживает заголовка, а значит, они будут рассмотрены подробно.
Форматы отображения
Здесь есть нечто интересное. Количество битов для цвета и альфа, поддерживаемые конкретным устройством, образуют формат отображения. Класс перечисления хранит список форматов отображения в AppDisplayFormats, который по умолчанию содержит все возможные форматы, которые Direct3D может обработать:
D3DFMT_R5G6B5 // 16-битовый, 6 для зеленого
D3DFMT_X1R5G5B5 // 16-битовый, 5 на каждый канал
D3DFMT_A1R5G5B5 // 16-битовый, 1 для альфа
D3DFMT_X8R8G8B8 // 32-битовый, 8 на каждый канал
D3DFMT_A8R8G8B8 // 32-битовый, 8 для альфа
D3DFMT_A2R10G10B10 // 32-битовый, 2 для альфа
Как бесполезное упражнение, вы можете попытаться выяснить, сколько цветов каждый формат может породить. Заметьте, что добавленные в список форматы должны быть согласованы с AppMinRGBBits и AppMinAlphaBits, т.е. если ваше приложение требует 8-битового альфа, не стоит добавлять форматы меньше 8-битового альфа в список.
Замечание по спискам и перечислениям Direct3D
Форматы Direct3D определены в огромном перечислении в d3d9types.h по имени D3DFORMAT, принудительно приведенном к 32-битовому (DWORD) размеру, как и большинство перечислений Direct3D. DWORDARRAY – основанный на шаблоне массив значений DWORD, typedef для CTArray<DWORD>. Класс шаблона, CTArray, реализованный в tarray.h, работает как стандартный массив объектов любого типа - т.е. вы можете использовать оператор [] – но он инкапсулирует другие функции обработки массива, такие как Append(добавить в конец), Find(найти) и Sort(сортировать), и они убирают за собой. Класс CTArray заменяет стандартное использование средой разработки SDK класса CArrayList, включенный в dxutil.h/dxutil.cpp. Классы на основе шаблонов из библиотеки STL std::list или std::vector не применяются.
Буферы невидимых поверхностей
Буферизация невидимых поверхностей аналогична способу, с помощью которого вы можете сделать анимацию с помощью блокнота бумаги, именуемого переворачиванием (перелистыванием) страниц. На каждой странице художник немного изменяет рисунок, чтобы при быстром перелистывании страниц казалось, что рисунок движется.
Direct3D реализует данную функциональность с помощью цепочки свопинга. Цепочка свопинга – серия буферов Direct3D, которые переключаются на экране таким же образом, как художник перелистывает одну страницу за другой. Первый буфер называется кадровым буфером цвета. Приложения пишут в буферы за ним, т.е. в буферы невидимых поверхностей, и затем переключают кадровый буфер, чтобы один буфер невидимых поверхностей появился на экране. В то время как система выводит на экран изображение, ваша программа снова пишет в другой буфер невидимых поверхностей. Когда процесс выполняется непрерывно, он обеспечивает эффективный метод приведения изображения в движение.
Поэтому буфер невидимых поверхностей является невидимой поверхностью (т.е. блоком памяти), на которой могут быть нарисованы растровые и другие изображения. Это противоположно видимому кадровому буферу, отображающему видимое в текущий момент изображение. Цепочка свопинга – набор буферов, которые переставляются по очереди, чтобы создать анимацию с плавными переходами между кадрами. Буферы невидимых поверхностей также имеют формат цвета/альфа, и, по умолчанию, список перечисления хранит все возможные форматы, которые Direct3D определяет в AppBackBufferFormats, который продолжает такой же список форматов отображения.
Для приложений с оконным интерфейсом формат буфера невидимых поверхностей не обязан совпадать с форматом режима отображения, если аппаратное обеспечение поддерживает преобразование цветов, например, превращение X8R8G8B8 в R5G6B5. В этом случае среда выполнения позволит воспроизводить любой допустимый формат буфера невидимых поверхностей на любом формате рабочего стола. Исключение сделано для режимов 8 битов на пиксель (256 цветов), так как устройства, как правило, больше не работают в таких режимах, хотя 10 с лишним лет назад они применялись.
Полноэкранные приложения не могут выполнять преобразование цветов. Поэтому формат буфера невидимых поверхностей должен по всем параметрам совпадать с форматом отображения, за исключением битов альфа-канала. Причина состоит в том, что форматы отображения полноэкранных приложений не могут содержать альфа-канал, а буферы невидимых поверхностей могут. Поэтому если формат отображения - D3DFMT_X1R5G5B5, то допустимые форматы буфера невидимых поверхностей включают D3DFMT_X1R5G5B5 и D3DFMT_A1R5G5B5, но исключают D3DFMT_R5G6B5 (обратите внимание на 6-битовый зеленый). В целом, для приложений лучше отсутствие преобразования цветов и совпадение форматов буфера невидимых поверхностей и отображения.
Кстати, последний формат – 10 битов на канал – доступен, как формат отображения, только в полноэкранных режимах и на быстрых ПК с новейшими графическими платами. Можно мечтать, что через пару лет ПК, адаптеры дисплея и Direct3D все будут поддерживать 32-бит на канал в качестве формата отображения. Это будет нечто, выходящее за пределы истинной цветопередачи! Назовем это сверхистинной цветопередачей! Вернемся к реальности, хотя, вероятно, художники ILM и Dreamworks уже используют эти форматы ежедневно. Хватит говорить об этом.
Форматы буфера глубины/трафарета
Буфер глубины, часто называемый z-буфером, хранит данные о глубине (значения координаты z), используемые для определения того, как 3D объекты перекрывают друг друга. Обычно реализуемые аппаратным обеспечением, z-буферы решают проблему определения, какие элементы в сцене рисуются перед другими, чтобы они могли скрыть те, которые находятся позади них. Это экономит немалое время выполнения и объем памяти. Существуют также w-буферы, использующие однородные w-координаты из местоположения точки (x,y,z,w) в пространстве проекции. Однако они не поддерживаются столь широко в аппаратном обеспечении, как z-буферы, и вам придется совершенствовать свою алгебру матриц, чтобы использовать их.
Буфер трафарета сродни реальному трафарету, являющемуся вырезающей поверхностью, которая при накладывании ее поверх другой поверхности позволяет видеть некоторую ее часть через прорези или отверстия, но остальная ее часть при этом закрыта. В нашем контексте трафарет обычно используется для маскировки (скрытия) пикселей на изображении. Более распространенные визуальные эффекты, достигаемые с помощью трафаретов, называются переводные картинки и рисование контура. В Direct3D форматы буфера глубины и трафарета объединены в одну и ту же группу констант:
D3DFMT_D16 // 16-битовый z-буфер
D3DFMT_D15S1 // 16-битовый z-буфер, 1-битовый трафарет
D3DFMT_D24X8 // 32-битовый z-буфер, 24-битовая глубина
D3DFMT_D24S8 // 32-битовый z-буфер, 8-битовый трафарет
D3DFMT_D24X4S4 // 32-битовый z-буфер, 4-битовый трафарет
D3DFMT_D32 // 32-битовый z-буфер
Таким образом, комбинация формата глубины/трафарета и единственная функция перечисления. Список форматов глубины/трафарета класса перечисления, AppDepthStencilFormats, разрешает каждый из этих форматов по умолчанию. Как и в случае форматов отображения и буфера невидимых поверхностей, форматы глубины/трафарета должны соответствовать ограничениям AppMinDepthBits и AppMinStencilBits. Кроме того, можно вообще отключить использование буфера глубины путем установки AppUsesDepthBuffer в false(ложь).
Множественная выборка
Множественная выборка – метод, применяемый Direct3D для выполнения сглаживания (устранения зубчатости) всей сцены. То есть, уменьшение ступенчатости линий, которые должны быть ровными, тем самым стирая ребра каждого многоугольника в сцене. Множественная выборка уменьшает рельефность (отчетливость) таких артефактов путем взятия выборок соседних пикселей каждого ребра и создания плавного перехода цветов вокруг них. Это может использоваться вместе с множественными прогонами визуализации, изменяющими разные подгруппы выборки при каждом прогоне визуализации, чтобы воспроизвести такие спецэффекты, как размытие в движении, эффекты глубины резкости фокуса, размытие отражения, и т.д.
Типы множественной выборки Direct3D непосредственно показывают количество выборок, доступное для сглаживания всей сцены. Исключение - D3DMULTISAMPLE_NONMASKABLE (со значением 1), который скорее активирует уровень качества множественной выборки. Уровень качества, введенный в версии Direct3D 9.0, может использоваться для разложения на множители количества выборок и достижения определенного отношения визуального качества-к-производительности. Допустим, вы находите поддержку сглаживания для 6 выборок с 4 уровнями качества. Вы можете использовать и сравнить отношения 6/1, 6/2 и 6/3 для воспроизведения. Это означает, что итоговая глубина цвета (каждого канала RGB) будет разложена на столько множителей, и вы сможете определить, который из них обеспечивает наилучшее соотношение производительности и качества.
Класс перечисления добавляет все типы множественной выборки в соответствующий список, AppMultiSamplingTypes, по умолчанию.