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, 2, 3번째 XMVECTOR는 FXMVECTOR로 전달해야 한다.
- 4번째 XMVECTOR는 GXMVECTOR로 전달해야 한다.
- 5, 6번째 XMVECTOR는 HXMVECTOR로 전달해야 한다.
- 7번째 이후로는 CXMVECTOR로 전달해야 한다.
단, 생성자에서는 __vectorcall의 제한으로 인해, 규칙이 더 간단해진다.
- 처음 3개의 XMVECTOR는 FXMVECTOR로 전달한다.
- 그 이후에는 모두 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
'내용정리 > DirectX12' 카테고리의 다른 글
07. DirectX12 template 프로젝트 분석 01 - 20.05.29 (0) | 2020.05.29 |
---|---|
06. DirectXMath.h에서의 Matrix, Transformation 관련 기능 (0) | 2020.05.29 |
04. 기초 필수 수학 - Transform (0) | 2020.05.22 |
03. 기초 필수 수학 - Matrix (0) | 2020.05.15 |
02. 기초 필수 수학 - Vector (0) | 2020.05.08 |