代码之家  ›  专栏  ›  技术社区  ›  Morgan Johnson

使用模板在编译时跨结构字段迭代

  •  1
  • Morgan Johnson  · 技术社区  · 7 年前

    我在一个教授DirectX 11的类中担任助教,目前的问题是生成输入布局的D3D11\u INPUT\u ELEMENT\u DESC数组。讲师认为它很难看并且“接近硬件”在讲师看来,应该有一个干净漂亮的函数,我们可以简单地提供顶点结构,并获得适当的输入布局。我正在尝试编写这个函数。

    我做了一些研究,普遍的共识是,因为C++没有反射,所以不可能直接实现,但使用宏和boost phoenix有一个难看的解决方法(从某种程度上讲)。不幸的是,我无法使用Boost。我的技术限制是C++、Visual Studio Community 2017、Windows 10 SDK和2010年6月的DirectX 11 SDK。我意识到DirectX已经包含在Windows SDK中,但我们希望从2010年6月的版本中获得一些实用程序。

    这是我的理想解决方案:

    struct Vertex
    {
        XMFLOAT3 pos;
        XMFLOAT3 col;
        XMFLOAT3 norm;
        .
        .
        .
    };
    
    const char*[] bindings = {
        "POSITION",
        "COLOR",
        "NORMAL",
        .
        .
        .
    };
    
    //Takes a struct as template and a list of semantic bindings to create
    //an array of D3D11_INPUT_ELEMENT_DESCs for runtime processing.
    template <typename T>
    constexpr D3D11_INPUT_ELEMENT_DESC* processStruct(const char** semantics)
    {
        //what do I put here?
    }
    
    D3D11_INPUT_ELEMENT_DESC* layoutDescriptor = processStruct<Vertex>(bindings);
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Mauri    7 年前

    我不清楚如何使用顶点结构器和绑定字符串构建D3D11\u INPUT\u ELEMENT\u DESC。然而,以下尝试可能会帮助您实现目标:

    #include <thread>
    #include <iostream>
    
    const char* bin[] = {
        "pos",
        "col",
        "normal",
        "other"
    };
    
    class desc {
        public:
        constexpr desc() : desText(0){}
        constexpr desc(const char * str): desText(str) {}
        constexpr desc operator+(const desc) { return *this; }
        void printName() { std::cout << desText << std::endl;}
        const char* desText;
    };
    
    const int ARRAY_SIZE = 4;
    
    template <int N, int I=N-1>
    class Table : public Table<N, I-1>
    {
    public:
        static const desc dummy;
    };
    
    template <int N>
    class Table<N, 0>
    {
    public:
        static const desc dummy;
        static desc array[N];
    };
    
    template <int N, int I>
    const desc Table<N, I>::dummy = Table<N, 0>::array[I] = desc(bin[I]) + Table<N, I-1>::dummy;
    
    template <int N>
    const desc Table<N, 0>::dummy = Table<N, 0>::array[0] = desc(bin[0]);
    
    template <int N>
    desc Table<N, 0>::array[N];
    
    template class Table<ARRAY_SIZE>;
    
    int main(int, char**)
    {
        for (int i=0; i < ARRAY_SIZE; ++i)
            Table<ARRAY_SIZE>::array[i].printName();
    }
    

    live example