태그 보관물: D3DX

D3D 디바이스 소실 처리

http://www.gpgstudy.com/forum/viewtopic.php?topic=1451

디바이스 소실의 두가지 경우

1. 디바이스 소실되었고 복구 불가능의 경우

: 이 경우에는 대책이 없다. 전부(IDirect3DDevice를 통해 생성된 모든 리소스들과 IDirect3DDeivce객체) 해제한 후 처음부터 다시 생성한다.

2. 디바이스 소실되었고 복구 가능의 경우

: 이 경우에는 디바이스에 올라간 리소스(리소스 생성시 D3DPOOL_DEFAULT 플래그를 이용하여 생성된 객체들)들만 새로 로딩하면 된다.

특이사항

디바이스가 소실되어도 IDirect3DDevice관련 함수들이 성공을 반환 할 경우가 있다.

도움말에 보면 “디바이스가 소실되어도 동작은 보증된다”고 되어있다. 물론 이때의 동작은 헛동작이다. 아무 효과가 없는것이다. 왜 이런식인가 생각해보니, 밑의 글을 읽어보면 알겠지만,, 언제 어떻게 디바이스 손실이 발생할지 모르니 프로그래머로써는 이런 상황을 대처 할 수 없는것이다. 디바이스와 관련된 모든 함수들에 대해서, 리턴값을 체크하지 않는한 불가능하다는 얘기이다. 그리고 손실된 디바이스 자원이 언제 넘어오게 될지도 모르는 상황에서 이런 처리는 너무 고난이도일껏 같다. 차라리 처리되는것 처럼 보이고, 실제로는 처리가 안되게 하는것이 훨씬 이득일껏 같다. 어디까지 제 추측입니다. 틀렸어도 양해를..

왜 이딴게 있는걸까?

예를들면, 2개의 응용프로그램 A와 B가 돌아가는 상황에서, A란 놈과 B란 놈 둘다 비디오 램을 많이 사용하는 프로그램이었다 치자. 이 상황에서 A란 프로그램이 돌아가고 있는 상황이어서 비디오 램의 여유분이 없었다 치자, 자.. 이제 문제의 B가 실행되어 졌을 경우,, 어떻게 해야할까? Win32는 멀티 태스킹 환경이다. 고로 여러 응용프로그램들이 같은 하드웨어 자원을 공유한다. 즉, DOS처럼 하나의 응용프로그램이 하드웨어 자원을 독점하면 안된다는 것이다. 고로 윈도우즈가 택한방식이 활성화 애플리케이션에게 자원을 넘겨주자는 방식이다. A가 활성화되면, A에게 자원을 주고, B가 활성화되면 B에게 자원을 준다. 그러므로 사용자는 두 응용프로그램을 동시에 사용할 수 있는것이다. 덕분에 프로그래머는 귀찮지만은… 어디까지 제 추측입니다. 틀렸어도 양해를.. 아니지 지적을..

디바이스 소실 처리

IDirect3DDevice::TestCooperativeLevel()을 호출하여, 디바이스를 복구 할 수 있는지 검사해본다. 반환값(HRESULT)이

D3DERR_DEVICELOST인 경우 디바이스가 소실되었고 아직 복구할 수 없는 상태이다. 복구할 수 있을때까지 대기한다.
D3DERR_DEVICENOTRESET인 경우 디바이스가 소실되지만 지금 복구할 수 있는 상태이다. 디바이스를 복구한다.
디바이스 복구

. D3DPOOL_DEFAULT로 잡은 리소스들을 전부 릴리즈한다. %%%(안그러면 다음에 호출될 IDirect3DDevice::Reset()이 실패할것이다.)
. IDirect3DDevice::Reset()을 호출한다. %%%(Reset()을 그냥 IDirect3DDevice의 복구명령어라 생각하면 이해가 편함)
. 디바이스를 다시 셋팅한다.(랜더스테이트, 뷰 행렬등..)
. D3DPOOL_DEFAULT로 잡은 리소스들을 다시 로드한다.
Adapter나 D3DDEVTYPE이 변경되어야 하는 경우에는 디바이스를 다시 생성해야 한다.

. 모든 리소스들을 릴리즈한다.
. 디바이스를 릴리즈한다.
. 디바이스를 새로 생성한다.
. 디바이스를 다시 셋팅한다.(랜더스테이트, 뷰 행렬등..)
. 모든 리소스들을 다시 로드한다.
디바이스가 소실되는경우

풀스크린 모드일때..

다른 애플리케이션이 디바이스를 점유하는 경우.
애플리케이션이 작업표시줄로 최소화 되는 경우.
다른 애플리케이션이 풀스크린 모드로 생성될경우.
전력관리 이벤트(WM_POWERBROADCAST)가 발생했을 경우.
윈도우 모드일때..

전력관리 이벤트가 발생했을 경우.
다른 애플리케이션이 풀스크린 모드로 생성될경우.. (이경우 제 카드에서는 문제가 없었음)
디스플레이 등록정보에서 색상모드를 변경하는 경우.
테스트 사항

카드 : Radeon 9000 128M, OS : Win 2000

A,B : D3D를 사용하는 애플리케이션

