DirectX 9, 10의 D3DX Library에, 11에서는 XNA Math에서 3차원 그래픽에 필요한 것들을 지원한다.

코드상에서는 xnamath.h를 include 하면 사용이 가능하다고 설명되어 있다.

하지만 현재 예시 DirectX12 코드에서는 관련 기능들이 DiretXMath.h에 선언이 되어 있다.

명확하게 이전 되었다는 내용을 찾지는 못했지만, xnamath.h와 DirectXMath.h의 document를 보면 설명이 동일하다.

때문에 여기서는 DirectXMath.h를 기준으로 설명하겠다.

또한 관련해서 답이 충분히 될법한 링크 또한 첨부한다.

https://docs.microsoft.com/en-us/windows/win32/dxmath/pg-xnamath-migration#header-changes

 

Code Migration from the XNA Math Library - Win32 apps

Code Migration from the XNA Math Library In this article --> This overview describes the changes required to migrate existing code using the XNA Math library to the DirectXMath library. The DirectXMath library uses a new set of headers. Replace the xnamath

docs.microsoft.com

 

이 Library는 벡터 연산에 매우 유용하다.

이를 설명하기 위해서는 먼저 Library의 연산 과정을 조금 언급해야 한다.

DirectXMath Library는 Windows와 XBox 360에서 사용가능한 특별한 하드웨어 레지스터들을 활용한다.

Windows에서는 SSE2(Streaming SIMD Extensions) 명령집합을 사용하는데,
SIMD의 명령덜은 128비트 너비의 SIMD(Single Instruction Multiple Data) 레지스터들을 이용해
한 명령에서 32비트 float나 int 4개를 동시에 처리가 가능하다.

 

DirectXMath에서 핵심 Vector 형식은 SIMD 하드웨어 레지스터들에 대응되는 XMVECTOR이다.

#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
typedef __m128 XMVECTOR;
#elif defined(_XM_ARM_NEON_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
typedef float32x4_t XMVECTOR;
#else
typedef __vector4 XMVECTOR;
#endif

128bit 크기로, 하나의 SIMD 명령으로 처리되는 4개의 32bit float 값들로 이루어져있다.

저기서 _XM_SSE_INTRINSICS_는 SSE나 SSE2를, _XM_ARM_NEON_INTRINSICS_는 Windows RT.

즉, 모바일 플랫폼을 나타낸다.

_XM_NO_INTRINSICS_는 Windows 환경이 아닌 곳에서 DirectXMath가 따로 사용되는 경우를 일컫는다.

 

여기서 __m128은 특별한 SIMD 형식이다.

이 형식의 Vector들은 계산 시 반드시 SIMD의 장점을 취하게 된다.

게다가 2, 3차원 Vector일 경우, 사용하지 않는 element를 0으로 설정해 동일하게 SIMD의 장점을 취한다.

 

다만 여기에는 몇가지 규칙이 있는데, 플랫폼마다 규칙이 다르다.

특히 Windows 23bit와 64bit, XBox 360의 규칙들이 서로 다르다.

이런 차이로부터 독립적이기 위해, XMVECTOR 대신 CXXMVECTOR 형식과 FXMVECTOR형식을 사용한다.

// Fix-up for (1st-3rd) XMVECTOR parameters that are pass-in-register for x86, ARM, ARM64, and vector call; by reference otherwise
#if ( defined(_M_IX86) || defined(_M_ARM) || defined(_M_ARM64) || _XM_VECTORCALL_ ) && !defined(_XM_NO_INTRINSICS_)
typedef const XMVECTOR FXMVECTOR;
#else
typedef const XMVECTOR& FXMVECTOR;
#endif

// Fix-up for (4th) XMVECTOR parameter to pass in-register for ARM, ARM64, and x64 vector call; by reference otherwise
#if ( defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || (_XM_VECTORCALL_ && !defined(_M_IX86) ) ) && !defined(_XM_NO_INTRINSICS_)
typedef const XMVECTOR GXMVECTOR;
#else
typedef const XMVECTOR& GXMVECTOR;
#endif

// Fix-up for (5th & 6th) XMVECTOR parameter to pass in-register for ARM64 and vector call; by reference otherwise
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || _XM_VECTORCALL_ ) && !defined(_XM_NO_INTRINSICS_)
typedef const XMVECTOR HXMVECTOR;
#else
typedef const XMVECTOR& HXMVECTOR;
#endif

