Глава 19. Работа со шрифтами и вывод надписей 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Глава 19. Работа со шрифтами и вывод надписей



Вывод текста через компонент GLWindowsBitmapFont

 

Кидаем на форму элемент GLWindowsBitmapFont с вкладки GLScene, выбираем его свойство Ranges, появляется окошко, в котором нажимаем кнопку «Добавить». Затем в свойствах StartASCII и StopASCII выбираем, с какого до какого номера будут отображаться символы. Чтобы не было ошибки «Characters are too large or too many. Unable to create font texture.» в Windows Vista и выше, нужно указать от #32 до #151 и от #153 до #255 (с #32 по #127 номера идут символы, цифры и английский алфавит; с #128 по #255 дополнительный алфавит; символ #152 вызывает сбой). Чтобы использовались именно русские буквы, нужно в свойстве Charset установить RUSSIAN_CHARSET.

В инспекторе объектов сцены выберите GLHUDText (HUD objects — HUD text), задайте ему созданный шрифт в поле BitmapFont и в поле Text напишите нужный текст.

Чтобы надписи не перекрывались другими объектами, нужно делать их последним в иерархии объектов сцены.

 

 


Глава 20. Выделение объектов мышкой

 

Часто бывает нужно выбрать какой-нибудь объект на экране. Для этого можно использовать функцию GLSceneViewer1.Buffer.GetPickedObject(x, y), которая возвращает объект, находящийся на экране по координатам (x, y).

Пример выделения объекта мышкой:

procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject; Button:

TMouseButton; Shift: TShiftState; X, Y: Integer);

var

pick: TGLCustomSceneObject;

begin

pick:=(GLSceneViewer1.Buffer.GetPickedObject(x, y) as

TGLCustomSceneObject);

if pick<>nil then

pick.Material.FrontProperties.Emission.Color.SetColor(1,0,0,1);

end;

 

Здесь командой (GLSceneViewer1.Buffer.GetPickedObject(x, y) as TGLCustomSceneObject) выполняется преобразование типа выбранного объекта к базовому типу объектов GLScene. Затем проверяется, был ли выбран какой-либо объект, и если да, то он окрашивается в красный цвет.

Стандартные демки, демонстрирующая описанное, находятся в Demos\interface\fadingintf и Demos\movements\objmove.


Глава 21. Создание сцены в режиме runtime

 

Создавать объекты так же можно и в ходе выполнения программы. Каждый создаваемый объект в GLScene должен быть привязан к объекту более высокого уровня. Корневой объект самого высокого уровня — GLScene1.Objects (если сцены называется GLScene1). Таким образом, создание объекта принадлежащего корневому объекту будет выглядеть так:

var

Object1: TGLBaseSceneObject;

Object1:=TGLCube.CreateAsChild(GLScene1.Objects);

Обратите внимание, что переменная Object1 у нас универсальная, поэтому мы можем не меняя типа переменной присвоить ей любой объект (если он ещё не присвоен). А вот так будет выглядеть создание объекта дочернего к уже созданному:

var

GLSphere: TGLSphere;

GLSphere:=TGLSphere.CreateAsChild(Object1);

GLSphere.Position.SetPoint(0,0,1);

Чтобы обратиться к свойству дочернего объекта, можно написать <тип объекта>(Object2.Chidren[номер]).свойство, если типы разные может подойти TGLSceneObject или TGLBaseSceneObject. Созданные объекты нужно удалять с помощью метода Free или процедуры FreeAndNil. Всех наследников можно удалить, вызвав DeleteChildren.


 


Глава 22. Тени

ShadowPlane

 

GLShadowPlane (Special objects — Shadow plane) похож на обычный GLPlane. Его особенностью является то, что другие объекты могут отбрасывать на него тени.

Создадим примитивное приложение, использующее ShadowPlane. Создайте стандартное приложение и добавьте в сцену GLSphere (Position = (0; 1; -5)) и GLShadowPlane (Position = (0; -1; 0)). Источнику света установите Position = (0; 7; -5).

Теперь настроим наш GLShadowPlane. Свойству ShadowLight присвойте наш источник света, свойству ShadowingObject присваиваем объект, который будет отбрасывать тень (GLSphere). Также необходимо развернуть его (Direction = (0; 1; 0)) и увеличить (Width = Height = 20).

Всё! Запускаем и наслаждаемся тенями. Внизу расположена отлично иллюстрирующая картинка.

Если объектов, которые должны отбрасывать тень, много, то в свойство ShadowingObject следует поставить DummyCube со всеми этими объектами.

 

Неплохой пример можно посмотреть в стандартной папке Demos в specialsFX\shadowplane.

GLShadowVolume

 

