Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Графика DirectX в Delphi - Михаил Краснов

Графика DirectX в Delphi - Михаил Краснов

Читать онлайн Графика DirectX в Delphi - Михаил Краснов

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 35 36 37 38 39 40 41 42 43 ... 69
Перейти на страницу:

Что вы узнали в этой главе

Для работы с видео имеется много способов, и, как всегда, нам пришлось выбирать из них работающие.

Кроме того, вы получили инструмент для создания собственных фильмов.

Глава 7 Обзор библиотеки Direct3D

Модуль DirectXGraphics

Тип TColor и цвет в Direct3 D

Примитивы

Точки

Режимы воспроизведения

Блоки установок

Окрашенные вершины

Отрезки

Треугольник

Полноэкранный режим

Что вы узнали в этой главе

С этой главы мы начнем переход к принципиально новой технологии программирования двумерной и трехмерной графики и рассмотрим основные понятия такого подхода.

Примеры к главе располагаются в каталоге ExamplesE7.

Модуль DirectXGraphics

Итак, приступаем к изучению части DirectX, связанной с трехмерной графикой, хотя наши первые построения будут выполняться на плоскости. Теперь большая часть изученного в предыдущих главах книги непосредственно нами использоваться не будет, но многие подходы, понятия и приемы, с которыми мы уже познакомились, перекликаются с новым материалом. Например, в наших проектах мы встретим знакомые понятия главного объекта и порождаемых его методами вспомогательных объектов, и последовательность выполняемых нами действий будет во многом родственна предыдущим примерам.

Начнем наш путь с простейшего примера, проекта каталога Ex01. Если DirectDraw было удобнее начинать изучать с полноэкранных приложений, то с Direct3D мы познакомимся на примерах оконных приложений. В первом проекте данной главы клиентская часть окна окрашивается синим цветом. Это минимальное приложение, использующее Direct3D. Окно непрерывно перерисовывается, а в его заголовке выводится значение FPS.

Вначале бегло посмотрим код, потом некоторые ключевые моменты обсудим подробнее.

Прежде всего, замечаем, что в списке uses модуля дописан модуль DirectXGraphics. Это базовый модуль, играющий для наших последующих примеров такую же роль, какую играл ранее модуль DirectDraw. В этом модуле содержится описание базовых интерфейсов, типов и констант.

Имя формы этого и последующих примеров я задал frmD3D.

В разделе private описания класса формы мною внесены следующие строки: FD3D IDIRECT3D8; // Главный объект

FD3DDevice IDIRECT3DDEVICE8; // Объект устройства

FActive BOOL; // Вспомогательный флаг

ThisTickCount DWORD; // Отсчет времени для подсчета FPS

LastTickCount DWORD;

function InitDSD : HRESULT; // Инициализация системы

function Render HRESULT; // Воспроизведение

procedure Cleanup; // Удаление объектов

procedure ErrorOut (const Caption : PChar; const hError : HRESULT);

Сообщение об ошибке выводится пока в отдельном окне, для оконных приложений здесь не должно возникать проблем:

procedure TfrmDSD.ErrorOut (const Caption : PChar;

const hError : HRESULT);

begin

FActive := False; // Остановить перерисовку окна

Cleanup; // Удалить все объекты

MessageBox (Handle, PChar(DXGErrorString (hError)), Caption, 0)

end;

Функция DXGErrorString возвращает описание ошибки, код которой передается в качестве аргумента. Эта функция представлена в модуле Directxcraphics.

В процедуре очистки памяти объекты высвобождаются знакомым нам способом:

procedure TfrmD3D.Cleanup;

begin

if Assigned (FDSDDevice) then begin

FD3DDevice._Release;

FD3DDevice := nil;

end;

if Assigned (FD3D) then begin

FD3D._Release;

FD3D := nil;

end;

end;

Данная процедура вызывается при выводе описания аварийной ситуации и при завершении работы приложения, в обработчике onDestroy окна.

Инициализация графической системы включает действия, смысл которых нам интуитивно понятен и без дополнительных комментариев:

Function TfrmD3D.InitD3D : HRESULT;

var

d3ddm : TD3DDISPLAYMODE; // Вспомогательные структуры

d3dpp : TD3DPRESENT_PARAMETERS;

hRet : HRESULT;

begin

FD3D := nil;

FD3DDevice := nil;

// Создаем главный объект

FD3D := Direct3DCreate8(D3D_SDK_VERSION);

if FD3D = nil then begin

Result := _FAIL;

Exit;

end;

// Получаем установки рабочего стола

hRet := FDSD.GetAdapterDisplayMode(D3DADAPTERJ3EFAULT, d3ddm);

if FAILED(hRet) then begin

Result := hRet;

Exit;

end;

// Заполняем структуру, задающую параметры работы

ZeroMemory(@d3dpp, SizeOf(d3dpp)); // Обнуляем поля

with d3dpp do begin

Windowed := True; // Используется оконный режим

SwapEffect := D3DSWAPEFFECT_DISCARD; // Режим переключения буферов

BackBufferFormat := d3ddm.Format; // Формат заднего буфера

end;

// Создаем вспомогательный объект, объект устройства