// Fix-up for (7th+) XMVECTOR parameters to pass by reference
typedef const XMVECTOR& CXMVECTOR;

 

32bit와 64bit의 차이는 복사 전달과 참조전달이다.

FXMVECTOR, CXMVECTOR. 더 나아가 GXMVECTOR, HXMVECTOR의 차이는 다음과 같다.

매개변수로 XMVECTOR을 전달 할 때,

  1. 1, 2, 3번째 XMVECTOR는 FXMVECTOR로 전달해야 한다.
  2. 4번째 XMVECTOR는 GXMVECTOR로 전달해야 한다.
  3. 5, 6번째 XMVECTOR는 HXMVECTOR로 전달해야 한다.
  4. 7번째 이후로는 CXMVECTOR로 전달해야 한다.

단, 생성자에서는 __vectorcall의 제한으로 인해, 규칙이 더 간단해진다.

  1. 처음 3개의 XMVECTOR는 FXMVECTOR로 전달한다.
  2. 그 이후에는 모두 CXMVECTOR로 전달한다.

함수에 전달 할 때 XMVECTOR가 연속적이지 않아도 상관 없다.

XMVECTOR들만 순번을 매겨 위 형식을 적용한다.

이와 관련된 문서를 첨부한다.

https://docs.microsoft.com/en-us/windows/win32/dxmath/pg-xnamath-internals

 

Library Internals - Win32 apps

Library Internals In this article --> This topic describes the internal design of the DirectXMath library. Calling Conventions To enhance portability and optimize data layout, you need to use the appropriate calling conventions for each platform supported

docs.microsoft.com

 

XMVECTOR는 16Byte 경계에 정렬되어야 하는데, Local/Global Value에서는 자동으로 정렬된다.

Field의 경우, XMVECTOR 대신 XMFLOAT2, XMFLOAT3, XMFLOAT4를 사용하는 것이 바람직하다.

// 2D Vector; 32 bit floating point components
struct XMFLOAT2
{
    float x;
    float y;

    XMFLOAT2() = default;

    XMFLOAT2(const XMFLOAT2&) = default;
    XMFLOAT2& operator=(const XMFLOAT2&) = default;

    XMFLOAT2(XMFLOAT2&&) = default;
    XMFLOAT2& operator=(XMFLOAT2&&) = default;

    XM_CONSTEXPR XMFLOAT2(float _x, float _y) : x(_x), y(_y) {}
    explicit XMFLOAT2(_In_reads_(2) const float *pArray) : x(pArray[0]), y(pArray[1]) {}
};
// 3D Vector; 32 bit floating point componentsstruct XMFLOAT3
{
    float x;
    float y;
    float z;

    XMFLOAT3() = default;

    XMFLOAT3(const XMFLOAT3&) = default;
    XMFLOAT3& operator=(const XMFLOAT3&) = default;

    XMFLOAT3(XMFLOAT3&&) = default;
    XMFLOAT3& operator=(XMFLOAT3&&) = default;

    XM_CONSTEXPR 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]) {}
};
// 4D Vector; 32 bit floating point components
struct XMFLOAT4
{
    float x;
    float y;
    float z;
    float w;

    XMFLOAT4() = default;

    XMFLOAT4(const XMFLOAT4&) = default;
    XMFLOAT4& operator=(const XMFLOAT4&) = default;

    XMFLOAT4(XMFLOAT4&&) = default;
    XMFLOAT4& operator=(XMFLOAT4&&) = default;

    XM_CONSTEXPR 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]) {}
};

하지만 이 형식들을 계산에 직접 사용하면 SIMD의 장점을 취하지 못한다.

SIMD를 활용하려면 이 형식의 Instance를 XMVECTOR 형식으로 변환해야 한다.

이를 위해 DirectXMath에서는 다양한 적재 함수들을 제공한다.

XMVECTOR    XM_CALLCONV     XMLoadInt2(_In_reads_(2) const uint32_t* pSource);
XMVECTOR    XM_CALLCONV     XMLoadInt2A(_In_reads_(2) const uint32_t* PSource);
XMVECTOR    XM_CALLCONV     XMLoadFloat2(_In_ const XMFLOAT2* pSource);
XMVECTOR    XM_CALLCONV     XMLoadFloat2A(_In_ const XMFLOAT2A* pSource);
XMVECTOR    XM_CALLCONV     XMLoadSInt2(_In_ const XMINT2* pSource);
XMVECTOR    XM_CALLCONV     XMLoadUInt2(_In_ const XMUINT2* pSource);

