Download presentation
Presentation is loading. Please wait.
1
DirectX 9 Ch1. Direct3D 초기화
2
목표 Direct3D가 그래픽 하드웨어와 상호작용하는 방법 Direct3D에서 COM의 역할 이해
이 책의 예제 애플리케이션에서 이용하고 있는 범용적인 구조에 익숙해진다.
3
1.1 Direct3D 개요 Direct3D는 3D 가속 하드웨어를 이용하여 3D를 표현하는 저수준 그래픽 API
Application, Direct3D, 하드웨어 간의 관계 HAL(Hardware Abstraction Layer) : 장치로 하여금 특별한 작업을 수행하도록 하는 장치 고유의 코드 Direct3D가 각 장치의 세부적인 부분을 제어할 필요없게 함 하드웨어 장치에 독립적인 규약 확립이 가능 HAL에서 구현하지 않은 Direct3D함수 호출시 에러 발생 Application Direct3D HAL Graphic device
4
1.1 Direct3D 개요 REF 장치 D3DDEVTYPE
모든 Direct3D API를 소프트웨어로 애뮬레이트하는 레퍼런스 래스터라이저를 제공 순수한 개발 목적으로 제공 D3DDEVTYPE HAL 장치는 D3DDEVTYPE 열거형 멤버인 D3DDEVTYPE_HAL로 지정 REF 장치도 D3DDEVTYPE_REF로 지정 장치를 만들 때 어떤 타입을 원하는지 지정해야함
5
1.2 COM COM(Component Object Model) : DirectX를 프로그래밍 언어에 독립적으로 만들어주고 하위 호환성을 갖출 수 있게 하는 기술 COM객체 = 인터페이스,C++ 클래스와 비슷하게 이용 다른 COM 인터페이스의 메서드나 특수한 함수를 통해 COM 인터페이스의 포인터를 얻음 C++new키워드로 COM인터페이스 만드는 것이 아님 인터페이스를 이용한 작업이 모두 끝나면 인터페이스의 Release 메서드를 호출 COM객체가 자신의 메모리 관리를 스스로 수행 COM의 정의 :
6
1.3.1 표면(surface) Direct3D가 주로 2D이미지 데이터를 보관하는데 이용하는 픽셀의 행렬
실제 픽셀 데이터는 선형 배열에 보관 표면의 너비와 높이는 픽셀 단위로 계산 피치는 byte로 계산, 하드웨어에 따라 너비보다 길수있음 피치 = 너비 x sizeof(pixelFormat)이 아닐수 있음.
7
1.3.1 표면(surface) IDirect3DSurface9 인터페이스 사용
LockRect – 표면 메모리로의 포인터 제공. 약간의 포인터 연산을 거치면 표면 내의 각 픽셀을 읽고 쓸 수 있음 UnlockRect – LockRect를 호출하고 표면 메모리에 대한 작업이 끝난 뒤에는 호출하여 표면의 잠금을 해제 GetDesc – 표면에 대한 정보를 D3DSURFACE_DESC 구조체를 통하여 얻음 // _surface가 IDirect3DSurface9 인터페이스로의 포인터라고 가정 D3DSURFACE_DESC surfaceDesc; _surface -> GetDesc(&surfaceDesc); //표면 정보를 얻는다. D3DLOCKED_RECT lockedRect; // 구조체 구조 : INT Pitch 표면피치, void *pBits 표면메모리 시작 포인터 _surface -> lockRect(&lockedRect, 0, 0); //잠근데이터를 얻을 포인터, 전체 표면을 잠근다, 잠금 플래그 를 지정하지 않는다. DWORD* imageData = (DWORD*)lockedRect.pBits; for(int i = 0; i < surfaceDesc.Height; i++) { for(int j = 0; j < surfaceDesc.Width; j++) { int index = i * lockedRect.Pitch / 4 + j; //피치는 byte 단위이며 DWORD당 4byte이므로 //피치를 4로 나누었음에 주의 imageData[index] = 0xffff0000; //Red } _surface -> UnlockRect(); //잠금 해제
8
1.3.2 멀티 샘플링(Multisampling)
픽셀 매트릭스로 이미지를 표현할 때 나타나는 거친 이미지를 부드럽게 만드는 데 이용되는 기술 D3DMULTISAMPLE_TYPE : 표면에 적용할 멀티 샘플링 레벨을 지정할 수 있도록 하는 값들로 구성 D3DMULTISAMPLE_NONE – 멀티 샘플링을 지정안함 D3DMULTISAMPLE_1_SAMPLE ··· D3DMULTISAMPLE_16_SAMPLE – 1에서 16까지의 멀티샘플링을 지정 멀티 샘플링 타입과 연계된 품질 레벨도 있으며, DWORD로 지정 IDirect3D9::CheckDeviceMultiSampleType 메서드로 그래픽카드에서 지원하는 멀티샘플링 타입과 품질 레벨 확인
9
1.3.3 픽셀 포맷 표면이나 텍스처를 만들기 위해서는 Direct3D자원의 픽셀 포맷을 지정해야함
D3DFORMAT 열거형 멤버로 지정 D3DFMT_R8G8B8 – 24bit 픽셀 포맷 D3DFMT_X8R8G8B8 – 32bit픽셀 포맷. 가장 왼쪽 8bit 사용하지 않음 D3DFMT_A8R8G8B8 – 32bit 픽셀 포맷. 가장 왼쪽 8bit 알파 D3DFMT_A16B16G16R16F – 64bit 부동소수점 픽셀 포맷. 가장 왼쪽부터 16bit씩 alpha, blue, green, red D3DFMT_A32B32G32R32F – 128bit 부동소수점 픽셀 포맷. 가장 왼쪽부터 32bit씩 alpha, blue, green, red 픽셀 포맷의 전체 목록은 SDK문서에서 D3DFORMAT 참조
10
1.3.4 메모리 풀 다양한 Direct3D 자원들을 여러 가지 종류의 메모리 풀에 보관가능
메모리 풀은 D3DPOOL 열거형 멤버로 지정 D3DPOOL_DEFAULT – 자원의 타입과 이용 방식에 가장 적합한 자원들을 메모리에 보관하도록 Direct3D에 요청. 반드시 IDirect3DDevice9::Reset 호출 이전에 해제되어야 하며, reset 호출 이후에 다시 초기화 D3DPOOL_MANAGED – Direct3D에 의해 자동관리. D3DPOOL_SYSTEMMEM – 시스템 메모리 내에 보관될 자원을 지정 D3DPOOL_SCRATCH – 앞서의 D3DPOOL_SYSTEMMEM과는 달리 이 풀의 자원은 그래픽 장치의 제한을 따라서는 안됨. 이 풀 내의 자원에 직접 접근할 수 없지만, 자원을 두 풀 사이에 서로 복사하는 것은 가능
11
1.3.5 스왑 체인과 페이지 플리핑 스왑 체인지 – Direct3D는 보통 두 개나 세 개의 표면을 하나의 컬렉션으로 관리
IDirect3DSwapChain9 인터페이스를 통해 이용가능 but대부분 Direct3D가 직접 관리 표면1 표면2 전면 버퍼 후면 버퍼 표면2 교환 표면1 전면 버퍼 후면 버퍼 표면1 교환 표면2 전면 버퍼 후면 버퍼
12
1.3.6 깊이 버퍼 이미지 데이터가 아닌 특정 픽셀의 깊이 정보를 포함하는 표면
최종 렌더링된 이미지의 각 픽셀에 해당하는 항목들을 포함한다. 깊이 버퍼의 포맷은 깊이 테스트의 정확도를 결정 대부분 24bit 깊이 버퍼로 충분 D3DFMT_D32 – 32bit 깊이 버퍼를 지정 D3DFMT_D24S8 – 24bit 깊이 버퍼를 지정, 8bit 스텐실 버퍼 예약 D3DFMT_D24X8 – 24bit 깊이 버퍼를 지정 D3DFMT_D24X4S4 – 24bit 깊이 버퍼를 지정, 4bit 스텐실 버퍼 예약 D3DFMT_D16 – 16bit 깊이 버퍼를 지정
13
1.3.7 버텍스 프로세싱 소프트웨어 버텍스 프로세싱 하드웨어 버텍스 프로세싱 언제나 지원되며 항상 이용 가능
그래픽 카드가 버텍스 프로세싱을 지원하는 경우에만 이용 가능 소프트웨어 방식에 비해 성능이 우수하므로 버텍스 프로세싱을 이용하는 것이 유리
14
1.3.8 장치 특성 Direct3D가 제공하는 모든 기능들은 D3DCAPS9 구조체 내의 비트와 데이터 멤버에 대응
기본적인 방식은 특정 하드웨어의 특성에 따라 D3DCAPS9 인스턴스의 멤버를 초기화하고 D3DCAPS9 인스턴스의 대응되는 비트나 데이터 멤버를 확인하여 장치가 특정한 기능을 제공하는지 확인 bool supportHardwareVertexProcessing; //만약 비트가 켜져 있다면 장치가 기능을 지원한다는 의미 if ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { //비트가 켜져 있으므로 기능이 지원된다. supportsHardwareVertexProcessing = true; } else //비트가 꺼져 있으므로, 기능이 지원되지 않는다. hardwareSupportsVertexProcessing = false;
15
1.4 Direct3D 초기화하기 1. IDirect3D9 인터페이스로의 포인터를 얻는다. 2. IDirect3DDevice9 인터페이스를 만들기 위해 장치특성(D3DCAPS9)을 확인한다. 3. D3DPRESENT_PARAMETERS 구조체 인스턴스를 초기화한다. 이 구조체는 우리가 만들고자하는 IDirect3DDevice9 인스턴스의 특성을 지정하기 위한 몇 가지 데이터 멤버들을 포함 4. 초기화된 D3DPRESENT_PARAMETERS에 따라 IDirect3DDevice9 객체를 만듬
16
1.4.1 IDirect3D9 인터페이스 얻기 Direct3DCreate9의 단일 인자에는 항상 D3D_SDK_VERSION을 전달해야 함 실패하면 null 포인트 리턴 IDirect3D9 객체는 장치 검증과 IDirect3DDevice9 객체 생성의 두 가지 용도로 이용 IDirect3D9* _d3d9; _d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
17
1.4.2 하드웨어 버텍스 프로세싱 확인하기 IDirect3DDevice9 객체를 생성할 때는 반드시 원하는 버텍스 프로세싱 모드를 지정해야 한다. 하드웨어 버텍스 프로세싱을 지원하는지 여부 확인을 위해 D3DCAPS9 인스턴스를 초기화 Adapter – 특성을 얻고자 하는 물리 디스플레이 어댑터를 지정 DevieType – 이용할 장치타입 지정. 하드웨어(D3DDEVTYPE_HAL), 소프트 웨어(D3DDEVTYPE_REF) pCaps – 초기화된 특성 구조체를 리턴 HRESULT IDirect3D9::GetDeviceCapts(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps);
18
1.4.2 하드웨어 버텍스 프로세싱 확인하기 버텍스 프로세싱의 타입을 변수 vp에 보관했음에 주의
D3DCAPS9 caps; D3d9->GetDeviceCaps( D3DADAPTER_DEFAULT, // 기본 디스플레이 어댑터를 표기 deviceType, // 장치 타입을 지정, 보통 D3DDEVTYPE_HAL &caps); // 기본 디스플레이 어댑터의 특성으로 채워진 D3DCAPS9 구조체를 리턴 //하드웨어 버텍스 프로세싱을 이용할 수 있는가? int vp = 0; if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) { //하드웨어 버텍스 프로세싱이 지원된다는 사실을 ‘vp‘에 저장 vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { //소프트웨어 버텍스 프로세싱을 이용해야 한다는 사실을 ‘vp‘에 저장 vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; 버텍스 프로세싱의 타입을 변수 vp에 보관했음에 주의 이후 IDirect3DDevice9 객체를 만들 때 버텍스 프로세싱의 타입을 지정해야 하기 때문
19
1.4.3 D3DPRESENT_PARAMETERS 구조체 채우기
Typedef struct _D3DPRESENT_PARAMETERS_ { UINT BackBufferWidth; //픽셀 단위의 후면버퍼 너비 UINT BackBufferHeight; //픽셀 단위의 후면버퍼 높이 D3DFORMAT BackBufferFormat; //후면 버퍼의 픽셀 포맷 UINT BackBufferCount; //이용할 후면 버퍼의 수. 보통 한 개의 후면버퍼 사용 D3DMULTISAMPLE_TYPE MultiSampleType; //후면 버퍼에 이용할 멀티 샘플링의 타입 DWORD MultiSampleQuality; //멀티 샘플링의 레벨 D3DSWAPEFFECT SwapEffect; //플리핑 체인의 버퍼가 교환되는 방법을 지정 HWND hDeviceWindow; //서비스와 연결된 윈도우 핸들 //드로잉의 대상이 될 애플리케이션 윈도우를 지정 BOOL Windowed; //윈도우 모드일때 true, 전체화면 모드일때 false를 지정 BOOL EnableAutoDepthStencil; //자동으로 깊이/스텐실 버퍼를 만들고 관리하길 원하면 true D3DFORMAT Auto DepthStencilFormat; //깊이/스텐실 버퍼의 포맷 DWORD Flags; //몇 가지 부가적인 특성 UINT FullScreen_RefreshRateInHz; //재생율을 지정 D3DPRESENT_RATE_DEFAULT UINT PresentationInterval; //D3DPRESENT 집합의 멤버 } D3DPRESENT_PARAMETERS;
20
1.4.4 IDirect3DDevice9 인터페이스 만들기
D3DPRESENT_PARAMETERS를 채운 뒤 다음 메서드로 IDirect3dDevice9객체를 만들 수 있음. HRESULT IDirect3D9::CreateDevice { UINT Adapter, //만들어질 IDirect3DDevice9 객체와 대응될 디스플레이 어댑터를 지정 D3DDEVTYPE DeviceType, //이용할 장치 타입을 지정(하드웨어 or 소프트웨어) HWND hFocusWindow; //장치와 연결될 윈도우 핸들. 보통은 장치가 드로잉을 수행할 윈도우 DWORD BehaviorFlags, //D3DCREATE_HARDWARE_VERTEXPROCESSING or //D3DCREATE_SOFTWARE_VERTEXPROCESSING D3DPRESENT_PARAMETERS *pPresenttationParameters, //장치 특성의 일부를 정의하는 //초기화된 //D3DPRESENT_PARAMETERS //인스턴스를 지정 IDirect3DDevice9** ppReturnedDeviceInterface //생성된 장치를 리턴 };
21
1.4.4 IDirect3DDevice9 인터페이스 만들기
호출 예 IDirect3DDevice9* device = 0; hr = d3d9->CreateDevice ( D3DADAPTER_DEFAULT, //기본 어댑터 D3DDEVTYPE_HAL, //창치 타입 hwnd, //장치와 연결된 윈도우 D3DCREATE_HARDWARE_VERTEXPROCESSING, //버텍스 프로세싱 타입 &d3dpp, //시연 인자 &device); //생성된 장치 if( FAILED(hr)) { ::MessageBox(0, “CreateDevice () – FAILED”, 0, 0); return 0; }
Similar presentations