直接在屏幕/客户端坐标上绘制纹理

时间:2012-01-08 17:32:08

标签: directx

如果重要的话,我正在使用正交投影,我可以使用世界坐标在世界上绘制纹理。对于HUD对象,它最初工作正常,但是一旦我有一个相机并且它移动,我所有的HUD纹理都会随着世界一起移动,因此迟早会离开相机的视野。

为了在HUD上绘制,必须使用客户端坐标(左上角或中心为(0,0))绘制它们。有关如何做到这一点的任何想法?我对此很陌生,所以我希望得到更详细的帮助。

谢谢!

1 个答案:

答案 0 :(得分:2)

如果您设置了标识视图和投影矩阵,那么所有坐标都将简单地传递到屏幕。后投影和w除-1,-1是左下角,1,1是右上角,0,0是中心。

现在,如果你想传递屏幕坐标,你需要设置一个世界矩阵,使得0,0,z出现为-1,1,z和1024,768,z(例如)出现为1,-1,z,1(z用于给出特定的深度,可用于将HUD元素叠加在一起)。对线性代数的充分理解对此有很大帮助。

基本上如果你要写它,你会做以下

xout = (x / (width * 0.5f)) - 1.0f;
yout = -((y / (height * 0.5f)) - 1.0f);
zout = z;
wout = 1.0f;

所以,如果你记得你的矩阵,你会得到类似的东西。

m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m32, m33,

矩阵扩展使输入x坐标始终由第一列转换,如下所示:

xout = m00 * x + m10 * y + m20 * z + m30 * w;

首先要记住的是,传递到directX(x,y,z)的坐标三元组会扩展为四元组(x,y,z,1)。

通过这种方式,我们可以很容易地看到,如果m10和m20为0,那么我们有效地将x乘以某个值,然后我们在m30中添加以前的值。

回到我们关于如何计算xout的原始描述,我们可以看到,如果我们将m00设置为“1.0f /(width * 0.5f)”并且m30设置为-1.0f,那么我们将计算我们所追求的。因此假设:

xscale = 1.0f / (width * 0.5f);
yscale = -1.0f / (height * 0.5f);
zscale = 1.0f;
xtrans = -1.0f;
ytrans = 1.0f;
ztrans = 0.0f;

然后我们可以按如下方式定义世界矩阵:

xscale,      0,      0,      0
     0, yscale,      0,      0
     0,      0, zscale,      0
xtrans, ytrans, ztrans,      1

将该矩阵设置为您的世界矩阵(请记住将视图和投影设置为标识),现在可以使用屏幕坐标输入坐标。