【DX12】DirectX Math库 Vector和Matrix类型 XMVECTOR、XMMATRIX

本文详细介绍了DirectX Math库中的核心向量类型XMVECTOR及其衍生类型,包括XMVECTORF32和XMFLOATn的使用,以及向量的参数传递规则。此外,还探讨了矩阵类型XMMATRIX及其与XMFLOAT4X4的转换。内容涵盖了向量的运算、内存对齐和函数调用约定,帮助理解如何在DirectX编程中高效利用SIMD技术。
摘要由CSDN通过智能技术生成

DirectX Math Library 是一个3D数学库,包含在Windows SDK中。该库使用了SSE2(Streaming SIMD Extensions 2)指令集。使用128位宽的SIMD(Single Instruction Multiple Data)寄存器,因此做向量计算会更快。

注:在X86平台下,需要在VS中手动设置,启用SSE2(Enable Enhanced Instruction Set)。在任何平台下,都要手动启用fast floating point model。在project prote具体方法请查阅资料。

1 Vector

1.1 XMVECTOR

DirectX Math Library库中核心的Vector类型:XMVECTOR。是对SIMD硬件寄存器的映射。在当前CPU上SSE2指令集可用时,它是这样定义的:

typedef _m128 XMVECTOR;

_m128是由Microsoft提供的基本数据类型,用于与SSE、SSE2内部指令一起使用的。在16字节边界上自动对齐。ARM处理器不支持该类型。

虽然这是一个128位宽的寄存器,能存储一个四维的Vector,但当我们使用二维或三维的Vector运算时,为了效率,仍然会去使用XMVECTOR类型。

XMVECTOR的数据不能直接访问。可以转换成XMFLOAT类型(转换方法见下文),也可通过特定的接口get或set其某个分量:

// XM_CALLCONV 的作用之后会解释
// 为什么这个地方是FXMVECTOR,多了个‘F’,之后会解释
float XM_CALLCONV XMVectorGetX(FXMVECTOR V);
XMVECTOR XM_CALLCONV XMVectorSetX(FXMVECTOR V, float x);

XMVECTOR重载了加减乘除等运算符,可以方便的进行运算。

1.2 XMVECTORF32

XMVECTOR的常量实例,应定义为XMVECTORF32。

例如:

static const XMVECTORF32 g_vHalfVector = {
  0.5f ,0.5f, 0.5f, 0.5f};

XMVECTORF32可以转换为四维float数组,或者XMVECTOR。

1.3 XMFLOATn

上文提到,XMVECTOR需要16位对齐,当定义为局部或者全局变量时,这个对齐操作是自动的。当定义为类的成员变量时,推荐使用XMFLOAT2、XMFLOAT3、XMFLOAT4来代替。这些类型的数据结构,实际只是封装了几个普通的float变量。

XMVECTOR与XMFLOATn之间可以相互转换。当要进行计算操作时,建议将XMFLOATn转换为XMVECTOR。XMFLOATn到XMVECTOR的转换,需要通过DirectX Math loading functions来完成。
XMVECTOR到XMFLOATn的转换,需要通过DirectX Math storage functions来完成。

转换函数的申明如下:

// 加载XMFLOAT2到XMVECTOR
XMVECTOR XM_CALLCONV XMLoadFloat2(cosnt XMFLOAT2 *pSource);

// 存储XMVECTOR到XMFLOAT2
void XM_CALLCONV XMStoreFloat2(XMFLOAT2 *pDestination, FXMVECTOR V); 

1.4 参数传递

由于XMVECTOR的数据存储在寄存器,而不在堆栈上,因此参数传递时会有些特殊。基本的想法是,能用寄存器传递的就用寄存器传递,不能的就用栈。具体可以通过寄存器传递的参数数量,根据平台和编译器而定。

为此,增加了几种用于参数传递的数据类型,FXMVECTOR、GXMVECTOR、HXMVECTOR、CXMVECTOR。基本的使用规则是:

  1. 前三个XMVECTOR参数使用FXMVECTOR
  2. 第四个XMVECTOR参数使用GXMVECTOR
  3. 第五六个XMVECTOR参数使用HXMVECTOR
  4. 其他使用CXMVECTOR

而宏XM_CALLCONV,就是用于告诉编译器该函数调用时,有这种特别的参数传递规则。

所以会看到这样的定义:

void XM_CALLCONV XMStoreFloat2(XMFLOAT2 *pDestination, FXMVECTOR V); 

但是,这些规则在构造函数中并不适用。在构造函数中:

  1. 前三个XMVECTOR参数使用FXMVECTOR
  2. 其他使用CXMVECTOR
  3. 不要使用XM_CALLCONV

另外,这些规则只是针对于XMVECTOR类型本身。而对于复合类型,XMVECTOR&、XMVECTOR*并不会使用寄存器传递,和普通参数同等看待。

有了上面的基础可以看两个例子。有助于理解。

#include <windows.h> // 为了使用函数XMVeri
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值