「dx12 ドラゴンブック」前編 学習ノート (2)

1. DirectXMath ライブラリのベクトル演算:
(1) ベクトル型:
 コア ベクトル型は XMVECTOR で、SIMD ハードウェア レジスタにマップされます。
 typedef __m128 XMVECTOR;
 ここで __m128 は特殊な SIMD 型です。
 XMVECTOR 型のデータは、ローカル変数とグローバル変数に対して自動的に実装される 16 バイトで整列する必要があります。
 クラスのデータ メンバーには、代わりに XMFLOAT2、XMFLOAT3、および XMFLOAT4 型を使用することをお勧めします。
 SIMD テクノロジの効率的な機能を最大限に活用するには、これらの型のインスタンスを XMVECTOR 型に変換する必要もあります。変換処理は、DirectXMath ライブラリのロード機能によって実現できます。逆に、DirectXMath ライブラリは、XMVECTOR 型を XMFLOATn 型に変換するためのストレージ関数も提供します。
 概要:
  a. ローカル変数またはグローバル変数には XMVECTOR 型を使用します。
  b. クラスのデータ メンバーには、XMFLOAT2、XMFLOAT3、XMFLOAT4 型を使用します。
  c. 操作前に、ロード関数を使用して XMFLOATn 型を XMVECTOR 型に変換します。
  d. XMVECTOR インスタンスを使用して操作を実行します。
  e. ストレージ関数を使用して、XMVECTOR 型を XMFLOATn 型に変換します。
2.ロードと保管方法:

#include <iostream>
#include <DirectXMath.h>
#include <DirectXPackedVector.h>

int main()
{
    typedef __m128 XMVECTOR;
    typedef const XMVECTOR FXMVECTOR;

    //通过下列方法将数据从XMFLOATn类型加载到XMVECTOR类型中
    //将数据从XMFLOAT2类型中加载到XMVECTOR类型
    XMVECTOR XM_CALLCONV XMFLoadFloat2(const XMFLOAT2 *pSource);
    //将数据从XMFLOAT3类型中加载到XMVECTOR类型
    XMVECTOR XM_CALLCONV XMFLoadFloat3(const XMFLOAT3 *pSource);
    //将数据从XMFLOAT4类型中加载到XMVECTOR类型
    XMVECTOR XM_CALLCONV XMFLoadFloat4(const XMFLOAT4 *pSource);

    //通过下列方法将数据从XMVECTOR类型加载到XMFLOATn类型中
    //将数据从XMVECTOR类型中加载到XMFLOAT2类型
    void XM_CALLCONV XMStoreFloat2(XMFLOAT2 *pDestination, FXMVECTOR V);
	//将数据从XMVECTOR类型中加载到XMFLOAT3类型
	void XM_CALLCONV XMStoreFloat3(XMFLOAT3 * pDestination, FXMVECTOR V);
	//将数据从XMVECTOR类型中加载到XMFLOAT4类型
	void XM_CALLCONV XMStoreFloat4(XMFLOAT4 * pDestination, FXMVECTOR V);

	//从XMVECTOR实例中得到某一个向量分量或将某一向量分量转换为XMVECTOR类型
	//取分量
	float XM_CALLCONV XMVectorGetX(FXMVECTOR V);
	float XM_CALLCONV XMVectorGetY(FXMVECTOR V);
	float XM_CALLCONV XMVectorGetZ(FXMVECTOR V);
	float XM_CALLCONV XMVectorGetW(FXMVECTOR V);
	//存分量
	XMVECTOR XM_CALLCONV XMVectorSetX(FXMVECTOR V, float x);
	XMVECTOR XM_CALLCONV XMVectorSetY(FXMVECTOR V, float y);
	XMVECTOR XM_CALLCONV XMVectorSetZ(FXMVECTOR V, float z);
	XMVECTOR XM_CALLCONV XMVectorSetW(FXMVECTOR V, float w);
}

struct XMFLOAT2
{
	float x;
	float y;
	
	XMFLOAT2() {}
	XMFLOAT2(float _x, float _y) : x(_x), y(_y) {}
	explicit XMFLOAT2(_In_reads_(2) const float *pArray) : x(pArray[0]), y(pArray[1]) {}
		
	XMFLOAT2& operator= (const XMFLOAT2& Float2) { x = Float2.x; y = Float2.y; return *this; }
};
 
struct XMFLOAT3
{
	float x;
	float y;
	float z;
	
	XMFLOAT3() {}
	XMFLOAT3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
	explicit XMFLOAT3(_In_reads_(3) const float *pArray) : x(pArray[0]), y(pArray[1]), z(pArray[2]) {}
	
	XMFLOAT3& operator= (const XMFLOAT3& Float3) { x = Float3.x; y = Float3.y; z = Float3.z; return *this; }
};
 
struct XMFLOAT4
{
	float x;
	float y;
	float z;
	float w;
	
	XMFLOAT4() {}
	XMFLOAT4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {}
	explicit XMFLOAT4(_In_reads_(4) const float *pArray) : x(pArray[0]), y(pArray[1]), z(pArray[2]), w(pArray[3]) {}
	
	XMFLOAT4& operator= (const XMFLOAT4& Float4) { x = Float4.x; y = Float4.y; z = Float4.z; w = Float4.w; return *this; }
};

通常の開発では、名前空間 DirectX を使用して定数データ型を作成できます。

3. パラメータ転送:
 効率を向上させるために、XMVECTOR 型の値を関数のパラメータとして使用し、スタックに格納する代わりに直接 SSE/SSE2 レジスタに転送することができます。
 この方法で渡される引数は、ユーザーが使用するプラットフォームとコンパイラによって異なります。したがって、コードをより用途の広いものにし、特定のプラットフォームやコンパイラの影響を受けないようにするために、XMVECTOR 型のパラメーターは、FXMVECTOR、GXMVECTOR、HXMVECTOR、および CXMVECTOR 型を使用して渡されます。
 関数名をロードする前に、必ず呼び出し規約に XM_CALLCONV の注釈を付けてください。
 XMVECTOR 引き渡しパラメーターの規則:
  a. 最初の 3 つの XMVECTOR パラメーターは型 FXMVECTOR を使用する必要があります;
  b. 4 番目の XMVECTOR パラメーターは型 GXMVECTOR を使用する必要があります; c
  . 5 番目と 6 番目の XMVECTOR パラメーターは型 HXMVECTOR を使用する必要があります;
  d. 残りの XMVECTOR パラメーターは型を使用する必要がありますNote: Do not use XM_CALLCONV  for constructors  . __vectorcall の制限により、C++ コンストラクターには GXMVECTOR または HXMVECTOR を使用しないことをお勧めします
最初の 3 つの XMVECTOR 値には FXMVECTOR を使用し、残りの値には CXMVECTOR を使用します。XMVECTOR 型のパラメーターの間に、XMVECTOR 型以外の他のパラメーターを混在させることもできます。現時点では、XMVECTOR パラメーターの規則が引き続き適用され、XMVECTOR パラメーターの数をカウントするときに、他の種類のパラメーターは無視されます。
最新の公式番号



XMVECTOR パラメーターを渡す規則は、「入力」パラメーターにのみ適用されます。「出力」XMVECTOR パラメーター (つまり、XMVECTOR& または XMVECTOR*) は SSE/SSE2 レジスターを占有しないため、非 XMVECTOR タイプのパラメーターと同じように扱われます。

おすすめ

転載: blog.csdn.net/weixin_47819574/article/details/126727014