Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник по GLScene.doc
Скачиваний:
255
Добавлен:
16.12.2018
Размер:
7.18 Mб
Скачать

Глава 10. Использование 3d моделей.

I. Форматы моделей

Есть много распространенных форматов, в которых хранятся 3D модели. Как правило, эти модели - сложные объекты, которые тяжело смоделировать вручную примитивами. Поэтому 3D редакторы предлагают множество решений, как сделать их создание наиболее интуитивно понятным и совершенным. Например Autodesk в 3DS MAX предлагает ипользовать модификаторы и разбивку модели на полигоны/сплайны/патч-поверхности./NURBS-поверхности. Кроме того ещё одним преимущество моделей в том, что их можно использовать не только в одном движке а во многих, поддерживающих заданный формат.

Некоторые гейм-мейкерские компании зачастую создают свой формат и таких форматов очень много. Например, компания Valve, создавая Half-Life, начала использовать собственный формат Valve SMD, который является очень удобным и его часто используют в GLScene.

3D Studio Max - очень нужная каждому гейммейкеру программа (рис 1), по ней достаточно много хороших учебников и по сей причине мы не будем останавливаться на том, как пользоваться 3D Studio. Следует только отметить, что после окончания создания модели её нужно экспортировать в специальный файл (для этого выберете в меню макса File->Export, снимите все галочки в выскочившем окошке и сохраните в файл с требуемым расширением).

рис 1

Чтобы работать с моделями из 3D Studio Max, нужно подключить модуль модуль, соответствующий расширению экспортированного файла. Какие именно модули, смотрите описание поддерживаемых форматов ниже. Учтите, GLScene поддерживает не все форматы 3D моделей, предлагаемые 3DS MAX и уж тем более не все существующие форматы.

Внизу записаны форматы, которые поддерживает GLScene. Все они так же доступны на официальном англоязычном сайте сцены www.GLScene.org по адресу http://glscene.sourceforge.net/wikka/GlsceneFaq#q_extra_003 (см. вверху).

Полностью доступные форматы

Необходимый модуль

Описание

3DS (3DStudio, and many others)

GLFile3DS

Файл .3ds состоит из последовательности чанков — фрагментов, содержащих либо данные, либо несколько вложенных чанков. Каждый чанк начинается со стандартного заголовка, в котором хранится тип чанка и его размер. Далее, каждый конкретный тип чанка имеет свою внутреннюю структуру. Обычно нужно прочитать лишь несколько нужных чанков, содержащих данные меши (вертексы, текстурныее координаты и индексы) и материалы; остальные чанки можно при этом пропускать.

MD2 (Quake2, анимация)

GLFileMD2

Имеет морфную анимацию, но выглядят модели с этим форматом "не ахти".

MD3 (Quake3, анимация)

GLFileMD3

Так же как и *.md2 имеет морфную анимацию, но по сравнению с последним может иметь больше полигонов.

OBJ (WaveFront, and many others)

GLFileOBJ

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

SMD (Half-Life, скелетная анимация)

GLFileSMD

Разработанный компонией Valve, формат является лучшим для использования в физически правильных приложениях.

NMF (файлы, содержащие карты нормалей, ATI панели инструментов)

GLFileNMF

GTS (GNU Triangulated Surface)

GLFileGTS

GL2 (Ghoul2, aka MDX)

GLFileGL2

OCT (FSRad)

GLFileOCT

Octree Format проекта RADIANCE, разрабатываемового при поддержки министерства энергетики США и поддержки со стороны Швейцарского федерального правительства. Вот официальный сайт RADIANCE http://radsite.lbl.gov/radiance/index.html.

Частично доступные форматы

Описание

BSP (Quake3 BSP)

GLBSP

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

PLY (Stanford)

GLFilePLY

Существуют модификации данного формата. Стандартный модуль будет работать только с самым простым вариантом.

LWO (LightWave)

GLFileLWO

MS3D (MilkShape)

GLFileMS3D

Данный формат использует редактор Milk Shape.

STL

GLFileSTL

TIN

GLFileTIN

Некий векторный файл.

II. GLActor

Для использования моделей игроков существует специальной компонент GLActor.

Вот пример загрузки модели из файла в компонент:

GLActor1.LoadFromFile('имя файла модели');

Наложение текстуры на модель:

GLActor1.Material.Texture.Enabled:=True;

