【问题标题】:How does DirectX read in vertices?DirectX 如何读取顶点?
【发布时间】:2024-01-16 13:04:01
【问题描述】:

所以我浏览了一些教程和资源,例如 DirectX 文档/参考本身,或者我错过了一些东西,或者我真的找不到我的问题的答案。

问题如题所述:DirectX如何将Vertices中的数据读入Vertex Buffers?

当然,我知道您必须提供一个或多个 FVF 代码。但它没有说明如何正确设置您的 Vertex 结构。我唯一能想到的是,DirectX 在线性“时间线”中检查标志,当然,因此可能需要相同数据类型和顺序的标志也必须位于结构的首位。

作为我的意思的一个小例子:

struct MyVertex {
    float x, y, z;
    float nx, ny, ny;
};

!=

struct MyVertex {
    float nx, ny, nz;
    float x, y, z;
};

使用 FVF 代码:

D3DFVF_XYZ | D3DFVF_NORMAL

nxnynz代表法线顶点的3D坐标。

感谢任何有关如何正确设置顶点结构的帮助...

此致,

德里亚

【问题讨论】:

    标签: directx structure vertexdata


    【解决方案1】:

    您需要确保 C++ 和 HLSL 结构与在顶点格式中指定的顺序相匹配(如果您指定 XYZ 然后是 Normal,则您的结构必须与此匹配),然后您需要使用 device->CreateBuffer要从顶点结构数组创建顶点缓冲区,之后可以释放和释放顶点结构数组,因为 DirectX 将从那里独立管理缓冲区数据,要更改渲染循环中的数据,缓冲区必须是可写的,并且可以在创建后使用 ID3D10Buffer Map 和 Unmap 进行更新。

    MSDN:
    创建顶点缓冲区http://msdn.microsoft.com/en-us/library/windows/desktop/bb173544(v=vs.85).aspx 缓冲区:http://msdn.microsoft.com/en-us/library/windows/desktop/bb173510(v=vs.85).aspx

    例如:C++

    D3D10_INPUT_ELEMENT_DESC layoutPosTexNormCInstanced[] = 
    {
    {"POSITION",     0, DXGI_FORMAT_R32G32B32_FLOAT,    0,  0, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"TEXCOORD",     0, DXGI_FORMAT_R32G32_FLOAT,       0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"NORMAL",       0, DXGI_FORMAT_R32G32B32_FLOAT,    0, 20, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"TANGENT",      0, DXGI_FORMAT_R32G32B32_FLOAT,    0, 32, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"BINORMAL",     0, DXGI_FORMAT_R32G32B32_FLOAT,    0, 44, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_SINT,      0, 56, D3D10_INPUT_PER_VERTEX_DATA, 0 }, //4
    {"mTransform",   0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1,  0, D3D10_INPUT_PER_INSTANCE_DATA, 1 },
        {"mTransform",   1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D10_INPUT_PER_INSTANCE_DATA, 1 },
        {"mTransform",   2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D10_INPUT_PER_INSTANCE_DATA, 1 },
        {"mTransform",   3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 48, D3D10_INPUT_PER_INSTANCE_DATA, 1 },
    };
    
    
    //Contains the position, texture coordinate and normal for lighting calculations.
    struct DX10VertexNormal
    {
    //Constructor.
    DX10VertexNormal()
    {
        ZeroMemory(this, sizeof(DX10VertexNormal));
        boneIndex[0] = -1;
        boneIndex[1] = -1;
        boneIndex[2] = -1;
        boneIndex[3] = -1;
    };
    
    //PAD to 4.
    D3DXVECTOR3 pos;
    D3DXVECTOR2 tcoord;
    D3DXVECTOR3 normal;
    D3DXVECTOR3 tangent;
    D3DXVECTOR3 binormal;
    int boneIndex[4];
    
    };
    

    HLSL:

    ///Holds the vertex shader data for rendering 
    ///instanced mesh data, with position, texture coord, 
    ///and surface normal for lighting calculations.
    struct VS_Instanced_PosTexNorm_INPUT
    {
      float4 Pos: POSITION;
      float2 Tex: TEXCOORD;
      float3 Norm: NORMAL;
      float3 Tangent: TANGENT;
      float3 Binormal: BINORMAL;
      int4 boneIndex: BLENDINDICES;
      row_major float4x4 mTransform : mTransform;
      uint InstanceId : SV_InstanceID;
    };
    

    【讨论】:

    • 它基本上使用语义('POSITION'、'TEXCOORD' 等)来知道什么结构在哪里,当它从 CPU 写入 GPU 时,DirectX 会在您渲染时自动执行此操作这种技术!)
    • 请注意,vert decls 不是 D3D10+ 功能,它们是在 9 中引入和首选的,在 10 中成为必需的。它们比 FVF 灵活得多(允许很多 FVF 不能做的事情),但确实需要实际创建。
    • 感谢您的回答。它很好地解决了我的问题。 @peachykeen:也感谢您的留言。提供我目前使用的详细教程的网站是从 DX9 开始的。在那里,大部分基础知识都得到了处理。 DX10 和 11 在网站的不同部门进行了处理,并在基础知识的基础上添加了更多内容,所以我很确定某处的网站也这么说。
    相关资源