- •Введение
- •Глава 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
- •Предметный указатель
Использованиечастицванимации
// Увеличить количество вершин и очистить буфер, если он заполнен Num++;
if(Num >= NumParticles) {
//разблокировать буфер и визуализировать полигоны pVB->Unlock(); ppDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, \
0, 0, Num*4, 0, Num*2);
//Еще раз блокировать буфер вершин
pVB->Lock(0, 0, (void**)&Ptr, D3DLOCK_DISCARD);
// Обнулить количество вершин Num=0;
}
// Перейти к следующей частице Particle = Particle->m_Next;
}
После того как вы просмотрели все частицы, необходимо последний раз разблокировать буфер вершин. Если в нем все еще находятся вершины, необходимо визуализировать их.
//Разблокировать буфер вершин pVB->Unlock();
//Визуализировать полигоны, если они остались if(Num)
pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, \ 0, 0, Num*4, 0, Num*2);
}
Вот и весь эффективный способ визуализации неограниченного количества частиц при помощи маленького буфера вершин! А теперь давайте объединим все рассмотренное ранее и создадим пару классов, которые помогали бы полностью управлять частицами.
Управление частицами с помощью класса
Ранее в этой главе, в разделе "Оживление частиц", вы видели, как создавать класс, содержащий данные частицы. Этот класс, cParticle, является великолепной отправной точкой для создания пары вспомогательных классов. На самом деле необходимо создать по крайне мере два класса. Класс cParticle содержит информацию об одной частице, такую как положение, размер и тип. В этом классе нет ничего такого, за исключением того, что мы хотим хранить в нем данные и указатели на связанный список частиц.
366
Второй класс отвечает за весь список частиц и управляет их созданием и уничтожением во времени. Это позволяет визуализировать все частицы, содержащиеся в связанном списке этого класса. Этот тип класса называется излучателем частиц, потому что он ответственен за излучение частиц. Я определил один из классов излучения так:
class cParticleErnitter
{
protected:
IDirect3DDevice9 *m_pDevice; // Родительское 3-D устройство
//Тип излучателя DWORD m_EmitterType;
//Буферы вершин и индексов, содержащих вершины IDirect3DVertexBuffer9 *m_VB; IDirect3DIndexBuffer9 *m_IB;
//Максимальное количество частиц в буфере DWORD m_NumParticles;
//Расположение излучателя (в трехмерном пространстве) D3DXVECTOR3 m_vecPosition;
//Корневой объект связанного списка частиц
cParticle *m_Particles;
// Количество ссылок класса static DWORD m_RefCount;
static IDirect3DVertexShader9 *m_pShader; // Вершинный шейдер static IDirect3DVertexDeclaration9 *m_pDecl; // Объявление вершин static IDirect3DTexture9 **m_pTextures; // Текстуры
public:
cParticleEmitter();
~cParticleEmitter();
BOOL Create(IDirect3DDevice9 *pDevice, D3DXVECTOR3 *vecPosition,
DWORD EmitterType,
DWORD NumParticlesPerBuffer = 32); void Free();
void Add(DWORD Type, D3DXVECTOR3 *vecPos, float Size, DWORD Color, DWORD Life,
D3DXVECTOR3 *vecVelocity); void ClearAll();
void Process(DWORD Elapsed);
// Функции, подготавливающие частицу к визуализации BOOL Begin(D3DXMATRIX *matView, D3DXMATRIX *matProj); void End();
void Render();
};
Использованиечастицванимации
Ничего себе - множество вопросов в которых надо разбираться! Давайте рассмотрим этот класс по частям, чтобы лучше понять, что он делает. Сначала имеется набор защищенных переменных. В каждом классе излучателя частиц содержится указатель на 3D устройство, буферы вершин и индексов, используемые для визуализации частиц.
Т. к. каждый излучатель предназначен для разных целей (один может излучать частицы огня, другой осколки), существует переменная типа частиц (m_EmitterType). Значение этой переменной зависит от типа используемых частиц. Для демонстрационной программы этой книги я использовал следующие типы излучателей частиц:
// Тип излучаемых частиц #define EMITTER_CLOUD 0 #define EMITTER_TREE 1 #define EMITTER_PEOPLE 2
В зависимости от типа излучаемых частиц вы передаете определяемое макросом значение, функции cParticleEmitter::Create и, кроме этого, используемый объект 3D устройства и количество частиц, которые могут находится в буфере вершин. Также необходимо указать в качестве параметра вектор, определяющий положение излучателя частиц в трехмерном мире.
Далее в списке защищенных переменных следует корневой объект частицы (m_Particles), который используется для хранения связанного списка частиц, создаваемых излучателем. Как вы можете видеть из объявления класса cParticleEmitter, существует только одна функция (Add), которая позволяет вам добавлять частицы
всцену. Чтобы добавить частицу, просто вызовете Add, указав тип частицы.
Ясоздавал типы частиц на основе используемых текстур. Например, я имею три текстуры для трех типов излучателей. Одна содержит изображение частицы огня, другая содержит изображения частицы дыма, и третья содержит изображение частицы вспышки. Тип частиц определяется так:
#define PARTICLE_FIRE 0 #define PARTICLE_SMOKE 1 #define PARTICLE_FLASH 2
Возвращаясь к функции Add, вы задаете положение (в мировом пространстве) в сцене добавляемой частицы. Каждая частица имеет собственную продолжительность жизни, цвет, размер и стартовую скорость, которые вы устанавливаете при вызове функции Add. Продолжительность жизни измеряется в миллисекундах, цвет измеряется значением D3DCOLOR, размер является вещественным значением,. а скорость - объектом D3DXVECTOR.
368 |
Глава 12 |
|
Обычно функция Add не используется напрямую для добавления частиц - это |
является задачей функции Update излучателя (хотя это не должно останавливать вас от использования Add, когда это необходимо). На самом деле функция Update служит двум целям: обновлять все частицы, содержащиеся в связанном списке, и определять, необходимо ли добавить еще частиц в связанный список.
Несколько указателей на объекты завершают список защищенных переменных. Этими указателями являются вершинный шейдер, объявление элементов вершин и массив текстур, используемый для визуализации частиц. Заметьте, что каждый из этих объектов является статическим, т. е. все экземпляры излучателей частиц разделяют их, что помогает сохранить память.
Количество ссылок, содержащихся в переменной m_RefCount, предназначено для слежения за тремя статическими объектами. Когда создается излучатель (с помощью вызова Create), количество ссылок увеличивается; когда излучатель уничтожается (вызовом Free или деструктором класса), количество ссылок уменьшается. Вершинный шейдер и текстуры загружаются при первом вызове инициализации излучателя (внутри функции Create); когда освобождается последний излучатель (количество ссылок равно 0), все объекты освобождаются.
Пока что я описал все, за исключением четырех функций - ClearAll, Begin, End и Render. Функция ClearAll очищает список частиц излучателя, предоставляя вам новый список. Вы можете вызвать эту функцию где угодно, чтобы заставить излучатель удалить все частицы.
Что касается функций Begin, End и Render, они используются совместно для визуализации частиц. Когда вы используете частицы, основанные на вершинном шейдере, должны быть некоторые состояния визуализации и другие настройки, которые одинаковы для всех излучателей. Вы можете сэкономить время, установив сначала эти данные, потом визуализировав частицы, после чего закончить, переустановив соответствующие состояния и данные визуализации. Этой цели и служат эти три функции.
В функции Begin, используемой для частиц, основанных на вершинных шейдерах, установите FVF в NULL, после чего установите используемые вершинный шейдер
иобъявление, сохраните транспонированное преобразование вид*проекция, сохраните векторы направлений вверх и вправо. После того как вы вызвали функцию Begin (которая в качестве параметров использует матрицы преобразования вида и проекции), вы можете вызывать функцию Render для визуализации частиц. Этот процесс одинаков для всех частиц, созданных из одного класса, т. к. используются одни и те же текстуры
ивершинный шейдер. Кактолько вы закончите визуализировать частицы, просто вызовете End для очистки вершинного шейдера и объявления.
Класс излучателя частиц по своей конструкции является очень простым: он просто хранит список частиц и визуализирует их. Для каждого кадра игры вызы-