【问题标题】:DirectX 11 Vertices CoordinatesDirectX 11 顶点坐标
【发布时间】:2013-10-07 13:26:47
【问题描述】:

我正在处理我的第一个 C++ 和 DirectX 11 项目,我目前的目标是在屏幕上绘制一个彩色三角形。这运行良好,没有任何问题。但是,有一个部分我想更改,但我不知道如何更改。我已经尝试过寻找解决方案,但我还没有找到任何解决方案,我猜是因为我真的不知道我应该寻找什么。

目前我像这样设置我的三角形 3 个顶点:

VertexPos vertices[] =
{
    { XMFLOAT3(  0.5f,  0.5f, 1.0f )},
    { XMFLOAT3(  0.5f, -0.5f, 1.0f )},
    { XMFLOAT3( -0.5f, -0.5f, 1.0f )},
}

VertexPos 的定义如下:

struct VertexPos
{
    XMFLOAT3 pos;
};

目前,我的顶点位置设置在 -1.0F 到 1.0F 的范围内,其中 0.0F 是中心。我怎样才能改变它,以便我可以使用这样的“真实”坐标来定位我的顶点:

VertexPos vertices[] =
{
    { XMFLOAT3(  100.0f,  300.0f, 1.0f )},
    { XMFLOAT3(  200.0f,  200.0f, 1.0f )},
    { XMFLOAT3(  200.0f,  300.0f, 1.0f )},
}

【问题讨论】:

  • 您必须设置一个适当的投影矩阵并将坐标与顶点着色器中的矩阵相乘。如果您刚刚开始,请阅读更多教程,您就会知道。

标签: c++ directx coordinates directx-11 vertices


【解决方案1】:
  1. 常规方式:

    • 创建正交投影矩阵(XMMatrixOrthographicLH(),如果您使用 XMMATH)
    • 使用此矩阵在 CPU 端(C++ 代码)和 GPU 大小(顶点着色器)上创建常量缓冲区
    • 在顶点着色器中将顶点位置乘以正交投影矩阵
  2. 更简单的方法(来自 F.Luna 书):

    XMFLOAT3 SpriteBatch::PointToNdc(int x, int y, float z)
    {
        XMFLOAT3 p;
    
        p.x = 2.0f*(float)x/mScreenWidth - 1.0f;
        p.y = 1.0f - 2.0f*(float)y/mScreenHeight;
        p.z = z;
    
        return p;
    }
    

    几乎相同,但在 CPU 方面。当然,您也可以将此代码移至着色器。

附:可能您的书/手册/教程稍后会了解它。所以,你最好相信它并一步一步地流动。

编码愉快! =)

【讨论】:

  • 感谢您的回复 Drop。我明白。我感到困惑的原因是因为几个月前我在 DirectX 9 中完成了一个教程,然后可以这样做:struct CUSTOMVERTEX { FLOAT x, y, z, rhw; DWORD color; }CUSTOMVERTEX OurVertices[] = { {320.0f, 50.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255),}, {520.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0),}, {120.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0),}, }; 那么他们是否从 DirectX 11 中删除了此功能?如果是,为什么?编辑:嗯,对不起,但代码标签不起作用:/
  • 是的,固定函数管道和预先转换的顶点声明不再存在。现在您必须编写自己的着色器程序并根据需要在其中转换顶点。为什么?嗯,我不知道答案。可能是因为大多数开发人员不需要它,并且将其包含在新的 API 中会使其更难以实现。
  • 使用第二种方法而不是使用第一种方法是否有很大的性能优势?
  • @PhoenixX_2 标准答案:视情况而定。在很多因素上。可以肯定的是,您确实需要尝试几种方法,分析并比较它们。乍一看,您似乎通过使用像PointToNdc 这样的函数来节省一些乘法。但是,“经典”向量矩阵 SIMD 优化乘法可能会更快。很难说,真的。无论如何,除非您使用正交投影绘制许多对象,否则您不太可能在这里遇到性能瓶颈。