2017-11-06 29 views
0

私はDirectX9を使用して単純な2Dゲームを構築しようとしています。スケーリングの適用なしでスプライトのディメンションと座標を使用できるようにしたいと考えています。DirectX 9 - 正確な次元で2Dスプライトを描画する

フランクルナの「DirectX 9.0cで3Dゲームプログラミング入門」の本は、Direct3Dのスプライト機能を使って2Dでグラフィックをレンダリングするトリックを示していますが、ブックコードではまだカメラを設定していますD3DXMatrixLookAtLHおよびD3DXMatrixPerspectiveFovLHに変換され、スプライトイメージはパースペクティブにスケーリングされます。スプライトが元の寸法でレンダリングされる場所にビューと投影を設定するにはどうしたらいいですか?X-Y座標はウィンドウ内の実際のピクセル位置として扱うことができますか?

UPDATE

これは理想的なソリューションではないかもしれないが、私は回避策を考え出すでした。私が90度の視野を持つ投影行列を設定し、z = 0に近い平面を設定すると、D3DXMatrixLookAtRHで原点(0、0、0)を見て、画面の幅の半分で戻ってきます(Isosceles Right Triangleの高さはベースの半分です)。

は、だから私のクライアント領域は、x 400 400であることのため、以下の設定が私の仕事:

// get client rect 
RECT R; 
GetClientRect(hWnd, &R); 
float width = (float)R.right; 
float height = (float)R.bottom; 

// step back by 400/2=200 and look at the origin 
D3DXMATRIX V; 
D3DXVECTOR3 pos(0.0f, 0.0f, (-width*0.5f)/(width/height)); // see "UPDATE 2" below 
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); 
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); 
D3DXMatrixLookAtLH(&V, &pos, &target, &up); 
d3dDevice->SetTransform(D3DTS_VIEW, &V); 

// PI x 0.5 -> 90 degrees, set the near plane to z=0 
D3DXMATRIX P; 
D3DXMatrixPerspectiveFovLH(&P, D3DX_PI * 0.5f, width/height, 0.0f, 5000.0f); 
d3dDevice->SetTransform(D3DTS_PROJECTION, &P); 

は、すべてのテクスチャフィルタをオフにする(またはD3DTEXF_POINTに設定)最高ピクセル精度の感触を得るように思われます。

要求された400 x 400サイズのCreateWindowEx()が387 x 362のようなクライアント領域を返したため、GetClientRect()で確認し、差を計算してウィンドウサイズを再調整しなければならなかったSetWindowPos()初期作成後。

下記のスクリーンショットは、上記の手順を実行した結果を示しています。元のビットマップ(右)は、スケーリング/ストレッチがアプリケーション(左)に適用されずにレンダリングされました...最終的に!

enter image description here

Iは、アスペクト比が1でない場合のために上記の方法をテストしていない2

UPDATE:1。私はコードを調整しました - あなたのカメラの位置を戻す量は... window_width * 0.5/aspect_ratio(またはwidth/height)でなければなりません。

+0

15年前から従来のDirect3D 9を使用しているのはなぜですか? DirectX 11を使用してください。 –

+0

XPを実行しているマシンの1台でこれを実行できるようにしたかっただけです。ちょうど実験するために:-) – morezoom

答えて

0

DirectX Tool KitSpriteBatchクラスは、あなたが記述したものとまったく同じように設計されています。 Direct3Dを使用して描画する場合、画面の座標は右上隅に(-1、-1)〜(1,1)で(-1、-1)です。

これは、右上に(0,0)のスクリーン座標で指定するためのマトリックスを設定します。中心が異なるDirect3Dの10/11/12より少し定義されたDirect3Dの9画素で

// Compute the matrix. 
float xScale = (mViewPort.Width > 0) ? 2.0f/mViewPort.Width : 0.0f; 
float yScale = (mViewPort.Height > 0) ? 2.0f/mViewPort.Height : 0.0f; 

switch(rotation) 
{ 
case DXGI_MODE_ROTATION_ROTATE90: 
    return XMMATRIX 
    (
     0,  -yScale, 0, 0, 
     -xScale, 0,  0, 0, 
     0,  0,  1, 0, 
     1,  1,  0, 1 
    ); 

case DXGI_MODE_ROTATION_ROTATE270: 
    return XMMATRIX 
    (
     0,  yScale, 0, 0, 
     xScale, 0,  0, 0, 
     0,  0,  1, 0, 
     -1,  -1,  0, 1 
    ); 

case DXGI_MODE_ROTATION_ROTATE180: 
    return XMMATRIX 
    (
     -xScale, 0,  0, 0, 
     0,  yScale, 0, 0, 
     0,  0,  1, 0, 
     1,  -1,  0, 1 
    ); 

default: 
    return XMMATRIX 
    (
     xScale, 0,  0, 0, 
     0,  -yScale, 0, 0, 
     0,  0,  1, 0, 
     -1,  1,  0, 1 
    ); 
} 

ので、従来のAPIにおける典型的な解決策は、全ての位置にオフセット0.5,0.5半中心を追加しました。 Direct3D 10/11/12でこれを行う必要はありません。

+0

ありがとうございました。私はこのツールキットをチェックします - 2D図面を作成する際には便利です。 – morezoom

関連する問題