XMVECTOR    XM_CALLCONV     XMLoadInt3(_In_reads_(3) const uint32_t* pSource);
XMVECTOR    XM_CALLCONV     XMLoadInt3A(_In_reads_(3) const uint32_t* pSource);
XMVECTOR    XM_CALLCONV     XMLoadFloat3(_In_ const XMFLOAT3* pSource);
XMVECTOR    XM_CALLCONV     XMLoadFloat3A(_In_ const XMFLOAT3A* pSource);
XMVECTOR    XM_CALLCONV     XMLoadSInt3(_In_ const XMINT3* pSource);
XMVECTOR    XM_CALLCONV     XMLoadUInt3(_In_ const XMUINT3* pSource);

XMVECTOR    XM_CALLCONV     XMLoadInt4(_In_reads_(4) const uint32_t* pSource);
XMVECTOR    XM_CALLCONV     XMLoadInt4A(_In_reads_(4) const uint32_t* pSource);
XMVECTOR    XM_CALLCONV     XMLoadFloat4(_In_ const XMFLOAT4* pSource);
XMVECTOR    XM_CALLCONV     XMLoadFloat4A(_In_ const XMFLOAT4A* pSource);
XMVECTOR    XM_CALLCONV     XMLoadSInt4(_In_ const XMINT4* pSource);
XMVECTOR    XM_CALLCONV     XMLoadUInt4(_In_ const XMUINT4* pSource);

또한, 반대로 XMVECTOR Instance를 XMFLOAT* 형식으로 변환하는 저장 함수도 제공한다.

