次の方法で共有


インデックス付き頂点ブレンディングの使い方 (Direct3D 9)

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 または宣言を使って 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 の最下位バイトにあります。使われるワールド行列インデックスの数は、D3DRS_VERTEXBLEND 列挙型によって定義されるブレンディングに使われる行列の数に渡される数値と同じです。

宣言を使う場合は、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()
};