Direct3D Initialization Objectives
Transcription
Direct3D Initialization Objectives
Direct3D Initialization 6th Week, W k 2009 Objectives ■ ■ ■ ■ ■ ■ To learn how Direct3D interacts with graphics hardware To understand the role that COM plays with Di t3D Direct3D To learn fundamental graphics concepts, such as how 2D images are stored, page flipping, and depth buffering To find out how to initialize and draw text with Di t3D Direct3D To become familiar with the general structure that the sample applications of this book employ To discover how to debug your Direct3D applications Direct3D Overview ■ Direct3D ■ ■ A low-level graphics API (Application Programming Interface) A mediator between the application and the graphic device (3D hardware) Application pp ■ Direct3D HAL Graphics Device HAL (Hardware Abstraction Layer) ■ The set of device-specific code that instructs the device to perform an operation Devices ■ HAL (a hardware device) ■ ■ SW ((a software ft d device) i ) ■ ■ ■ ■ 3D hardware acceleration – modern 3D games Using features that are not available in hardware Slower than a hardware implementation Not implementing all Direct3D operations REF (a reference device) ■ ■ A reference rasterizer – emulating the entire Direct3D API in software For development only – slow enough that it’s not practical i l to use ffor anything hi b but testing i COM ■ Component Object Model ■ ■ Construction – to obtain pointers to COM ■ ■ ■ An interface which can be thought of and used as a C++ class Through Th h special i l ffunctions ti or b by th the methods th d off another COM interface Not creating a COM interface with the C++ new keyword Destruction ■ Calling Release method rather than delete it Some Preliminaries ■ ■ ■ ■ ■ ■ ■ ■ ■ Surfaces The Swap Chain and Page Flipping Pixel Formats Display p y Adapters p Depth Buffers Multisampling Memory Pools Vertex Processing i and d Pure Devices i Device Capabilities Surfaces ■ A matrix of pixels that Direct3D uses primarily to store 2D image data ■ Pitch (bytes) ≠ Width (pixels) Pitch Width (0,0) (0,2) +X · · · (1 0) (1,0) Height · · · Pitch Area Surface Element – Pixel +Y The Swap Chain & Page Flipping (1) ■ Swap Chain ■ ■ A collection of surfaces (usually two or three) Surface 1 Surface 2 Front Buffer Back Buffer Æ Displaying Æ Rendering P Page Fli Flipping i (Double D bl B Buffering ff i ) ■ ■ Providing smooth, flicker-free animation between frames ‘Presenting’: back buffer ↔ front buffer The Swap Chain & Page Flipping (2) ■ Ex) Presenting two times Surface 1 Front Buffer Surface 2 Swap Surface 2 Front Buffer Back Buffer Surface 1 Swap Back Buffer Surface 1 Surface 2 Front Buffer Back Buffer Pixel Formats ■ Specifying the pixel formats when creating surfaces ■ ■ ■ How many bits are allocated for RGBA How the bits are organized in memory S Some common pixel i l fformats t ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ D3DFMT_X1R5G5B5 D3DFMT_R5G6B5 D3DFMT_R8G8B8 D3DFMT_X8R8G8B8 D3DFMT_A8R8G8B8 D3DFMT_A8 D3DFMT_R16F D3DFMT 3 _A16B16G16R16F 6 6G 6 6 D3DFMT_R32F D3DFMT_A32B32G32R32F Display Adapters ■ Referring to a physical graphic card ■ ■ IDi IDirect3D9 t3D9 interface i t f ■ ■ A system may have more than one adapter Î Enumerating all available adapters Î Picking the best one for the application A stepping-stone to creating the IDi IDirect3DDevice9 t3DD i 9 interface inte face Primary display adapter ■ ■ The one displaying the Windows desktop D3DADAPTER_DEFAULT identifier Depth Buffers (1) ■ A surface that contains depth information about a particular pixel ■ ■ Depth buffering or z-buffering ■ ■ ■ Depth value: 0.0~1.0 0.0 1.0 (the closest ~ the farthest) Determining which pixels of an object are in front of another Computing a depth value for each pixel and performing f i ad depth h test The format of the depth buffer ■ ■ ■ ■ ■ D3DFMT_D32 D3DFMT D32 D3DFMT_D24S8 D3DFMT_D24X8 D3DFMT D24X4S4 D3DFMT_D24X4S4 D3DFMT_D16 Depth Buffers (2) ■ Depth test ■ Comparing the depths of pixels competing to be written to a particular pixel location on the back P3 buffer P2 P P1 d2 d1 P d3 Viewer View Window View Window Drawing Order Od Depth h Test Backk Buffer ff Viewer Initialization Default Color Cylinder d3 < 1.0 10 P3 Sphere d1 < d3 P1 Cone d2 > d1 P1 P1 d1 P2 P3 d2 d3 Depth h Buffer ff 1.0 d3 d1 d1 Multisampling ■ Antialiasing technique ■ ■ Taking the neighboring pixels into consideration when computing the final color of a pixel The type of multisampling ■ ■ D3DMULTISAMPLE_NONE D3DMULTISAMPLE NONE D3DMULTISAMPLE_2_SAMPLES, …, D3DMULTISAMPLE 16 SAMPLES D3DMULTISAMPLE_16_SAMPLES “Stairstep” (aliasing) Antialiasing Memory Pools ■ Memory type RAM (system memory), VRAM (video memory), or AGP memory (Accelerated Graphics Port) Î The graphic device can directly access VRAM or AGP ■ ■ The Direct3D memory pool ■ ■ ■ ■ determining the memory type in which a resource is placed D3DPOOL MANAGED D3DPOOL_MANAGED D3DPOOL_DEFAULT D3DPOOL SYSTEM D3DPOOL_SYSTEM Vertex Processing and Pure Devices ■ Software Vertex Processing ■ ■ Hardware Vertex Processing ■ ■ ■ ■ Always supported (Æ always can be used) Only can be used if the graphics card supports vertex processing p g in hardware Faster than software Unloading g calculation from CPU Pure Device ■ ■ Referring g to a device in which some of Get style y methods (e.g. render state, transform state, lights, and texture Get methods) are disabled O l can b Only be specified ifi d with ith vertex t h hardware d processing i Device Capabilities ■ Initializing the members of a D3DCAPS9 object based on the capabilities of a particular hardware device ■ To check whether a device supports a feature by checking the corresponding data member or bit in a D3DCAPS9 instance Initializing Direct3D Acquire a pointer to IDirect3D9 interface Verify hardware support Check the device capabilities (D3DCAPS) Initialize an instance of the D3DPRESENT_PARAMETERS Create the IDirect3DDevice9 interface Acquiring an IDirect3D9 Interface ■ A Direct3D function to acquire a pointer to an IDirect3D9 interface IDirect3D9* md3dObject; md3dObject = Direct3DCreate9(D3D_SDK_VERSION); ■ D3D_SDK_VERSION: to guarantee that the application is built against the correct header files Verifying HAL Support (1) ■ Verifying that the pixel format combination for the display and back buffer are supported by the hardware HRESULT IDirect3D9::CheckDeviceType( UINT Adapter, D3DDEVTYPE DeviceType, D i T D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed ); ■ ■ ■ ■ Adapter: the display adapter DeviceType: the device type (usually D3DDEVTYPE_HAL) DisplayFormat, BackBufferFormat: the display and back buffer formats Windowed: windowed (true) or full-screen (false) mode Verifying HAL Support (2) D3DDISPLAYMODE mode; md3dObject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode); HR(md3dObject >CheckDeviceType(D3DADAPTER DEFAULT HR(md3dObject->CheckDeviceType(D3DADAPTER_DEFAULT, mDevType, mode.Format, mode.Format, true)); HR(md3dObject->CheckDeviceType(D3DADAPTER_DEFAULT, mDevType, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, false)); Checking for Hardware Vertex Processing (1) ■ First, initializing a D3DCAPS9 instance based First on the capabilities of the primary display adapter HRESULT IDirect3D9::GetDeviceCaps( UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps ); ■ ■ ■ ■ Adapter: the display adapter DeviceType: the device type (e.g. D3DDEVTYPE HAL or D3DDEVTYPE_REF) D3DDEVTYPE_HAL D3DDEVTYPE REF) pCaps: initialized capabilities structure to be returned Then, checking the capabilities Checking for Hardware Vertex Processing (2) D3DCAPS9 caps; HR(md3dObject->GetDeviceCaps(D3DADAPTER_DEFAULT, mDevType, &caps)); DWORD devBehaviorFlags = 0; if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) devBehaviorFlags |= mRequestedVP; else devBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; // If pure device and HW T&L supported if( caps.DevCaps & D3DDEVCAPS_PUREDEVICE && devBehaviorFlags & D3DCREATE D3DCREATE_HARDWARE_VERTEXPROCESSING HARDWARE VERTEXPROCESSING ) devBehaviorFlags |= D3DCREATE_PUREDEVICE; D3DPRESENT PARAMETERS (1) D3DPRESENT_PARAMETERS ■ Filling out an instance of the D3DPRESENT_PARAMETERS structure typedef struct _D3DPRESENT_PARAMETERS_ D3DPRESENT PARAMETERS { UINT BackBufferWidth, BackBufferHeight; D3DFORMAT BackBufferFormat; UINT U BackBufferCount; ac u e Cou t; D3DMULTISAMPLE_TYPE MultiSampleType; DWORD MultiSampleQuality; p D3DSWAPEFFECT SwapEffect; HWND hDeviceWindow; BOOL Windowed; BOOL EnableAutoDepthStencil; D3DFORMAT AutoDepthStencilFormat; DWORD Flags; UINT FullScreen_RefreshRateInHz; UINT PresentationInterval; } D3DPRESENT_PARAMETERS; D3DPRESENT PARAMETERS (2) D3DPRESENT_PARAMETERS ■ ■ ■ ■ ■ ■ ■ ■ BackBufferWidth, BackBufferHeight: width and height of the back buffer surface in pixel BackBufferFormat: pixel format of the back buffer BackBufferCount: number of back buffers to use MultiSampleType, MultiSampleQuality: type and quality li llevell off multisampling li li SwapEffect: how the buffers in the flipping chain will be swapped EnableAutoDepthStencil: true Æ creating and g the depth/stencil p buffer automaticallyy maintaining AutoDepthStencilFormat: the format of the depth/stencil buffer PresentationInterval: immediate / default D3DPRESENT PARAMETERS (3) D3DPRESENT_PARAMETERS D3DPRESENT_PARAMETERS md3dPP; md3dPP.BackBufferWidth md3dPP.BackBufferHeight md3dPP.BackBufferFormat md3dPP.BackBufferCount md3dPP.MultiSampleType md3dPP.MultiSampleQuality md3dPP.SwapEffect md3dPP.hDeviceWindow md3dPP.Windowed 3 md3dPP.EnableAutoDepthStencil md3dPP.AutoDepthStencilFormat md3dPP.Flags d3dPP Fl md3dPP.FullScreen_RefreshRateInHz md3dPP.PresentationInterval D3DPRESENT INTERVAL IMMEDIATE; D3DPRESENT_INTERVAL_IMMEDIATE; = = = = = = = = = = = = = = 0; 0; D3DFMT_UNKNOWN; 1; D3DMULTISAMPLE_NONE; 0; D3DSWAPEFFECT_DISCARD; mhMainWnd; true; true; D3DFMT_D24S8; 0 0; D3DPRESENT_RATE_DEFAULT; Creating the IDirect3DDevice9 Interface (1) ■ Finally creating the IDirect3DDevice9 interface HRESULT IDirect3D9::CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, De iceT pe HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT PARAMETERS *pPresentationParameters D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface ); ■ ■ ■ ■ ■ ■ Adapter: the display adapter DeviceType: the device type hFocusWindow: handle to the window BehaviorFlags: the creation flag pPresentationParameters: an initialized D3DPRESENT_PARAMETERS _ instance ppReturnedDeviceInterface: the created device Creating the IDirect3DDevice9 Interface (2) IDirect3DDevice9* gd3dDevice = 0; HR(md3dObject->CreateDevice( D3DADAPTER DEFAULT // primary adapter D3DADAPTER_DEFAULT, mDevType, // device type mhMainWnd, // window associated with device devBehaviorFlags, // vertex processing &md3dPP, // present parameters &gd3dDevice)); // return created device Lost Devices (1) ■ E g ) using Alt+Tab from full-screen E.g.) full screen mode ■ ■ an event that causes the device to be lost Only two device methods work: ■ IDirect3DDevice9::TestCooperativeLevel – g the current state of the device returning ■ ■ ■ ■ ■ D3DERR_DEVICELOST – the device is lost and cannot be reset yet D3DERR DRIVERINTERNALERROR – an internal driver error D3DERR_DRIVERINTERNALERROR has occurred D3DERR_DEVICENOTRESET – the device is lost but can be restored by calling IDirect3DDevice9::Reset D3D_OK – the device is running IDirect3DDevice9::Reset Lost Devices (2) bool D3DApp::isDeviceLost() { // Get the state of the graphics device. HRESULT hr = gd3dDevice->TestCooperativeLevel(); // If the device is lost and cannot be reset yet then // sleep for a bit and we'll we ll try again on the next // message loop cycle. if( hr == D3DERR_DEVICELOST ) { Sleep(20); return true; } // Driver error, exit. else if( hr == D3DERR_DRIVERINTERNALERROR ) { MessageBox(0 "Internal MessageBox(0, Internal Driver Error...Exiting Error Exiting", 0, 0 0); PostQuitMessage(0); return true; } // The device is lost but we can reset and restore it. else if( hr == D3DERR_DEVICENOTRESET D3DERR DEVICENOTRESET ) { onLostDevice(); HR(gd3dDevice->Reset(&md3dPP)); onResetDevice(); return false; } else return false; } Downloading Sample Program ‘Hello Hello Direct3D’ Direct3D Solution Project Æ Properties ■ Configuration Properties Æ Linker Æ Input ■ Additional Dependencies: d3d9.lib d3dx9d.lib dxguid lib dxerr9 dxguid.lib dxerr9.lib lib dinput8 dinput8.lib lib Result – Hello Direct3D Sample Code: Hello Direct3D d3dApp.h : the core Direct3D application class code d3dApp.cpp d3dUtil.h : useful utility code derivation HelloDirect3D.cpp pp code : our application D3DApp (1) class D3DApp { public: D3DApp(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP); virtual ~D3DApp(); HINSTANCE getAppInst(); HWND getMainWnd(); virtual virtual virtual virtual i t l virtual bool void void void id void checkDeviceCaps() { return true; } onLostDevice() {} onResetDevice() {} updateScene(float d t S (fl t dt) {} drawScene() {} virtual void initMainWindow(); virtual void initDirect3D(); virtual int run(); virtual LRESULT msgProc(UINT msg, WPARAM wParam, LPARAM lParam); void enableFullScreenMode(bool enable); bool isDeviceLost(); D3DApp (2) protected: std::string td t i mMainWndCaption; M i W dC ti D3DDEVTYPE mDevType; DWORD mRequestedVP; HINSTANCE HWND IDirect3D9* bool D3DPRESENT_PARAMETERS mhAppInst; h mhMainWnd; md3dObject; mAppPaused; md3dPP; }; D3DApp (3) ■ Data Members ■ ■ ■ ■ ■ ■ ■ ■ mMainWndCaption: string value to appear in the main window’s title bar mDevType: device type (D3DDEVTYPE_HAL or D3DDEVTYPE_REF) mRequestedVP: vertex processing i type mhAppInst: copy of the application instance handle mhMainWnd: copy of the main application window handle md3dObject: pointer to an IDirect3D9 object mAppPaused: true Æ the application is paused md3dPP: copy of D3DPRESENT_PARAMETERS D3DApp (4) ■ Non-Framework Non Framework Methods ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ D3DApp: constructor (calling initMainWindow and initDirect3D) ~D3DApp: destructor (releasing COM interfaces) getAppInst: to return mhAppInst getMainWnd: to return mhMainWnd initMainWindow: to initialize the main application window initDirect3D: to initialize Direct3D enableFullScreenMode: to switch to full-screen mode isDeviceLost: to check the state of the device msgProc: g window p procedure function run: message loop D3DApp (5) ■ Framework Methods ■ ■ ■ ■ ■ checkDeviceCaps: checking device to verify that the hardware supports any special features onLostDevice: being called before a device is to be reset onResetDevice: being called after a device has been reset updateScene: being called every frame and used to update the 3D application over time drawScene: being invoked every frame and used to draw current frame “d3dApp d3dApp.cpp cpp” “d3dUtil d3dUtil.h h” (1) #ifndef D3DUTIL_H #define D3DUTIL_H #if defined(DEBUG) | defined(_DEBUG) #ifndef D3D_DEBUG_INFO D3D DEBUG INFO #define D3D_DEBUG_INFO #endif #endif #include #include #include #include #include <d3d9.h> <d3dx9.h> <dxerr9.h> <string> <sstream> // Globals for convenient access. class D3DApp; extern D3DApp* gd3dApp; extern IDirect3DDevice9 IDirect3DDevice9* gd3dDevice; “d3dUtil d3dUtil.h h” (2) // Clean up #define ReleaseCOM(x) { if(x){ x->Release();x = 0; } } // Debug #if defined(DEBUG) | defined(_DEBUG) #ifndef HR # #define HR(x) { HRESULT hr = x; if(FAILED(hr)) { DXTrace(__FILE__, __LINE__, hr, #x, TRUE); } } #endif \ \ \ \ \ \ \ #else #ifndef HR #define HR(x) x; #endif #endif #endif // D3DUTIL_H Debugging Direct3D Applications (1) ■ Turning on Direct3D debugging ■ ■ Control Panel Æ DirectX or Programs Æ Microsoft DirectX SDK Æ DirectX Utilities Æ DirectX Control Panel Î Performance speed is significantly decreased Debugging Direct3D Applications (2) ■ Enabling Direct3D debugging by defining the following symbol #if defined(DEBUG) | defined( defined(_DEBUG) DEBUG) #ifndef D3D_DEBUG_INFO #define D3D_DEBUG_INFO #endif #endif ■ ■ Linking “d3dx9d.lib” for debug builds instead of “d3dx9.lib” (for release mode) HR macro ■ For further details about an error code, DXTrace function used HRESULT DXTrace(CHAR *strFile, DWORD dwline, HRESULT hr, CHAR *strMsg, BOOL bPopMsgBox); Debugging Direct3D Applications (3) #if defined(DEBUG) | defined( defined(_DEBUG) DEBUG) #ifndef HR #define HR(x) { HRESULT hr = x; if(FAILED(hr)) { DXTrace(__FILE__, __LINE__, hr, #x, TRUE); } } #endif #else #ifndef HR #define HR(x) x; #endif #endif \ \ \ \ \ \ \ Hello Direct3D (1) ■ Deriving a new class from D3DApp and overriding the framework functions class HelloD3DApp : public D3DApp { public: HelloD3DApp(HINSTANCE hInstance, std::string winCaption, i i D3DDEVTYPE 3 d devType, DWORD requestedVP); d ) ~HelloD3DApp(); bool void void void void checkDeviceCaps(); onLostDevice(); onResetDevice(); updateScene(float dt); drawScene(); private: ID3DXFont* mFont; ID3DXFont }; Hello Direct3D (2) ■ Instantiating an instance of our child class and entering the message loop int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) { // Enable run-time memory check for debug builds. #if defined(DEBUG) | defined(_DEBUG) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif HelloD3DApp app(hInstance, "Hello Direct3D", D3DDEVTYPE_HAL, D3DCREATE_HARDWARE_VERTEXPROCESSING); gd3dApp = &app; return gd3dApp->run(); gd3dApp >run(); } “HelloDirect3D HelloDirect3D.cpp cpp” Exercises ■ Change the main window: ■ ■ ■ the background color the title Change the text: ■ ■ ■ ■ ■ its font f its size its position drawing your name fixed color Result – Exercises 연습문제 ■ 메인 윈도우를 변경하시오. 변경하시오 ■ ■ ■ 배경색 타이틀 텍스트를 변경하시오. ■ ■ ■ ■ ■ 폰트 크기 위치 내용 (이름 출력) 색상 제출 방법 ■ 소스 코드 ■ ■ *.cpp, *.h, *.sln, *.vcproj 실행 결과 화면 캡쳐 Æ chap04.jpg ■ Alt + PrintScreen Æ 그림판 림판 Æ 붙여넣기 여넣기 Æ 저장 ■ 위 파일들을 압축 Æ ‘본인학번.zip’ ■ 수업시간 전까지 조교에게 e-mail로 제출