1 1
1.6.DirectXMath 라이브러리
Window 8 이상에선 DirectXMath 라이브러리를 활용해 DiretX 응용 프로그램을 다룬다.
DirectXMath 라이브러리는 SSE2 명령 집합을 활용한다.
- 128비트 너비의 SIMD 레지스터를 이용해 32비트
float
및int
네 개를 하나의 명령에서 처리 가능함!
DirectXMath 라이브러리를 사용하기 위해 DirectXMath.h를 포함시켜야 한다. 추가 자료가 필요하다면 DirectXPackedVector.h 헤더 파일도 포함시켜보자.
- DirectXMath.h의 코드는
DirectX
의 이름 공간 안에 속함 - DirectXPackedVector.h의 코드는
DirectX::PackedVector
이름 공간에 속함
1.6.1. 벡터 형식
XMVECTOR
: DirectXMath의 핵심 벡터 형식- 32비트 부동소수점 값 네 개로 구성 => SIMD 명령으로 한 번에 처리
typedef __m1238 XMVECTOR
로 정의됨- SIMD를 올바르게 활용되려면 벡터가 반드시
__m128
형식이어야 함!
- SIMD를 올바르게 활용되려면 벡터가 반드시
- 클래스 자료 멤버는
XMFLOAT2
,XMFLOAT3
,XMFLOAT4
변수 사용 권장- 지역/전역 변수는 자동으로 alignment가 이루어지므로 고려x
- 단, 해당 구조체를 사용하면 SIMD를 제대로 활용하지 못하므로 형변환 필요
- 계산 수행 전 적재(load) 함수를 활용해
XMVECTOR
로 변환 - 계산 수행 후 저장(store) 함수를 활용해
XMFLOAT
n으로 변환
- 계산 수행 전 적재(load) 함수를 활용해
1.6.2. 적재 및 저장 함수
XFLOATn → XMVECTOR 적재
```c++ // XMFLOAT2 XMVECTOR XM_CALLCONV XMLoadFloat2(const XMFLOAT2 *pSource); // XMFLOAT3 XMVECTOR XM_CALLCONV XMLoadFloat3(const XMFLOAT3 *pSource); // XMFLOAT4 XMVECTOR XM_CALLCONV XMLoadFloat4(const XMFLOAT4 *pSource); ```XMVECTOR → XFLOATn 저장
```c++ // XMFLOAT2 void XM_CALLCONV XMStoreFloat2(XMFLOAT2 *pDestination, FXMVECTOR V); // XMFLOAT3 void XM_CALLCONV XMStoreFloat3(XMFLOAT3 *pDestination, FXMVECTOR V); // XMFLOAT4 void XM_CALLCONV XMStoreFloat4(XMFLOAT4 *pDestination, FXMVECTOR V); ```XMVECTOR → XFLOATn 저장
```c++ // XMFLOAT2 void XM_CALLCONV XMStoreFloat2(XMFLOAT2 *pDestination, FXMVECTOR V); // XMFLOAT3 void XM_CALLCONV XMStoreFloat3(XMFLOAT3 *pDestination, FXMVECTOR V); // XMFLOAT4 void XM_CALLCONV XMStoreFloat4(XMFLOAT4 *pDestination, FXMVECTOR V); ```XMVECTOR의 특정 성분 조회/변경
```c++ // 조회 float XM_CALLCONV XMVectorGetX(FXMVECTOR V); float XM_CALLCONV XMVectorGetY(FXMVECTOR V); float XM_CALLCONV XMVectorGetZ(FXMVECTOR V); float XM_CALLCONV XMVectorGetW(FXMVECTOR V); // 변경 float XM_CALLCONV XMVectorSetX(FXMVECTOR V); float XM_CALLCONV XMVectorSetY(FXMVECTOR V); float XM_CALLCONV XMVectorSetZ(FXMVECTOR V); float XM_CALLCONV XMVectorSetW(FXMVECTOR V); ```1.6.3. 매개변수 전달
- SSE/SSE2 레지스터를 활용해기 위해 플랫폼/컴파일러 의존성 제거
- 함수 호출 시
XMVECTOR
의 매개변수로FMVECTOR
,GXMVECTOR
,HXMVECTOR
,CXMVECTOR
형식 사용 - 호출 규약 의존성을 없애기 위해 함수 이름 앞에
XM_CALLCONV
지시자 추가
- 함수 호출 시
XMVECTOR
매개변수 전달 규칙- 매개변수 ~세 번째
FXMVECTOR
, 네 번째GXMVECTOR
, 다섯째, 여섯째HXMVECTOR
, 그 이상CXMVECTOR
형식 지정 XMVECTOR
형식의 인수들을 받는 생성자를 작성할 때는 ~세 번째FXMVECTOR
, 나머지CXMVECTOR
사용- 생성자에는
XM_CALLCONV
호출 규약 지시자를 사용하지 않음
- 생성자에는
- 매개변수 ~세 번째
- 출력
XMVECTOR
매개변수는 SSE/SSE2 레지스터를 사용하지 않으므로 다른 매개변수들과 동일하게 취급XMVECTOR&
,XMVECTOR*
1.6.4. 상수 벡터
const XMVECTOR
인스턴스에는 반드시XMVECTORF32
형식 사용- 중괄호 초기화 구문 등
XMVECTORF32
: 16바이트 경계에 align되는 구조체XMVECTOR0
로의 변환 연산자 제공
1.6.7. 설정 함수
XMVECTOR
객체의 내용을 설정하는 용도
설정 함수
```c++ // 0벡터 반환 XMVECTOR XM_CALLCONV XMVectorZero(); // 벡터 (1, 1, 1, 1) 반환 XMVECTOR XM_CALLCONV XMVectorSplateOne(); // 벡터 (x, y, z, w) 반환 XMVECTOR XM_CALLCONV XMVectorSet(float x, float y, float z, float w); // 벡터 (s, s, s, s) 반환 XMVECTOR XM_CALLCONV XMVectorReplicate(float value); // 벡터 (vx, vx, vx, vx) 반환 XMVECTOR XM_CALLCONV XMVectorSplatX(FXMVECTOR V); XMVECTOR XM_CALLCONV XMVectorSplatY(FXMVECTOR V); XMVECTOR XM_CALLCONV XMVectorSplatZ(FXMVECTOR V); ```1.6.8. 벡터 함수들
- 벡터 연산을 위한 함수 제공
- 함수 이름 숫자에 따라 2,3,4 차원 벡터 구분
벡터 함수
```c++ // ||v|| 반환 XMVECTOR XM_CALLCONV XMVector3Length(FMVECTOR V); // ||v||^2 반환 XMVECTOR XM_CALLCONV XMVector3LengthSq(FMVECTOR V); // v1 * v2 반환 XMVECTOR XM_CALLCONV XMVector3Dot(FMVECTOR V1, FMVECTOR V2); // v1 X v2 반환 XMVECTOR XM_CALLCONV XMVector3Cross(FMVECTOR V, FMVECTOR V2); // v / ||v|| 반환 XMVECTOR XM_CALLCONV XMVector3Normalize(FMVECTOR V); // v1과 v2 사이의 각도 반환 XMVECTOR XM_CALLCONV XMVector3AngleBetweenVectors(FXMVVECTOR V1, FXMVECTOR V2); void XM_CALLCONV XMVector3ComponentsFromNormal( XMVECTOR* pPrarllel, // proj_n(v) 반환 XMVECOTR* pPerpendicular, // perp_n(v) 반환 FXMVECTOR V, // 입력 v FXMVECTOR Normal); // 입력 n // v1 = v2 반환 bool XM_CALLCONV XMVector3Equal(FXMVECTOR V1, FXMVECTOR V2); // v1 != v2 반환 bool XM_CALLCONV XMVector3NotEqual(FXMVECTOR V1, FXMVECTOR V2); ```예제 코드
```c++ #include출력 결과 </details>
> **<요약>** > > > > 1. 벡터는 크기와 방향을 모두 가진 물리적 수량을 나타내는 데 쓰임 > * 기하학적으로는 벡터를 지향 선분으로 표현 > * "표준 위치": 꼬리가 원점과 일치하도록 이동된 벡터 > * 표준 위치에 있는 벡터는 좌표계에 상대적인 그 머리의 좌표 성분을 이용해 수치적으로 서술 가능 > > > > 2. 벡터 $\mathbf{u} = (u_{x}, u_{y}, u_{z})$와 $\mathbf{v} = (v_{x}, v_{y}, v_{z})$에 대한 벡터 연산 > > * 덧셈: $\mathbf{u} + \mathbf{v} = (u_{x}+v_{x},\space u_{y}+v_{y}, \space u_{z}+v_{z})$ > > * 뺄셈: $\mathbf{u} - \mathbf{v} = (u_{x}-v_{x},\space u_{y}-v_{y}, \space u_{z}-v_{z})$ > > * 스칼라 곱셈: $k\mathbf{u} = (ku_{x}, \space ku_{y}, \space ku_{z})$ > > * 길이: $\lVert \mathbf{u} \rVert=\sqrt{x^{2} + y^{2} + z^{2} }$ > > * 정규화: $\hat{\mathbf{u}} = {\mathbf{u} \over \lVert \mathbf{u} \rVert} = ({x \over \lVert \mathbf{u} \rVert}, \space {y \over \lVert \mathbf{u} \rVert}, \space {z \over \lVert \mathbf{u} \rVert})$ > > * 내적: $\mathbf{u} \cdot \mathbf{v} = \lVert \mathbf{u} \rVert \space \lVert \mathbf{u} \rVert \cos\theta = u_{x}+v_{x},\space u_{y}+v_{y}, \space u_{z}+v_{z}$ > > * 외적: $\mathbf{u} \times \mathbf{v} = (u_{y}v_{z}-v_{z}u_{y}, \space u_{z}v_{x}-v_{x}u_{z}, \space u_{x}v_{y}-v_{y}u_{x}, \space)$ > > > > 3. 코드에서 벡터를 효율적으로 다루기 위해 DirectXMath의 `XMVECTOR` 형식 사용 > > * SIMD 연산들을 이용해 벡터를 효율적으로 처리함 > > * 클래스 자료 멤버: `XMFLOAT2`, `XMFLOAT3`, `XMFLOAT4` 클래스 사용 > > * 필요에 따라 적재 함수를 이용해 `XMVECTOR`로 변환 후 저장 함수를 이용해 다시 `XMFLOAT`n 으로 변환 > > * 초기화 구문을 이용해 상수 벡터를 정의할 때는 `XMVECTORF32` 형식을 사용해야 함 > > > > 4. `XMVECTOR` 인스턴스를 인수로 함수를 호출할 경우 > > * 효율성을 위해 SSE/SSE2 레지스터를 통해 함수에 전달(스택 사용X) > > * 플랫폼 독립적인 방식으로 처리하려면 `XMVECTOR` 매개변수에 `FMVECTOR`, `GXMVECTOR`, `HXMVECTOR` 형식 지정 > * 함수의 매개변수 ~세 번째 `FXMVECTOR`, 네 번째 `GXMVECTOR`, 다섯째, 여섯째 `HXMVECTOR`, 그 이상 `CXMVECTOR` > > > > 5. DirectXMath 라이브러리에서 중복적재된 연산자 제공 > > *벡터의 길이 및 길이 제곱 계산, 두 벡터의 내적과 외적 계산, 벡터 정규화를 위한 편의용 함수도 제공한다!* > ```c++ > XMVECTOR XM_CALLCONV XMVector3Length(FMVECTOR V); > XMVECTOR XM_CALLCONV XMVector3LengthSq(FMVECTOR V); > XMVECTOR XM_CALLCONV XMVector3Dot(FMVECTOR V1, FMVECTOR V2); > XMVECTOR XM_CALLCONV XMVector3Cross(FMVECTOR V, FMVECTOR V2); > XMVECTOR XM_CALLCONV XMVector3Normalize(FMVECTOR V); > ``` 요약>
Leave a comment