访问 CXMMatrix 的浮点数 - () 运算符不起作用
Access floats of CXMMatrix - () operator not working
我正在尝试在 directX11 上使用 "Frank Luna" 书中的更新代码,其中我使用 VS2017 和 WindowsSDK10。我从 Frank 那里读到了一些关于迁移的笔记,并做了他在下面 link 中所说的一切:
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);
...
但我得到:
call of an object of a class type without appropriate operator() or
conversion functions to pointer-to-function type
和
term does not evaluate to a function taking 2 arguments
它指向 CXMMATRIX 类型的参数 M,在 DirectXMath.h 中定义如下:
// Fix-up for (2nd+) XMMATRIX parameters to pass by reference
typedef const XMMATRIX& CXMMATRIX;
关于 !?
的所有这些错误是什么?
Frank Luna 的书总体上是对 Direct 11 API 的精彩介绍,但不幸的是,它大量使用了旧版 DirectX SDK,根据 MSDN 已弃用。其中一个方面是他实际上使用的是 xnamath 库(a.k.a.xboxmath 版本 2)而不是 DirectXMath 库(a.k.a.xboxmath 版本 3)
见Book Recommendations and Introducing DirectXMath
我在将库重新设计为 DirectXMath 时进行了一些更改。首先,这些类型实际上位于 C++ 命名空间中,而不是全局命名空间中。在你的 headers 中,你应该使用全名规范:
#include <DirectXMath.h>
void MyFunction(..., DirectX::CXMMATRIX M);
在你的 cpp 源文件中你应该使用:
#include <DirectXMath.h>
using namespace DirectX;
另一个变化是强烈反对对 XMVECTOR
和 XMMATRIX
数据类型使用 'per-element' 访问。正如 DirectXMath Programmers Guide 中所讨论的,这些类型是设计为无法直接访问的 SIMD 寄存器类型的代理 by-element。相反,您转换为允许 per-element 访问的 XMFLOAT4X4
表示,因为这是一个标量结构。
您可以通过以下事实看到这一点:您尝试使用的运算符仅为 'no-intrinsics' 模式定义(即当使用标量而不是 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
同样,根据设计,此过程有点 'verbose' 因为它让您知道它不是免费的。有些人发现 DirectXMath 的这一方面使用起来有点令人沮丧,尤其是在他们刚开始使用时。在那种情况下,我建议您看一下 SimpleMath wrapper in the 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。
如果您只想进行纯标量数学运算,请使用 non-SIMD 类型:
void ExtractFrustumPlanes(XMFLOAT4 planes[6], const XMFLOAT4X4& M)
或更好的是使用 SimpleMath,这样您就可以避免编写显式转换 to/from XMVECTOR
或 XMMATRIX
using DirectX::SimpleMath;
void ExtractFrustumPlanes(Vector4 planes[6], const Matrix& M)
Note that the latest version of DirectXMath is on GitHub and NuGet.
我正在尝试在 directX11 上使用 "Frank Luna" 书中的更新代码,其中我使用 VS2017 和 WindowsSDK10。我从 Frank 那里读到了一些关于迁移的笔记,并做了他在下面 link 中所说的一切: 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);
...
但我得到:
call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type
和
term does not evaluate to a function taking 2 arguments
它指向 CXMMATRIX 类型的参数 M,在 DirectXMath.h 中定义如下:
// Fix-up for (2nd+) XMMATRIX parameters to pass by reference
typedef const XMMATRIX& CXMMATRIX;
关于 !?
的所有这些错误是什么?Frank Luna 的书总体上是对 Direct 11 API 的精彩介绍,但不幸的是,它大量使用了旧版 DirectX SDK,根据 MSDN 已弃用。其中一个方面是他实际上使用的是 xnamath 库(a.k.a.xboxmath 版本 2)而不是 DirectXMath 库(a.k.a.xboxmath 版本 3)
见Book Recommendations and Introducing DirectXMath
我在将库重新设计为 DirectXMath 时进行了一些更改。首先,这些类型实际上位于 C++ 命名空间中,而不是全局命名空间中。在你的 headers 中,你应该使用全名规范:
#include <DirectXMath.h>
void MyFunction(..., DirectX::CXMMATRIX M);
在你的 cpp 源文件中你应该使用:
#include <DirectXMath.h>
using namespace DirectX;
另一个变化是强烈反对对 XMVECTOR
和 XMMATRIX
数据类型使用 'per-element' 访问。正如 DirectXMath Programmers Guide 中所讨论的,这些类型是设计为无法直接访问的 SIMD 寄存器类型的代理 by-element。相反,您转换为允许 per-element 访问的 XMFLOAT4X4
表示,因为这是一个标量结构。
您可以通过以下事实看到这一点:您尝试使用的运算符仅为 'no-intrinsics' 模式定义(即当使用标量而不是 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
同样,根据设计,此过程有点 'verbose' 因为它让您知道它不是免费的。有些人发现 DirectXMath 的这一方面使用起来有点令人沮丧,尤其是在他们刚开始使用时。在那种情况下,我建议您看一下 SimpleMath wrapper in the 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。
如果您只想进行纯标量数学运算,请使用 non-SIMD 类型:
void ExtractFrustumPlanes(XMFLOAT4 planes[6], const XMFLOAT4X4& M)
或更好的是使用 SimpleMath,这样您就可以避免编写显式转换 to/from XMVECTOR
或 XMMATRIX
using DirectX::SimpleMath;
void ExtractFrustumPlanes(Vector4 planes[6], const Matrix& M)
Note that the latest version of DirectXMath is on GitHub and NuGet.