インデックス付き頂点ブレンディングの使い方
インデックス付き頂点ブレンディングの使い方
256 ~ 511 の範囲のトランスフォーム ステートは、8 ビットのインデックスを使ってインデックス付けできる最大 256 個の行列を格納するために確保されている。D3DTS_WORLDMATRIX マクロを使って、インデックス 0 ~ 255 を対応するトランスフォーム ステートにマッピングする。次のサンプル コードは、IDirect3DDevice9::SetTransform メソッドを使ってトランスフォーム ステート番号 256 の行列を単位行列に設定する方法を示している。
D3DMATRIX matBlend1;
D3DXMatrixIdentity( &matBlend1 );
m_pD3DDevice->SetTransform( D3DTS_WORLDMATRIX(0), &matBlend );
インデックス付き頂点ブレンディングの有効と無効を切り替えるには、D3DRS_INDEXEDVERTEXBLENDENABLE レンダリング ステートを TRUE に設定する。このレンダリング ステートが有効になっている場合は、頂点ごとにパック DWORD で行列インデックスを渡さなければならない。このレンダリング ステートを無効にし、頂点ブレンディングを有効にすることは、すべての頂点について行列インデックス 0、1、2、3 を指定することに等しい。次のコードは、IDirect3DDevice9::SetRenderState メソッドを使って、インデックス付き頂点ブレンディングを有効にする。
m_pD3DDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE );
頂点ブレンディングの有効と無効を切り替えるには、IDirect3DDevice9::SetRenderState レンダリング ステートを D3DVERTEXBLENDFLAGS 列挙型の D3DRS_DISABLE 以外の値に設定する。このレンダリング ステートが D3DRS_DISABLE に設定されていない場合は、各頂点に必要な重みの数を渡さなければならない。次のコードは、IDirect3DDevice9::SetRenderState を使って、各頂点に対して 3 つの重みで頂点ブレンディングを有効にする。
m_pD3DDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS );
インデックス付き頂点ブレンディングのサポートの判定
インデックス付き頂点ブレンディング行列の最大サイズを判定するには、D3DCAPS9 構造体の MaxVertexBlendMatrixIndex メンバを調べる。次のコードは、IDirect3DDevice9::GetDeviceCaps メソッドを使って、このサイズを取得する。
D3DCAPS9 d3dCaps;
m_pD3DDevice->GetDeviceCaps( &d3dCaps );
IndexedMatrixMaxSize = d3dCaps.MaxVertexBlendMatrixIndex;
MaxVertexBlendMatrixIndex に設定された値が 0 の場合、デバイスはインデックス付きの行列をサポートしていない。
注 ソフトウェア頂点処理が使われている場合は、法線ブレンディングがあってもなくても、256 個の行列をインデックス付き頂点ブレンディングに使える。
Direct3D に対する行列インデックスの受け渡し
ワールド行列インデックスは、従来の頂点シェーダである柔軟な頂点フォーマット (FVF) または宣言を使って Microsoft® Direct3D® に渡すことができる。
次のコードは、従来の頂点シェーダの使い方を示している。
struct VERTEX
{
float x,y,z;
float weight;
DWORD matrixIndices;
float normal[3];
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4 |
D3DFVF_NORMAL);
従来の頂点シェーダを使う場合、行列インデックスは D3DFVF_XYZBn フラグを使って頂点位置と共に渡される。行列インデックスは DWORD 内のバイトとして渡され、最後の頂点加重の直後に存在しなければならない。頂点加重も D3DFVF_XYZBn を使って渡される。パック DWORD は、index3、index2、index1、index0 を保持し、index0 は DWORD の最下位バイトにある。使われるワールド行列インデックスの数は、D3DRENDERSTATETYPE 列挙型によって定義されるブレンディングに使われる行列の数に渡される数値に等しい。
宣言を使う場合は、D3DVSDE_BLENDINDICES が行列インデックスを取得する入力頂点レジスタを定義する。行列インデックスは、D3DVSDT_UBYTE4 として渡す必要がある。
次のコードは、宣言の使い方を示している。固定機能による頂点シェーダを使わない限り、成分の順序はまったく重要ではない点に注意すること。
次に頂点の宣言を示す。
struct VERTEX
{
float x,y,z;
float weight;
DWORD matrixIndices;
float normal[3];
}
次に、対応するレジスタの宣言を示す。
// Create the shader declaration.
D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 },
{ 0, 16, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 },
{ 0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
D3DDECL_END()
};