// D3D9GraphicLayer.cpp: implementation of the CD3D9GraphicLayer class. // ////////////////////////////////////////////////////////////////////// #include "D3D9GraphicLayer.h" /* ********************************************************************* * CD3D9GraphicLayer * ÆÄÀÏ : D3D9GraphicLayer.h * ±â´É : Caldron Engine³» D3D9 µð¹ÙÀ̽ºµîÀ» Å©¸®¿¡ÀÌÆ® ½ÃÄÑÁÖ´Â BaseGraphic Layer ½Ç app¿¡¼­ »ç¿ëÇÒ ½Ã¿¡ ÀÌ ·¹À̾ »ó¼Ó¹Þ¾Æ D3d Layer·Î »ç¿ëÇÑ´Ù. * ÀÛ¼ºÀÏ : 2003.10.30 * history : wizardbug ( 2003.10.30) ********************************************************************** */ LPDIRECT3DDEVICE9 Caldron::Base::CD3D9GraphicLayer::ms_pD3DDevice = NULL; Caldron::Base::CD3D9GraphicLayer::CD3D9WindowInfo Caldron::Base::CD3D9GraphicLayer::m_WindowInfo; Caldron::Base::CD3D9GraphicLayer::CD3D9ModeInfo Caldron::Base::CD3D9GraphicLayer::m_ModeInfo; Caldron::Base::CD3D9GraphicLayer::CD3D9GraphicLayer() { m_pD3D9Obj = NULL; m_hWnd = 0; m_pExceptionMgr = new CExceptionMgr; } Caldron::Base::CD3D9GraphicLayer::~CD3D9GraphicLayer() { ReleaseAll(); } void Caldron::Base::CD3D9GraphicLayer::ReleaseAll() { SafeRelease(m_pD3D9Obj); SafeRelease(ms_pD3DDevice); CLogMgr::_Close(); SafeDelete(m_pExceptionMgr); } HRESULT Caldron::Base::CD3D9GraphicLayer::InitD3DLayer(HINSTANCE hInstance,HWND hWnd,DWORD dwWidth, DWORD dwHeight, bool bWindowed,D3DFORMAT ColorFormat,D3DFORMAT ZFormat, DWORD dwVertexProcess,D3DMULTISAMPLE_TYPE Antial) { if((m_pD3D9Obj = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) { CLogMgr::_LogError("CD3D9GraphicLayer::InitD3DLayer() : D3D9 Object Create Failed"); m_WindowInfo.m_bD3DRunning = false; return E_FAIL; } m_ModeInfo.m_ColorFormat = ColorFormat; m_ModeInfo.m_DepthStencilFormat = ZFormat; m_ModeInfo.m_dwVertexProcessing = dwVertexProcess| D3DCREATE_MULTITHREADED; m_ModeInfo.m_MultiSampling = Antial; m_WindowInfo.m_hInstance = hInstance; m_WindowInfo.m_dwWidth = dwWidth; m_WindowInfo.m_dwHeight = dwHeight; m_WindowInfo.m_bWindowed = bWindowed; ZeroMemory(&m_PresentParameters,sizeof(m_PresentParameters)); m_PresentParameters.Windowed = m_WindowInfo.m_bWindowed; m_PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; m_PresentParameters.EnableAutoDepthStencil = true; m_PresentParameters.AutoDepthStencilFormat = m_ModeInfo.m_DepthStencilFormat; m_hWnd = m_PresentParameters.hDeviceWindow = hWnd; m_PresentParameters.BackBufferWidth = m_WindowInfo.m_dwWidth; m_PresentParameters.BackBufferHeight = m_WindowInfo.m_dwHeight; m_PresentParameters.BackBufferFormat = m_ModeInfo.m_ColorFormat; m_PresentParameters.BackBufferCount = 1; CheckD3DFormat(!(m_WindowInfo.m_bWindowed),m_ModeInfo.m_ColorFormat,&(m_PresentParameters.BackBufferFormat)); m_ModeInfo.m_ColorFormat = m_PresentParameters.BackBufferFormat; m_PresentParameters.MultiSampleType = m_ModeInfo.m_MultiSampling; m_PresentParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; if(ms_pD3DDevice != NULL) { SafeRelease(ms_pD3DDevice); } HRESULT hr; if(Failed(hr = m_pD3D9Obj->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,m_hWnd,m_ModeInfo.m_dwVertexProcessing, &m_PresentParameters,&ms_pD3DDevice))) { if(m_ModeInfo.m_dwVertexProcessing & D3DCREATE_HARDWARE_VERTEXPROCESSING) { m_ModeInfo.m_dwVertexProcessing &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; m_ModeInfo.m_dwVertexProcessing |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; if(Failed(m_pD3D9Obj->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,m_hWnd,m_ModeInfo.m_dwVertexProcessing, &m_PresentParameters,&ms_pD3DDevice))) { CLogMgr::_LogError("CD3D9GraphicLayer::InitD3DLayer() : D3D9 Device Create Failed"); m_WindowInfo.m_bD3DRunning = false; return E_FAIL; } } if(m_ModeInfo.m_dwVertexProcessing & D3DCREATE_MULTITHREADED) { m_ModeInfo.m_dwVertexProcessing &= ~D3DCREATE_MULTITHREADED; if(Failed(m_pD3D9Obj->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,m_hWnd,m_ModeInfo.m_dwVertexProcessing, &m_PresentParameters,&ms_pD3DDevice))) { CLogMgr::_LogError("CD3D9GraphicLayer::InitD3DLayer() : D3D9 Device Create Failed"); m_WindowInfo.m_bD3DRunning = false; return E_FAIL; } } } //D3DDISPLAYMODE pMode; //ms_pD3DDevice->GetDisplayMode( 0,&pMode); InitScene(); CheckDeviceCaps(); m_WindowInfo.m_bD3DRunning = true; return S_OK; } // Lost ½Ã¿¡ E_FAIL return HRESULT Caldron::Base::CD3D9GraphicLayer::CheckDeviceLost() { if(!ms_pD3DDevice) { CLogMgr::_LogError("CD3D9GraphicLayer::ChecDeviceLost() : Device == NULL"); return E_FAIL; } switch(ms_pD3DDevice->TestCooperativeLevel()) { case D3DERR_DEVICELOST: CLogMgr::_LogError("CD3D9GraphicLayer::ChecDeviceLost() : Device Lost"); Sleep(100); // Device °¡ D3DERR_DEVICENOTRESET »óŰ¡ µÉ¶§±îÁö ±â´Ù¸°´Ù. m_WindowInfo.m_bD3DRunning = false; return E_FAIL; case D3DERR_DEVICENOTRESET: { if(Failed(ms_pD3DDevice->Reset(&m_PresentParameters))) { CLogMgr::_LogError("CD3D9GraphicLayer::ChecDeviceLost() : Reset Failed"); m_WindowInfo.m_bD3DRunning = false; return E_FAIL; } InitScene(); m_WindowInfo.m_bD3DRunning = true; return S_OK; } default: m_WindowInfo.m_bD3DRunning = true; return S_OK; } } void Caldron::Base::CD3D9GraphicLayer::SaveSetting() { } void Caldron::Base::CD3D9GraphicLayer::LoadSetting() { } void Caldron::Base::CD3D9GraphicLayer::InitScene() // Scene Init { } HRESULT Caldron::Base::CD3D9GraphicLayer::ChangePresentMode(UINT UIPresent) { m_PresentParameters.PresentationInterval = UIPresent; //change device mode if(ms_pD3DDevice == NULL) { CLogMgr::_LogError("CD3D9GraphicLayer::ChangeMode() : Device == NULL"); return E_FAIL; } if(FAILED(ms_pD3DDevice->Reset(&m_PresentParameters))) { // Mode Back. m_PresentParameters.AutoDepthStencilFormat = m_ModeInfo.m_DepthStencilFormat; m_PresentParameters.BackBufferWidth = m_WindowInfo.m_dwWidth; m_PresentParameters.BackBufferHeight = m_WindowInfo.m_dwHeight; m_PresentParameters.BackBufferFormat = m_ModeInfo.m_ColorFormat; ms_pD3DDevice->Reset(&m_PresentParameters); InitScene(); CLogMgr::_LogError("CD3D9GraphicLayer::ChangeMode() : Reset Failed"); return E_FAIL; } // Success Info Setting InitScene(); return S_OK; } HRESULT Caldron::Base::CD3D9GraphicLayer::ChangeMode(DWORD dwWidth, DWORD dwHeight, D3DFORMAT Pixel, D3DFORMAT Zbuffer,UINT uiPresent) { //set new parameters m_PresentParameters.AutoDepthStencilFormat = Zbuffer; m_PresentParameters.BackBufferWidth = dwWidth; m_PresentParameters.BackBufferHeight = dwHeight; m_PresentParameters.BackBufferFormat = Pixel; m_PresentParameters.PresentationInterval = uiPresent; CheckD3DFormat(!m_WindowInfo.m_bWindowed,Pixel,&(m_PresentParameters.BackBufferFormat)); //change device mode if(ms_pD3DDevice == NULL) { CLogMgr::_LogError("CD3D9GraphicLayer::ChangeMode() : Device == NULL"); return E_FAIL; } if(FAILED(ms_pD3DDevice->Reset(&m_PresentParameters))) { // Mode Back. m_PresentParameters.AutoDepthStencilFormat = m_ModeInfo.m_DepthStencilFormat; m_PresentParameters.BackBufferWidth = m_WindowInfo.m_dwWidth; m_PresentParameters.BackBufferHeight = m_WindowInfo.m_dwHeight; m_PresentParameters.BackBufferFormat = m_ModeInfo.m_ColorFormat; CheckD3DFormat(!m_WindowInfo.m_bWindowed,Pixel,&(m_PresentParameters.BackBufferFormat)); ms_pD3DDevice->Reset(&m_PresentParameters); InitScene(); CLogMgr::_LogError("CD3D9GraphicLayer::ChangeMode() : Reset Failed"); return E_FAIL; } // Success Info Setting m_WindowInfo.m_dwWidth = dwWidth; m_WindowInfo.m_dwHeight = dwHeight; m_ModeInfo.m_ColorFormat = Pixel; m_ModeInfo.m_DepthStencilFormat = Zbuffer; InitScene(); return S_OK; } HRESULT Caldron::Base::CD3D9GraphicLayer::CheckDeviceCaps() { if(ms_pD3DDevice == NULL) { CLogMgr::_LogError("CD3D9GraphicLayer::CheckDeviceCaps() : Device == NULL"); return E_FAIL; } /////////////// Cap °Ë»ç ·çƾ µé¾î°¡¾ß ÇÔ /* if(ms_pD3DDevice->m_D3dCaps->TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE ) return S_OK; */ return E_FAIL; } HRESULT Caldron::Base::CD3D9GraphicLayer::SetFullScreen(bool bWin) { m_PresentParameters.Windowed = !bWin; //change device mode if(ms_pD3DDevice == NULL) { CLogMgr::_LogError("CD3D9GraphicLayer::ChangeMode() : Device == NULL"); return E_FAIL; } CheckD3DFormat(!bWin,m_ModeInfo.m_ColorFormat,&(m_PresentParameters.BackBufferFormat)); if(FAILED(ms_pD3DDevice->Reset(&m_PresentParameters))) { // Mode Back. m_PresentParameters.Windowed = m_WindowInfo.m_bWindowed; CheckD3DFormat(!m_WindowInfo.m_bWindowed,m_ModeInfo.m_ColorFormat,&(m_PresentParameters.BackBufferFormat)); ms_pD3DDevice->Reset(&m_PresentParameters); InitScene(); CLogMgr::_LogError("CD3D9GraphicLayer::ChangeMode() : Reset Failed"); return E_FAIL; } m_WindowInfo.m_bWindowed = !bWin; InitScene(); return S_OK; } // Àüüȭ¸é ¸ðµåÀ϶§ Color Bit Áö¿ø ÇÏ´ÂÁö Test HRESULT Caldron::Base::CD3D9GraphicLayer::CheckD3DFormat(bool bFullScreen,D3DFORMAT iDepth,D3DFORMAT *pFormat) { if(bFullScreen){ switch(iDepth) { case D3DFMT_R5G6B5: case D3DFMT_X1R5G5B5: (*pFormat)= Find16BitMode(); break; case D3DFMT_A8R8G8B8: case D3DFMT_X8R8G8B8: (*pFormat)= Find32BitMode(); break; default: (*pFormat)=D3DFMT_UNKNOWN; break; } } else { //D3D will automatically use the Desktop's format (*pFormat)=D3DFMT_UNKNOWN; } return S_OK; } D3DFORMAT Caldron::Base::CD3D9GraphicLayer::Find16BitMode() { const D3DFORMAT BufferFormats[]={D3DFMT_R5G6B5,D3DFMT_X1R5G5B5}; const int iFormatCount=sizeof(BufferFormats)/sizeof(D3DFORMAT); HRESULT hr; for(int count=0;countCheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, BufferFormats[count], //The is the primary (viewable) buffer format BufferFormats[count], //This is the back (drawable) buffer format FALSE); if(Succeeded(hr)){ return BufferFormats[count]; } } CLogMgr::_LogError("CD3D9GraphicLayer::Find16BitMode() : 16Bit Mode Not Support"); return D3DFMT_UNKNOWN; } D3DFORMAT Caldron::Base::CD3D9GraphicLayer::Find32BitMode() { const D3DFORMAT BufferFormats[]={D3DFMT_A8R8G8B8,D3DFMT_X8R8G8B8}; const int iFormatCount=sizeof(BufferFormats)/sizeof(D3DFORMAT); HRESULT hr; for(int count=0;countCheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, BufferFormats[count], //The is the primary (viewable) buffer format BufferFormats[count], //This is the back (drawable) buffer format FALSE); if(Succeeded(hr)){ return BufferFormats[count]; } } CLogMgr::_LogError("CD3D9GraphicLayer::Find16BitMode() : 16Bit Mode Not Support"); return D3DFMT_UNKNOWN; } void Caldron::Base::CD3D9GraphicLayer::Render() { if(Succeeded(CheckDeviceLost())) { RenderScene(); Update(); // Show the frame on the primary surface. ms_pD3DDevice->Present( NULL, NULL, NULL, NULL ); } }