4

我正在尝试在 DirectX 中做一些 3D 的东西(我正在从 OpenGL 迁移)并且我遇到了障碍。

我想访问 XMMATRIX 的值并查看 Microsoft 文档,应该有一个 () 运算符:

    float&  operator ()(
  size_t Row,
  size_t Column
);

所以我尝试这样使用:

XMMATRIX i = XMMatrixIdentity();
float j = i(0,0);

但是 Intellisense 给了我错误:

IntelliSense:在没有适当的 operator() 或将函数转换为指针函数类型的情况下调用类类型的对象。

如果我忽略 Intellisense 并编译,我会收到编译时错误:

错误 C2064:术语不计算为采用 2 个参数的函数

有人知道为什么会这样吗?或者另一种访问矩阵元素的方法?

谢谢你的时间。

PS 如果这些信息有帮助,我正在为 Windows 8 创建一个 C++/DirectX 现代 UI 应用程序。

4

5 回答 5

6

检查此 MSDN 链接,您会发现它取决于您拥有的 DirectX 或 XNA 数学标头以及当时有效的预处理器定义。默认情况下,出于优化原因,矩阵和向量结构将使用 SSE 和内在函数实现,这使得提供行/列访问变得困难且昂贵。

尝试_XM_NO_INTRINSICS_在项目属性的 C++ 条目的预处理器指令中定义,或#define _XM_NO_INTRINSICS_#include任何 DirectX 标头之前定义。

DirectXMath.h我的 Windows 8 VS2012 系统上的这段摘录显示了您收到此错误的原因:

struct XMMATRIX
{
    // ... code removed for clarity

#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

    // ... code removed for clarity
};
于 2013-07-04T19:50:39.590 回答
5

由于底层 SIMD 指令集,单个元素的访问XMVECTOR效率XMMATRIX非常低,因此 DirectXMath 库不通过成员方法支持它。根据您的需要,有多种方法可以实现这一目标。

如果您只需要 (0,0) 元素,您可以使用:

float j = XMVectorGetX( i.r[0] );

如果您要访问 XMMATRIX 的大部分或全部单个元素,最好的解决方案是将其转储到XMFLOAT4X4

XMFLOAT4X4 tmp;
XMStoreFloat4x4( &tmp, i );
float j = tmp.m[0][0]; // or float j = tmp._11

我将提交一个文档错误,因为 MSDN 上提到的 operator() 实际上是“XNAMath”,而不是“DirectXMath”。有关一些背景信息,请参阅此博客文章

如果您发现 DirectXMath 对您的需求来说过于硬核,您可能需要考虑在DirectX Tool Kit中使用SimpleMath

于 2014-10-20T05:32:48.783 回答
1

我发现这是可行的,我的代码也基于相同的光线拾取教程,并且正在从 xnamath 转移到 directxmath。

这将从矩阵中选择正确的值,而无需禁用 SSE Intrinsics。

“投影”是一个 XMMATRIX,包含来自相机的视图矩阵。

    XMVECTOR xv = projection.r[0];
    XMVECTOR yv = projection.r[1];
    PRVecX =  ((( 2.0f * mouseX) / Window::ClientWidth) - 1 ) / XMVectorGetX(xv);
    PRVecY = -((( 2.0f * mouseY) / Window::ClientHeight) - 1 ) / XMVectorGetY(yv);

使用定义禁用内在函数是一个主意,因为它会极大地减慢您的程序。在可能的情况下,将您的代码转换为正确加载和存储内在值,如上所述。

于 2015-02-03T10:29:22.150 回答
1

在文件头添加#define _XM_NO_INTRINSICS_。</p>

#include <windows.h>
#define _XM_NO_INTRINSICS_//must before #include <DirectXMath.h>
#include <DirectXMath.h>
#include <iostream>
于 2017-02-24T08:58:41.563 回答
0

你可以试试:

XMMATRIX i = XMMatrixIdentity();
float j = i.r[0].m128_f32[0];
于 2014-10-19T18:32:44.057 回答