- •Введение
- •Глава 1. Подготовка к изучению книги
- •Установка DirectX SDK
- •Выбор отладочных или рабочих версий библиотек
- •Настройка вашего компилятора
- •Установка директорий DirectX SDK
- •Привязывание к библиотекам DirectX
- •Установка используемого по умолчанию состояния символа
- •Использование вспомогательного кода книги
- •Использование вспомогательных объектов
- •Проверка вспомогательных функций
- •Двигаясь дальше по книге
- •Глава 2. Синхронизация анимации и движения
- •Использование движения, синхронизированного по времени
- •Считывание времени в Windows
- •Анимирование с использованием временных меток
- •Перемещение, синхронизированное со временем
- •Движение вдоль траекторий
- •Создание анализатора маршрутов .X файла
- •Создание внутриигровых кинематографических последовательностей
- •Посмотрите демонстрационные программы
- •TimedAnim
- •TimedMovement
- •Route
- •Cinematic
- •Глава 3. Использование формата файла .X
- •Работа с .X шаблонами и объектами данных
- •Определение шаблонов
- •Работа со стандартными шаблонами DirectX
- •Открытие .X файла
- •Перечисление объектов данных
- •Получение данных объекта
- •Создание класса .X анализатора
- •Загрузка мешей с использованием D3DX
- •Загрузка мешей, используя анализатор .X
- •Загрузка скелетных мешей
- •Загрузка анимации из .X
- •Загрузка специализированных данных из .X
- •Посмотрите демонстрационные программы
- •ParseFrame
- •Глава 4. Работа со скелетной анимацией
- •Начало скелетной анимации
- •Использование структур скелетов и иерархий костей
- •Использование скелетной структуры и скелетного меша
- •Загрузка иерархий из .X
- •Изменение положения костей
- •Обновление иерархии
- •Работа со скелетными мешами
- •Загрузка скелетных мешей из .X
- •Создание контейнера вторичного меша
- •Сопоставление костей фреймам
- •Обновление скелетного меша
- •Визуализация скелетных мешей
- •Глава 5. Использование скелетной анимации, основанной на ключевых кадрах
- •Использование наборов скелетных анимаций, основанных на ключевых кадрах
- •Использование ключей при анимации
- •Работа с четырьмя типами ключей
- •Считывание данных анимации из .X файлов
- •Прикрепление анимации к костям
- •Обновление анимации
- •Посмотрите демонстрационные программы
- •Глава 6. Комбинирование скелетных анимаций
- •Комбинирование скелетных анимаций
- •Соединение преобразований
- •Улучшение объектов скелетной анимации
- •Посмотрите демонстрационные программы
- •Глава 7. Создание кукольной анимации
- •Работа с физикой твердого тела
- •Создание твердого тела
- •Расположение и ориентирование твердых тел
- •Обработка движения твердых тел
- •Использование сил для создания движения
- •Соединение твердых тел с помощью пружин
- •Обеспечение обнаружения столкновений и ответной реакции
- •Создание систем кукольной анимации
- •Определение состояния твердого тела
- •Хранение костей
- •Создание класса управления куклой
- •Создание данных костей
- •Вычисление ограничивающего параллелепипеда кости
- •Установка сил
- •Объединение костей
- •Обработка столкновений
- •Восстановление соединений костей
- •Перестроение иерархии
- •Посмотрите демонстрационные программы
- •Глава 8. Работа с морфирующей анимацией
- •Морфинг в действии
- •Определение исходного и целевого меша
- •Морфинг мешей
- •Создание морфированного меша при помощи обработки
- •Визуализация морфированных мешей
- •Расчленение наборов
- •Создание морфирующего вершинного шейдера
- •Посмотрите демонстрационные программы
- •Глава 9. Использование морфирующей анимации, основанной на ключевых кадрах
- •Использование наборов морфируемой анимации
- •Создание шаблонов .X для морфируемой анимации
- •Загрузка данных морфируемой анимации
- •Визуализации морфированного меша
- •Получение данных морфируемого меша из альтернативных источников
- •Посмотрите демонстрационные программы
- •Глава 10. Комбинирование морфированных анимаций
- •Комбинирование морфированных анимаций
- •Использование базового меша в комбинированных морфированных анимациях
- •Вычисление разностей
- •Комбинирование разностей
- •Создание вершинных шейдеров комбинированного морфирования
- •Использование вершинного шейдера морфируемого комбинирования
- •Посмотрите демонстрационные программы
- •Глава 11. Морфируемая лицевая анимация
- •Основы лицевой анимации
- •Использование комбинированного морфирования
- •Использования фонем для речи
- •Создание лицевых мешей
- •Создание базового меша
- •Создание выражений лица
- •Создание мешей визем
- •Создание анимационных последовательностей
- •Создание последовательностей фонем
- •Использование анализатора файлов .X для последовательностей
- •Проигрывание лицевых последовательностей со звуком
- •Использование DirectShow для звука
- •Синхронизация анимации со звуком
- •Зацикливание воспроизведения звуков
- •Посмотрите демонстрационные программы
- •Глава 12. Использование частиц в анимации
- •Работа с частицами
- •Основы
- •Рисование частиц с помощью квадратных полигонов
- •Работа с точечными спрайтами
- •Улучшения визуализации частиц при помощи вершинных шейдеров
- •Оживление частиц
- •Передвижение частиц при помощи скорости
- •Использование интеллекта при обработке
- •Создание и уничтожение частиц
- •Управление частицами с помощью класса
- •Использование излучателей в проектах
- •Создание движков частиц в вершинных шейдерах
- •Посмотрите демонстрационные программы
- •Глава 13. Имитирование одежды и анимация мешей мягких тел
- •Имитация одежды в ваших проектах
- •Получение данных одежды из мешей
- •Приложение сил для создания движения
- •Воссоздание и визуализация меша одежды
- •Восстановление исходного меша
- •Добавление дополнительных пружин
- •Загрузка данных масс и пружин из .X файла
- •Создание анализатора .X данных одежды
- •Работа с обнаружением столкновений и реакцией на них
- •Определение объектов столкновений
- •Обнаружение и реакция на столкновения
- •Создание класса меша одежды
- •Использование мешей мягких тел
- •Восстановление мешей мягких тел
- •Посмотрите демонстрационные программы
- •Глава 14. Использование анимированных текстур
- •Использование анимации текстур в ваших проектах
- •Работа с преобразованиями текстур
- •Создание преобразования текстур
- •Установка матриц преобразования текстуры
- •Использование преобразования текстур в проектах
- •Использование файлов видео в качестве текстур
- •Импорт видео при помощи DirectShow
- •Создание специализированного фильтра
- •Работа со специализированным фильтром
- •Создание менеджера анимированных текстур
- •Окончание современной анимации
- •Веб-сайты
- •Рекомендуемые книги
- •DirectX 9.0 SDK
- •GoldWave Demo
- •Paint Shop Pro Trial Version
- •TrueSpace Demo
- •Microsoft Agent and LISET
- •Предметный указатель
Использованиечастицванимации |
337 |
Возвращаясь к игре с монстрами, можно использовать частицы для представления маленьких машин, движущихся по улицам города. Простого текстурированного (с использование биллбординга) квадратного полигона будет достаточно для этих машин, а что если вместо этого использовался бы трехмерный меш? Он просто бы потребовал визуализации нескольких дополнительных многоугольников в каждом кадре, и, поверьте мне, эффект от этих маленьких машин, движущихся по городу, стоил бы дополнительного времени визуализации.
Хорошо, если не касаться визуализации мешей, то большая часть рисуемых частиц будет состоять из квадратных полигонов. Вы можете рисовать их различными способами, но в этой книге я покажу вам три. Первый метод рисования частиц, наверное, является самым простым, но как вы скоро увидите, он имеет свои недостатки.
Рисование частиц с помощью квадратных полигонов
Рисование частиц настолько же просто, насколько и рисование многоугольников, потому что частица - это просто меняющий размеры текстурированный квадратный полигон. На рис. 12.4 показан внешний вид двух треугольников, которые используются для создания частиц. На этом рисунке я показал частицу, имеющую размер 10 единиц.
Вершины
Полигоны
Рис. 12.4. Частица, имеющая размер 10 единиц, имеет протяженность 5 единиц в направлениях осей х и у
338 |
Глава 12 |
|
В дополнение к координатам вершин, используемым при рисовании частицы, |
необходима еще пара вещей. Во-первых, необходима текстура, используемая для улучшения внешнего вида частицы. Является ли эта текстура дымом, сгустком света или испуганным человеком, вам необходимо хранить картинку в объекте текстуры. Кроме текстур многоугольникам необходима информация о текстурных координатах для наложения текстуры на многоугольник.
Для упрощения, я буду использовать только одну текстуру для каждого типа частиц в этой главе. Другими словами, если имеются частицы дыма и огня, я загружу две текстуры. Любой экземпляр любой частицы будет использовать собственную текстуру при визуализации. Возможно вы захотите объединить все текстуры частиц в одну, для улучшения частиц.
Следующее, что вам необходимо для создания данных многоугольника частиц, это рассеянная (diffuse) составляющая цвета. Возможность изменять цвет частиц во время выполнения очень полезна, потому что изменения цвета могут представлять различные циклы жизни частиц. Например, огонь медленно охлаждается и меняет свой цвет по мере того, как он удаляется от источника тепла. Вместо использования множества текстур для представления различных уровней нагрева вы можете использовать одну и ту же текстуру и просто менять рассеянный цвет частицы.
Последнее, что вам нужно, это размер частицы. В общем, частицы могут иметь любой размер, от небольшого пятна пыли до метеора, крушащего Землю. Для определения размера частицы вам необходимо выбрать габариты частицы, используя те же мировые координаты, что используют трехмерные меши.
Предположим, вы хотите, чтобы частица была 20 единиц в ширину и 50 единиц в высоту. Этот размер применяется только к осям х и у (т. к. на самом деле частица является плоским объектом, который всегда направлен к смотрящему). При создании частицы ее центр располагается в начале координат мира. Используя размеры частицы, вы можете создать вершины, представляющие ее углы. Эти вершины располагаются, используя размеры частицы, деленные пополам, в качестве смещения. Например, частица размеров 20x50 лежит от-10 до 10 на оси х и от-25 до 25 на оси у.
Вот и все об этом, теперь вы должны располагать достаточным количеством информации, чтобы начать рисовать частицы! Подытожим: необходимо иметь размер и координаты вершин частицы (используя размер в качестве базы), текстурные координаты и рассеянную составляющую цвета для каждой вершины. Смелее, объедините все эти компоненты в одну структуру вершин, как я сделал тут:
typedef struct {
D3DXVECTOR3 vecPos; // Координаты вершины частицы D3DCOLOR Diffuse; // Рассеянный цвет
Использование частицванимации
float u, v; // Текстурные координаты } sVertex;
Не забудьте определять объявление FVF для только что созданной структуры.
#define VERTEXFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
Используя структуру вершин и FVF, вы можете создать небольшой буфер вершин, который содержал бы достаточно вершин для рисования одной частицы. Для частицы используются два треугольника, это означает, что потребуется создать шесть вершин (три для каждого треугольника). Используя полосу треугольников, можно сократить количество вершин до четырех.
Буфер вершин можно создать, используя следующий код:
IDirect3DVertexBuffer9 *pVB = NULL; pDevice->CreateVertexBuffer(4*sizeof(sVertex), \
D3DUSAGE_WRITEONLY, \ VERTEXFVF, D3DPOOL_DEFAULT, \ &pVB, NOLL);
После того как вы создали буфер вершин (он создается один раз в программе), вы можете заполнить его данными частицы. Предположим, вы хотите нарисовать частицу, имеющую размер 10 единиц (и в направлении оси х и в направлении оси у), используя всю поверхность текстуры, имеющую белый цвет. Для этого вам необходимо использовать следующий код:
//Size = размер частицы, в данном случае 10.0 float Size = 10.0;
//Получить размер,деленный пополам, для установки координат вершин float HalfSize = Size / 2.0f;
//Заблокировать буфер вершин и заполнить его данными вершин sVertex *Vertex = NULL;
pVB->Lock(0, 0, (void**)&Vertex, 0);
//Верхний левый угол, вершина номер 0
pVB[0].vecPos = D3DXVECTOR3(-Size, Size, 0.0f); pVB[0].Diffuse = D3DCOLOR_RGBA(255,255,255,255); pVB[0].u = 0.0f; pVB[0].v = 0.0f;
//Верхний правый угол, вершина номер 1 pVB[1].vecPos = D3DXVECTOR3(Size, Size, 0.0f); pVB[1].Diffuse = D3DCOLOR_RGBA(255,255,255,255) ; pVB[1].u = 1.0f; pVB[1].v = 0.0f;
//Нижний левый угол, вершина номер 2 pVB[2].vecPos = D3DXVECTOR3(-Size, -Size, 0.0f); pVB[2].Diffuse = D3DCOLOR_RGBA(255,255,255,255); pVB[2].u = 0.0f; pVB[2].v = 1.0f;
340 |
Глава 12 |
//Нижний правый угол, вершина номер 3 pVB[3].vecPos = D3DXVECTOR3(Size, -Size, 0.0f); pVB[3].Diffuse = D3DCOLOR_RGBA(255,255,255,255); pVB[3].u = 1.0f; pVB[3].v = 1.0f;
//Разблокировать буфер вершин
pVB->Unlock();
Теперь вершинный буфер готов к визуализации. Однако есть небольшая тонкость. Вы заметите, что координаты вершин располагают многоугольники в центре координат трехмерного мира, расширяясь в направлении осей х и у. Т. к. точка обзора может находится где угодно в мире, необходимо расположить многоугольники, используя преобразование мира перед визуализацией.
Также необходимо повернуть многоугольники таким образом, чтобы они были направлены на смотрящего, что, как вы помните, является целью биллбординга. Необходимо вычислить биллборд-преобразование, чтобы повернуть многоугольники
ксмотрящему. Используя это преобразование, вы добавляете координаты частицы
вместо, где она должны быть нарисована (в мировых координатах).
Предупреждение. Использование функции GetTransform для получения преобразования Direct3D сильно замедляетработу и не всегда возможно. Лучше всего хранить глобальныепреобразованиямира,видаипроекции,которыеможнопотомиспользовать.Однако покая последую плохим путем и буду использовать GetTransform вучебных целях.
Для создания биллборд-преобразования необходимо получить матрицу преобразования вида и вычислить обратную ей матрицу (таким образом меняя порядок содержащихся в ней преобразований на обратный), используя функцию D3DXMatrixInverse, как показано тут:
// Получить матрицу преобразования вида и обратить ее D3DXMATRIX matView;
pDevice->GetTransform(D3DTS_VIEW, &matView); D3DXMatrixInverse(&matView, NULL, &matView);
Использование обратного преобразования позволит вращать вершины частицы в направлении, обратном направлению вида, таким образом выравнивая координаты к смотрящему. После получения обратного преобразования вида необходимо непосредственно добавить координаты частицы для расположения ее в трехмерном мире. Вы можете сделать это, сохранив координаты х, у и z в элементах _41, _42 и_43 соответственно только что вычисленной обратной матрице преобразования и установив результирующую матрицу преобразования в качестве мирового преобразования.
Использованиечастицванимации
//Положим ParticleXPos,ParticleYPos и ParticleZPos содержат мировые
//координаты рисуемой частицы. Добавить координаты рисуемой частицы matView._41 = ParticleXPos;
matView._42 = ParticleYPos; matView._43 = ParticleZPos;
//Установить результирующую матрицу в качестве преобразования мира pDevice->SetTransform(D3DTS_WORLD, &matView);
После того как вы установили матрицу преобразования мира, можно визуализировать многоугольники. Для того чтобы частицы комбинировались со сценой, необходимо убедиться, что используется z-буфер и альфа-тестирование. Использование z-буфера позволяет убедиться, что частицы корректно отображаются в сцене, а альфа-тестирование позволяет убедиться в том, что прозрачные части текстуры частицы не рисуются (позволяя видеть оставшуюся геометрию через эти прозрачные части). Также вы можете включить альфа смешивание, если хотите создать некоторые эффекты смешивания цветов.
Пропустив установку z-буфера (вы должны были сделать ее ранее), вы можете включить альфа тестирование и альфа смешивание так:
// Включить альфа тестирование
pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); pDevice->SetRenderState(D3DRS_ALPHAREF, 0x08); pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
// Включить альфа смешивание (простого добавочного типа) pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);
Что касается альфа-тестирования, я выбрал использования правила сравнения больше или равно. Это означает, что если пиксели текстуры частицы имеют значение альфа большее или равное 8, то они визуализируются, в противном же случае они пропускаются. Использование альфа-тестирования означает необходимость использования функции D3DXCreateTextureFromFileEx для загрузки текстур, задав цветовой режим, использующий альфа каналы (такой как D3DFMT_A8R8G8B8), и цветовой ключ непрозрачного черного (D3DCOLOR_RGBA(0,0,0,255)), как показано в следующем кусочке кода:
D3DXCreateTextureFromFileEx(
pDevice,
"Particle.bmp",
D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX DEFAULT, D3DCOLOR_RGBA(0,0,0,255), NULL, NULL, &pTexture);