15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Страница была взята с http://www.chat.ru/~kindelk/

Эта страничка посвящена программированию 3D графики под DirectX на Microsoft Visual C++.
Если ты хочешь забацать свою первую трехмерную игрушку, но не знаешь с чего начать, то ты попал по назначению.
Что тебе понадобится ? Microsoft Visual C++ 6.0 (на счет более ранних версий - неуверен).
DirectX SDK - это набор библиотек для программирования DirectX.   Обычно эти библиотеки содержатся в MVC++, но если вдруг, по какой-либо причине, они отсутствуют - скачай DirectX 7 SDK (1Mb) .Еще пригодится переведенный стилусом ;) хэлп по DirectX 2. Лежит он тут (600 Kb) . Вообще, желательна хоть какая-нибудь документация по функциям DirectX. Ну вот пожалуй и все, что тебе нужно ....

И еще, если ты продвинутый в плане программирования под DirectX человек, то советую уйти с этой страницы, потому как ничего нового для себя здесь не найдешь.... Страничка создавалась для полных чайников в этом деле.


Введение
Первая программа. MeshBuilder.
Наложение текстуры
Анимация
Морфинг
Продвинутые примеры

 

DirectX включает в себя несколько основных компонентов, которые лежат в основе программирования win32-игр и обеспечивают их быстродействие.
DirectDraw - позволяет управлять аппаратными средствами ЭВМ, обеспечивая прямой и быстрый доступ к видеопамяти.
DirectSound - программирование звука и его воспроизведение.
DirectPlay - модемная коммуникация и сетевые аспекты программирования игр.
Direct3D - включает в себя как высокоуровневый, так и низкоуровневый С-интерфейс, управляющий 3d-обьектами.
DirectInput - контроль за периферийными устройствами в твоей игре - джойстиком, мышью, клавиатурой.

Основной акцент я делаю на освещение Direct3D (Retained Mode).


И так, пускай для начала поставим себе цель просто вывести на экран примитивный объект. Давай загрузим   несложный примерчик. Скачай файл portal.zip . С него начинал и я. Проэкт этой демонстрационной програмки разбит по разделам:

dvizok.cpp - это основной модуль программы,
defines.h - здесь мы описываем переменные,
scenes.h - здесь производим инициализацию.
Прокомпилируем этот пример. Мы видим  изображение портала.

Давай разберемся как мы добились подобного результата. Я опущу рассказ об инициализации Direct3D, DirectDraw,DirectInput. А приступаю сразу к непосредственно к алгоритму программы. Откроем файл scenes.h Сначала мы создали 2 фрейма (один для будующей трехмерной модели, другой - для источника света). Фрейм - это что то наподобие системы координат. Каждый объект, будь то 3-х мерная модель или источник освещения, связывается с некоторым фреймом. Когда мы хотим переместить какой-нибудь объект или повернуть его - мы не будем вручную преобразовывать все точки этого объекта,мы всего лишь перенесем его систему координат (т.е. фрейм). Потом мы создали источники света (ведь как без света можно увидеть объект), устанавливили камеру,   загрузили модель из .X файла  и связали ее с системой координат. Вот впринципе и весь алгоритм программы. Файл .X мы загружаем в переменную типа DIRECT3DRMMESHBUILDER2. Объект данного типа включает в себя информацию о 3-х мерной моделе : список вершин (vertices),  граней (faces), нормалей к граням (normals) и т.д. ..X файлы - это майкрософтовский формат 3D файлов. В комплект поставки SDK входит конвертер 3DS файлов от 3D studio в формат .X. (conv3ds.exe), а при отсутсвии такового его ты можешь скачать здесь. Да, ксати, запускать этот конвертер желательно с ключом -t. Теперь берем какую-нибудь 3DS модель, ну например с http://www.3dcafe.com/ . Конвертируем его в .X файл и модель готова к употреблению. Иногда 3-х мерная модель слишком велика, тогда ее нужно сжимать методом DIRECT3DRMMESHBUILDER2.Scale. В общем случае загрузка объекта осуществляется следующим образом :

1. Создать фрейм (DIRECT3DRM.CreateFrame)
2. Инициализировать MeshBuilder  (DIRECT3DRM.CreateMeshBuilder)
3. Загрузить в MeshBuilder 3-x мерную модель (DIRECT3DRMMESHBUILDER2.Load)
4. Визуализировать нашу модель во фрейме (DIRECT3DRMFRAME2.AddVisual)

Теперь будем работать с фреймом (frame) или как мы его называли система координат. Можно поставить фрейм во вращение или просто перенести его на определенное расстояние и вообще много еще чего можно с ним сотворить. Подробнее читай об этом в хэлпе к Directx2, о котором я упоминал в самом начале рассказа. К примеру, давай поставим наш фрейм во вращение функцией

    lpWorldFrame->SetRotation(d3drm.scene, D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(-0.05));

Вставь эту строчку в модуле scenes.h где-нибудь после инициализации фрейма lpWorldFrame. Здесь фрейм вертится вокруг вектора (0,1,0)  на угол равный -0.05 радиан. Вектор (0,1,0) берется в системе координат d3drm.scene - т.е. в глобальной системе координат.


Теперь поговорим о текстурировании. Текстура - это обычная картинка в любом из графических форматов (мы используем файлы формата BMP). Текстурирование - это наложение текстуры на 3-х мерную модель. Загрузим следующий пример money.zip. Запускаем программу на выполнение.

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

