Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DirectX. Продвинутая Анимация (2004) [rus].pdf
Скачиваний:
335
Добавлен:
16.08.2013
Размер:
8.39 Mб
Скачать

Использованиеанимированныхтекстур

При использовании анимации текстур вы работаете на уровне полигонов (изменяя источник изображения или координаты текстур, используемые многоугольником), а не с вершинами, как при обычной анимации. Для этой книги я выбрал две наиболее популярные на сегодняшний день технологии анимации: преобразование текстур и видео анимация текстур.

Давайте начнем с самой простой технологии и посмотрим, как можно использовать преобразования текстур в игровом проекте.

Работа с преобразованиями текстур

Одним из самых недооцениваемых (и, наверное, самых простых) способов анимации текстур является их преобразование. Совсем как преобразование мира изменяет координаты вершин модели перед ее визуализацией, преобразование текстур изменяет данные текстурных координат модели перед ее визуализацией.

Какая может быть польза от преобразований, текстур? Предположим, необходимо анимировать несколько полигонов. Например, вы хотите создать воду, падающую в виде водопада и медленно текущую по руслу. Возможно ли добиться такого эффекта, используя обычные преобразования вершин? Возможно, но это будет очень не просто, я уверяю вас.

Используя анимацию текстур, вы можете плавно перемещать текстуру воды по полигонам, создавая таким образом водопад и поток. Не изменяя меша, вы оживляете вашу сцену! Однако вы можете не ограничиваться перемещением текстур - вы можете также вращать их. Представьте текстуру воды, движущуюся и вращающуюся одновременно! Секрет использования преобразования текстур заключается в... преобразованиях.

Создание преобразования текстур

В отличие от трехмерных эквивалентов, преобразования текстур являются двухмерными и используют матрицы преобразования 3x3. Больше нет нужды перемещать по оси z и вращать по осям х и у. Остается перемещение по осям х/у (при этом ось у перевернута и направлена вниз) и вращение по оси z. Нe беспокойтесь, потому что этого будет достаточно!

Самое простое преобразование текстуры, которое может быть выполнено, - это перемещение. Перемещения текстур в Direct3D задаются значениями, находящимися в диапазоне от 0 до 1, совсем как в текстурных координатах. Например, если ваша текстура имеет размер 256 пикселей, и вы хотите переместить ее на 64 пикселя вправо, задайте значение перемещения равным 0.25 (четверть размера текстуры, или 64 пикселя).

424

Глава 14

По умолчанию текстуры облегают многоугольник при любом преобразовании. Это означает, что если переместить текстуру на 64 пикселя вправо, последние 64 колонки пикселей переместятся в левую сторону текстуры. Это облегание текстур нас полностью устраивает, поэтому будем его использовать.

Замечание. DirectX проверяет все значения, задаваемые к качестве перемещения текстур, чтобы они попадали в диапазон от 0 до 1, так что в этой части от вас не требуется никаких действий. Таким образом, вы можете все время увеличивать или уменьшать значения перемещения и быть уверенными, что они всегда будут лежать в диапазоне от 0 до 1.

Для упрощения вы можете использовать объекты матриц D3DX для создания преобразований текстур. Я знаю, я сказал, что преобразования текстур используют матрицу 3x3, но если вы ограничитесь использованием перемещения по осям х/у и вращением по оси z, вы можете с небольшими изменениями использовать матрицы D3DX 4x4, как показано в следующем разделе "Установка матриц преобразования текстур".

Имея возможность использовать матрицу D3DX, вы можете создать матрицу перемещения так:

// Прототип функции D3DXMatrixTranslation из DX SDK D3DXMATRIX *D3DXMatrixTranslation(D3DXMATRIX *pOut, FLOAT x, FLOAT у, FLOAT z);

D3DXMATRIX matTranslation;

 

D3DXMatrixTranslation(&matTranslation,

0.5f, 0.5f, 0.0f);

В этом коде приведен прототип D3DXMatrixTranslation, которая будет вами использоваться, и небольшая иллюстрация установки преобразования, перемещающего текстуру влево и вверх на половину ширины и высоты текстуры (в пикселях). Заметьте, что перемещение по z равно 0.0, каким оно и должно быть для всех преобразований текстур.

Вспомните, я говорил, что перемещение зависит от размера текстуры. Хотя задаваемые значения и представляют собой процентные соотношения размеров текстуры, на которые необходимо ее переместить (при этом 0 означает 0%, а 1.0 - 100%), если вам нужна абсолютная точность, необходимо работать с пикселями. Например, если вы применяете преобразования, приведенные выше (значение 0.5, которое означает половину размеров текстуры по осям х и у), для текстуры размером 256x128 она переместиться на 128 пикселей влево и 64 пикселя вправо. Если вы запомните принцип работы значений перемещения, то все будет нормально.