. A:win, B:win ==> A:full, B:win // (A를 풀스크린으로 전환) %%%-A:ok, B:ok
. A:full, B:win ===> A:win B:win // (A를 윈도우모드로 전환) %%%- A:ok, B:lost(고칠수 있음)
. A:full, B:win ===> A:full(minimize), B:win // (마우스로 바탕화면을 찍거나 Alt+Tab) %%%- A:lost(고칠수 없음), B:lost(고칠수 없음)
. A:full(lost), B:win ===> A:full(lost), B:full // (B를 풀스크린으로 전환) %%%- A:lost상태 유지, B:ok (A는 시작하기 전에 이미 lost상태였음)
. A:full(lost), B:full ===> A:full(lost), B:full(lost) // (바탕화면 찍음) %%%- A:(lost상태유지), B:lost(고칠수 없음) (A는 시작전에 이미 lost상태였음)
. A:full, B:win ===> A:종료, B:win(lost) // (A를 종료) %%%- A:종료됨, B:lost(고칠수 있음)
X. 기타 등등, 여러 상황에 따라 디바이스 로스트가 발생 된다. 이런 상황이 더 있으나 해결책을 어느정도 찾은것 같으므로 더 이상은 생략.

X. 그리고 다른 그래픽 카드의경우는 어떻게 처리될지 잘모르겠음.

결론

1. Present()함수의 리턴값은 항상 체크해야 한다. 위와 같이 언제 디바이스 손실이 발생 할지 모른다.

2. 임의로 체크해 보고 싶은 경우. TestCooperativeLevel()함수를 이용하자.

방법론

필수사항 : Present()리턴값은 항상 반드시 꼭 체크하자. 언제 어떻게 어떤 이유로 Present()가 실패할지 모른다. 이건 필수이다.

그리고 Present()가 실패하면 위와같은 방법으로 복구하면 될꺼 같다.

0. Present()함수 실패시만 복원한다.

단점으로는 에러를 알아내는 시점이 Present()가 호출될때(뷰포트를 하나 생성한 경우라면 한프레임에 한번씩)뿐 이라는 것이다. 이 단점은 랜더링 결과물에 접근하여, 그것이 애플리케이션 로직에 적용되는 경우라면 치명적일 수 있다고 예상된다. 그점을 제외하면 가장 무난할 껏 같다.

1. CD3DApplication(Direct3D Wizzard에서 제공)의 방식

이 클래스를 보면,, 꽤나 복잡한 방식(주로 윈도우 메세지를 핸들링한다.)으로 처리 하는데(즉, 디바이스 손실이 일어나기전에 미치 처리함)으로 해결하고 있다. 꼭 이렇게 까지 해야 하는지는 잘모르겠지만… 요는 여러가지 상황에 미리 대처한다는 방식이다. 위의 <테스트 사항>같은 짓을 많이 시도해보고, 어느때 디바이스가 손실되는지 정확하게 알아낸 후, 미리알 수 있는경우(풀스크린에서 Alt+tab에 의해 갑자기 비활성화 시킨다든지 등등) 할수 있는데까지 까지 하는것이다. 그런 눈물겨운 노력이 CD3DApplication에 보면 잘 나온다. 이런건 보고 베끼자…^^ 이경우 100% 문제를 해결했다고 볼 수는 없다고 생각되지만 0번의 경우보단 낫다. 이런 문제를 봐선 Direct3D의 설계의 결함같기도 하다. 결국 이런 문제들을 100% 해결 할 수는 없다고 생각된다.

결과 : 실제로 1번과 같이 대부분 예측되는 치명 적인 몇몇 가지들에 대해 미리 알아내서 처리해주면,, 거의 문제는 안생긴다. 대신 코딩이 지저분해지는건 어쩔수 없다.

stub code

void RenderAll()
{
// …
// 모든 그래픽들에 대한 랜더링을 한다.
// …

// 백버퍼 플리핑.
hr = m_pDevice->Present( NULL, NULL, NULL, NULL );
if ( FAILED(hr) )
{
if ( D3DERR_DEVICELOST == hr )
{
// 디바이스를 소실했고, 복구가 불가능 상태
}
else ( D3DERR_DEVICENOTRESET == hr )
{
// 디바이스를 소실했지만, 복구가 가능한경우.
}
}
}
설계

한가지 방법은 랜더러 클래스(또는 이런 이벤트를 처리할 객체)에 두가지상황(디바이스 손실시 복구가능/복구불가능)이 발생했을때, 로딩할 목록을 등록해 놓은 후, 이벤트가 발생하면 각각 해당 이벤트에 맞게끔 다시 로드하는 식으로, 구성하면 될 껏 같다.

//**** 디바이스 리소스 인터페이스..
// 디바이스 의존적인 리소스들의 추상클래스.
struct IDeviceRes
{
virtual void Invalidate() = 0;
virtual bool SetValidate() = 0;
};

//**** 텍스쳐 클래스
class CTextureRes : public IDeviceRes
{
public:
virtual void Invalidate() { 텍스쳐 해제; }
virtual bool SetValidate() { 텍스쳐 다시 로드; }

bool Load();
void Unload();

protected:
char m_szFileName[256];
LPDIRECT3DTEXTURE9 m_pTexture;
};

