РАПИДОГРАФ ФИОЛЕТОВОГО КВАРЦА


Новости
Статьи
Файлы
О себе
Гостевая







BASS Photo Gallery Dumpy home page




E-mail

 

DirectX 8 - Урок 2. Использование матриц преобразований

Что такое матрицы преобразований и зачем они нужны ? Перед тем как разобраться с этим понятием, вспомним немного математику.

Пусть у нас имеется некая вершина v1 , которую мы хотим переместить в вершину v2, вращая ее против часовой стрелки на угол A.

Рисунок 1. Поворот вершины против часовой стрелки

Воспользовавшись простыми формулами, находим координаты точки v2:

x2 = x1*cos(A)
y2 = y1*sin(A) , где x1 и y1 - координаты точки v1

Зная правило умножения вектора на матрицу, мы можем записать наши формулы в более элегантном виде:

| x | | a11 a12 | = | x' |
| y | | a21 a22 |    | y' |

, где x' = x*a11 + y*a21
       y' = x*a12 + y*a22

подставив a11 = cos(A), a12 = 0, a21 = 0, a22 = sin(A), получим:

| x2 | = | x1 | | cos(A)   0 |
| y2 |    | y1 | | 0   sin(A) |

, где x2 = x1*cos(A)
       y2 = y1*sin(A)

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

M = | cos(A)   0 |
      | 0    sin(A) |

Когда вы работаете с 3-D графикой, вы можете преобразовывать любую вершину в другую, используя уже 4-х мерную матрицу.

Основные матричные преобразования - это перемещение, вращение и масштабирование. Следующая матрица перемещает вершину (x,y,z) в вершину (x',y',z') на расстояние Tx, Ty, Tz:

Для вращение вершины (x,y,z) вокруг произвольной координатной оси, используются следующие матрицы:

,вращение вокруг оси X

,вращение вокруг оси Y

,вращение вокруг оси Z

Для масштабирования вершины (x,y,z) на коэффициенты Sx,Sy,Sz, применяется следующая матрица:

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

W = M1*M2*M3

,где например M1 - матрица поворота вокруг оси X, M2 - матрица перемещения, M3 - матрица масштабирования. Тогда умножая любую вершину на матрицу W , мы получим три преобразования сразу.

Понятие матриц неразрывно связано с понятием геометрического конвейера Direct3D. Он состоит из трех матриц преобразования:

Рисунок 2. Геометрический конвейер Direct3D

Входными данными геометрического конвейера являются вершины, точнее их координаты ( Vertices - вершины ). Они последовательно преобразуются через три матрицы: World - мировую, View - видовую, Projection - проекционную. Потом все точки проходят отсечение - clipping ( т.е. отсекаются все точки, которые не будут видны на экране ), масштабируются и приводятся к экранным координатам - viewport scalling .

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

1. Мировое преобразование меняет локальные координаты модели, в мировые координаты.

2. Видовое преобразование, отражая расположение наблюдателя в мировом пространстве, преобразует точки в пространство камеры.

3. Проективное преобразование переносит координаты точек из пирамиды просмотра (viewing frustum) в кубоид, который потом и будет отражаться на экране.

Теперь плавно перейдем от теоретической части к практической. Возьмем за основу пример из первого нашего урока. Сперва напишем функцию, которая будет устанавливать матрицы преобразования геометрического конвейера Direct3D:

// Функция SetMatrices() устанавливает матрицы преобразований
void SetMatrices(void)
{
    D3DXMATRIX matWorld;
    D3DXMATRIX matView;
    D3DXMATRIX matProj;

    // Установка мировой матрицы
    D3DXMatrixRotationY(&matWorld,timeGetTime()/f);
    d3d_device->SetTransform(D3DTS_WORLD,&matWorld);
    // Установка видовой матрицы
    D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(f,f,-f),
                                &D3DXVECTOR3(f,f,f),
                                &D3DXVECTOR3(f,f,f)); 
    d3d_device->SetTransform(D3DTS_VIEW,&matView);
    // Установка проектной матрицы 
    D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,f,f,f); 
    d3d_device->SetTransform(D3DTS_PROJECTION,&matProj);
}

Немного изменим функцию прорисовки сцены, добавив в нее вызов предыдущей функции:

// Функция RenderDirect3D() прорисовывает сцену
void RenderDirect3D(void)
{
    // Очищение заднего буфера
    d3d_device->Clear(0,NULL,D3DCLEAR_TARGET,
                         D3DCOLOR_XRGB(0,0,0),f,0);

    // Начало прорисовки сцены
    d3d_device->BeginScene();

    // Установка матриц преобразований
    SetMatrices();

    // Прорисовка сцены 
    d3d_device->SetStreamSource(0,d3d_vb,sizeof(CUSTOMVERTEX)); 
    d3d_device->SetVertexShader(D3DFVF_CUSTOMVERTEX); 
    d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST,0,3);

    // Конец прорисовки сцены
    d3d_device->EndScene();
    d3d_device->Present(NULL,NULL,NULL,NULL);
}

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


Взято с DirectX Design

Все права проигнорированны © 2002, StasH
Сайт создан в системе uCoz