我正在尝试在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个参数的函数
任何人都知道为什么会这样?或者另一种访问Matrix元素的方法?
感谢您的时间。
P.S。我正在为Windows 8创建一个C ++ / DirectX现代UI应用程序,如果这些信息有用的话。
答案 0 :(得分:4)
检查this MSDN link,您将看到它取决于您拥有的DirectX或XNA数学标头以及当时有效的预处理器定义。默认情况下,出于优化原因,矩阵和向量结构将使用SSE和内在函数实现,这使得提供行/列访问变得困难且昂贵。
尝试在项目属性的C ++条目的预处理器指令中定义_XM_NO_INTRINSICS_
,或在#define _XM_NO_INTRINSICS_
任何DirectX标头之前#include
。
我的Windows 8 VS2012系统上DirectXMath.h
的摘录显示了您收到此错误的原因:
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
};
答案 1 :(得分:1)
由于底层的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
我将提交一个doc bug,因为MSDN上提到的operator()实际上是" XNAMath",而不是" DirectXMath"。有关背景信息,请参阅this blog post。
如果您发现DirectXMath对您的需求有点过于强硬,您可能需要考虑在SimpleMath中使用DirectX Tool Kit。
答案 2 :(得分:1)
我发现这个工作正常,我也将我的代码基于相同的光线拾取教程,并且从xnamath转到directxmath。
这将从矩阵中选择正确的值,而无需禁用SSE内在函数。
"投影"是一个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);
使用定义禁用内在函数是一个错误的想法,因为它会极大地降低您的程序速度。如上所述,尽可能转换代码以正确加载和存储内在值。
答案 3 :(得分:0)
您可以尝试:
XMMATRIX i = XMMatrixIdentity();
float j = i.r[0].m128_f32[0];