如何在DirectX中初始化XMVECTOR?

时间:2018-06-18 09:57:37

标签: c++ directx

我刚刚开始使用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成员,所以我无法理解这种数据类型的工作原理。

我真的很感激一些帮助!提前谢谢!

1 个答案:

答案 0 :(得分:2)

到目前为止,实际上该线程中提到的所有方法都是有效的方法,但是具有不同的用途和性能含义。

如果要创建四个浮点常量值的“向量常量”,最好的答案是使用XMVECTORF32

static const XMVECTORF32 s_MyValue = { 1.f, 2.f, 3.f, 4.f };

编译器通常可以将其放入程序的数据段中,因此在运行时,您只需调用MOVAPS即可将数据放入SSE寄存器中。

  

XMVECTORU32XMVECTORI32类型做同样的事情,但是假设您要将元素初始化为unsigned intint,通常与按位或选择一起使用。 DirectXMath库执行的操作不多于几个整数操作。

如果要将数据存储在内存中,一个好的解决方案是在数据结构中使用XMFLOAT4并使用XMLoadFloat4将其放入XMVECTOR

XMVECTOR v = XMLoadFloat4(&myClass.myValue);
// This is equivalent in SSE to using _mm_loadu_ps
  

DirectXMath库中的绝大多数类型旨在用于数据结构。您使用XMVECTORXMMATRIX进行所有计算,并使用装入和保存例程将数据输入和输出这些类型。

如果您需要从一组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 / XMVectorSetXPtrXMVectorSetY / XMVectorSetYPtrXMVectorSetZ / 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