- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Графика DirectX в Delphi - Михаил Краснов
Шрифт:
Интервал:
Закладка:
// Инициализация матрицы трансформаций сферы
matSphere := IdentityMatrix;
// Переносим сферу по оси Y
matSphere._42 := -0.5;
end;
Я ввел в сцену четыре источника света. Три точечных источника предназначены для освещения стен комнаты, конус и сфера освещаются направленным источником света:
procedure TfrmDSD.SetupLights,
var
LightO : TD3DLight8;
Lightl : TD3DLight8;
Light2 : TD3DLight8;
Light3 : TD3DLight8;
begin
ZeroMemory(@LightO, SizeOf(LightO));
with LightO do begin
Type := D3DLIGHT POINT;
Diffuse.r := 0.4; // Поскольку присутствует три источника,
Diffuse.g := 0.4; // их яркость задается небольшой
Diffuse.b := 0.4;
Specular := Diffuse;
Ambient := Diffuse;
Position := D3DVector(0.5, 0.75, 1.5);
AttenuationO := 1.0;
Attenuationl := 1.0;
Attenuation2 := 0.0;
Range := 2.56; end;
ZeroMemory(@Light1, SizeOf(Light1));
with Lightl do begin
_Type := D3DLIGHT_POINT;
Diffuse.r := 0.4;
Diffuse.g := 0.4;
Diffuse.b := 0.4;
Specular := Diffuse;
Ambient := Diffuse;
Position := D3DVector(0.5, 0.3, 0.3);
AttenuationO := 1.0;
Attenuationl := 1.0;
Attenuation2 := 0.0;
Range := 2.5;
end;
ZeroMemory(@Light2, SizeOf(Lightl));
with Light2 do begin
_Type := D3DLIGHT_POINT;
Diffuse.r := 0.4;
Diffuse.g := 0.4;
Diffuse.b := 0.4;
Specular := Diffuse;
Ambient := Diffuse;
Position := DSDVector(0.5, -0.3, 0.3);
AttenuationO := 1.0;
Attenuationl := 1.0;
Attenuation2 := 0.0;
Range := 2.5;
end;
// Один направленный источник света
Lights:=InitDirectionalLight(DSDVector(-0.5, -0.5, -1),
1.0, 1.0, 1.0, 0);
// Источники только инициализируются, но пока не включаются
with FDSDDevice do begin SetLight(0, LightO);
SetLight(1, Lightl);
SetLight(2, Light2);
SetLight(3, Light3);
end;
end;
При рисовании объектов включаем только определенные источники света:
procedure TfrmD3D.DrawScene;
begin
// Стены комнаты - 10 независимых треугольников
with FD3DDevice do begin
// Матрица идентичности возвращает в мировую систему координат
SetTransform(D3DTS_WORLD, IdentityMatrix);
SetMaterial(Materialwhite); // Стены из белого материала
LightEnable(0, True); // Работают только точечные источники
LightEnabled, True);
LightEnable (2, True);
LightEnable(3, False); // Направленный источник выключаем
DrawPrimitive(D3DPT_TRIANGLELIST, 0, 10);
end;
// Конус и сфера освещаются только направленным источником with FDSDDevice do begin
LightEnable(0, False);
LightEnabled, False);
LightEnable(2, False);
LightEnable(3, True);
SetMaterial(MaterialConus); // Синий материал конуса
SetTransform(D3DTS_WORLD, matCone); // Неизменное положение конуса
DrawPrimitive(D3DPTJTRIANGLEFAN, 30, 49); // Сам конус
DrawPrimitive(D3DPT_TRIANGLEFAN, 81, 49); // Основание конуса
end;
// Перемещаем сферу в новое положение
matSphere._41 := cos (Angle) / 2; // Меняем только два элемента
matSphere._43 := sin (Angle) / 2; // текущей матрицы трансформаций
// Вывод сферы; источник света - текущий, направленный
with FDSDDevice do begin
// Переносим систему координат
SetTransform(D3DTS_WORLD, matSphere);
SetMaterial(MaterialSphere) ;
DrawPrimitive(D3DPTJFRIANGLELIST, 30 + 51 + 51, 1200);
end;
end;
Обратите внимание, что среди задаваемых режимов воспроизведения появилось что-то новое для нас.
with FD3DDevice do begin
// Все вершины примитивов перечисляются по часовой стрелке
SetRenderState(D3DRS_CULLMODE, D3DCOLL_CCW);
SetRenderState(D3DRS_ZENABLE, D3DZBJTRUE);
SetRenderState(D3DRS_AMBIENT, S00202020);
SetRenderState{D3DRS_LIGHTING, Dword (True));
// Конус масштабируется, поэтому включаем пересчет нормалей
SetRenderState(D3DRS_NORMALIZENORMALS, DWORD (True));
end;
Включение режима DSDRS_AMBIENT равносильно включению дополнительного источника света, эмулирующего окружающую среду. Свет этого рассеянного источника излучается из всех направлений. Предназначен такой источник для передачи присутствия на сцене, в данном случае, воздуха, в котором лучи света рассеиваются во всех направлениях.
Записи, определяющие источник света и материал, содержат поля Diffuse, Ambient и specular. Первая структура соответствует диффузным свойствам объекта: для источника света это светофильтр, накладываемый на него; для материала это непосредственно цвет материала, та составляющая падающего света, которая не поглощается поверхностью. Это самая весомая составляющая получающегося цвета. Вторая, рассеянная составляющая проявляется в областях, примыкающих к области, на которую непосредственно падает свет. Используется она в комбинации с третьей, зеркальной составляющей для передачи таких свойств, как гладкость или матовость. Комбинируя значения этих составляющих, можно получать яркие или тусклые блики на поверхности объекта.
Разницы в том, задаются оптические свойства материала или источника, нет, но вы можете комбинировать свойства источника и материала для того, чтобы передать, что на сцене присутствуют, например, светящиеся объекты и объекты с обычными свойствами.
Проект из каталога Ех03 наглядно демонстрирует смысл атрибутов свойств материала и источника света. Это развитие примера с тором. Теперь мы можем произвольно задавать значения всех параметров (рис. 10.3).
При нажатии кнопок вызывается стандартный диалог задания цвета. Выбранный пользователем цвет устанавливается в качестве параметров источника света или материала. Обратите внимание, как подготавливается диалог:
procedure TfrmD3D.Button2Click(Sender: TObject);
begin
// Предоставляем пользователю увидеть установленный диффузный цвет
ColorDialogl.Color :=
Round(MaterialTorus.Diffuse.R * 255) +
Round(MaterialTorus.Diffuse.G * 255 * $100) +
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;
Это очень важный момент, не упустите его.
Формат вершин включает в себя координаты, нормаль и цветовую составляющую:

