2008년 04월 05일
D3D Chapter 02>> Direct3D 9 초기화 (Sample Code:Tut01_CreateDevice)
:: 오늘의 넋두리---------------------------------------------------------------------------------
프로그램의 흐름을 잡아라! (Sample Code: Tut01_CreateDevice)에서 Window의 흐름을 파악했다.
이제서야 Direct3D를 접근할 수 있게 된것이다. 아... ㅜ.ㅜ
오늘 안에 Tut05_Textures까지 정리를 해야 하는데... 그래야 강의 진도를 맞추는데... 아... ㅜ.ㅜ
그나마 게임애니메이션과가 MT를 간덕에 시간이 남는구만... 아... OTL
------------------------------------------------------------------------------------------------
Direct3D 9의 초기화!
Tutorials Code ::
C:\Program Files\Microsoft DirectX SDK (March 2008)\Samples\C++\Direct3D\Tutorials\Tut01_CreateDevice
예제 코드의 처리 과정은 [Figure. 01]과 같다. 여기서 주목해야 할 부분은 InitD3D와 메시지 루프에서 호출되는 Cleanup과 Render function들이다.

------------------------------------------
::HRESULT InitD3D(HWND hWnd)
Direct3D 9을 초기화 하는 부분으로 Window가 설정되고 메모리에 생성이 된 후, 그 Window가 화면상에 출력 되기 전에 호출된다. return 값으로는 HRESULT(double word:4byte)로 SUCCEEDED 메크로를 활용하여 판별된다. S_OK를 return하면 True가 E_FAIL을 return하면 False가 된다.
예제의 Direct3D의 초기화는 다음과 같이 이루어진다.
- Direct3D object 와 Direct3D Device를 선언
- Direct3D object생성
- D3DPRESENT_PARAMETERS 구조체 정의로 화면 설정
- D3DPRESENT_PARAMETERS의 설정에 따라 Direct3D Device 생성
1. Direct3D object 와 Direct3D Device를 선언
Direct3D의 기능을 사용하기 위해서는 Direct3D에 의해 제공되어지는 interface들을 통하여 사용하여야 한다. Direct3D object는 Direct3D에서 제공하는 기능을 수행하기 위한 object로 IDirect3D9 interface를 통하여 관리 또는 기능을 수행하며, Direct3D Device는 Direct3D의 rendering component로 IDirect3DDevice9 interface을 통하여 관리 또는 기능을 수행한다.
또한 이러한 인터페이스 들은 d3d9.h에 포인터로 재정의 되어있다.
<d3d9.h>______________________________________________________________________
typedef struct IDirect3D9 *LPDIRECT3D9, *PDIRECT3D9;
typedef struct IDirect3DDevice9 *LPDIRECT3DDEVICE9, *PDIRECT3DDEVICE9;
---------------------------------------------------------------------------------
위와 같이 재정의 되어 있는 자료형으로 Direct3D object와 Direct3DDevice를 연결 할 interface인 IDirect3D9과 IDirect3DDevice9을 아래와 같이 선언하였다.
<예제> 18 Line
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
2. Direct3D object생성
위에서 선언된 인터페이스 포인터는 특정 함수를 통해 다음 그림과 같이 Direct3D의 각 component에 접근을 하게 된다.