1. Создать оберточную функцию (DIRECT3DRM.CreateWrap)
2. Загрузить текстуру в память (DIRECT3DRM.LoadTexture)
3. Связать 3-х мерную модель с текстурой (DIRECT3DRMMESHBUILDER2.SetTexture)
4. Разрешить перспективно-корректированое наложение текстуры  на модель           (DIRECT3DRMMESHBUILDER2.SetPerspective)
5. Приложить обертку к моделе (DIRECT3DRMWRAP.Apply)

Ну хорошо, загружать модели и налаживать на них текстуры ты научился. Теперь неплохо бы как-нибудь анимировать наши 3-х мерных модели, всмысле переместить их, повертеть, сжать и растянуть. В предидущих примерах мы вертели портал, могли бы его переместить. Предложу другой метод анимации с помощью объекта DIRECT3DRMANIMATION; Суть его состоит в следующем: мы всего лишь задаем в каком месте мы бы хотели видеть наш объект в определенный момент времени (задаем ключи), а объект DIRECT3DRMANIMATION уже сам равномерно интерполирует между соседними ключами текущее положение объекта. Вот например, в момент времени 0 мы задали положение фрейма (0,0,0) а в момент времени 100 мы задали ключ (10,-20,0). Значит в момент времени 20 мы получим следующие координаты фрейма (2,-4,0).

Подобный метод анимации используется в редакторах 3D Studio. Скачай пример animat.zip . Наша модель доллара  движется по траектории квадрата. Здесь я задал положение модели только в пяти точках. В действительности, несложно заметить, что модель движется по траетории эллипса, благодаря опции D3DRMANIMATION_SPLINEPOSITION, что дало нам возможность "срезать углы". Обрати внимание на файл dvizhok.cpp. Мы видим счетчик timeT, который и задает текущее время в анимации. В общем случае инициализация производится так :

1. Инициализировать анимацию (DIRECT3DRM.CreateAnimation)
2. Задать опции анимации (DIRECT3DRMANIMATION.SetOptions)
3. Связать анимацию со фреймом (DIRECT3DRMANIMATION.SetFrame)
4. Добавить ключи анимации (DIRECT3DRMANIMATION.AddPositionKey)

Задание времени в анимации производится оператором DIRECT3DRMANIMATION.SetTime


 

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

Пускай у нас есть две 3-х мерные модели src1 и src2 типа DIRECT3DRMMESHBUILDER2. Мы хотим получить третий объект mesh того же типа, но полученный морфингом из src1 и src2. Введем переменную weight типа float и лежащую в диапазоне от 0 до 1. Эта переменная отвечает степень морфинга, т.е. насколько наша модель morph будет похожа на src1 и на src2. Например, при значении weight=0.5 наш морфированый объект будет являться чем-то средним между src1 и src2, а при weight=0.8 mesh будет слабо отличаться от src2, при weight равном нулю или единице mesh полностью морфируется в src1 или src2 соответственно. Введем также переменную antiweight=1-weight.

Пускай s1[n].x,s1[n].y,s1[n].z - координата n-ой вершины в объекте src1 , s2[n].x,s2[n].y,s2[n].z - координата n-ой вершины объекта src2 ,и, наконец m[n].x,m[n].y.m[n].z - координата n-ой вершины в объекте mesh. Тогда

m1[n].x=s1[n].x*weight+s2[n].x*antiweight

m1[n].y=s1[n].y*weight+s2[n].y*antiweight

m1[n].z=s1[n].z*weight+s2[n].z*antiweight

Вот и весь алгоритм. У тебя мог возникнуть вопрос, как же получить эту самую n-ую координату нашей модели. Нет ничего проще - используй функцию DIRECT3DRMMESHBUILDER2.GetVertices. Пример использования морфинга смотри в исходниках программы FISH, ссылку на которую ты найдешь ниже по странице.


 

Это , впринципе, и вся начальная информация, необходимая тебе для начала собственного проекта. Могу предложить несколько своих "проб пера". Загрузи файл fly.zip.

Вполне возможно, что ты не разберешься в алгоритме этой довольно-таки простой программы, но отсюда ты можешь черпнуть массу идей, которые пригодятся тебе в дальнейшем. Например, неплохо бы создать свой класс, состоящий из MeshBuilder-а, фрейма и анимации. Такой класс создал я, и благодаря ему за день написал скромную програмку, претендующую (только лишь претендующую) на звание скринсейвера fish.zip


В дальнейшем я собираюсь разобраться в наложении анимированных текстур. Т.е. налаживать AVI текстуру на модель объекта.  Благодаря этой технологии, например, наложены взрывы в игре DukeNukem. Также, собираюсь найти и выложить инфу о проигрывании MP3 файлов. Так что работа продвигается.... В заключение хочу сказать огромное спасибо Kozhukhov Denis, с сайта которого

Choсo Snow Creation   я любезно спиз.... ой.... слямзил, т.е. вытянул движок, ставший основой всех моих DirectX приложений.


Вытянуть полную заархивированую версию этой страницы можно здесь book.zip (3.2 Mb)

По любым вопросам и замечаниям пиши slimdoggy@hotmail.com

Потеряный Лось. Днепропетровск 2000.