我正在尝试在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;
所有这些错误都是关于什么的?!
答案 0 :(得分:1)
Frank Luna的书总体上是对Direct 11 API的一个很好的介绍,但遗憾的是,它大量使用了每MSDN弃用的旧版DirectX SDK。其中一个方面是他实际上使用xnamath库(a.k.a. xboxmath版本2)而不是DirectXMath库(a.k.a. xboxmath版本3)
请参阅Book Recommendations和Introducing DirectXMath
在将库重新编写为DirectXMath时,我做了一些更改。首先,类型实际上是在C ++命名空间而不是全局命名空间。在标题中,您应该使用全名规范:
#include <DirectXMath.h>
void MyFunction(..., DirectX::CXMMATRIX M);
在您的cpp源文件中,您应该使用:
#include <DirectXMath.h>
using namespace DirectX;
另一个变化是强烈反对在XMVECTOR
和XMMATRIX
数据类型上使用“按元素”访问权限。正如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包装器。您可以使用Vector3
,Vector4
,Matrix
等类型,并根据需要自由转换(通过C ++运算符和构造函数)到XMVECTOR
和XMMATRIX
。它的效率不高,但使用起来要宽松得多。
您编写的特定功能也有点问题。首先,混合XMFLOAT4
和XMMATRIX
参数有点奇怪。对于'in-register,SIMD-friendly'调用约定,您可以使用:
void XM_CALLCONV ExtractFrustumPlanes(XMVECTOR planes[6], FXMMATRIX M)
有关原因的详细信息,请参阅MSDN。
如果您想完全标量数学,请使用非SIMD类型:
void ExtractFrustumPlanes(XMFLOAT4 planes[6], const XMFLOAT4X4& M)
或更好地使用SimpleMath,这样您就可以避免必须将显式转换写入XMVECTOR
或XMMATRIX
using DirectX::SimpleMath;
void ExtractFrustumPlanes(Vector4 planes[6], const Matrix& M)