//**** 텍스쳐를 관리할 클래스(클라이언트에서 접근하여 사용)
class CDataContainer
{
public:
LoadTexture( const char* szFileName )
{
// 1. 텍스쳐 로딩
// 2. 만약 텍스쳐가 VRam에 잡혔다면..(D3DPOOL_DEFAULT)
// 2.1 랜더러의 의 VRam리스트에 등록(m_pRenderer->m_VRamRes)
// 3. 텍스쳐가 다른모드로 생성되었다면..(D3DPOOL_MANAGED or etc..)
// 3.1 랜더러의 의 Managed리스트에 등록(m_pRenderer->m_ManagedRes)
}

UnloadTexture( const char* szFileName )
{
// 랜더러의 디바이스 목록에서 지운다.
m_pRenderer->Unregist( szFileName );
}

protected:
vector m_TextureContainer;
CRenderer* m_pRenderer;
}

//**** 문제의 랜더러 클래스
class CRenderer
{
public:
// 디바이스가 해제 됬거나 해제 하라.
// – 이 함수는 외부에서 임의로 호출이 가능하다.
void InvalidateDevice( HRESULT hrDeviceState )
{
if ( FAILED( hrDeviceState )
{
if ( D3DERR_DEVICENOTRESET == hrDeviceState )
{
// 1. m_VRamRes 리소스만 해제한다.
// for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->Invalidate(); }
}
else if ( D3DERR_DEVICELOST == hrDeviceState )
{
// 1. m_VRamRes과 m_ManagedRes들에 대해서 해제한다.(전 리소스들에 대해 수행)
// for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->Invalidate(); }
// for_each(m_ManagedRes의 시작에서 끝가지) { m_ManagedRes[i]->Invalidate(); }

// 2. 디바이스를 릴리즈한다.
}
}
m_hrDeviceState = hrDeviceState; // 디바이스 상태값 업데이트
}

// 디바이스가 활성화하라.
// – 이 함수도 외부에서 임의로 호출이 가능하다.
bool SetValidateDevice()
{
if ( FAILED(m_hrDeviceState) )
{
if ( D3DERR_DEVICENOTRESET == m_hrDeviceState )
{
//**** 디바이스를 복구할수 있다.
// 1. IDrect3DDevice::Reset()한다.
// 2. 랜더 스테이트 / 뷰행렬 셋팅
// 3. m_VRamRes 리소스들을 다시 로딩한다.
// for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->SetValidate(); }
}
else if ( D3DERR_DEVICELOST == m_hrDeviceState )
{
//**** m_VRamRes 복구할수 없다.
// 1. 디바이스를 재생성한다.
// 2. 랜더 스테이트 / 뷰행렬 셋팅
// 3. m_VRamRes / m_ManagedRes 리소스를 로딩한다.
// for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->SetValidate(); }
// for_each(m_ManagedRes의 시작에서 끝가지) { m_ManagedRes[i]->SetValidate(); }
}

// 검증해본다.
m_hrDeviceState = m_pDevice->TestCooperativeLevel();
return SUCCEEDED(m_hrDeviceState);
}
return true;
}

// 랜더링한다.
void RenderAll()
{
//**** 디바이스가 유효한 상태가 아니라면 그냥 리턴.
if ( FAILED(m_hrDeviceState) ) return;

// …
//**** 모든 그래픽들에 대한 랜더링을 한다.
// …

//**** 백버퍼 플리핑.
m_hrDeviceState = m_pDevice->Present( NULL, NULL, NULL, NULL );
if ( FAILED(m_hrDeviceState) )
{
// 디바이스에 뭔가 이상이 있다면,,
InvalidateDevice( m_hrDeviceState );

// 외부에 알려준다. 아마 누군가에게 알려줄 필요가 있을껏이다.
// CApp나 혹은 다른 누군가에게..
}
}

protected:
//**** properties
// 디바이스 의존적인 메모리 관리
vector m_VRamRes; // POOL_DEFAULT
vector m_ManagedRes; // MANAGED or etc
HRESULT m_hrDeviceState; // 현재의 디바이스 상태값

LPDIRECT3DDEVICE9 m_pDevice;
};
추신

괜찮은 방법이나, 사용되어지는 방법이 있으면 올려주세요. 저도 구현은 안해본 사람입니다. 아마 틀린 부분도 있으리라 생각됩니다. 많은 지적을.. 써놓고 보니 장문이네요.

< 덧글 >

그리고 업데이트 내용입니다. gpgstudy.com의 손님께서 쓰신글의 요약입니다.

TestCooperativeLevel()로 D3DERR_DEVICENOTRESET임을 확인한후 Reset()을 했을때 실패할 수도 있다는군요.

나중에 TestCooperativeLevel()로 확인해 보니 D3DERR_DEVICELOST였다고 합니다. 결국 Reset()이 실패했을경우에도 다시 체크를 한후 소실상태라면 디바이스를 다시 생성해야 할껏같습니다.

Math in Direct3DX, Vector

http://mormegil.wz.cz/prog/3dref/D3DXmath.htm

Vector

D3DXVecNAdd(Out, V1, V2) : N 벡터를 덧셈한다.
[latex]Out=V_1+V_2[/latex]

D3DXVecNBaryCentric(Out, V_1, V_2, V_3, f, g) :  N 벡터를 사용해, 중심 좌표의 점을 돌려준다.
[latex]Out = V_1+ f\cdot (V_2 – V_1) + g\cdot (V_3 – V_1 )[/latex]

D3DXVecNCatmullRom(Out, V1, V2, V3, V4, s) : Catmull-Rom SPLine 보간을 실행한다.
[latex]Out=\left(1, s, s^2, s^3\right) \begin{pmatrix}
0&1&0&0\\
-0.5&0&0.5&0\\
1&-2.5&2&-0.5\\
-0.5&1&-1.5&0.5\\
\end{pmatrix}
\begin{pmatrix} V_1\\V_2\\V_3\\V_4\\ \end{pmatrix}
[/latex]

D3DXVecNDot(U, V) : N 벡터의 내적을 계산한다.
[latex]Result=U \cdot V= \sum_{i}U_{i}V_{i}[/latex]

D3DXVecNHermite(Out, V1, T1, V2, T2, s) : Hermite SPLine 보간을 실행한다.
[latex]Out=\left(1, s, s^2, s^3\right) \begin{pmatrix}
1&0&0&0\\
0&0&1&0\\
-3&3&-2&-1\\
2&-2&1&1\\
\end{pmatrix}
\begin{pmatrix} V_1\\V_2\\T_1\\T_2\\ \end{pmatrix}
[/latex]

D3DXVecNLength(V) : N벡터의 길이를 돌려준다.
[latex]Result=\left| V\right|=\sqrt{\left(\sum_{i}V^{2}_{i}\right)}[/latex]

D3DXVecNLengthSq(V) : N벡터의 길이의 2 승을 돌려준다.
[latex]Result=\left| V\right|=\sum_{i}V^{2}_{i}[/latex]

D3DXVecNLerp(Out, V1, V2, s) :  N벡터간의 선형 보간을 실행한다.
[latex]Out = V_1 + s \left( V_2 – V_1 \right)[/latex]

D3DXVecNMaximize(Out, U, V) : N벡터의 최대치로 구성되는 벡터를 만든다
[latex]Out_{i}=max\left(U_{i},V_{i}\right)[/latex]

D3DXVecNMinimize(Out, U, V) : N벡터의 최소치로 구성되는 벡터를 만든다
[latex]Out_{i}=min\left(U_{i}, V_{i}\right)[/latex]

D3DXVecNNormalize(Out, V) : 벡터의 정규화한 벡터를 돌려준다.
[latex]Out=\frac{V}{\left|V\right|}[/latex]

D3DXVecNScale(Out, V, s)
[latex]Out=sV[/latex]

D3DXVecNSubtract(Out, V1, V2)
[latex]Out = V_1-V_2[/latex]

2D Vector

D3DXVec2CCW(U,V) :외적
[latex]Result = U_xV_y – U_yV_x[/latex]

D3DXVec2Transform(Out, V, M) : 행렬에 의한 2D 벡터를 변환 한다.
[latex]a=\left(V_x , V_y , 0, 1\right)[/latex]
[latex]b=\left(a \times M \right)^T[/latex]
[latex]Out=\left(b_x , b_y\right)[/latex]

D3DXVec2TransformCoord(Out, V, M) : w = 1 에 투영된 행렬에 의한 2D벡터 변환
[latex]a=\left(V_x, V_y, 0, 1\right)[/latex]
[latex]b=\left(a \times M \right)^T[/latex]
[latex]Out=\frac{1}{b_w}\left(b_x, b_y\right)[/latex]

D3DXVec2TransformNormal(Out, V, M) : 행렬에 의해 2D 벡터 법선을 변환 한다.
[latex]a=\left(V_x, V_y, 0, 0\right)[/latex]
[latex]b=\left(a\times M\right)^T[/latex]
[latex]Out=\left(b_x, b_y\right)[/latex]

3D Vector

D3DXVec3Cross(Out, V1, V2) : 외적
[latex]Out = V_1 \times V_2[/latex]

D3DXVec3Project(Out, V, Viewport, Proj, View, World) : 월드공간 -> 스크린 공간 투영
[latex]a=\left(V_x, V_y, V_z, 1\right)[/latex]
[latex]b=a\times World\times View\times Proj[/latex]
[latex]c=\frac{b}{b_w}[/latex]
[latex]Out_x=Viewport_X+Viewport_{Width}*\left(1+c_x\right)/2[/latex]
[latex]Out_y=Viewport_Y+Viewport_{Height}*\left(1-c_y\right)/2[/latex]
[latex]Out_z=Viewport_{MinZ}+c_z*\left(Viewport_{MaxZ}-Viewport_{MinZ}\right)[/latex]

D3DXVec3Transform(Out, V, M) : 행렬에 의한 3D 벡터를 변환 한다.
[latex]a=\left(V_x , V_y , V_z, 1\right)[/latex]
[latex]b=\left(a \times M \right)^T[/latex]
[latex]Out=\left(b_x , b_y, b_z\right)[/latex]

D3DXVec3TransformCoord(Out, V, M) : w = 1 에 투영된 행렬에 의한 3D벡터 변환
[latex]a=\left(V_x, V_y, V_z, 1\right)[/latex]
[latex]b=\left(a \times M \right)^T[/latex]
[latex]Out=\frac{1}{b_w}\left(b_x, b_y, b_z\right)[/latex]

D3DXVec3TransformNormal(Out, V, M) : 행렬에 의해 3D 벡터 법선을 변환 한다.
[latex]a=\left(V_x, V_y, V_z, 0\right)[/latex]
[latex]b=\left(a\times M\right)^T[/latex]
[latex]Out=\left(b_x, b_y, b_z\right)[/latex]

D3DXVec3Unproject(Out, V, Viewport, Proj, View, World) : 월드공간 <- 스크린 공간 투영
[latex]M=\left(World\times View\times Proj\right)^{-1}[/latex]
[latex]a_x=\left(V_x-Viewport_x\right)*2/ \left(Viewport_{Width}\right)^{-1}[/latex]
[latex]a_y=1-\left(V_y-Viewport_y\right)*2/Viewport_{Height}[/latex]
[latex]a_z=\left(V_z-Viewport_{MinZ}\right) / \left(Viewport_{MaxZ}-Viewport_{MinZ}\right)[/latex]
[latex]a_w=1[/latex]
[latex]b=\left(a\times M\right)^T[/latex]
[latex]Out=\frac{1}{b_w}\left(b_x, b_y, bz\right)[/latex]

4D Vector

D3DXVec4Cross(Out, U, V, W) : 4차원 벡터의 외적
[latex]a = V_xW_y – V_yW_x[/latex]
[latex]b = V_xW_z – V_zW_x[/latex]
[latex]c = V_xW_w – V_wW_x[/latex]
[latex]d = V_yW_z – V_zW_y[/latex]
[latex]e = V_yW_w – V_wW_y[/latex]
[latex]f = V_zW_w – V_wW_z[/latex]
[latex]Outx = fU_y – eU_z + dU_w[/latex]
[latex]Outy = fU_x + cU_z – bU_w[/latex]
[latex]Outz = eU_x – cU_y + aU_w[/latex]
[latex]Outw = dU_x + bU_y – aU_z[/latex]

D3DXVec4Transform(Out, V, M) : 행렬에 의한 4D 벡터를 변환 한다.
[latex]Out=\left(V\times M\right)^T[/latex]

Matice(4×4)
D3DXMatrixAffineTransformation(Out, s, c, r, t)

[latex]Out=begin{bmatrix}0&0&0&0\0&0&0&0\0&0&0&0\0&0&0&0\end{bmatrix}[latex]

D3DXMatrixfDeterminant(M)
[latex]Result = det M[latex]

D3DXMatrixIdentity(Out)
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixInverse(Out, D, M)
[latex]D = det M[latex]
[latex]Out = M-1[latex]

D3DXMatrixIsIdentity(M)
[latex]Result = M≡E[latex]

D3DXMatrixLookAtRH(Out, Eye, At, Up)
[latex]v = Normalized(Eye-At)[latex]
[latex]l = Uptimes v[latex]
[latex]u = vtimes l[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixLookAtLH(Out, Eye, At, Up)
[latex]v = Normalized(At−Eye)[latex]
[latex]r = Uptimes v[latex]
[latex]u = vtimes r[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixMultiply(Out, M1, M2)
[latex]Out = M1times M2[latex]

D3DXMatrixOrthoRH(Out, w, h, n, f)
[latex]Q = (f-n)-1[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixOrthoLH(Out, w, h, n, f)
[latex]Q = (f−n)−1[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixOrthoOffCenterRH(Out, l, r, t, b, n, f)
[latex]Q = (f-n)-1[latex]
[latex]w = r-l[latex]
[latex]h = b-t[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixOrthoOffCenterLH(Out, l, r, t, b, n, f)
[latex]Q = (f-n)-1[latex]
[latex]w = r-l[latex]
[latex]h = b-t[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixPerspectiveRH(Out, w, h, n, f)
[latex]Q = (f-n)-1[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixPerspectiveLH(Out, w, h, n, f)
[latex]Q = (f−n)−1[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixPerspectiveFovRH(Out, Fovy, Aspect, n, f)
[latex]Q = (f−n)−1[latex]
[latex]y = cotg(Fovy)⁄2[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixPerspectiveFovLH(Out, Fovy, Aspect, n, f)
[latex]Q = (f−n)−1[latex]
[latex]y = cotg(Fovy)⁄2[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixPerspectiveOffCenterRH(Out, l, r, t, b, n, f)
[latex]Q = (f−n)−1[latex]
[latex]w = r−l[latex]
[latex]h = b−t[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixPerspectiveOffCenterLH(Out, l, r, t, b, n, f)
[latex]Q = (f−n)−1[latex]
[latex]w = r−l[latex]
[latex]h = b−t[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixReflect(Out, Plane)
[latex](a,b,c,d) = (Planea,Planeb,Planec,Planed)⁄√(Planea²+Planeb²+Planec²)[latex]
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixRotationAxis(Out, V, Angle)
s = sin Angle
c = cos Angle
d = 1−c
(x,y,z) = V
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixRotationQuaternion(Out, Q)
(x,y,z,w) = Q
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixRotationX(Out, Angle)
s = sin Angle
c = cos Angle
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixRotationY(Out, Angle)
s = sin Angle
c = cos Angle
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixRotationYawPitchRoll(Out, Yaw, Pitch, Roll)
(sa,sb,sc) = sin (Roll, Pitch, Yaw)
(ca,cb,cc) = cos (Roll, Pitch, Yaw)
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixRotationZ(Out, Angle)
s = sin Angle
c = cos Angle
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixScaling(Out, x, y, z)
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixShadow(Out, Light, Plane)
(a,b,c,d) = (Planea,Planeb,Planec,Planed)⁄√(Planea²+Planeb²+Planec²)
(x,y,z,w) = Light
f = Lightx⋅Planea + Lighty⋅Planeb + Lightz⋅Planec + Lightw⋅Planed
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixTransformation(Out, Scenter, Srot, Scaling, Rotcenter, Rot, Trans)
D3DXMatrixTranslation(A, -Scenterx, -Scentery, -Scenterz)
D3DXMatrixScaling(B, Scalingx, Scalingy, Scalingz)
D3DXMatrixRotationQuaternion(C, Srot)
u = Scenter − Rotcenter
D3DXMatrixTranslation(D, ux, uy, uz)
D3DXMatrixRotationQuaternion(E, Rot)
v = Rotcenter + Trans
D3DXMatrixTranslation(F, vx, vy, vz)
Out = A×CT×B×C×D×E×F

D3DXMatrixTranslation(Out, x, y, z)
[latex]Out=E=begin{bmatrix}1&0&0&0\0&1&0&0\0&0&1&0\0&0&0&1\end{bmatrix}[latex]

D3DXMatrixTranspose(Out, M)
Out = MT

Plane

D3DXPlaneDot(P, V)
Result = (Pa, Pb, Pc, Pd)⋅V

D3DXPlaneDotCoord(P, V)
Result = (Pa, Pb, Pc)⋅V + Pd

D3DXPlaneDotNormal(P, V)
Result = (Pa, Pb, Pc)⋅V

D3DXPlaneIntersectLine(Out, P, U, V)
n = (Planea, Planeb, Planec)
d = V − U
Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]

D3DXPlaneFromPointNormal(Out, P, N)
Planea = Nx
Planeb = Ny
Planec = Nz
Planed = −N⋅P

D3DXPlaneNormalize(Out, P)
q = 1⁄√(Pa² + Pb² + Pc²)
Outa = q⋅Pa
Outb = q⋅Pb
Outc = q⋅Pc
Outd = q⋅Pd

D3DXPlaneFromPoints(Out, A, B, C)
v = (B − A) × (C − A)
n = 1⁄|v| v
Outa = nx
Outb = ny
Outc = nz
Outd = −n⋅A

D3DXPlaneTransform(Out, P, M)
Q = P⁄|P|
u = (Qa, Qb, Qc, 0)
D = Qd
A = (−Dux, −Duy, −Duz, 1)
B = A×M
v = u×M
q = 1⁄|v|
Outa = qvx
Outb = qvy
Outc = qvz
Outd = −qv⋅B

DirectX 함수

COLOR
D3DXColorAdd – 2 개의 색값을 덧셈 해, 새로운 색값을 생성 한다.
D3DXColorAdjustContrast – 색의 콘트라스트값을 조정한다.
D3DXColorAdjustSaturation – 색의 채도값을 조정한다.
D3DXColorLerp – 선형 보간을 사용해 색값을 생성 한다.
D3DXColorModulate – 2 개의 색을 블렌드 한다.
D3DXColorNegative – 있는 색값에 대한 부의 색값을 생성 한다.
D3DXColorScale – 색값을 스케일링 한다.
D3DXColorSubtract – 2 개의 색값을 뺄셈 해, 새로운 색값을 생성 한다.

ETC
D3DXFloat16To32Array – 16 비트 부동 소수점의 배열을 32 비트 부동 소수점으로 변환한다.
D3DXFloat32To16Array – 32 비트 부동 소수점의 배열을 16 비트 부동 소수점으로 변환한다.
D3DXFresnelTerm – 후레넬항을 계산한다.

Matrix
D3DXCreateMatrixStack – ID3DXMatrixStack 인터페이스의 인스턴스를 생성 한다.
D3DXMatrixAffineTransformation – 아핀 변환 행렬을 생성 한다.
D3DXMatrixDeterminant – 행렬의 행렬식을 돌려준다.
D3DXMatrixIdentity – 단위행렬을 생성 한다.
D3DXMatrixInverse – 행렬의 역행열을 계산한다.
D3DXMatrixIsIdentity – 행렬이 단위행렬인지 아닌지를 판정한다.
D3DXMatrixLookAtLH – 왼손 좌표계 뷰 행렬을 생성 한다.
D3DXMatrixLookAtRH – 오른손 좌표계 뷰 행렬을 생성 한다.
D3DXMatrixMultiply – 2 개의 행렬의 적을 계산한다.
D3DXMatrixMultiplyTranspose – 2 개의 행렬의 전치적을 계산한다.
D3DXMatrixOrthoLH – 왼손 좌표계 정사영 행렬을 생성 한다.
D3DXMatrixOrthoOffCenterLH – 커스터마이즈 한 왼손 좌표계 정사영 행렬을 생성 한다.
D3DXMatrixOrthoOffCenterRH – 커스터마이즈 한 오른손 좌표계 정사영 행렬을 생성 한다.
D3DXMatrixOrthoRH – 오른손 좌표계 정사영 행렬을 생성 한다.
D3DXMatrixPerspectiveFovLH – 시야에 근거해, 왼손 좌표계 퍼스펙티브 투영 행렬을 생성 한다.
D3DXMatrixPerspectiveFovRH – 시야에 근거해, 오른손 좌표계 퍼스펙티브 투영 행렬을 생성 한다.
D3DXMatrixPerspectiveLH – 왼손 좌표계 퍼스펙티브 투영 행렬을 생성 한다.
D3DXMatrixPerspectiveOffCenterLH – 커스터마이즈 한 왼손 좌표계 퍼스펙티브 투영 행렬을 생성 한다.
D3DXMatrixPerspectiveOffCenterRH – 커스터마이즈 한 오른손 좌표계 퍼스펙티브 투영 행렬을 생성 한다.
D3DXMatrixPerspectiveRH – 오른손 좌표계 퍼스펙티브 투영 행렬을 생성 한다.
D3DXMatrixReflect – 평면에 대해서 좌표계를 반전한 행렬을 생성 한다.
D3DXMatrixRotationAxis – 임의의 축을 회전축으로 해 회전하는 행렬을 생성 한다.
D3DXMatrixRotationQuaternion – 쿼터니온으로부터 회전 행렬을 생성 한다.
D3DXMatrixRotationX – x 축을 회전축으로 해 회전하는 행렬을 생성 한다.
D3DXMatrixRotationY – y 축을 회전축으로 해 회전하는 행렬을 생성 한다.
D3DXMatrixRotationYawPitchRoll – 요, 피치, 및 롤을 지정해 행렬을 생성 한다.
D3DXMatrixRotationZ – z 축을 회전축으로 해 회전하는 행렬을 생성 한다.
D3DXMatrixScaling – x 축, y 축, z 축으로 따라 스케일링 하는 행렬을 생성 한다.
D3DXMatrixShadow – 지오메트리를 평면에 투영 하는 행렬을 생성 한다.
D3DXMatrixTransformation – 변환 행렬을 생성 한다.
D3DXMatrixTranslation – 오프셋(offset)를 지정해 행렬을 생성 한다.
D3DXMatrixTranspose – 행렬의 전치행렬을 돌려준다.

Plane
D3DXPlaneDot – 평면과 4D 벡터의 내적을 계산한다.
D3DXPlaneDotCoord – 평면과 3D 벡터의 내적을 계산한다. 벡터의 w 파라미터는, 1 이다고 보여진다.
D3DXPlaneDotNormal – 평면과 3D 벡터의 내적을 계산한다. 벡터의 w 파라미터는, 0 이다고 보여진다.
D3DXPlaneFromPointNormal – 점트와 법선으로부터 평면을 생성 한다.
D3DXPlaneFromPoints – 3 개의 점으로부터 평면을 생성 한다.
D3DXPlaneIntersectLine – 평면과 직선의 교점을 조사한다.
D3DXPlaneNormalize – 평면의 법선의 길이를 정규화하기 위해(때문에), 평면의 계수를 정규화한다.
D3DXPlaneTransform – 행렬을 사용해 평면을 변환 한다. 입력 행렬은, 실제의 변환의 역전치행렬이다.
D3DXPlaneTransformArray – 행렬을 사용해 평면을 변환 한다. 입력 행렬은, 실제의 변환의 역전치행렬이다.

Quaternion
D3DXQuaternionBaryCentric – 중심 좌표의 쿼터니온을 돌려준다.
D3DXQuaternionConjugate – 쿼터니온의 공역을 돌려준다.
D3DXQuaternionDot – 2 개의 쿼터니온의 내적을 돌려준다.
D3DXQuaternionExp – 지수함수를 계산한다.
D3DXQuaternionIdentity – 항등 쿼터니온을 돌려준다.
D3DXQuaternionInverse – 쿼터니온을 모두 부려, 재정규화한다.
D3DXQuaternionIsIdentity – 쿼터니온이 항등 쿼터니온일지 어떨지를 판정한다.
D3DXQuaternionLength – 쿼터니온의 길이를 돌려준다.
D3DXQuaternionLengthSq – 쿼터니온의 길이의 2 승을 돌려준다.
D3DXQuaternionLn – 자연대수를 계산한다.
D3DXQuaternionMultiply – 2 개의 쿼터니온의 적을 계산한다.
D3DXQuaternionNormalize – 정규화한 길이의 쿼터니온을 계산한다.
D3DXQuaternionRotationAxis – 임의의 축을 회전축으로서 쿼터니온을 회전시킨다.
D3DXQuaternionRotationMatrix – 회전 행렬로부터 쿼터니온을 생성 한다.
D3DXQuaternionRotationYawPitchRoll – 요·피치·롤을 지정해 쿼터니온을 생성 한다.
D3DXQuaternionSlerp – 구면선형 보간을 사용해, 2 개의 쿼터니온간을 보간 한다.
D3DXQuaternionSquad – 구면2차 보간을 사용해, 쿼터니온간을 보간 한다.
D3DXQuaternionSquadSetup – 구면2차 보간의 제어 포인트를 설정한다.
D3DXQuaternionToAxisAngle – 쿼터니온의 회전축과 회전 각도를 계산한다.

2D Vector
D3DXVec2Add – 2 개의 2D 벡터를 추가한다.
D3DXVec2BaryCentric – 지정한 2D 벡터를 사용해, 중심 좌표의 점을 돌려준다.
D3DXVec2CatmullRom – 지정된 2D 벡터를 사용해, Catmull-Rom 보간을 실행한다.
D3DXVec2CCW – 2 개의 2D 벡터의 외적을 계산해, z 요소를 돌려준다.
D3DXVec2Dot – 2 개의 2D 벡터의 내적을 계산한다.
D3DXVec2Hermite – 지정된 2D 벡터를 사용해, 에르미트의 스플라인 보간을 실행한다.
D3DXVec2Length – 2D 벡터의 길이를 돌려준다.
D3DXVec2LengthSq – 2D 벡터의 길이의 2 승을 돌려준다.
D3DXVec2Lerp – 2 개의 2D 벡터간의 선형 보간을 실행한다.
D3DXVec2Maximize – 2 개의 2D 벡터의 최대치로 구성되는 2D 벡터를 돌려준다.
D3DXVec2Minimize – 2 개의 2D 벡터의 최소 값으로 구성되는 2D 벡터를 돌려준다.
D3DXVec2Normalize – 2D 벡터의 정규화한 벡터를 돌려준다.
D3DXVec2Scale – 2D 벡터를 스케일링 한다.
D3DXVec2Subtract – 2 개의 2D 벡터를 뺄셈 한다.
D3DXVec2Transform – 지정된 행렬에 의해 2D 벡터를 변환 한다.
D3DXVec2TransformArray – 지정된 행렬에 의해 2D 벡터의 배열을 변환 한다.
D3DXVec2TransformCoord – 지정된 행렬에 의해 2D 벡터를 변환 해 w = 1 에 투영 한다.
D3DXVec2TransformCoordArray – 지정된 행렬에 의해 배열 (x, y, 0, 1)을 변환 해 w = 1 에 투영 한다.
D3DXVec2TransformNormal – 지정된 행렬에 의해 2D 벡터 법선을 변환 한다.
D3DXVec2TransformNormalArray – 지정된 행렬에 의해 배열 (x, y, 0, 0)을 변환 한다.

3D Vector
D3DXVec3Add – 2 개의 3D 벡터를 추가한다.
D3DXVec3BaryCentric – 지정한 3D 벡터를 사용해, 중심 좌표의 점을 돌려준다.
D3DXVec3CatmullRom – 지정된 3D 벡터를 사용해, Catmull-Rom 보간을 실행한다.
D3DXVec3Cross – 2 개의 3D 벡터의 외적을 계산한다.
D3DXVec3Dot – 2 개의 3D 벡터의 내적을 계산한다.
D3DXVec3Hermite – 지정된 3D 벡터를 사용해, 에르미트의 스플라인 보간을 실행한다.
D3DXVec3Length – 3D 벡터의 길이를 돌려준다.
D3DXVec3LengthSq – 3D 벡터의 길이의 2 승을 돌려준다.
D3DXVec3Lerp – 2 개의 3D 벡터간의 선형 보간을 실행한다.
D3DXVec3Maximize – 2 개의 3D 벡터의 최대치로 구성되는 3D 벡터를 돌려준다.
D3DXVec3Minimize – 2 개의 3D 벡터의 최소 값으로 구성되는 3D 벡터를 돌려준다.
D3DXVec3Normalize – 3D 벡터의 정규화한 벡터를 돌려준다.
D3DXVec3Project – 개체 공간으로부터 스크린 공간에 벡터를 투영 한다.
D3DXVec3ProjectArray – 개체 공간으로부터 스크린 공간에 벡터를 투영 한다.
D3DXVec3Scale – 3D 벡터를 스케일링 한다.
D3DXVec3Subtract – 2 개의 3D 벡터를 뺄셈 한다.
D3DXVec3Transform – 지정된 행렬에 의해 벡터 (x, y, z, 1)를 변환 한다.
D3DXVec3TransformArray – 지정된 행렬에 의해 배열 (x, y, z, 1)을 변환 한다.
D3DXVec3TransformCoord – 지정된 행렬에 의해 3D 벡터를 변환 해 w = 1 에 투영 한다.
D3DXVec3TransformCoordArray – 지정된 행렬에 의해 배열 (x, y, z, 1)을 변환 해 w = 1 에 투영 한다.
D3DXVec3TransformNormal – 지정된 행렬에 의해 3D 벡터 법선을 변환 한다.
D3DXVec3TransformNormalArray – 지정된 행렬에 의해 배열 (x, y, z, 0)을 변환 한다.
D3DXVec3Unproject – 스크린 공간으로부터 개체 공간에 벡터를 투영 한다.
D3DXVec3UnprojectArray – 스크린 공간으로부터 개체 공간에 벡터를 투영 한다.

4D Vector
D3DXVec4Add – 2 개의 4D 벡터를 추가한다.
D3DXVec4BaryCentric – 지정한 4D 벡터를 사용해, 중심 좌표의 점을 돌려준다.
D3DXVec4CatmullRom – 지정된 4D 벡터를 사용해, Catmull-Rom 보간을 실행한다.
D3DXVec4Cross – 4 차원 벡터의 외적을 산출한다.
D3DXVec4Dot – 2 개의 4D 벡터의 내적을 요구한다.
D3DXVec4Hermite – 지정된 4D 벡터를 사용해, 에르미트의 스플라인 보간을 실행한다.
D3DXVec4Length – 4D 벡터의 길이를 돌려준다.
D3DXVec4LengthSq – 4D 벡터의 길이의 2 승을 돌려준다.
D3DXVec4Lerp – 2 개의 4D 벡터간의 선형 보간을 실행한다.
D3DXVec4Maximize – 2 개의 4D 벡터의 최대치로 구성되는 4D 벡터를 돌려준다.
D3DXVec4Minimize – 2 개의 4D 벡터의 최소 값으로 구성되는 4D 벡터를 돌려준다.
D3DXVec4Normalize – 4D 벡터의 정규화한 벡터를 돌려준다.
D3DXVec4Scale – 4D 벡터를 스케일링 한다.
D3DXVec4Subtract – 2 개의 4D 벡터를 뺄셈 한다.
D3DXVec4Transform – 지정된 행렬에 의해 4D 벡터를 변환 한다.
D3DXVec4TransformArray – 행렬을 지정해 벡터의 배열을 변환 한다.