矩陣類型及其操作
在Direct3D中,頂點坐標變換通常是借助于矩陣實現的,因此下面首先介紹在Direct3D中提供的各種矩陣類型和相關的矩陣運算函數。
1、D3DMATRIX矩陣類型
D3DMATRIX是Direct3D中最簡單的矩陣類型,其定義如下:
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;
顯然,D3DMATIX中存放的是一個4x4的二維浮點數組,可以通過_ij的格式訪問該數組中的每個元素,i表示該元素的行數,j表示該元素的列數。例如,_34表示第三行、第四列的元素。
2、D3DXMATRIX矩陣類型
該類型矩陣定義如下:
#ifdef __cplusplus
typedef struct D3DXMATRIX : public D3DMATRIX
{
public:
D3DXMATRIX() {};
D3DXMATRIX( CONST FLOAT * );
D3DXMATRIX( CONST D3DMATRIX& );
D3DXMATRIX( CONST D3DXFLOAT16 * );
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 );
// access grants
FLOAT& operator () ( UINT Row, UINT Col );
FLOAT operator () ( UINT Row, UINT Col ) const;
// casting operators
operator FLOAT* ();
operator CONST FLOAT* () const;
// assignment operators
D3DXMATRIX& operator *= ( CONST D3DXMATRIX& );
D3DXMATRIX& operator += ( CONST D3DXMATRIX& );
D3DXMATRIX& operator -= ( CONST D3DXMATRIX& );
D3DXMATRIX& operator *= ( FLOAT );
D3DXMATRIX& operator /= ( FLOAT );
// unary operators
D3DXMATRIX operator + () const;
D3DXMATRIX operator - () const;
// binary operators
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;
#else //!__cplusplus
typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX;
#endif //!__cplusplus
3、D3DXMATRIXA16矩陣類型
D3DXMATRIXA16稱為16字節對齊矩陣(16-byte
aligned matrix),它是從矩陣D3DXMATRIX中繼承而來的,其定義如下:
typedef D3DX_ALIGN16 _D3DXMATRIXA16
D3DXMATRIXA16, *LPD3DXMATRIXA16;
//---------------------------------------------------------------------------
// Aligned Matrices
//
// This class helps keep matrices 16-byte aligned as preferred by P4 cpus.
// It aligns matrices on the stack and on the heap or in global scope.
// It does this using __declspec(align(16)) which works on VC7 and on VC 6
// with the processor pack. Unfortunately there is no way to detect the
// latter so this is turned on only on VC7. On other compilers this is the
// the same as D3DXMATRIX.
//
// Using this class on a compiler that does not actually do the alignment
// can be dangerous since it will not expose bugs that ignore alignment.
// E.g if an object of this class in inside a struct or class, and some code
// memcopys data in it assuming tight packing. This could break on a compiler
// that eventually start aligning the matrix.
//---------------------------------------------------------------------------
#ifdef __cplusplus
typedef struct _D3DXMATRIXA16 : public D3DXMATRIX
{
_D3DXMATRIXA16() {}
_D3DXMATRIXA16( CONST FLOAT * );
_D3DXMATRIXA16( CONST D3DMATRIX& );
_D3DXMATRIXA16( CONST D3DXFLOAT16 * );
_D3DXMATRIXA16( 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 );
// new operators
void* operator new ( size_t );
void* operator new[] ( size_t );
// delete operators
void operator delete ( void* ); // These are NOT virtual; Do not
void operator delete[] ( void* ); // cast to D3DXMATRIX and delete.
// assignment operators
_D3DXMATRIXA16& operator = ( CONST D3DXMATRIX& );
} _D3DXMATRIXA16;
#else //!__cplusplus
typedef D3DXMATRIX _D3DXMATRIXA16;
#endif //!__cplusplus
當使用了Intel Pentium 4運行一個D3DX數學函數時,16字節對齊矩陣D3DXMATRIXA16為完成相應操作進行了優化。當使用VC++.net或使用安裝了processor
pack的VC6++時,將開啟字節對齊功能。但不幸的是,編譯器無法探測到是否安裝了processor
pack,所以字節對齊僅僅只對VC++.net默認開啟。對于其他編譯器,16字節對齊矩陣D3DXMATRIXA16將被當作D3DXMATRIX進行操作。
經過擴展后的結構體D3DXMATRIX和D3DXMATRIXA16對許多運算符進行了重載,所以可以直接進行轉換運算、賦值運算以及多種一元、二元運算,大大方便了矩陣類型變量的運算。
4、常見的矩陣運算函數
因為矩陣的運算相對比較復雜,所以Direct3D提供了一組矩陣運算函數,例如,通過函數D3DXMatrixTranslation()構造一個平移矩陣;通過函數D3DXMatrixRotationX()、D3DXMatrixRotationY()和D3DXMatrixRotationZ()構造繞x、y和z軸轉動一定角度的矩陣;通過函數D3DXMatrixScaling()構造一個縮放矩陣;通過函數D3DXMatrxiIdentity()將一個矩陣單位化;通過函數D3DXMatrixMultiply()計算兩個矩陣的積;通過函數D3DXMatrixInverse()求原矩陣的逆矩陣;通過函數D3DXMatrixTranspose()計算原矩陣的轉置矩陣。