我正在尝试使用DirectX9构建一个简单的2D游戏,我希望能够使用精灵尺寸和坐标而不应用缩放。
我正在关注的这本书(由Frank Luna撰写的“使用DirectX 9.0c进行3D游戏编程简介”)展示了使用Direct3D的精灵函数在2D中渲染图形的技巧,但书籍代码仍然使用D3DXMatrixLookAtLH设置摄像机和D3DXMatrixPerspectiveFovLH,精灵图像以透视方式进行缩放。如何将视图和投影设置为以原始尺寸渲染精灵的位置,并将X-Y坐标作为窗口内的实际像素位置进行寻址?
更新
虽然这可能不是理想的解决方案,但我确实提出了一种解决方法。我意识到如果我将投影矩阵设置为90度视场和近平面z = 0,那么我所要做的就是用D3DXMatrixLookAtRH和步骤查看原点(0,0,0)后退一半的屏幕宽度(Isosceles Right Triangle的高度是基数的一半)。
因此,对于我的客户区域为400 x 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重新调整窗口大小()在最初创建之后。
下面的屏幕截图显示了采取上述步骤的结果。渲染原始位图(右),在应用程序中没有应用缩放/拉伸(左)......最后!
更新2
当宽高比不是1:1时,我没有测试上述方法。我调整了代码 - 你为相机位置退后的数量应该是...... window_width * 0.5 / aspect_ratio(或宽度/高度)。
答案 0 :(得分:0)
DirectX Tool Kit SpriteBatch
类旨在完全按照您的描述进行操作。使用Direct3D绘图时,屏幕坐标为(-1,-1)到(1,1),右上角有(-1,-1)。
这将设置一个矩阵,让您在屏幕坐标中指定右上角的(0,0)。
// 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
);
}
在Direct3D 9中,像素中心的定义与Direct3D 10/11/12稍有不同,因此传统API中的典型解决方案是在所有位置添加0.5,0.5半中心偏移。您不需要使用Direct3D 10/11/12执行此操作。