Тени можно строить при помощи стандартного компонента GLScene GLShadowVolume (Special Objects — Shadow Volume). Алгоритм этого компонента используется в Doom 3 и в Chronicles of Riddick. Тени выглядят достаточно хорошо, но требуют немало ресурсов. Компонент весьма заморочен, но разобраться можно!

Ставим в сцену GLShadowVolume.

Все, на что будет падать тень, вставляем в него (то есть он должен стать их родителем).

Источник света добавляем в список Ligths (во время выполнения так: GLShadowVolume. Lights.AddCaster(obj)).

Добавляем все объекты, которые отбрасывают тень, в список Occluders
(во время выполнения так: GLShadowVolume1.Occluders.AddCaster(obj)).

Не забывайте всегда присваивать GLSceneViewer1.Buffer.ContextOptions:= [roStencilBuffer];

У камеры свойство ObjectStyle должно быть csInfinitePerspective, иначе возможны артефакты.

Стандартная демка лежит по адресу Demos\specialsFX\shadowvolumes.

В этой максимально упрощёной демке GLShadowVolume создаётся и настраивается runtime:

GLZShadows

 

GLZShadows обеспечивает хорошие, но никудышно реализованные тени (подобные были в SplinterCell 3). Он рендерит в текстуру вид с «точки зрения» источника света, а потом эту текстуру накидывает на объекты. Пример можно взять здесь: Demos\specialsFX\shadows.

Lightmap

 

Lightmap (лайтмап, лайтмэп, в переводе — карта освещения) — метод освещения пространства в 3D-приложениях, заключающийся в том, что создается текстура, содержащая информацию об освещённости трехмерных моделей.

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

Почти всегда карты освещения выравниваются с обычными текстурами полигонов, и каждый пиксель карты соответствует 4-32 текселам текстуры. Размеры карты определяются размерами минимального, ограничивающего полигон, прямоугольника, стороны которого параллельны текстурным векторам. Этот метод применяется для создания всего статического освещения сцены. Освещение генерируется для статической геометрии до начала цикла рендеринга, и во время рендеринга в основном не изменяется. На современном оборудовании реализация полностью динамического освещения с использованием карт освещения невозможна из-за большой ресурсоемкости процесса создания лайтмапов. Этот подход рассматривается как основа для большинства других алгоритмов отрисовка теней в реальном времени.

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

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

Итак, как же это вложить в GLScene? Ответ прост. Начнём!

Для удачного запуска проекта необходимо создать в папке, из которой запускается проект, файл House.3ds. В нём придётся провести некоторую подготовительную работу. Я использовал 3DS Max. Итак, нужно:

Создать модель.

Полигоны, которые имеют различные материалы, поместить в отдельные объекты.

Расставить источники света.

Всем объектам назначить материал.

С отдельных объектов нужно отрендерить карты освещения. Выберите в меню Render\Render to texture (или кнопка «0»), в открывшейся форме выбираем линейку Output, в ней кнопку Add, там выбираем Lightmap. Далее, если нужно, меняем настройки и жмём Render. Затем нужно расставить текстурные координаты, для этого нужно для определённой области сетки модели назначить модификатор UVW Map.

Склейте все отдельные объекты в один без изменения Material ID (кнопка Attach).

Вернитесь к назначенным материалам и в закладке Self-Illumination присвойте карты освещения.

А теперь в Delphi (после создания стандартного проекта с GLCadencer):

Выставим камере Position = (5; 5; 5);

Создадим GLFreeForm и назовём его map (наша карта);

Поместим на форму GLMaterialLibrary и назовём её Materials (будем грузить сюда материалы, на которых будет лежать тень).

Поместим ещё одну GLMaterialLibrary с именем LightMaps (будем грузить сюда текстуру с тенью, саму LightMap).

Теперь создадим в LightMaps материал и запишем в FormCreate следующий код:

Materials.TexturePaths:=ExtractFilePath(Paramstr(0));

LightMaps.TexturePaths:=ExtractFilePath(Paramstr(0));

Map.MaterialLibrary:=Materials; // Присваиваем материал

Map.LightmapLibrary:=LightMaps; // Присваиваем LightMap

Map.LoadFromFile('House.3DS');

 

with Materials.Materials.FindItemID(2) do begin

TextureScale.Scale(15); //Растягиваем текстуру

Material.Texture.TextureMode:=tmDecal;

end;

with Materials.Materials.FindItemID(1) do begin

TextureScale.Scale(6);

Material.Texture.TextureMode:=tmDecal;

end;

with Materials.Materials.FindItemID(0) do begin

TextureScale.Scale(2);

Material.Texture.TextureMode:=tmDecal;

end;

Map.Scale.Scale(0.02);

Всё! Можно запустить и посмотреть, что получилось! А готовый пример можно взять отсюда: http://www.glscene.ru/download.php?view.165.



Поделиться:


Последнее изменение этой страницы: 2016-04-19; просмотров: 391; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.224.44.108 (0.025 с.)