我刚刚开始使用DirectXMath。我想用 相交功能检查两个三角形是否相交。但每次我调用函数时,我都会得到一个exeption。我认为这是因为我没有以正确的方式创建XMVECTOR参数。我尝试了两种方式:
DirectX::XMVECTOR r = DirectX::XMVectorSet(m_x, m_y, m_z, 1.0f);
DirectX::XMVECTORI32 t = { m_x, m_y, m_z, 1.0f };
两种方式都不起作用,因为XMVECTOR没有x y z成员,所以我无法理解这种数据类型的工作原理。
我真的很感激一些帮助!提前谢谢!
答案 0 :(得分:2)
到目前为止,实际上该线程中提到的所有方法都是有效的方法,但是具有不同的用途和性能含义。
如果要创建四个浮点常量值的“向量常量”,最好的答案是使用XMVECTORF32
:
static const XMVECTORF32 s_MyValue = { 1.f, 2.f, 3.f, 4.f };
编译器通常可以将其放入程序的数据段中,因此在运行时,您只需调用MOVAPS
即可将数据放入SSE寄存器中。
XMVECTORU32
和XMVECTORI32
类型做同样的事情,但是假设您要将元素初始化为unsigned int
或int
,通常与按位或选择一起使用。 DirectXMath库执行的操作不多于几个整数操作。
如果要将数据存储在内存中,一个好的解决方案是在数据结构中使用XMFLOAT4
并使用XMLoadFloat4
将其放入XMVECTOR
:
XMVECTOR v = XMLoadFloat4(&myClass.myValue);
// This is equivalent in SSE to using _mm_loadu_ps
DirectXMath库中的绝大多数类型旨在用于数据结构。您使用
XMVECTOR
和XMMATRIX
进行所有计算,并使用装入和保存例程将数据输入和输出这些类型。
如果您需要从一组4个标量浮点变量中设置一个向量,那么XMVectorSet
就是这样的:
XMVECTOR v = XMVectorSet( m_x, m_y, m_y, 1.f );
// This is equivalent in SSE to using _mm_set_ps.
如果要将单个标量值加载到所有四个位置,则可以使用:
XMVECTOR v = XMVectorReplicate( m_a );
// This is equivalent in SSE to using _mm_set_ps1.
如果要将标量值从内存中的值加载到所有四个位置,则另一个选择是:
XMVECTOR v = XMVectorReplicatePtr( &m_a );
// This is equivalent in SSE to using _mm_load_ps1.
// If you were building with /arch:AVX, it would be _mm_broadcast_ss
还有一些特殊用途的函数,例如XMVectorSetX
/ XMVectorSetXPtr
,XMVectorSetY
/ XMVectorSetYPtr
,XMVectorSetZ
/ XMVectorSetZPtr
,{{ 1}} / XMVectorSetW
,以及速度较慢的XMVectorSetWPtr
/ XMVectorSetByIndex
。
如果您不熟悉DirectXMath,请花一些时间通读DirectXMath Programming Guide。它并不特别长,并且包含了信息和提示。
另请参阅Introducing DirectXMath和我的其他blog posts。另外,请务必检查GitHub project。
某些人发现DirectXMath的SIMD友好对齐规则有些令人沮丧,尤其是当它们刚开始使用时,这就是为什么我还创建了SimpleMath wrapper的原因,该DirectX Tool Kit包含在{{3}}中。在这种情况下,您将使用类似
XMVectorSetIndexPtr
的名称,然后可以在任何使用Vector4 v( m_x, m_y, m_z, 1.f );
的地方使用v
。