GLActor1.Material.Texture.Image.LoadFromFile('имя файла текстуры');

А теперь немного практики по использованию 3D моделей. Создайте новый проект, поместите на форму GLScene, GLSceneViewer(установите его Allign в AllClient), GLCadencer. В свойстве GLCadencer-а scene выберете GLScene1. Создайте актера: Scene objects->Add object->Mesh objects->Actor. Создайте камеру GLCamera, которая будет смотреть на актёра (для этого в её свойстве TargetObject выберете GLActor1).Установите position равным (0,3,-1)-это отодвинет ёё (камеру) от актёра. В свойстве Camera объекта GLSceneViewer выберете GLCamera. Кроме того, создадим источник света (GLLightSourse) и установим position равным (2,2,2).

Создавать модели не обязательно, их можно найти в интернете (невсегда бесплатно). Мы сейчас не будем разрабатывать модель, а возьмём её из образцов GLScene. Зайдите в паку со сценой(GLScene) а потом в папки \Demos\media\. Там найдите файл waste.md2, копируем его в папку с нашем проектом, также скопируем оттуда файл waste.jpg - это одежда игрока, точнее, текстура которой покрывается модель, те, кто умеют рисовать могут подредактировать этот файл (только нужно учитывать что модель имеет не правильную форму и рисовать лучше по старой картинке). Мы используем файл с расширением md2, значит необходимо подключить модуль GLFileMD2. Текстура формата Jpeg, значит в uses надо добавить модуль Jpeg. Теперь в FormCreate напишем:

GLActor1.LoadFromFile('waste.md2'); GLActor1.Material.Texture.Image.LoadFromFile('waste.jpg'); //Загрузить текстуру GLActor1.Material.Texture.Disabled:=false; //Разрешить текстуру GLActor1.Scale.SetVector(0.04, 0.04, 0.04, 0); // Scale-это масштаб, и мы умножаем каждую его координату на 0.04 (при этом модель уменьшится в 25 раз) GLActor1.AnimationMode:=aamLoop; GLActor1.SwitchToAnimation('stand');

Последние две строчки задают анимацию. Модель может быть анимирована, тоесть сама делать движения, которые будут повторяться. Наша модель имеет несколько анимаций, названых определёнными именами, в данном случае мы включили анимацию 'stand' которая показывает, как модель стоит. Строка GLActor1.AnimationMode:=aamLoop; задаёт циклический тип анимации. Кстати, проигрывание анимации было бы не возможно без GLCadencer.

Теперь давайте сделаем так, чтоб при нажатии какой-нибудь клавиши мы видели анимацию бега модели. Для обработки нажатия клавиш знакомую нам используем функцию IsKeyDown(клавиша), которая возвращает значение True, если клавиша была нажата. Функция IsKeyDown находится в модуле GLKeyboard следовательно, его нужно добавить в Uses.Теперь в событии OnProgress Cadencer’а напишем:

PROCEDURE TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);

VAR s:string;

BEGIN

if IsKeyDown(VK_RETURN) then

begin

if GLActor1.CurrentAnimation<>'run' then

GLActor1.SwitchToAnimation('run'); // при нажатии на W играется анимация "бежать"

end

else

if GLActor1.CurrentAnimation<>'stand' then

GLActor1.SwitchToAnimation('stand'); // иначе играется анимация "стоять"

end;

Эта процедура немного сложна из-за проверок. Реализовать её можно по-разному, но эта версия будет наиболее понятной. Сначала проверяем, нажал ли игрок клавишу Enter. Если нажал, то проверяем какя сейчас проигрывается анимация: если та, что нам надо то нет смысла запускать её сначала, но если проигрывается другая анимация, то мы запускаем нужную методом GLActor1.SwitchToAnimation('run');

Таким же не хитрым образом поступаем и с анимацией стоять. Блок begin …end объяснит компилятору,

к какому then относится else. Всё готово запускаем проект и жмём Enter (рис. снизу).

Напоследок скажу, что для загрузки моделей формата .3ds GLActor использовать не рекомендуется, а вместо него нужно использовать TGLFile3DSActor, работа с которым описана ниже.

III. TGLFile3DSActor

Как уже отмечалось, GLActor не рекомендуется использовать с .3ds моделями. Для использования данного формата рекомендуется TGLFile3DSActor. Это наследник GLActor и создавать его можно только в режиме runtime. Для использования данного объекта нужно подключить модуль TGLFile3DSActor. Вот пример кода:

