访问CXMMatrix - ()运算符的浮点数不起作用

时间:2018-04-29 14:48:46

标签: c++ directx directx-11

我正在尝试在directX11上使用“Frank Luna”书的更新代码,其中我使用VS2017和WindowsSDK10。我已经阅读了一些关于弗兰克移民的说明,并在下面的链接中说了一下: http://www.d3dcoder.net/Data/Book4/d3d11Win10.htm

但被困在这里。我知道@poncho也有同样的问题并且回答得很好: Access floats of XMMatrix - () operator not working

但我遇到类型CXMMATRIX而不是XMMATRIX的问题,我无法通过为他提供的解决方案获得结果。

所以我必须访问CXMMATRIX的行和列:

void ExtractFrustumPlanes(XMFLOAT4 planes[6], CXMMATRIX M)
{
    //
    // Left
    //
    planes[0].x = M(0,3) + M(0,0);
    planes[0].y = M(1,3) + M(1,0);
    planes[0].z = M(2,3) + M(2,0);
    planes[0].w = M(3,3) + M(3,0);
...

但我明白了:

  

调用没有适当的operator()或类的类类型的对象   转换函数到指针到函数类型

  

术语不评估为采用2个参数的函数

它指向CXMMATRIX类型的参数M,其在DirectXMath.h中定义如下:

// Fix-up for (2nd+) XMMATRIX parameters to pass by reference
typedef const XMMATRIX& CXMMATRIX; 

所有这些错误都是关于什么的?!

1 个答案:

答案 0 :(得分:1)

Frank Luna的书总体上是对Direct 11 API的一个很好的介绍,但遗憾的是,它大量使用了每MSDN弃用的旧版DirectX SDK。其中一个方面是他实际上使用xnamath库(a.k.a. xboxmath版本2)而不是DirectXMath库(a.k.a. xboxmath版本3)

请参阅Book RecommendationsIntroducing DirectXMath

在将库重新编写为DirectXMath时,我做了一些更改。首先,类型实际上是在C ++命名空间而不是全局命名空间。在标题中,您应该使用全名规范:

#include <DirectXMath.h>

void MyFunction(..., DirectX::CXMMATRIX M);

在您的cpp源文件中,您应该使用:

#include <DirectXMath.h>

using namespace DirectX;

另一个变化是强烈反对在XMVECTORXMMATRIX数据类型上使用“按元素”访问权限。正如DirectXMath Programmers Guide中所讨论的,这些类型是SIMD寄存器类型的设计代理,不能通过元素直接访问。相反,您转换为允许每个元素访问的XMFLOAT4X4表示,因为这是一个标量结构。

您可以通过以下事实看到这一点:您尝试使用的运算符仅定义为“无内在函数”模式(即使用标量而不是SSE,ARM-NEON等SIMD操作时):

#ifdef _XM_NO_INTRINSICS_
    float operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float& operator() (size_t Row, size_t Column) { return m[Row][Column]; }
#endif

同样,按照设计,这个过程有点'冗长',因为它让你知道它不是免费的。有些人发现DirectXMath的这个方面有点令人沮丧,尤其是在他们刚开始使用时。在这种情况下,我建议您查看SimpleMath中的DirectX Tool Kit包装器。您可以使用Vector3Vector4Matrix等类型,并根据需要自由转换(通过C ++运算符和构造函数)到XMVECTORXMMATRIX 。它的效率不高,但使用起来要宽松得多。

您编写的特定功能也有点问题。首先,混合XMFLOAT4XMMATRIX参数有点奇怪。对于'in-register,SIMD-friendly'调用约定,您可以使用:

void XM_CALLCONV ExtractFrustumPlanes(XMVECTOR planes[6], FXMMATRIX M)

有关原因的详细信息,请参阅MSDN

如果您想完全标量数学,请使用非SIMD类型:

void ExtractFrustumPlanes(XMFLOAT4 planes[6], const XMFLOAT4X4& M)

或更好地使用SimpleMath,这样您就可以避免必须将显式转换写入XMVECTORXMMATRIX

using DirectX::SimpleMath;

void ExtractFrustumPlanes(Vector4 planes[6], const Matrix& M)
  

请注意,最新版本的DirectXMath位于GitHubNuGet