Result := FD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Handle,

D3DCREATE_SOFTWARE_VERTEXPROCESSING,

d3dpp, FD3DDevice);

end;

Главным интерфейсом является СОМ-объект класса IDIRECTSDS, методы которого позволяют получить доступ к функциям библиотеки. Главный объект создается первым, а уничтожается последним. Создается он с помощью функции Direct3DCreate8, единственным аргументом которой является константа, сообщающая системе, какая версия DirectX SDK использовалась при компиляции приложения.

Методы главного объекта позволяют узнать текущие установки видеосистемы, и следующим действием нашей программы служит вызов метода GetAdapterDisplayMode. Как правило, обязательным это действие является только для оконных приложений, поскольку такие установки требуются для задания параметров заднего буфера.

У метода GetAdapterDispiayMode два аргумента:

* константа, задающая адаптер, для которого запрашиваются установки; указатель на вспомогательную переменную, в которую помещается результат, являющийся описанием характеристик устройства.

Предопределенным значением первого аргумента пока может использоваться только D3DADAPTER_DEFAULT, нулевая константа, соответствующая первичному устройству. Для описания характеристик служит переменная типа TD3DDISPLAYMODE, запись:

TD3DDisplayMode = packed record

Width : Cardinal; // Ширина рабочего стола

Height : Cardinal; // Высота рабочего стола

RefreshRate : Cardinal; // Частота регенерации

Format : TD3DFormat; // Формат пиксела

end;

То есть, чтобы вывести текущую ширину рабочего стола, можно вставить такую строку:

ShowMessage (IntToStr (d3ddm.Width));

Значением частоты регенерации для основного устройства мы получим ноль.

Последний элемент записи позволяет узнать формат пиксела. Возможные значения этого поля перечислены в модуле DirectxGraphics. Все они начинаются на префикс "DЗDFМТ_". Констант довольно-таки много, я не стану детально рассматривать их все, только посмотрим, как можно идентифицировать две наиболее распространенных:

case d3ddm.Format of

D3DFMT_X8R8G8B8 : ShowMessage ('Формат пиксела: 32-битный RGB.');

D3DFMT_R5G6B5 : ShowMessage ('Формат пиксела: 16-битный 5-6-5.');

else ShowMessage ('Формат пиксела в списке отсутствует. ') ;

end;

Обратите внимание, что при цветовой палитре рабочего стола, меньшей 16 бит на пиксел, работа DirectSD невозможна.

На следующем шаге инициализации задаются параметры работы, заполняются поля структуры типа TDSDPRESENT^PARAMETERS. В этом примере я выполняю только минимальный набор обязательных действий.

Логическое значение поля windowed задает режим работы приложения: наше приложение должно работать в оконном режиме. В поле swapEffect заносится константа, задающая порядок работы с задним буфером. Я использую константу D3DSWAFEFFECT_DiscARD, соответствующую режиму, при котором DirectX не заботится о сохранности содержимого заднего буфера при циклическом переключении страниц. В поле BackBufferFormat помещается формат пиксела для заднего буфера. Именно здесь необходимы полученные на предыдущем шаге характеристики рабочего стола.

И после этого вызывается метод главного объекта createDevice, с помощью которого создается дочерний интерфейс типа IDIRECTSDDEVICES. Объект такого типа представляет собой непосредственно устройство вывода. Собственно, с помощью его методов и производятся воспроизведение и модификация изображения. У метода CreateDevice шесть аргументов. Первым является устройство вывода, используемая здесь константа нам уже знакома. Вторым аргументом передается константа, задающая тип воспроизведения: использовать или нет аппаратное ускорение. Указание в качестве аргумента константы D3DDEVTYPE_HAL соотвстствют первому случаю, второму - D3DDEVTYPE_REF. Еще одна возможная константа - D3DDEVTYPE_sw, предназначена для подключения встраиваемых модулей, зарегистрированных в DirectX.

На маломощных видеокартах даже в самых простых программах, использующих DirectSD, будет порождаться исключение. Вы можете предусмотреть обработку этого исключения, чтобы попытаться повторно инициализировать систему с параметром DSDDEVTYPE_REF. Тогда скорость работы будет настолько низкой, что вряд ли пользователи останутся удовлетворенными.

Третьим аргументом метода createDevice задается идентификатор окна, в котором осуществляется вывод, свойство Handle формы хранит значение этого идентификатора. Следующий параметр задает порядок работы с вершинами: обрабатываются математические операции центральным процессором либо ускорителем. Здесь мы будем использовать константу DSDCREATE SOFTWAREJ/ERTEXPROCESSING, чтобы наши профаммы работали на всех графических картах. Пятый, предпоследний, аргумент метода createDevice - переменная типа TDSDPRESENT^PARAMETERS, с помощью которой мы передаем заполненную нами ранее структуру. В ней же будут содержаться скорректированные системой значения устанавливаемого режима. Например, количество задних буферов в примере задается первоначально равным нулю, система скорректирует это значение при создании объекта устройства. Добавьте в код следующую строку:

1 ... 35 36 37 38 39 40 41 42 43 ... 69
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Графика DirectX в Delphi - Михаил Краснов.
Комментарии