- •Введение
- •Глава 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
- •Предметный указатель
Использованиеанимированныхтекстур
параметра. Четвертую переменную msTimeout вы устанавливаете равной величине времени, равной задержке между проверкой на возникновение события, или вы можете установить 0, чтобы ждать бесконечно.
Единственное событие, которое вы хотим получить, это окончание видео, представленное макросом EC_COMPLETE. Нe надо бесконечно ждать события; вместо этого необходимо подождать несколько миллисекунд, а потом продолжать получать события, пока их не останется. Как узнать, что больше не осталось событий? Как только функция GetEvent вернет ошибку, можно смело полагать, что больше событий нет.
Вот пример кода, который циклически получает текущее событие из интерфейса событий медиа (останавливаясь, когда событий больше не осталось), и небольшой блок кода, обрабатывающий событие, - EC_COMPLETE.
// Обработать все ожидающиеся события long lEventCode, lParam1, lParam2; while(1) {
// Получить события и подождать миллисекунду if(FAILED(pMediaEvent->GetEvent(&lEventCode, &lParam1, &lParam2,
1)))
break;
//Обработать события окончания видео, вызвав специальную функцию if(lEventCode == EC_COMPLETE)
EndOfAnimation(); // Здесь может быть любая функция
//Освободить ресурсы события
pMediaEvent->FreeEventParams(lEventCode, lParam1, lParam2);
}
Хa! Я попытался обмануть вас, использовав вызов новой функции интерфейса ImediaEvent - FreeEventParams. Каждый раз, когда вы получаете события с помощью функции GetEvent, необходимо сопровождать их соответствующим вызовом FreeEventParams, чтобы объект события медиа мог освободить все ресурсы, используемые для события.
Вот и все. Теперь вы можете воспроизводить, останавливать, приостанавливать, продолжать и изменять положение воспроизведения видео текстуры, а также проверять завершение воспроизведения (по достижении которого вы можете начать воспроизведение заново или сделать что-либо другое).
Создание менеджера анимированных текстур
Не то чтобы использование анимированных текстур было сложным (с помощью этой книги конечно), но ваша жизнь могла бы стать намного проще, если бы вы потратили немного времени и создали менеджер, который бы управлял фильтрами
446 |
Глава 14 |
и текстурами. Я взял на себя смелость и объединил все, что было сказано о текстурах
вэтой главе, в один класс, который вы можете использовать в своих игровых проектах. Вы можете найти этот класс, названный cAnimationTexture, на компакт-диске,
вдиректории \BookCode\Chap14\TextureAnim\. Объявление класса выглядит так:
class cAnimatedTexture
{
protected:
IGraphBuilder *m_pGraph; // граф фильтра
IMediaControl *m_pMediaControl; // Управление проигрыванием IMediaPosition *m_pMediaPosition; // Управление положением IMediaEvent *m_pMediaEvent; // Управление событиями IDirect3DDevice9 *m_pD3DDevice; // 3D устройство IDirect3DTexture9 *m_pTexture; // Объект текстуры
public:
cAnimatedTexture();
~cAnimatedTexture();
//Загрузить и освободить объект анимированной текстуры BOOL Load(IDirect3DDevice9 *pDevice, char *Filename); BOOL Free();
//Обновить текстуру и проверить цикл
BOOL Update();
//Вызывается в конце анимации virtual BOOL EndOfAnimation();
//Функции проиграть и остановить BOOL Play();
BOOL Stop();
//Начать анимацию заново или перейти к заданному времени BOOL Restart() ;
BOOL GotoTime(REFTIME Time);
//Вернуть указатель на объект текстуры
IDirect3DTexture9 *GetTexture();
};
Большая часть членов класса cAnimatedTexture должна быть вам знакома. В нем содержаться обычные интерфейсы DirectShow, используемые для воспроизведения событий и информации о положении, пара объектов Direct3D, применяемые для указания на используемое 3D устройство, и объект поверхности текстуры, указывающий на поверхность текстуры фильтра.
Наряду с переменными, в классе определено 11 функций. Среди которых - конструктор и деструктор класса, которые инициализирует его переменные и освобождают используемые ресурсы соответственно. Далее идет функция Load, которая
448 |
Глава 14 |
Замечание.ПрииспользованиифильтровDirectShow,разработанныхвэтойглаве,необходимозадатьфлагD3DCREATE_MULTITHREADEDпривызовеIDirect3D9::CreateDevice. Это позволяет сообщить Direct3D, что используется многопотоковое приложение (в котором фильтры являются отдельными потоками), и позволяет получить доступ кфильтрамданныхповерхноститекстуры.Такженеобходимоиспользоватьмногопотоковыединамическиебиблиотеки(устанавливаемыевнастройкахкомпилятора).
Создание буфера вершин
Чтобы использовать анимированную текстуру, необходимо сначала наложить ее в качестве обычной текстуры на полигон (или набор полигонов). Чтобы продемонстрировать анимированную текстуру, создайте простой квадратный полигон помощью двух треугольников. Вы можете сделать это при помощи буфера вершин и четырех вершин (задав ленту треугольников1).
// pDevice = предварительно инициализированное устройство Direct3D typedef struct {
float x, у, z; // 3D координаты float u, v; // Текстурные координаты
} sVertex;
#define VERTEXFVF (D3DFVF_XYZ | D3DFVF_TEX1)
// определить данные |
прямоугольника (два треугольника в ленте) |
|||||
sVertex Verts[4] = { |
|
|
|
|
||
{ |
-128.0f, |
128.0f, |
0.0f, |
0.0f, |
0.0f |
}, |
{ |
128.0f, |
128.0f, |
0.0f, |
1.0f, |
0.0f |
}, |
{ |
-128.0f, |
-128.0f, 0.0f, 0.0f, 1.0f }, |
||||
{ 128.0f, -128.0f, 0.0f, 1.0f, 1.0f |
} |
|||||
}; |
|
|
|
|
|
|
//Создать буфер вершин IDirect3DVertexBuffer9 *pVertices; pDevice->CreateVertexBuffer(sizeof(Verts), \
D3DUSAGE_WRITEONLY, VERTEXFVF, \ D3DPOOL_MANAGED, &pVertices);
//Установить данные вершин
BYTE *VertPtr;
pVertices->Lock(0, 0, (BYTE**)&VertPtr, D3DLOCK_DISCARD); memcpy(VertPtr, Verts, sizeof(Verts)); pVertices->Unlock();
В этом коде создается буфер вершин, содержащий четыре вершины, которые расположены в strip треугольниках, образующих квадрат. Здесь используется обычный буфер вершин, содержащий координаты вершин и один набор текстурных координат.
1. Лента треугольников (triangle strip) - один из способов задания полигона. Более подробно смотри справку по DirectX SDK.
Использованиеанимированныхтекстур
После того как вы создали буфер вершин, пришло время загрузить анимированную текстуру.
Совет. Если вы используете двухмерное проигрывание видео (в противоположность визуализации текстуры на несколько полигонов), вы можете заменить непреобразованные трехмерные координаты на набор преобразованных двухмерных (задав флаг FVFD3DFVF_WYZRHW).
Загрузка анимированных текстур
Вы подготовили буфер вершин и, конечно же, файл анимированной текстуры. Все, что осталось сделать, - это загрузить текстуру и визуализировать сцену! Для этого примера унаследуйте от класса cAnimatedTexture класс, который бы циклически проигрывал видео, перегружая функцию EndOfAnimation так, чтобы она вызывала Reset при окончании видео. Вот унаследованный класс, который вы можете использовать:
class cAnimTexture : public cAnimatedTexture
{
public:
BOOL EndOfAnimation() { Restart(); return TRUE; }
};
Далее просто создайте экземпляр класса cAnimTexture и при помощи функции Load загрузите видео.
cAnimTexture *g_Texture = new cAnimTexture(); g_Texture->Load(pDevice, "Texture.avi");
На данный момент текстура загружена, и вы готовы к визуализации сцены.
Подготовка к визуализации
Пришло время подготовится визуализировать полигоны, использующие анимированную текстуру. Выполнить это можно с помощью обычного кода - ничего необычного здесь не происходит. Просто установите источник потока вершин, шейдер, материал и текстуру. Все правильно, вам просто необходимо установить поверхность текстуры, содержащей видео данные; DirectShow сделает все остальное!
Следующий кусочек кода взят из примера этой главы и используется для установки источника потока вершин, FVF шейдера, материала и текстуры:
pDevice->SetFVF(VERTEXFVF); pDevice->SetStreamSource(0, pVB, sizeof(sVertex)); pDevice->SetMaterial(&Material); pDevice->SetTexture(0, g_Texture->GetTexture());