xファイルを読み込みスクリーン座標への変換をして各頂点をスクリーンに描画する処理を行っているのですが、
適切な位置に描画する事ができません。
適切な位置というのは、スクリーン上のモデル表示位置という事です。
取得している頂点がおかしい。或いは、変換が間違っている。と、思うのですが、自身では行き詰ってしまったので、解答おねがいします。
・簡単な処理の流れ(記事投稿現在)
1.xファイル読み込み
D3DXLoadMeshHierarchyFromXを使用
FVFの形式は、おそらく( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
2.メッシュデータから頂点データを取得
読み込んだデータは頂点バッファに格納され、直接触れないのでFVFの構造体(CUSTOM_VERTEX)の配列にコピーする
struct CUSTOM_VERTEX{
D3DXVECTOR3 postion; // 頂点座標
D3DXVECTOR3 normal; // 法線
DWORD dwColor; // 頂点の色
float u, v; // テクスチャ座標
};
// フレームデータ作成関数(読み込んだフレームのデータを自分で作った構造体(CUSTOM_FRAME)に格納)
HRESULT CreateFrame(){
HRESULT hr;
// 参照用フレームポインタ
LPD3DXFRAME t_pFrameRoot = m_pFrameRoot;
// フレーム数カウント変数
int i = 0;
// バッファロック用のポインタ
CUSTOM_VERTEX* pDataV;
WORD* pDataI;
while(t_pFrameRoot != NULL){
CUSTOM_FRAME *pFrame = new CUSTOM_FRAME;
// 各フレーム(メッシュ)における頂点の数 を 取得
pFrame->VertexNumber = t_pFrameRoot->pMeshContainer->MeshData.pMesh->GetNumVertices();
pFrame->PorigonNumber = t_pFrameRoot->pMeshContainer->MeshData.pMesh->GetNumFaces();
// 各フレーム(メッシュ)頂点データ を 作成
pFrame->pVertex = CreateVertex( pFrame->VertexNumber );
// 各フレーム(メッシュ)頂点インデックスデータ を 作成
WORD *index = new WORD[pFrame->VertexNumber] ;
pFrame->pIndex = index;
// 頂点バッファの作成
IDirect3DVertexBuffer9* pVB;
hr = (*(this->pD3DDev))->CreateVertexBuffer(
sizeof(CUSTOM_VERTEX)*pFrame->VertexNumber,
D3DUSAGE_WRITEONLY,
FVF_CUSTOM_OPTION,
D3DPOOL_MANAGED,
&pVB,
NULL
);
if(FAILED( hr )){
return E_FAIL;
}
// 頂点バッファの取得
t_pFrameRoot->pMeshContainer->MeshData.pMesh->GetVertexBuffer( &pVB );
pFrame->pVertexBuffer = pVB;
// 頂点バッファロック
t_pFrameRoot->pMeshContainer->MeshData.pMesh->LockVertexBuffer(D3DLOCK_READONLY,(void**)&pDataV);
// 頂点の取得
memcpy(pFrame->pVertex, pDataV, sizeof(CUSTOM_VERTEX)*pFrame->VertexNumber);// 書き込み
// アンロック
t_pFrameRoot->pMeshContainer->MeshData.pMesh->UnlockVertexBuffer();
// インデックスバッファ作成
IDirect3DIndexBuffer9* pIB;
(*(this->pD3DDev))->CreateIndexBuffer(
sizeof(WORD)*pFrame->VertexNumber,
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&pIB,
NULL
);
if(FAILED( hr )){
return E_FAIL;
}
t_pFrameRoot->pMeshContainer->MeshData.pMesh->GetIndexBuffer( &pIB );
pFrame->pIndexBuffer = pIB;
// ロック
t_pFrameRoot->pMeshContainer->MeshData.pMesh->LockIndexBuffer(D3DLOCK_READONLY,(void**)&pDataI);
// インデックス取得
memcpy(pFrame->pIndex, pDataI, sizeof(WORD)*pFrame->VertexNumber);// 書き込み
// アンロック
t_pFrameRoot->pMeshContainer->MeshData.pMesh->UnlockIndexBuffer();
// リストにフレームのポインタ を 格納
Frame_List.push_back( pFrame );
// 参照フレームを子フレームへ進める
t_pFrameRoot = t_pFrameRoot->pFrameFirstChild;i++;
}
FrameNumber = i;
return S_OK;
}
// 全体変換行列をセット
void SetAllMatrix(){
matAll = matView * matProj * matScreen;
}
// スクリーン座標に変換
void VTransWorldToScreen(const D3DXVECTOR3 *inVertex, D3DXVECTOR2 *outVertex){
D3DXVECTOR3 t_Vertex(0,0,0);
D3DXVec3TransformCoord(&t_Vertex, inVertex, &matAll);
t_Vertex.z;
outVertex->x = t_Vertex.x;
outVertex->y = t_Vertex.y;
}
// 描画
void Draw_VertexToScreenPosition( Matrix *t_Mat ){
// 変換後の座標
D3DXVECTOR2 t_Pos;
// 矩形描画インターフェース
Rectangle2D rect(pD3DDev);
int TO_SCREEN_RECT_SIZE = 2;
for(DWORD j = 0; j < FrameNumber ; j++){
for(DWORD i = 0;i < Frame_List[j]->VertexNumber-1; i++){
// 座標をスクリーン座標に変換
t_Mat->VTransWorldToScreen((&Frame_List[j]->pVertex.postion), &t_Pos);
// 矩形の初期化(x座標, y座標, インデックス)
rect.SetPoint(t_Pos.x-TO_SCREEN_RECT_SIZE, t_Pos.y-TO_SCREEN_RECT_SIZE, 0);
rect.SetPoint(t_Pos.x+TO_SCREEN_RECT_SIZE, t_Pos.y-TO_SCREEN_RECT_SIZE, 1);
rect.SetPoint(t_Pos.x-TO_SCREEN_RECT_SIZE, t_Pos.y+TO_SCREEN_RECT_SIZE, 2);
rect.SetPoint(t_Pos.x+TO_SCREEN_RECT_SIZE, t_Pos.y+TO_SCREEN_RECT_SIZE, 3);
// 矩形描画
rect.Draw();
}
}
}
*捕捉
SetAllMatrix()は、Render()関数の中で毎フレーム初期化しています。
頂点を、ウォッチして実行してみたのですが、xファイルの頂点情報と、読み込んだ頂点情報(バッファ格納後)は異なっています。
最適化などが、行われているのでしょうか?
無駄に頂点バッファ等を作成していますが、現在使っておりません。
DrawPrimitive()によりモデルの描画を行おうと、取得したバッファをそのまま入れてみたり、色々試してみたのですが、
ぐちゃぐちゃに表示されてしまうため、DrawSubset()により描画しています。
この問題についても心当たりあれば、解答お願いします。
拙い文章ですがよろしくお願いします。
画像も貼付いたします。