void        XM_CALLCONV     XMStoreInt2(_Out_writes_(2) uint32_t* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreInt2A(_Out_writes_(2) uint32_t* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreFloat2(_Out_ XMFLOAT2* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreFloat2A(_Out_ XMFLOAT2A* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreSInt2(_Out_ XMINT2* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreUInt2(_Out_ XMUINT2* pDestination, _In_ FXMVECTOR V);

void        XM_CALLCONV     XMStoreInt3(_Out_writes_(3) uint32_t* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreInt3A(_Out_writes_(3) uint32_t* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreFloat3(_Out_ XMFLOAT3* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreFloat3A(_Out_ XMFLOAT3A* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreSInt3(_Out_ XMINT3* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreUInt3(_Out_ XMUINT3* pDestination, _In_ FXMVECTOR V);

void        XM_CALLCONV     XMStoreInt4(_Out_writes_(4) uint32_t* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreInt4A(_Out_writes_(4) uint32_t* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreFloat4(_Out_ XMFLOAT4* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreFloat4A(_Out_ XMFLOAT4A* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreSInt4(_Out_ XMINT4* pDestination, _In_ FXMVECTOR V);
void        XM_CALLCONV     XMStoreUInt4(_Out_ XMUINT4* pDestination, _In_ FXMVECTOR V);

또한 XMVECTOR Object의 내용을 설정하는 용도의 함수들을 정의하고 있다.

//(0, 0, 0, 0)
XMVECTOR    XM_CALLCONV     XMVectorZero();

// (1, 1, 1, 1)
XMVECTOR    XM_CALLCONV     XMVectorSplatOne();

//(x, y, z, w)
XMVECTOR    XM_CALLCONV     XMVectorSet(float x, float y, float z, float w);

//(value, value, value, value)
XMVECTOR    XM_CALLCONV     XMVectorReplicate(float Value);

//(Vx, Vx, Vx, Vx)
XMVECTOR    XM_CALLCONV     XMVectorSplatX(FXMVECTOR V);

//(Vy, Vy, Vy, Vy)
XMVECTOR    XM_CALLCONV     XMVectorSplatY(FXMVECTOR V);

//(Vz, Vz, Vz, Vz)
XMVECTOR    XM_CALLCONV     XMVectorSplatZ(FXMVECTOR V);

//(Vw, Vw, Vw, Vw)
XMVECTOR    XM_CALLCONV     XMVectorSplatW(FXMVECTOR V);

이 외에 XMVECTOR Instance의 한 성분만 읽거나, 변경하는 조회, 설정 함수들도 제공한다.

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);

 

Const XMVECTOR Instance에는 반드시 XMVECTORF32 형식을 사용해야 한다.

간단히 말해, 초기화 구문을 사용하고자 할 때에는 항상 XMVECTORF32를 사용해야 한다는 것이다.

XMVECTORF32는 16Byte 경계로 정렬된 Structure로, XMVECTOR로의 변호나 연산자를 지원한다.

// Conversion types for constants
__declspec(align(16)) struct XMVECTORF32
{
    union
    {
        float f[4];
        XMVECTOR v;
    };

    inline operator XMVECTOR() const { return v; }
    inline operator const float*() const { return f; }
#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_)
    inline operator __m128i() const { return _mm_castps_si128(v); }
    inline operator __m128d() const { return _mm_castps_pd(v); }
#endif
};

또한 XMVECTORU32를 이용해 정수 자료를 담은 상수 XMVECTOR를 생성하는 것도 가능하다.

__declspec(align(16)) struct XMVECTORU32
{
    union
    {
        uint32_t u[4];
        XMVECTOR v;
    };

    inline operator XMVECTOR() const { return v; }
#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_)
    inline operator __m128i() const { return _mm_castps_si128(v); }
    inline operator __m128d() const { return _mm_castps_pd(v); }
#endif
};
XMGLOBALCONST XMVECTORU32 g_XMMaskX                 = { { { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 } } };
XMGLOBALCONST XMVECTORU32 g_XMMaskY                 = { { { 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000 } } };
XMGLOBALCONST XMVECTORU32 g_XMMaskZ                 = { { { 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000 } } };
XMGLOBALCONST XMVECTORU32 g_XMMaskW                 = { { { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF } } };

XMVECTOR에는 Vector의 덧셈, 뺄셈, 스칼라 곱셈을 위한 Operator Overloading이 지원된다.

보통은 직관적이라 활성화 하지만, 일부 응용 프로그램은 성능상의 이유로 이를 비활성화 한다.

Operator Overloading을 비활성화 하고 싶으면 macro 상수 XM_NO_OPERATOR_OVERLOADS를 정의해야 한다.

// Vector operators

#ifndef _XM_NO_XMVECTOR_OVERLOADS_
XMVECTOR    XM_CALLCONV     operator+ (FXMVECTOR V);
XMVECTOR    XM_CALLCONV     operator- (FXMVECTOR V);

XMVECTOR&   XM_CALLCONV     operator+= (XMVECTOR& V1, FXMVECTOR V2);
XMVECTOR&   XM_CALLCONV     operator-= (XMVECTOR& V1, FXMVECTOR V2);
XMVECTOR&   XM_CALLCONV     operator*= (XMVECTOR& V1, FXMVECTOR V2);
XMVECTOR&   XM_CALLCONV     operator/= (XMVECTOR& V1, FXMVECTOR V2);

XMVECTOR&   operator*= (XMVECTOR& V, float S);
XMVECTOR&   operator/= (XMVECTOR& V, float S);

XMVECTOR    XM_CALLCONV     operator+ (FXMVECTOR V1, FXMVECTOR V2);
XMVECTOR    XM_CALLCONV     operator- (FXMVECTOR V1, FXMVECTOR V2);
XMVECTOR    XM_CALLCONV     operator* (FXMVECTOR V1, FXMVECTOR V2);
XMVECTOR    XM_CALLCONV     operator/ (FXMVECTOR V1, FXMVECTOR V2);
XMVECTOR    XM_CALLCONV     operator* (FXMVECTOR V, float S);
XMVECTOR    XM_CALLCONV     operator* (float S, FXMVECTOR V);
XMVECTOR    XM_CALLCONV     operator/ (FXMVECTOR V, float S);
#endif /* !_XM_NO_XMVECTOR_OVERLOADS_ */

수학과 관련된 Library답게, DirectXMath Library에서도 다양한 공식에서 사용되는 상수의 근사값을 지원한다.

XM_CONST float XM_PI        = 3.141592654f;
XM_CONST float XM_2PI       = 6.283185307f;
XM_CONST float XM_1DIVPI    = 0.318309886f;
XM_CONST float XM_1DIV2PI   = 0.159154943f;
XM_CONST float XM_PIDIV2    = 1.570796327f;
XM_CONST float XM_PIDIV4    = 0.785398163f;

또한 radian과 degree를 변환하는 함수들도 제공한다.

// Unit conversion

inline XM_CONSTEXPR float XMConvertToRadians(float fDegrees) { return fDegrees * (XM_PI / 180.0f); }
inline XM_CONSTEXPR float XMConvertToDegrees(float fRadians) { return fRadians * (180.0f / XM_PI); }

그리고 최솟값, 최댓값을 위한 매크로 함수들도 정의한다.

#if defined(__XNAMATH_H__) && defined(XMMin)
#undef XMMin
#undef XMMax
#endif

template<class T> inline T XMMin(T a, T b) { return (a < b) ? a : b; }
template<class T> inline T XMMax(T a, T b) { return (a > b) ? a : b; }

 

XMVECTOR가 Operator Overloading으로만 연산을 하는 것은 아니다.

XMVECTOR 연산에 필요한 여러 함수들을 따로 지원하기도 한다.

/****************************************************************************
 *
 * 3D vector operations
 *
 ****************************************************************************/

bool        XM_CALLCONV     XMVector3Equal(FXMVECTOR V1, FXMVECTOR V2);
uint32_t    XM_CALLCONV     XMVector3EqualR(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3EqualInt(FXMVECTOR V1, FXMVECTOR V2);
uint32_t    XM_CALLCONV     XMVector3EqualIntR(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3NearEqual(FXMVECTOR V1, FXMVECTOR V2, FXMVECTOR Epsilon);
bool        XM_CALLCONV     XMVector3NotEqual(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3NotEqualInt(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3Greater(FXMVECTOR V1, FXMVECTOR V2);
uint32_t    XM_CALLCONV     XMVector3GreaterR(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3GreaterOrEqual(FXMVECTOR V1, FXMVECTOR V2);
uint32_t    XM_CALLCONV     XMVector3GreaterOrEqualR(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3Less(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3LessOrEqual(FXMVECTOR V1, FXMVECTOR V2);
bool        XM_CALLCONV     XMVector3InBounds(FXMVECTOR V, FXMVECTOR Bounds);

bool        XM_CALLCONV     XMVector3IsNaN(FXMVECTOR V);
bool        XM_CALLCONV     XMVector3IsInfinite(FXMVECTOR V);

XMVECTOR    XM_CALLCONV     XMVector3Dot(FXMVECTOR V1, FXMVECTOR V2);
XMVECTOR    XM_CALLCONV     XMVector3Cross(FXMVECTOR V1, FXMVECTOR V2);
XMVECTOR    XM_CALLCONV     XMVector3LengthSq(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3ReciprocalLengthEst(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3ReciprocalLength(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3LengthEst(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3Length(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3NormalizeEst(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3Normalize(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3ClampLength(FXMVECTOR V, float LengthMin, float LengthMax);
XMVECTOR    XM_CALLCONV     XMVector3ClampLengthV(FXMVECTOR V, FXMVECTOR LengthMin, FXMVECTOR LengthMax);
XMVECTOR    XM_CALLCONV     XMVector3Reflect(FXMVECTOR Incident, FXMVECTOR Normal);
XMVECTOR    XM_CALLCONV     XMVector3Refract(FXMVECTOR Incident, FXMVECTOR Normal, float RefractionIndex);
XMVECTOR    XM_CALLCONV     XMVector3RefractV(FXMVECTOR Incident, FXMVECTOR Normal, FXMVECTOR RefractionIndex);
XMVECTOR    XM_CALLCONV     XMVector3Orthogonal(FXMVECTOR V);
XMVECTOR    XM_CALLCONV     XMVector3AngleBetweenNormalsEst(FXMVECTOR N1, FXMVECTOR N2);
XMVECTOR    XM_CALLCONV     XMVector3AngleBetweenNormals(FXMVECTOR N1, FXMVECTOR N2);
XMVECTOR    XM_CALLCONV     XMVector3AngleBetweenVectors(FXMVECTOR V1, FXMVECTOR V2);
XMVECTOR    XM_CALLCONV     XMVector3LinePointDistance(FXMVECTOR LinePoint1, FXMVECTOR LinePoint2, FXMVECTOR Point);
void        XM_CALLCONV     XMVector3ComponentsFromNormal(_Out_ XMVECTOR* pParallel, _Out_ XMVECTOR* pPerpendicular, _In_ FXMVECTOR V, _In_ FXMVECTOR Normal);
XMVECTOR    XM_CALLCONV     XMVector3Rotate(FXMVECTOR V, FXMVECTOR RotationQuaternion);
XMVECTOR    XM_CALLCONV     XMVector3InverseRotate(FXMVECTOR V, FXMVECTOR RotationQuaternion);
XMVECTOR    XM_CALLCONV     XMVector3Transform(FXMVECTOR V, FXMMATRIX M);
XMFLOAT4*   XM_CALLCONV     XMVector3TransformStream(_Out_writes_bytes_(sizeof(XMFLOAT4)+OutputStride*(VectorCount-1)) XMFLOAT4* pOutputStream,
                                                     _In_ size_t OutputStride,
                                                     _In_reads_bytes_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) const XMFLOAT3* pInputStream,
                                                     _In_ size_t InputStride, _In_ size_t VectorCount, _In_ FXMMATRIX M);
XMVECTOR    XM_CALLCONV     XMVector3TransformCoord(FXMVECTOR V, FXMMATRIX M);
XMFLOAT3*   XM_CALLCONV     XMVector3TransformCoordStream(_Out_writes_bytes_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream,
                                                          _In_ size_t OutputStride,
                                                          _In_reads_bytes_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) const XMFLOAT3* pInputStream,
                                                          _In_ size_t InputStride, _In_ size_t VectorCount, _In_ FXMMATRIX M);
XMVECTOR    XM_CALLCONV     XMVector3TransformNormal(FXMVECTOR V, FXMMATRIX M);
XMFLOAT3*   XM_CALLCONV     XMVector3TransformNormalStream(_Out_writes_bytes_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream,
                                                           _In_ size_t OutputStride,
                                                           _In_reads_bytes_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) const XMFLOAT3* pInputStream,
                                                           _In_ size_t InputStride, _In_ size_t VectorCount, _In_ FXMMATRIX M);
XMVECTOR    XM_CALLCONV     XMVector3Project(FXMVECTOR V, float ViewportX, float ViewportY, float ViewportWidth, float ViewportHeight, float ViewportMinZ, float ViewportMaxZ,
                                             FXMMATRIX Projection, CXMMATRIX View, CXMMATRIX World);
XMFLOAT3*   XM_CALLCONV     XMVector3ProjectStream(_Out_writes_bytes_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream,
                                                   _In_ size_t OutputStride,
                                                   _In_reads_bytes_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) const XMFLOAT3* pInputStream,
                                                   _In_ size_t InputStride, _In_ size_t VectorCount,
                                                   _In_ float ViewportX, _In_ float ViewportY, _In_ float ViewportWidth, _In_ float ViewportHeight, _In_ float ViewportMinZ, _In_ float ViewportMaxZ,
                                                   _In_ FXMMATRIX Projection, _In_ CXMMATRIX View, _In_ CXMMATRIX World);
XMVECTOR    XM_CALLCONV     XMVector3Unproject(FXMVECTOR V, float ViewportX, float ViewportY, float ViewportWidth, float ViewportHeight, float ViewportMinZ, float ViewportMaxZ,
                                               FXMMATRIX Projection, CXMMATRIX View, CXMMATRIX World);
XMFLOAT3*   XM_CALLCONV     XMVector3UnprojectStream(_Out_writes_bytes_(sizeof(XMFLOAT3)+OutputStride*(VectorCount-1)) XMFLOAT3* pOutputStream,
                                                     _In_ size_t OutputStride,
                                                     _In_reads_bytes_(sizeof(XMFLOAT3)+InputStride*(VectorCount-1)) const XMFLOAT3* pInputStream,
                                                     _In_ size_t InputStride, _In_ size_t VectorCount,
                                                     _In_ float ViewportX, _In_ float ViewportY, _In_ float ViewportWidth, _In_ float ViewportHeight, _In_ float ViewportMinZ, _In_ float ViewportMaxZ,
                                                     _In_ FXMMATRIX Projection, _In_ CXMMATRIX View, _In_ CXMMATRIX World);

-----------------------------

본 블로그는 [DirectX11을 이용한 3D 게임 프로그래밍 입문]을 기반으로 공부를 하며,
DirectX12와 다른 부분을 수정해가며 정리를 하는 글입니다.

 

한글 자료가 필요하시다면, 부족하게나마 도움이 되었으면 합니다.

만약 더 자세한 내용이 필요하시다면, 공식 레퍼런스를 보시는 것을 추천합니다.

https://docs.microsoft.com/en-us/windows/win32/dxmath/ovw-xnamath-reference

 

DirectXMath programming reference - Win32 apps

DirectXMath programming reference In this article --> This section contains reference material for the DirectXMath Library. In this section DirectXMath DirectXMath programming guide -->

docs.microsoft.com

 

+ Recent posts