Var File3dsActor:TGLFile3DSActor;

procedure TForm1.FormCreate(Sender: TObject);

begin

File3dsActor := TGLFile3dsActor.CreateAsChild(GLScene1.Objects);

File3dsActor.LoadFromFile('a.3ds');

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

FreeAndNil(File3dsActor);

end;

IV. GLFreeForm

Кроме GLActor есть ещё один объект – GLFreeForm. Он предназначен для статичной геометрии (в отличие от Actor). Для загрузки моделей используйте те же функции что и для работы с GLActor. GLFreeForm поддерживает LightMaps (см. Глава 19.Тени > IV. Lightmap).

А теперь попробуем загрузить что-нибудь в GLFreeForm. Поместите на форму GLSceneViewer, GLScene1, создайте в последнем камеру и GLFreeForm. Поставьте камере значение 10. Не забывайте, что нужно подключить модуль, соответствующий выбранному вами расширению, для .obj это GLFileOBJ. Теперь в событие FormCreate формы будем грузить модель:

procedure TForm1.FormCreate(Sender: TObject);

begin

GLFreeForm.LoadFromFile(‘cube.obj’)

end;

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

Пожалуй одно из самых выжных свойств у GLFreeForm это osDirectDraw. Оно управляет включением (при значении True) или выключением использования дисплейных списков. Я рекомендую их всегда отключать. Стоит так же отметить, что Khronos Group (консорциум разработчиков OpenGL) собирается исключить дисплейные списки из OpenGL. Ещё одно свойство это FreeForm.MeshObjects.UseVBO, которое определяет, будут ли спользоваться вершинные массивы или нет. Я рекоминдую включать его всегда, за исключением случаев, когда вы загружаете во FreeForm модель формата 3DS.

Также важно знать, что объект поддерживает Ocree деревья. Построение этого дерева вызывается командой GLFreeForm.BuildOctree([TreeDepth:Integer = 3]). По сути, эта команда разбивает модель на кубы. На первом шаге мы получаем 8 кубов (отсюда и Octo-), на втором шаге разбиваем каждый из кубов еще на 8, тем самым получаем 64 пространственных куба. Для каждого куба хранятся координаты его вершин (по сути минимальные и максимальные координаты среди всех полигонов, попавших в этот куб). В дальнейшем, при проверке видимости или рейкаста, мы пропускаем те кубы (а соответственно и все полигоны, заключенные в них) которые целиком находятся в стороне от луча или вне видимости камеры, значительно увеличивая скорость отрисовки и трассировки, особенно больших объемов данных. И не забывайте, что обычным рейкастом здесь пользоваться не следует (скорость не повысится). Здесь нужно использовать GLFreeForm.OctreeRayCastIntersect(const rayStart, rayVector : TVector; intersectPoint : PVector = nil; intersectNormal : PVector = nil). Рекомендую посмотреть демки quadtreevisculling и OctreeDemo (из стандартной поставки сцены) и демку BSP-Culling (http://sourceforge.net/project/showfiles.php?group_id=29749&package_id=67801)

Но у GLFreeForm есть одно очень важное ограничение. Его не рекомендуется использовать для загрузки формата .3ds. Для этих целей следует использовать TGLFile3DsFreeForm, работа с которым рассматривается ниже.

V. GLFile3dsFreeForm

Если вы читали про GLFreeForm (см. выше), то обязаны были прочесть, что использовать его для загрузки .3ds моделей нежелательно. Дело в том, что могут появляться ошибки запуска на видеокартах ATI при компилировании проектов на некоторых версиях сцены. Специально для загрузки .3ds моделей был создан наследник GLFreeForm - GLFile3DsFreeForm. Для работы с ним необходимо подключить модуль GLFile3DSSceneObjects. Создать GLFile3DSSceneObjects можно только в режиме runtime. Вот пример:

Uses GLFile3DSSceneObjects;

Var FreeForm:TGLFile3DSFreeForm;

procedure TForm1.FormCreate(Sender: TObject);

begin

FreeForm := TGLFile3dsFreeForm.CreateAsChild(GLScene1.Objects);//Создаём TGLFile3dsFreeForm

FreeForm.LoadFromFile('a.3ds'); //Загружаем модель

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

FreeAndNil(FreeForm); //И не забывайте освобождать память

end;