Чтение онлайн

на главную - закладки

Жанры

Графика DirectX в Delphi

Краснов Михаил

Шрифт:

Round(MaterialTorus.Diffuse.В * 255 * $10000);

if ColorDialogl.Execute then

with MaterialTorus.Diffuse do begin

R := (ColorDialogl.Color and SFF) / 255;

G := ((ColorDialogl.Color and 3FFOO) shr 8) / 255;

В := ((ColorDialogl.Color and SFFOOOO) shr 16) / 255;

end;

end;

По умолчанию зеркальная составляющая в расчет не принимается, блики на поверхностях объектов не появляются. Чтобы учесть ее, надо включить режим D3DRS_SPECULARENABLE.

Я советую вам внимательно поработать

с этим примером. Для начала по отдельности включите одну из трех составляющих, чтобы увидеть, как они проявляются на поверхности объектов. Назначьте ей белый цвет, а всем остальным - черный, и посмотрите результат.

Этот пример может стать очень полезным в моменты, когда вам потребуется подобрать материал для построений. Ведь наверняка далеко не у каждого из вас под рукой окажется справочник оптических свойств материалов.

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

участки черного или очень темного цвета. Даже в таком случае, когда цвета объектов различаются кардинально, их очень тяжело отличать. Например, на поверхности объектов могут появляться блики одинакового цвета. А если на объекты накладывается текстура, или объекты покрашены одинаковым цветом, задача выбора по цвету становится неразрешимой. В случае DirectDraw мы решали подобную проблему использованием вспомогательной поверхности, на которой объекты раскрашивались по произвольной схеме, аналогичный метод можно применять и в Direct3D. Мы можем на вспомогательном, невидимом зрителю экране, повторить построения сцены, окрашивая объекты так, как нам удобно для их идентификации, и ориентироваться при выборе по значению пиксела в определенной точке этого экрана.

Вспомним, что нам системой предоставлены два экрана, передний и задний буферы, причем второй экран скрыт от зрителя до тех пор, пока не вызывается метод Present объекта устройства. Поэтому данным экраном мы можем воспользоваться для наших целей, осуществляя в него построения по нужной схеме, и не выкладывать его содержимое на передний экран. Система предоставляет нам доступ к содержимому заднего буфера, с помощью метода GetBackBuffer объекта устройства, результат помещается в объект типа IDirect3DSurface8.

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

Переходим к иллюстрации - проекту из каталога Ех04, где рисуется знакомая тестовая сцена, при щелчке кнопки мыши сообщается, какой объект находится под курсором (рис. 10.4).

Первым

делом обращаю ваше внимание на то, что при инициализации графической системы необходимо указать возможность запирания поверхности заднего буфера, для чего в поле Flags структуры ТD3DРRЕSЕNТ_РАРАМЕТЕRS не обходимо занести соответствующую константу:

ZeroMemory(@d3dpp, SizeOf(d3dpp));

with d3dpp do begin

Windowed := True;

SwapEffect := D3DSWAPEFFECT_DISCARD;

// Разрешаем запирание поверхности заднего буфера

Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

BackBufferFormat := d3ddm.Format;

EnableAutoDepthStencil := True;

AutoDepthStencilFormat := D3DFMT_D16;

end;

Это очень важный момент, не упустите его.

Формат вершин включает в себя координаты, нормаль и цветовую составляющую:

D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF_DIFFUSE;

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

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

with FDSDDevice do begin

SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

SetRenderState(D3DRS_AMBIENT, $00202020);

SetRenderState(D3DRS_LIGHTING, Dword (True));

SetRenderState(D3DRS_NORMALIZENORMALS, DWORD (True));

// Явно указываем использование материала

SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);

SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);

SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

end;

При движении курсора мыши по поверхности окна отслеживаются его координаты:

var

OX, OY : DWORD;

procedure TfrmD3D.FormMouseMove(Sender: TObject; Shift: TShiftState;

X, Y: Integer);

begin

OX := X;

OY := Y; end;

Вы можете оптимизировать часть кода, связанную с определением позиции, ведь для получения положение курсора в любой момент времени можно использовать функцию GetCursorPos.

Помимо функции Render, я ввел функцию укороченного воспроизведения, которая отображает сцену с измененными установками и не заканчивается переключением буферов:

function TfrmD3D.Draw : HRESULT;

var

hRet : HRESULT;

Поделиться:
Популярные книги

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9