0

MFC ウィンドウに direct3d 環境があり、どの 3d ソフトウェアにもあるように、座標系の軸を画面の隅に描画したいと考えています。これで問題ないと思っていたのですが、カメラを動かし始めると問題が発生しました。カメラをどのようにパン、ズーム、または回転させても、オブジェクトが同じ場所にあるように見える必要があります。

しかし、私は何か間違ったことをしているようで、誰かが私を正しい方向に向けることを望んでいた.

症状を示すYouTubeビデオも公開しました:http://www.youtube.com/watch?v=gwM0m8nbLts&feature=youtu.be

これは、オブジェクトを描画するための私のコードです:

    void CDEMView::DrawSomeBox()
{
// Define the needed matrices - object world, view and project 
D3DXMATRIX matObjectWorld;
    D3DXMatrixIdentity (&matObjectWorld);   // object world matrix
D3DXMATRIX matView;             
    D3DXMatrixIdentity (&matView);      // view matrix
D3DXMATRIX matProjection;   
    D3DXMatrixIdentity (&matProjection);    // projection matrix

// Get the needed matrices
_device->GetTransform(D3DTS_VIEW, &matView);
_device->GetTransform(D3DTS_PROJECTION, &matProjection);

// Get the viewport
D3DVIEWPORT9 viewport;
_device->GetViewport(&viewport);

// Get the center point of the object       
D3DXVECTOR3* p_centerPoint = BoxCenterVector; // this is from an external variable

// Get the point on the creen that is the screen projection of the object
D3DXVECTOR3 projectPoint;
D3DXVec3Project(&projectPoint, p_centerPoint ,&viewport, &matProjection, &matView, &matObjectWorld);

// choose the screen point where the object is to be drawn, relative to the Viewport's dimensions
D3DXVECTOR3 screenPoint;
screenPoint.x = 0.1*viewport.Width; // x position (horizontal) is 10% of the width of the screen (0% is left, 100% is right)
screenPoint.y = 0.9*viewport.Height;    // y position (vertical) is 90% of the height of the screen (0% is top, 100% is bottom)
screenPoint.z = projectPoint.z;     // 1-projectPoint.z*60/(-zoom);

//transform the screen position to a world position
D3DXVECTOR3 worldPoint;
D3DXVec3Unproject( &worldPoint, &screenPoint, &viewport, &matProjection, &matView, &matObjectWorld );

// now define how much to translate the box in order to get it to the point we want it to be (WorldPoint)
float transX, transY, transZ;
transX = worldPoint.x;
transY = worldPoint.y;
transZ = worldPoint.z;

// define a mesh to store the object into and create the object
ID3DXMesh* _SomeBox;
float boxSize = 2.0f;
D3DXCreateBox(_device,boxSize,boxSize,boxSize,&_SomeBox,NULL);

// define a material and set its color
D3DMATERIAL9 mat;

// Set the RGBA for diffuse reflection.
mat.Diffuse.r = 255;
mat.Diffuse.g = 0;
mat.Diffuse.b = 0;
mat.Diffuse.a = 0.5;

_device->SetMaterial(&mat);
_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); // D3DFILL_SOLID

// apply the translation matrix
D3DXMatrixTranslation(&matObjectWorld, transX, transY, transZ);
_device->SetTransform(D3DTS_WORLD, &matObjectWorld);

// draw the object
_SomeBox->DrawSubset(0);
// release the mesh
_SomeBox->Release();
}
4

2 に答える 2

0

問題を見つけるためにコードを詳しく調べていませんが、カメラの動きを補正しようとする必要を避けるために、少し異なるアプローチを取ることをお勧めします。座標軸をシーンと同じワールド空間に配置されたオブジェクトとして配置しようとする代わりに、ビューポートを座標軸を表示する領域に変更し、固定カメラとワールド マトリックスを使用して仮想シーンでレンダリングします。これは、変換コンポーネントを含まないメイン シーンのカメラ ビュー マトリックスです。

この方法では、カメラのズームを気にする必要さえありません。ビュー マトリックスの回転がワールド軸にどのように影響するかを直接表示するだけです。このアプローチには、シーンと相互作用する軸に関する問題を回避できるという利点もあります。軸を描画する前に軸をレンダリングするビューポートの z バッファーをクリアすると、メイン シーンと相互作用しない別のレイヤーのようになります。軸をオフスクリーン レンダー ターゲット テクスチャにレンダリングし、それをメイン シーンで四角形として表示することによっても、同じ効果を実現できますが、この場合、明確な利点がなく、より多くの作業が必要になります。

于 2013-05-24T18:44:43.137 に答える
0

少しやり過ぎではありますが、できることの 1 つは、最初に回転オブジェクトを平行移動せずにテクスチャに直角に回転するだけで描画することです。このリンクを参照してください。

このように、オブジェクトがどれだけ離れていても、同じサイズになります。テクスチャを作成したら、次の 2 つのいずれかを行うだけです。画面の左上隅にクワッドを 3D 変換なしでレンダリングするか、DirectX で提供されるスプライト インターフェイスを使用してテクスチャをレンダリングします。スプライト インターフェイスを使用すると、基本的に 2D クワッドを使用するのと同じことを行いますが、少し簡単かもしれません。私の経験からすると、かなり高速です。幸運を!

于 2013-07-13T16:41:18.807 に答える