XMVectorPermute

时间:2019-02-15 05:02:17

标签: c++ directx directx-11 directxmath

我是DirectX11的新手,我试图将使用DirectX Legacy编写的文件改编为新的DirectX,但是我对模板XMVectorPermute遇到了麻烦,该模板以前是Legacy文件中的函数。

我正在尝试使编译器识别DirectXMath.h中的模板:

// General permute template
template<uint32_t PermuteX, uint32_t PermuteY, uint32_t PermuteZ, uint32_t PermuteW>
    inline XMVECTOR     XM_CALLCONV     XMVectorPermute(FXMVECTOR V1, FXMVECTOR V2)
{
   //...Definition

通过使用以下代码:

template DirectX::XMVECTOR  DirectX::XMVectorPermute<PermuteXXY.i[0], PermuteXXY.i[1], PermuteXXY.i[2], PermuteXXY.i[3]>(FXMVECTOR V1, FXMVECTOR V2);

其中PermuteXXY定义为:

static CONST DirectX::XMVECTORI32 PermuteXXY =
{
    DirectX::XM_PERMUTE_0X, DirectX::XM_PERMUTE_0X, DirectX::XM_PERMUTE_0Y, DirectX::XM_PERMUTE_0W
};

,但是编译器或链接器无法匹配: Error reported

XM_PERMUTE_...被定义为const uint32_t中的DirectXMath.h,而XMVECTORI32被定义为并集:

union
    {
        int32_t i[4];
        XMVECTOR v;
    };

我不太擅长c ++模板,因此请尽可能彻底地帮助我。非常感谢!

1 个答案:

答案 0 :(得分:1)

这里有一些导致代码失败的问题。

首先,您不能使用XMVECTORI32的成员向XMVectorPermute提供模板参数。这不是因为类型不同(XMVECTORU32也会发生同样的情况)。我认为问题是因为数组i未声明为const,并且该值必须恒定才能用作模板参数。无论如何,VS2017都会拒绝编译代码。

第二,如果不为模板函数提供主体,则不能对其进行专门化处理。这意味着您的第二行是不完整的,并且需要您编写一个实现才能进行编译。

这并不意味着您是SOL,而是您需要更改方法。如果模板参数始终是常数(在代码中看起来应该是常数),则可以定义一个函数,该函数采用两个向量参数并指定要用于该特定操作的确切置换常数。

下面的代码是一个示例:

DirectX::XMVECTOR XMVectorPermuteXXY(DirectX::FXMVECTOR V1, DirectX::FXMVECTOR V2)
{
    return DirectX::XMVectorPermute<DirectX::XM_PERMUTE_0X,
                                    DirectX::XM_PERMUTE_0X, 
                                    DirectX::XM_PERMUTE_0Y,
                                    DirectX::XM_PERMUTE_0W>(V1, V2);
}

可以使用类似的方式定义需要指定的任何其他操作(XYXY,ZZWW,YYWZ等),并使用包装函数指定正确的模板参数。

第二种选择是使用XMVectorPermute的非模板版本,该版本采用两个向量和四个置换常数。这个版本可能会慢一些,但是允许您在运行时指定置换常量。

该代码如下:

XMVECTOR XMVectorPermuteXXY(FXMVECTOR V1, FXMVECTOR V2)
{
    return XMVectorPermute(V1, V2, 
                           XM_PERMUTE_0X, 
                           XM_PERMUTE_0X, 
                           XM_PERMUTE_0Y, 
                           XM_PERMUTE_0W);
}

根据要迁移的代码,您需要确定计划使用的版本。