먼저 Direct3D object를 생성해야 하는데 사용되는 함수는 d3d9.h에 선언 되어 있는 Direct3DCreate9이다.
함수의 원형은 다음과 같다.
IDirect3D9 * WINAPI Direct3DCreate9(UINT SDKVersion);
매개변수는 Direct3D SDK의 버전을 명시해 주는데 일반적으로 D3D_SDK_VERSION을 넘겨준다. D3D_SDK_VERSION 역시 d3d9.h에 정의 되어 있다.
<예제> 34 Line
// Create the D3D object, which is needed to create the D3DDevice.
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
3. D3DPRESENT_PARAMETERS 구조체 정의로 화면 설정
다음으로 D3DPRESENT_PARAMETERS 구조체를 정의 한다. 이 구조체가 무엇을 위한 것인지는 구조체 멤버의 속성을 통하여 알아 보도록 하자.
typedef struct D3DPRESENT_PARAMETERS {
... Members ...
} D3DPRESENT_PARAMETERS, *LPD3DPRESENT_PARAMETERS;
... Members ...
UINT BackBufferWidth, BackBufferHeight;
Backbuffer의 픽셀 단위의 너비와 높이, 윈도우 모드라면 0으로 지정하여 윈도우와 동일한 크기로 설정한다.
D3DFORMAT BackBufferFormat;
Backbuffer pixel format, 인수로는 d3d9types.h의 열겨형인 _D3DFORMAT의 멤버를 사용한다.
_D3DFORMAT)D3DFMT_UNKNOWN, D3DFMT_R8G8B8(24bit),D3DFMT_A8R8G8B8(32bit),D3DFMT_X8R8G8B8(32bit,좌측 8bit 사용 하지 않음), D3DFMT_R5G6B5(16bit), etc.
UINT BackBufferCount;
Backbuffer의 갯수, 더블,트리플 버퍼링이 가능하게 하는 멤버로 보통 한개만 생성한다.
D3DMULTISAMPLE_TYPE MultiSampleType;
안티 얼리어싱 등 특수효과를 위한 멀티 샘플링의 타입을 결정, 보통 D3DMULTISAMPLE_NONE으로 지정한다.
DWORD MultiSampleQuality;
멀티 샘플링의 질적인 정도 지정.
D3DSWAPEFFECT SwapEffect;
Backbuff의 값을 PRESENT(D3D 8.0이하 SURFACE)에 표현되는 기법 결정. 플링핑 방식과 카피 방식이 있다. d3d9types.h의 열거형인 _D3DSWAPEFFECT의 멤버를 사용한다.
_D3DSWAPEFFECT)D3DSWAPEFFECT_DISCARD, D3DSWAPEFFECT_FLIP, D3DSWAPEFFECT_COPY
HWND hDeviceWindow;
드로인의 대상 윈도우 핸들.
BOOL Windowed;
Window의 모드가 full-screen mode이냐 window mode이냐를 결정. 게임에서는 대부분 FALSE(full-screen mode).
BOOL EnableAutoDepthStencil;
자동 깊이 스텐실 버퍼를 만들것인지를 결정. 보통 true라고 하는데... ( ㅇ.ㅇ;;, ㅡㅡ;;)
D3DFORMAT AutoDepthStencilFormat;
위에서 말한 깊이 스텐실 버퍼인지 뭔지 하는 녀석의 포맷을 지정한다는데...
DWORD Flags;
부가 설정. 이것도 보통 0이라고 한다. 인수들을 보니, 후면 버퍼 잠금 지정 같은 설정을 가능하게 하는군.
UINT FullScreen_RefreshRateInHz;
전체 화면일때의 모니터 주파수를 설정하는 것으로 D3DPRESENT_RATE_ DEFAULT 플래그를 사용함으로 현재의 주파수를 사용하게 된다.
UINT PresentationInterval;
이거 정리 하느라고 이젠 잠이 온다... 12시 이전에 끝내려고 했지만 등록 날짜가 변해버렸다. 젠장... 이 멤버는 정말 알아보고 싶지 않다. 컥... 지친다.
아무리 지친다 하더라도 정리는 해야 하기 때문에! 위의 멤버들의 기능들로 하여금 D3DPRESENT_PARAMETERS는 무엇을 담고 있는지 자연스레 알게 되었다. 구조체 이름 그대로 PRESENT를 설정하는 PARAMETER들의 집합인 것이였다.
그리고 위에서 PRESENT가 어쩌고 Backbuffer가 어쩌고 했는데...
PRESENT라는 용어는 예전에 SURFACE라는 용어로 쓰였것으로 기본적으로 16bit와 2D로 설정된 Window를 3D 사용을 위해 작업공간의 설정을 변경해야한다. Direct3D 9에서는 그 작업공간을 PRESENT라고 한다. D3DPRESENT_PARAMETERS는 3D를 가능하게 하기 위해 PRESENT라는 작업공간을 설정하는 구조체인 것이다.
또한, Backbuffer는 3D의 특성과 관련이 있다. 3D는 2D와 달리 시야에서 보이지 않는 영역이 존재함을 알아야 한다. 그래서 그 보이지 않는 영역을 PRESENT에 뿌려주기 전에 버퍼에 저장을 해 두어야 하는데 그 버퍼는 PRESENT의 가로 세로의 동일한 크기로 RAM 혹은 Graphic card 내장 메모리에 할당되어 지게 된다. 이것이 바로 Backbuffer이며 D3DPRESENT_PARAMETERS의 BackBufferFormat을 통해 BackBuffer차지하는 한 픽셀이 차지하는 메모리 크기와 색을 설정한다.

