Введение в программирование трехмерных игр с DX9

       

Матрицы в библиотеке DX



Матрицы в библиотеке D3DX

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

Умножение вектора-строки на матрицу. То есть, если v — это вектор-строка 1 × 4, а T — это матрица 4 × 4, произведение vT определено и представляет собой вектор-строку 1 × 4.

Умножение матрицы на матрицу. То есть, если T — это матрица 4 × 4 и R — это матрица 4 × 4, произведения TR и RT определены и оба являются матрицами 4 × 4. Обратите внимание, что произведение TR не обязательно равно RT, поскольку операция умножения матриц не коммутативна.

Для представления вектора-строки 1 × 4 в библиотеке D3DX, мы будем использовать классы векторов D3DXVECTOR3 и D3DXVECTOR4. Конечно, в классе D3DXVECTOR3 только три компоненты, а не четыре. Однако обычно подразумевается что четвертая компонента равна нулю или единице (более подробно это будет обсуждаться в следующем разделе).

Для представления матриц 4 × 4 в библиотеке D3DX, мы используем класс D3DXMATRIX, определение которого выглядит следующим образом:

typedef struct D3DXMATRIX : public D3DMATRIX { public: D3DXMATRIX() {}; D3DXMATRIX(CONST FLOAT*); D3DXMATRIX(CONST D3DMATRIX&); D3DXMATRIX(FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44);

// получение элемента FLOAT& operator () (UINT Row, UINT Col); FLOAT operator () (UINT Row, UINT Col) const;

// приведение типа operator FLOAT* (); operator CONST FLOAT* () const;

// операторы присваивания D3DXMATRIX& operator *= (CONST D3DXMATRIX&); D3DXMATRIX& operator += (CONST D3DXMATRIX&); D3DXMATRIX& operator -= (CONST D3DXMATRIX&); D3DXMATRIX& operator *= (FLOAT); D3DXMATRIX& operator /= (FLOAT);


// унарные операторы D3DXMATRIX operator + () const; D3DXMATRIX operator - () const;

// бинарные операторы D3DXMATRIX operator * (CONST D3DXMATRIX&) const; D3DXMATRIX operator + (CONST D3DXMATRIX&) const; D3DXMATRIX operator - (CONST D3DXMATRIX&) const; D3DXMATRIX operator * (FLOAT) const; D3DXMATRIX operator / (FLOAT) const;

friend D3DXMATRIX operator * (FLOAT, CONST D3DXMATRIX&);

BOOL operator == (CONST D3DXMATRIX&) const; BOOL operator != (CONST D3DXMATRIX&) const; } D3DXMATRIX, *LPD3DXMATRIX;

Класс D3DXMATRIX наследует элементы данных от простой структуры D3DMATRIX, определенной следующим образом:

typedef struct _D3DMATRIX { union { struct { float _11, _12, _13, _14; float _21, _22, _23, _24; float _31, _32, _33, _34; float _41, _42, _43, _44; }; float m[4][4]; }; } D3DMATRIX;

Обратите внимание, что в классе D3DXMATRIX есть десятки полезных операторов для проверки равенства, сложения и вычитания матриц, умножения матрицы на скаляр, преобразования типов и — самое главное — перемножения двух объектов типа D3DXMATRIX. Поскольку умножение матриц так важно, приведем пример кода, использующего этот оператор:

D3DXMATRIX A(Е); // инициализация A D3DXMATRIX B(Е); // инициализация B D3DXMATRIX C = A * B; // C = AB

Другим важным оператором класса D3DXMATRIX являются скобки, позволяющие легко получить доступ к отдельным элементам матрицы. Обратите внимание, что при использовании скобок нумерация элементов матрицы начинается с нуля, подобно нумерации элементов массива в языке С. Например, чтобы обратиться к верхнему левому элементу матрицы, следует написать:

D3DXMATRIX M; M(0, 0) = 5.0f; // Присвоить первому элементу матрицы значение 5.0f.

Кроме того, библиотека D3DX предоставляет набор полезных функций, позволяющих инициализировать единичную матрицу D3DXMATRIX, транспонировать матрицу D3DXMATRIX и инвертировать матрицу D3DXMATRIX:

D3DXMATRIX *D3DXMatrixIdentity( D3DXMATRIX *pout // Матрица, инициализируемая как единичная );

D3DXMATRIX M; D3DXMatrixIdentity(&M); // M = единичная матрица

D3DXMATRIX *D3DXMatrixTranspose( D3DXMATRIX *pOut, // Результат транспонирования матрицы CONST D3DXMATRIX *pM // Транспонируемая матрица );

D3DXMATRIX A(...); // инициализация A D3DXMATRIX B; D3DXMatrixTranspose(&B, &A); // B = транспонированная(A)

D3DXMATRIX *D3DXMatrixInverse( D3DXMATRIX *pOut, // возвращает результат инвертирования pM FLOAT *pDeterminant, // детерминант, если необходим, иначе 0 CONST D3DXMATRIX *pM // инвертируемая матрица );

Функция инвертирования возвращает NULL, если переданная ей матрица не может быть инвертирована. Кроме того, в этой книге мы игнорируем второй параметр и всегда передаем в нем 0.

D3DXMATRIX A(...); // инициализация A D3DXMATRIX B; D3DXMatrixInverse(&B, 0, &A); // B = инвертированная(A)


Содержание раздела