DX9でスキンメッシュをシェーダーで描画するときのワールド行列

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
potato0206

DX9でスキンメッシュをシェーダーで描画するときのワールド行列

#1

投稿記事 by potato0206 » 9年前

[1] 質問文
 [1.1]現在DX9でスキンメッシュを使っているのですが、シェーダーを使って描画するときに送るワールドマトリックスがおかしいのかうまく表示されません。送る行列はどうすればいいのでしょうか。

 [1.2] 以下のようになっています。
 [1.3] 部分的に正しい位置に描画されるが、正しくないフレームもある。
 [1.4] 送る行列は何が正しいのか知りたいです。

[2] 環境  
 [2.1] OS : Windows7
 [2.2] コンパイラ名 : VC++ 2010

[3] その他
 ・スキンメッシュに最近触り始めました。DirectXでの学習期間は2年ほどです。

コード:

//=============================================================================
// メッシュコンテナの描画
// フレーム内のそれぞれのメッシュをレンダリングする
//-----------------------------------------------------------------------------
// 引数   : メッシュコンテナ情報
// 引数2  : フレーム情報
// 戻り値 : なし
//=============================================================================
VOID CSkinMesh::RenderMeshContainer(MYMESHCONTAINER* pMeshContainer, MYFRAME* pFrame)
{
	LPDIRECT3DDEVICE9 pDevice = GET_DEVICE;
	DWORD i,k,m;
	DWORD dwBoneIndex,dwBlendMatrixNum;    
	DWORD dwPrevBoneID;
	LPD3DXBONECOMBINATION pBoneCombination;
	UINT iMatrixIndex;
	D3DXMATRIX mStack;

	//警告削除
	(void*)m;
	(void*)dwBoneIndex;

	//平行光源の光の方向ベクトル
	D3DXVECTOR4 LightDir;
	LightDir = D3DXVECTOR4( CManager::GetLight()->GetLights()->Direction, 0.0f );

	//環境光の設定
	m_pLambert->SetAmbient( 0.5f );

	//スキンメッシュの場合
	if(pMeshContainer->pSkinInfo != NULL)
	{	
		pBoneCombination = (LPD3DXBONECOMBINATION)pMeshContainer->pBoneBuffer->GetBufferPointer();

		dwPrevBoneID=UINT_MAX;
		for(i = 0; i < pMeshContainer->dwBoneNum; i++)
		{
			dwBlendMatrixNum=0;
			for(k = 0; k< pMeshContainer->dwWeight; k++)
			{
				if (pBoneCombination[i].BoneId[k] != UINT_MAX) 
				{
					dwBlendMatrixNum=k;
				}
			}
			pDevice->SetRenderState(D3DRS_VERTEXBLEND, dwBlendMatrixNum);
			for(k = 0; k < pMeshContainer->dwWeight; k++) 
			{
				iMatrixIndex = pBoneCombination[i].BoneId[k];
				if (iMatrixIndex != UINT_MAX)
				{
					mStack=pMeshContainer->pBoneOffsetMatrices[iMatrixIndex] * (*pMeshContainer->ppBoneMatrix[iMatrixIndex]);
					pDevice->SetTransform( D3DTS_WORLDMATRIX(k), &mStack );
				}
			}
			pDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneCombination[i].AttribId].MatD3D );
			pDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneCombination[i].AttribId] );
			dwPrevBoneID = pBoneCombination[i].AttribId;

			//ワールド座標系のマトリックスと照明の方向ベクトルを格納する
                        //ここの送っている行列が正しくない
			m_pLambert->SetMatrix( &mStack, &LightDir );
			
			m_pLambert->CommitChanges();

			//シェーダーを開始する
			m_pLambert->Begin();
	
			//パスの開始
			m_pLambert->BeginPass();

			pMeshContainer->MeshData.pMesh->DrawSubset(i);

			m_pLambert->EndPass();
			m_pLambert->End();

			pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);

		}		
	}
	//通常メッシュの場合
	else
	{

		pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
		pDevice->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix);
		for (i = 0; i < pMeshContainer->NumMaterials; i++)
		{
			pDevice->SetMaterial( &pMeshContainer->pMaterials[i].MatD3D );
			pDevice->SetTexture( 0, pMeshContainer->ppTextures[i] );
			pMeshContainer->MeshData.pMesh->DrawSubset(i);
		}
	}
}

“C言語何でも質問掲示板” へ戻る