Tip> 한 Pixel이 몇 bit를 표현하느냐?? = 얼마의 Color를 지원하느냐??
또한, 256 color는 미리 Color Table을 만들어주는 것이 효율적이다.
음... 자고 일어나서 정리 해야 겠다.
4. D3DPRESENT_PARAMETERS의 설정에 따라 Direct3D Device 생성
Good morning? (ご,.こ) 윽... 어제부터 너무 오래 앉아 있었더니... 아니... 그보다. 움직이지 않았더니... ㅡㅡ;; 그래! 그보다는 앉아있는 자세가 너무 불량스러워서... 매우 피곤한 상태이다.
어제까지 무엇을 정리했는지도 기억이 나질 않고... very very bad morning이네...
자자! 다시 정신차리고 정리를 시작해 보도록하자!
D3DPRESENT_PARAMETERS의 설정이 끝나면 Direct3D Device를 생성해야 한다. 위의 1번에서도 말했듯이 Direct3D Device Component는 Rendering을 담당하는 녀석이다. [Figure. 04]에서와 같이, 구조적으로는 transform module, lighting module 그리고 rasterizing module이 있다.

Direct3D Device는 크게 2가지 타입을 갖는데 다음과 같다.
HAL(Hardware Abstraction Layer) DeviceREF(REFerence rasterize) device
Device의 생성은 Direct3D object의 CreateDevice함수 호출로 가능하다.
<예제> 56 Line
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
HRESULT CreateDevice(
... parameters ...
);
... parameters ...
UINT Adapter,
그래픽 카드, D3DADAPTER_DEFAULT(주 디스플레이 장치를 선택)
D3DDEVTYPE DeviceType,
D3DDEVTYPE_HAL, D3DDEVTYPE_REF, D3DDEVTYPE_SW, etc.
HWND hFocusWindow,
장치와 연결될 윈도우 핸들
DWORD BehaviorFlags,
#define D3DCREATE_FPU_PRESERVE 0x00000002L
- 배정밀도 연산. Dirct3D의 성능 저하 요인.
#define D3DCREATE_MULTITHREADED 0x00000004L
- 쓰레드 안전 모드로 수행하기 위해 속도를 낮춘다. 전역 크리티컬 섹션을 많이 사용하지 않는 것이 좋은 방법이란다.
#define D3DCREATE_PUREDEVICE 0x00000010L
- Get 계열의 함수 사용 금지.
#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L
- 정점 쉐이더를 지원시 소프트웨어를 이용하여 T&L(변형 & 라이팅)을 사용
#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L
- 정점 쉐이더를 지원시 하드웨어를 이용하여 T&L(변형 & 라이팅)을 사용
#define D3DCREATE_MIXED_VERTEXPROCESSING 0x00000080L
- H/W, S/W의 병행 사용
#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT 0x00000100L
- 드라이버 대신 Direct3D가 Resource를 관리
#define D3DCREATE_ADAPTERGROUP_DEVICE 0x00000200L
- 마스터 어댑터가 소유하는 모든 헤드를 구동하도록 장치에 지시.
#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX 0x00000400L
- ???
D3DPRESENT_PARAMETERS * pPresentationParameters,
위에서 정의한 PRESENT_PARAMETER 구조체.
IDirect3DDevice9 ** ppReturnedDeviceInterface
앞의 매개변수의 수준으로 생성된 Direct3D Device를 return. 1번에서 선언한 Direct3D Device component의 인터페이스 포인터를 인수로 지정한다.
이리하여 g_pd3dDevice에 생성된 Direct3D Device가 도킹 되었다.
잠시 쉬어 가도록 하자<^^;;;>______________________
재미난 비유를 들어 보자면... 이렇다.
때는 바야흐로 2008년 3월 우주 산업이 도래하여 X-Mode(아무의미없음 필자가 속한 동아리 이름)는 우주 정거장을 건설 하기 시작했다. 그리고 우주 전거장에 3D 시뮬레이션 모듈을 탑제 하려 했다. 그때 눈에 들어온 것이 마침 MS라는 녀석이 가지고 있는 Direct3D라는 부품(Component)이였다. 그래서 X-Mode는 Direct3D라는 거대한 부품을 우주로 운반을 해왔다. 하지만 Direct3D라는 부품과 우주 정거장은 금속 재질이 달라서(또는 크기가 너무 커서) 결합하는것이 불가능했다.
이러한 문제를 MS에게 제기하였더니 MS는 Interface라는 녀석을 보내 주었다. 그래서 Direct3D라는 부품은 우주정거장과 완전 결합형이 아닌 Interface라는 도킹시스템을 사용하여 우주 정거장 밖에 존재 하게 되었다. 그것이 바로 IDirecte3D이다. 그리고 X-Mode는 Direct3D에게 3D 시뮬레이션을 위해 D3DPRESENT_PARAMETERS라는 양식으로 시뮬레이션 장치의 규격을 지정하여 주자 Direct3D는 IDirect3D에 연결된 CreateDevice라는 작업실에서 IDirect3DDevice라를 interface를 도킹하여 주었다. 그 인터페이스를 따라 들어가 보니 렌더링을 하기 위한 갖가지 기능이 있었다. 라는 전설적인... 이야기... ㅋ ㅡㅡ^
이렇게 초기화가 모두 끝이 나면 Init3D는 S_OK를 리턴하게 되고 wWinMain의 SUCCEEDED 메크로는 True를 양산하게 되고 무사히 Window를 화면에 출력하고 메시지 루프로 진입하게 된다.
Tut01예제에서는 단 2가지 메시지에만 반응하며 그 메시지는 다음과 같다.
- WM_DESTROY: Window가 소멸되기 바로 전에 발생 - Cleanup() 호출
- WM_PAINT: Window를 다시 그려야 할 시점에서 발생 - Render() 호출
------------
::Cleanup
Direct3D object와 Direct3D Device componet의 할당 메모리를 Release해 준다.
----------
::Render
Direct3D Device를 통해서 그림을 그려준다. 어떤 그림도 그려지지 않고 파란색 배경만이 지정된 상태이다. 이 함수 부분은 다음 예제인 Tut02_Vertices를 통해서 알아보도록 하자.
이렇게 첫번째 예제인 Device 생성을 위한 Direct3D의 초기화에 대해서 정리 하였다.
이거... 너무 공들여서 정리를 하는건 아닌지... 이런 초기화는 거의 일정하게 정해진 룰안에서 사용된다. Direct3D 또한 그러하리라. 다음엔 Vertices를 보고 정리를 해봐야 겠다. 아... 이거... 코딩보다도... 라이브러리 보다도... 3D자체가 거부감이 드는군. 쩝
이 글과 관련있는 글을 자동검색한 결과입니다 [?]
- HRESULT CreateDevice by 케간지무늬
- struct D3DPRESENT_PARAMETERS by 케간지무늬
- D3D Chapter 04>> 정점 그리기(Sample Code:Tut02_Vertices) by 케간지무늬
- 프로그램의 흐름을 잡아라! (Sample Code: Tut01_CreateDevice) by 케간지무늬
- 프로그램의 흐름을 잡아라! by 케간지무늬
# by | 2008/04/05 10:45 | ▶▷DirectX◁◀ | 트랙백(2) | 덧글(0)






☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
제목 : struct D3DPRESENT_PARAMETERS
2008/04/09 수요일. struct D3DPRESENT_PARAMETERS:: 오늘의 넋두리--------------------------------------------------------------------------------- 앞에서 너무 장황한 설명을 늘어 놓다 보니깐 다음에 필요한 부분만을 찾아보려고 했을때 어려움이 있다는것을 알게 되었다.그래서 구조체나 상수, 함수 등은 이렇게 따로 분리를 하기로 한다. ......more
제목 : HRESULT CreateDevice
2008/04/09 수요일. HRESULT CreateDevice:: 오늘의 넋두리--------------------------------------------------------------------------------- 관련된 내용은 : Direct3D 9 초기화 (Sample Code:Tut01_CreateDevice)------------------------------------------------------......more