Использованиеанимированныхтекстур

Для вращательных преобразований текстуры вы можете использовать функцию D3DXMatrixRotationZ. Помните, что текстуры могут вращаться только относительно оси z. As long as you keep to the z-axis, вы можете использовать матрицу 4x4. Вот пример использования функции D3DXMatrixRotationZ для вращения текстуры на 1.57 радиан.

// Прототип функции D3DXMatrixRotationZ

D3DXMATRIX *D3DXMatrixRotationZ(D3DXMATRIX *pOut, FLOAT Angle);

D3DXMATRIX matRotation;

D3DXMatrixRotationZ(&matRotation, 1.57f);

Вращение происходит относительно центра координат текстуры, который находится в ее левом верхнем углу. Если вы хотите повернуть текстуру относительно другой точки, необходимо преобразовать текстуру, повернуть ее и снова преобразовать в начальное положение. Вот пример вращения текстуры относительно ее центра на 0.47 радиан:

D3DXMATRIX matTrans1, matTrans2, matRotation; D3DXMatrixTranslation(&matTrans1, -0.5f, -0.5f, 0.0f); D3DXMatrixTranslation(&matTrans2, 0.5f, 0.5f, 0.0f); D3DXMatrixRotationZ(&matRotation, 0.47f);

// Скомбинировать матрицы в одно преобразование D3DXMATRIX matTransformation;

matTransformation = matTrans1 * matRotation * matTrans2;

Каквы можете видеть из кодапримера, возможно комбинироватьлюбое число матриц для получения результирующей матрицы преобразования. После того как вы получили ее, необходимо передать ее Direct3D и визуализировать текстуру.

Установка матриц преобразования текстуры

После того как вы получили корректную матрицу D3DXMATRIX, содержащую все преобразования, вы можете визуализировать преобразованную текстуру. Однако сначала необходимо преобразовать матрицу 4x4 в матрицу 3x3, которая используется Direct3D для преобразования текстур. Это может сделать небольшая функция, как например эта:

void Matrix4x4To3x3(D3DXMATRIX *matOut, D3DXMATRIX *matIn)

{

matOut->_11 = matIn->_11; // Скопировать первую строчку matOut->_12 = matIn->_12;

matOut->_13 = matIn->_13; matOut->_14 = 0.0f;

426

Глава 14

matOut->_21 = matIn->_21; // Скопировать вторую строчку matOut->_22 = matIn->_22;

matOut->_23 = matIn->_23; matOut->_24 = 0.0f;

matOut->_31 = matIn->_41; // Скопировать нижнюю строчку, matOut->_32 = matIn->_42; // используемую для перемещения matOut->_33 = matIn->_43;

matOut->_34 = 0.0f;

mat0ut->_41 = 0.0f; // Очистить нижнюю строчку matOut->_42 = 0.0f;

matOut->_43 = 0.0f; matOut->_44 = 1.0f;

}

Вызов функции Matrix4x4To3x3 происходит так же просто, как и вызов любой функции D3DX для работы с матрицами. Все, что вам необходимо, это предоставить указатель на результирующую матрицу, как я сделал тут. (Заметьте, что исходная и результирующая матрицы могут быть одинаковыми.)

// Преобразовать матрицу в матрицу 3x3 Matrix4x4To3x3(&matTexture, &matTexture);

После того как вы задали в качестве параметра функции Matrix4x4To3x3 матрицу преобразования текстуры, вы можете установить результирующую матрицу 3x3 преобразования текстуры, используя функцию IDirect3DDevice9::SetTransform, установив флаг D3DTS_TEXTURE0.

// Установить преобразование в конвейер Direct3D pDevice->SetTransform(D3DTS_TEXTURE0, &matTexture);

На данный момент Direct3D почти готов к преобразованию текстур! Единственное, что осталось сделать, это сообщить Direct3D, что при вычислении преобразований используются двухмерные координаты текстуры. Вы можете сделать это следующим вызовом IDirect3DDevice9::SetTextureStageState:

pDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);

Вот теперь все готово! С этого момента к каждой визуализируемой текстуре (нулевого уровня) будет применяться преобразование. После того как вы обработаете все текстуры, вы можете отключить преобразования, вызвав SetTextureStageState, но на этот раз установив D3DTSS_TEXTURETRANSFORMFLAGS в D3DTTFF_DISABLE.

Соседние файлы в предмете Программирование на C++