"L. Spiro Engine"
|
00001 00016 #ifndef __LSG_DIRECTX9_H__ 00017 #define __LSG_DIRECTX9_H__ 00018 00019 #include "../Fnd/LSGFndBase.h" 00020 #include "../Fnd/LSGFndConstants.h" 00021 #include "Windows/LSSTDWindows.h" 00022 00023 #include <d3d9.h> 00024 #include <d3dx9.h> 00025 00026 namespace lsg { 00027 00028 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00029 // CONSTANTS 00030 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00034 enum LSG_BUFFERS { 00035 LSG_B_COLOR_BUFFER = D3DCLEAR_TARGET, 00036 LSG_B_STENCIL_BUFFER = D3DCLEAR_STENCIL, 00037 LSG_B_DEPTH_BUFFER = D3DCLEAR_ZBUFFER, 00038 LSG_B_ALL = LSG_B_COLOR_BUFFER | LSG_B_STENCIL_BUFFER | LSG_B_DEPTH_BUFFER, 00039 }; 00040 00041 00042 00043 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00044 // TYPES 00045 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00049 typedef class CDirectX9ShaderManager CShaderManager; 00050 class CShader; 00051 00052 00053 00054 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00055 // INTERFACE 00056 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00063 class CDirectX9 { 00064 public : 00065 // == Types. 00069 typedef struct LSG_DIRECTX9_INIT { 00073 HWND hWnd; 00074 00078 LSBOOL bWindowed; 00079 } * LPLSG_DIRECTX9_INIT, * const LPCLSG_DIRECTX9_INIT; 00080 00081 00082 // == Functions. 00089 static LSBOOL LSE_CALL InitDirectX9( LPCLSG_DIRECTX9_INIT _lpdiInit ); 00090 00094 static LSVOID LSE_CALL PostInitDirectX9(); 00095 00099 static LSVOID LSE_CALL DestroyDirectX9(); 00100 00104 static LSVOID LSE_CALL LoseDevice(); 00105 00109 static LSBOOL LSE_CALL ResetDevice(); 00110 00116 static LSE_INLINE LSBOOL LSE_CALL DeviceIsLost(); 00117 00123 static LSE_INLINE LSVOID LSE_CALL TogglingFullScreen( LSBOOL _bVal ); 00124 00131 static LSE_INLINE LSVOID LSE_CALL SetWindowParms( LSBOOL _bWindowed, HWND _hWnd ); 00132 00136 static LSVOID LSE_CALL SetInitialValues(); 00137 00144 static LSVOID LSE_CALL SetScreenSize( LSUINT32 _ui32Width, LSUINT32 _ui32Height ); 00145 00151 static IDirect3DDevice9 * GetDirectX9Device(); 00152 00158 static IDirect3D9 * GetDirectX9Object(); 00159 00165 static const D3DDEVICE_CREATION_PARAMETERS &GetCreationParms(); 00166 00172 static LSE_INLINE const D3DCAPS9 & LSE_CALL GetDeviceCaps(); 00173 00179 static LSE_INLINE const D3DPRESENT_PARAMETERS & LSE_CALL 00180 GetPresentParms(); 00181 00187 static LSE_INLINE IDirect3DSurface9 * LSE_CALL 00188 GetBackBufferSurface(); 00189 00195 static LSE_INLINE IDirect3DSurface9 * LSE_CALL 00196 GetDepthStencilSurface(); 00197 00206 static LSE_INLINE LSVOID LSE_FCALL SetMinMagMipFilters( LSUINT32 _ui32Slot, D3DTEXTUREFILTERTYPE _tftMin, D3DTEXTUREFILTERTYPE _tftMag, 00207 D3DTEXTUREFILTERTYPE _tftMip ); 00208 00215 static LSE_INLINE LSVOID LSE_FCALL SetAnisotropy( LSUINT32 _ui32Slot, LSUINT32 _ui32Level ); 00216 00224 static LSE_INLINE LSVOID LSE_FCALL SetTextureWrapModes( LSUINT32 _ui32Slot, D3DTEXTUREADDRESS _taU, D3DTEXTUREADDRESS _taV ); 00225 00239 static CMatrix4x4 LSE_CALL OffsetOrtho( LSREAL _fLeft, LSREAL _fRight, LSREAL _fBottom, LSREAL _fTop, LSREAL _fNear, LSREAL _fFar ); 00240 00241 00242 00243 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00244 // INTERFACE 00245 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00249 static LSE_INLINE LSVOID LSE_FCALL AssertError(); 00250 00254 static LSE_INLINE LSVOID LSE_FCALL Present(); 00255 00261 static LSE_INLINE LSVOID LSE_FCALL Clear( LSUINT32 _ui32Mask ); 00262 00266 static LSE_INLINE LSVOID LSE_FCALL ClearAll(); 00267 00276 static LSVOID LSE_CALL SetClearColor( LSREAL _fR, LSREAL _fG, LSREAL _fB, LSREAL _fA ); 00277 00283 static LSE_INLINE LSVOID LSE_FCALL SetClearDepth( LSREAL _fValue ); 00284 00293 static LSE_INLINE LSVOID LSE_FCALL SetViewport( LSINT32 _i32X, LSINT32 _i32Y, LSINT32 _i32Width, LSINT32 _i32Height ); 00294 00300 static LSE_INLINE LSVOID LSE_FCALL SetDepthTest( LSBOOL _bVal ); 00301 00307 static LSE_INLINE LSVOID LSE_FCALL SetDepthFunc( LSG_DEPTH_TEST _dtFunc ); 00308 00314 static LSE_INLINE LSVOID LSE_FCALL SetDepthWrite( LSBOOL _bVal ); 00315 00321 static LSE_INLINE LSVOID LSE_FCALL SetCulling( LSBOOL _bVal ); 00322 00328 static LSE_INLINE LSVOID LSE_FCALL SetCullMode( LSG_CULL_MODES _cmMode ); 00329 00335 static LSE_INLINE LSG_CULL_MODES LSE_CALL GetCullMode(); 00336 00342 static LSE_INLINE LSVOID LSE_FCALL SetBlendEnabled( LSBOOL _bVal ); 00343 00350 static LSE_INLINE LSVOID LSE_FCALL SetBlendFunc( LSG_BLEND_MODES _bmSrc, LSG_BLEND_MODES _bmDst ); 00351 00357 static LSE_INLINE LSVOID LSE_FCALL SetFillMode( LSG_FILL_MODES _fmMode ); 00358 00364 static LSE_INLINE LSBOOL LSE_FCALL BeginRender(); 00365 00369 static LSE_INLINE LSVOID LSE_FCALL EndRender(); 00370 00376 static LSE_INLINE CShaderManager * LSE_FCALL 00377 GetShaderManager(); 00378 00385 static LSVOID LSE_FCALL SetShader( CShader * _psShader ); 00386 00392 static CShader * LSE_FCALL GetShader(); 00393 00397 static LSVOID LSE_CALL PreRender(); 00398 00399 00400 00401 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00402 // METRICS 00403 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00409 static LSE_INLINE LSBOOL LSE_CALL NonPo2(); 00410 00416 template <typename tnType> 00417 static LSE_INLINE LSVOID LSE_CALL SafeRelease( tnType &_tObj ); 00418 00419 protected : 00420 // == Members. 00424 static IDirect3DDevice9 * m_pd3dDevice; 00425 00429 static IDirect3D9 * m_d3dObject; 00430 00434 static IDirect3DSurface9 * m_pd3s9Back; 00435 00439 static IDirect3DSurface9 * m_pd3s9DepthStencil; 00440 00444 static D3DCAPS9 m_cCaps; 00445 00449 static D3DDEVICE_CREATION_PARAMETERS m_dcpCreationParms; 00450 00454 static LSG_CULL_MODES m_cmCullMode; 00455 00459 static LSINT32 m_i32VertProcType; 00460 00464 static D3DPRESENT_PARAMETERS m_ppPresentParms; 00465 00469 static CShaderManager * m_psmShaderMan; 00470 00474 static LSUINT32 m_ui32ClearColor; 00475 00479 static LSFLOAT m_fDepthClear; 00480 00484 static LSBOOL m_bDeviceLost; 00485 00489 static LSBOOL m_bToggling; 00490 00494 static LSBOOL m_bDepthTest; 00495 00499 static LSBOOL m_bCulling; 00500 00504 static D3DTEXTUREFILTERTYPE m_tftMinFilter[LSG_MAX_TEXTURE_UNITS]; 00505 00509 static D3DTEXTUREFILTERTYPE m_tftMagFilter[LSG_MAX_TEXTURE_UNITS]; 00510 00514 static D3DTEXTUREFILTERTYPE m_tftMipFilter[LSG_MAX_TEXTURE_UNITS]; 00515 00519 static LSUINT32 m_ui32AnisoLevel[LSG_MAX_TEXTURE_UNITS]; 00520 00524 static D3DTEXTUREADDRESS m_taWrapU[LSG_MAX_TEXTURE_UNITS]; 00525 00529 static D3DTEXTUREADDRESS m_taWrapV[LSG_MAX_TEXTURE_UNITS]; 00530 00531 00532 // == Functions. 00536 static LSVOID LSE_CALL ResetInternal(); 00537 }; 00538 00539 00540 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00541 // DEFINITIONS 00542 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00543 // == Functions. 00549 LSE_INLINE LSBOOL LSE_CALL CDirectX9::DeviceIsLost() { 00550 return m_bDeviceLost; 00551 } 00552 00558 LSE_INLINE LSVOID LSE_CALL CDirectX9::TogglingFullScreen( LSBOOL _bVal ) { 00559 m_bToggling = _bVal; 00560 } 00561 00568 LSE_INLINE LSVOID LSE_CALL CDirectX9::SetWindowParms( LSBOOL _bWindowed, HWND _hWnd ) { 00569 // Get the width and height of the window. 00570 RECT rClient; 00571 ::GetClientRect( _hWnd, &rClient ); 00572 m_ppPresentParms.BackBufferWidth = rClient.right - rClient.left; 00573 m_ppPresentParms.BackBufferHeight = rClient.bottom - rClient.top; 00574 m_ppPresentParms.hDeviceWindow = _hWnd; 00575 m_ppPresentParms.Windowed = _bWindowed; 00576 m_ppPresentParms.BackBufferFormat = D3DFMT_A8R8G8B8; 00577 m_ppPresentParms.BackBufferCount = 1UL; 00578 } 00579 00585 LSE_INLINE IDirect3DDevice9 * CDirectX9::GetDirectX9Device() { 00586 return m_pd3dDevice; 00587 } 00593 LSE_INLINE IDirect3D9 * CDirectX9::GetDirectX9Object() { 00594 return m_d3dObject; 00595 } 00596 00602 LSE_INLINE const D3DDEVICE_CREATION_PARAMETERS & CDirectX9::GetCreationParms() { 00603 return m_dcpCreationParms; 00604 } 00605 00611 LSE_INLINE const D3DCAPS9 & LSE_CALL CDirectX9::GetDeviceCaps() { 00612 return m_cCaps; 00613 } 00614 00620 LSE_INLINE const D3DPRESENT_PARAMETERS & LSE_CALL CDirectX9::GetPresentParms() { 00621 return m_ppPresentParms; 00622 } 00623 00629 LSE_INLINE IDirect3DSurface9 * LSE_CALL CDirectX9::GetBackBufferSurface() { 00630 return m_pd3s9Back; 00631 } 00632 00638 LSE_INLINE IDirect3DSurface9 * LSE_CALL CDirectX9::GetDepthStencilSurface() { 00639 return m_pd3s9DepthStencil; 00640 } 00641 00650 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetMinMagMipFilters( LSUINT32 _ui32Slot, D3DTEXTUREFILTERTYPE _tftMin, D3DTEXTUREFILTERTYPE _tftMag, 00651 D3DTEXTUREFILTERTYPE _tftMip ) { 00652 if ( _tftMin != m_tftMinFilter[_ui32Slot] ) { 00653 m_tftMinFilter[_ui32Slot] = _tftMin; 00654 m_pd3dDevice->SetSamplerState( _ui32Slot, D3DSAMP_MINFILTER, _tftMin ); 00655 } 00656 if ( _tftMag != m_tftMagFilter[_ui32Slot] ) { 00657 m_tftMagFilter[_ui32Slot] = _tftMag; 00658 m_pd3dDevice->SetSamplerState( _ui32Slot, D3DSAMP_MAGFILTER, _tftMag ); 00659 } 00660 if ( _tftMip != m_tftMipFilter[_ui32Slot] ) { 00661 m_tftMipFilter[_ui32Slot] = _tftMip; 00662 m_pd3dDevice->SetSamplerState( _ui32Slot, D3DSAMP_MIPFILTER, _tftMip ); 00663 } 00664 } 00665 00672 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetAnisotropy( LSUINT32 _ui32Slot, LSUINT32 _ui32Level ) { 00673 _ui32Level = CStd::Clamp<LSUINT32>( _ui32Level, 1UL, CFndBase::m_mMetrics.ui32MaxAniso ); 00674 if ( _ui32Level != m_ui32AnisoLevel[_ui32Slot] ) { 00675 m_ui32AnisoLevel[_ui32Slot] = _ui32Level; 00676 m_pd3dDevice->SetSamplerState( _ui32Slot, D3DSAMP_MAXANISOTROPY, _ui32Level ); 00677 } 00678 } 00679 00687 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetTextureWrapModes( LSUINT32 _ui32Slot, D3DTEXTUREADDRESS _taU, D3DTEXTUREADDRESS _taV ) { 00688 if ( _taU != m_taWrapU[_ui32Slot] ) { 00689 m_taWrapU[_ui32Slot] = _taU; 00690 m_pd3dDevice->SetSamplerState( _ui32Slot, D3DSAMP_ADDRESSU, _taU ); 00691 } 00692 if ( _taV != m_taWrapV[_ui32Slot] ) { 00693 m_taWrapV[_ui32Slot] = _taV; 00694 m_pd3dDevice->SetSamplerState( _ui32Slot, D3DSAMP_ADDRESSV, _taV ); 00695 } 00696 } 00697 00701 LSE_INLINE LSVOID LSE_FCALL CDirectX9::AssertError() { 00702 } 00703 00707 LSE_INLINE LSVOID LSE_FCALL CDirectX9::Present() { 00708 if ( m_pd3dDevice->Present( NULL, NULL, NULL, NULL ) == D3DERR_DEVICELOST ) { 00709 // Handle a lost device. 00710 LoseDevice(); 00711 } 00712 00713 if ( DeviceIsLost() ) { 00714 ResetDevice(); 00715 } 00716 } 00717 00723 LSE_INLINE LSVOID LSE_FCALL CDirectX9::Clear( LSUINT32 _ui32Mask ) { 00724 m_pd3dDevice->Clear( 0UL, NULL, 00725 _ui32Mask & (LSG_B_COLOR_BUFFER | LSG_B_DEPTH_BUFFER | LSG_B_STENCIL_BUFFER), 00726 m_ui32ClearColor, 00727 m_fDepthClear, 00728 0 ); 00729 } 00730 00734 LSE_INLINE LSVOID LSE_FCALL CDirectX9::ClearAll() { 00735 Clear( LSG_B_ALL ); 00736 } 00737 00743 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetClearDepth( LSREAL _fValue ) { 00744 m_fDepthClear = static_cast<LSFLOAT>(_fValue); 00745 } 00746 00755 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetViewport( LSINT32 _i32X, LSINT32 _i32Y, LSINT32 _i32Width, LSINT32 _i32Height ) { 00756 if ( m_pd3dDevice ) { 00757 D3DVIEWPORT9 vpViewport = { 00758 _i32X, 00759 _i32Y, 00760 _i32Width, 00761 _i32Height, 00762 0.0f, 00763 1.0f 00764 }; 00765 m_pd3dDevice->SetViewport( &vpViewport ); 00766 } 00767 } 00768 00774 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetDepthTest( LSBOOL _bVal ) { 00775 _bVal = _bVal != false; 00776 if ( m_bDepthTest != _bVal ) { 00777 m_bDepthTest = _bVal; 00778 m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, _bVal ? D3DZB_TRUE : D3DZB_FALSE ); 00779 } 00780 } 00781 00787 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetDepthFunc( LSG_DEPTH_TEST _dtFunc ) { 00788 if ( CFndBase::m_dtDepthTestFunc != _dtFunc ) { 00789 CFndBase::m_dtDepthTestFunc = _dtFunc; 00790 static const D3DCMPFUNC dcfFuncs[] = { 00791 D3DCMP_NEVER, // LSG_DT_NEVER 00792 D3DCMP_ALWAYS, // LSG_DT_ALWAYS 00793 D3DCMP_LESS, // LSG_DT_LESS 00794 D3DCMP_EQUAL, // LSG_DT_EQUAL 00795 D3DCMP_NOTEQUAL, // LSG_DT_NOTEQUAL 00796 D3DCMP_LESSEQUAL, // LSG_DT_LESSEQUAL 00797 D3DCMP_GREATER, // LSG_DT_GREATER 00798 D3DCMP_GREATEREQUAL, // LSG_DT_GREATEREQUAL 00799 }; 00800 00801 m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, dcfFuncs[_dtFunc] ); 00802 } 00803 } 00804 00810 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetDepthWrite( LSBOOL _bVal ) { 00811 _bVal = _bVal != false; 00812 if ( CFndBase::m_bDepthWrite != _bVal ) { 00813 CFndBase::m_bDepthWrite = _bVal; 00814 m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, CFndBase::m_bDepthWrite ); 00815 } 00816 } 00817 00823 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetCulling( LSBOOL _bVal ) { 00824 _bVal = _bVal != false; 00825 if ( m_bCulling != _bVal ) { 00826 m_bCulling = _bVal; 00827 if ( !_bVal ) { 00828 m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); 00829 } 00830 else { 00831 static D3DCULL cModes[] = { 00832 D3DCULL_CCW, 00833 D3DCULL_CW 00834 }; 00835 m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, cModes[m_cmCullMode] ); 00836 } 00837 } 00838 } 00839 00845 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetCullMode( LSG_CULL_MODES _cmMode ) { 00846 assert( _cmMode == LSG_CM_CW || _cmMode == LSG_CM_CCW ); 00847 if ( m_cmCullMode != _cmMode ) { 00848 m_cmCullMode = _cmMode; 00849 if ( m_bCulling ) { 00850 static const D3DCULL cCull[] = { 00851 D3DCULL_CCW, 00852 D3DCULL_CW 00853 }; 00854 m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, cCull[_cmMode] ); 00855 } 00856 } 00857 } 00858 00864 LSE_INLINE LSG_CULL_MODES LSE_CALL CDirectX9::GetCullMode() { 00865 return m_cmCullMode; 00866 } 00867 00873 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetBlendEnabled( LSBOOL _bVal ) { 00874 if ( CFndBase::m_bBlending != (_bVal != false) ) { 00875 CFndBase::m_bBlending = (_bVal != false); 00876 m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, _bVal ); 00877 } 00878 } 00879 00886 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetBlendFunc( LSG_BLEND_MODES _bmSrc, LSG_BLEND_MODES _bmDst ) { 00887 static const D3DBLEND bModes[] = { 00888 D3DBLEND_ZERO, // LSG_BM_ZERO 00889 D3DBLEND_ONE, // LSG_BM_ONE 00890 D3DBLEND_SRCCOLOR, // LSG_BM_SRC_COLOR 00891 D3DBLEND_INVSRCCOLOR, // LSG_BM_INV_SRC_COLOR 00892 D3DBLEND_DESTCOLOR, // LSG_BM_DST_COLOR 00893 D3DBLEND_INVDESTCOLOR, // LSG_BM_INV_DST_COLOR 00894 D3DBLEND_SRCALPHA, // LSG_BM_SRC_ALPHA 00895 D3DBLEND_INVSRCALPHA, // LSG_BM_INV_SRC_ALPHA 00896 D3DBLEND_DESTALPHA, // LSG_BM_DST_ALPHA 00897 D3DBLEND_INVDESTALPHA, // LSG_BM_INV_DEST_ALPHA 00898 D3DBLEND_SRCALPHASAT, // LSG_BM_SRC_ALPHA_SAT 00899 }; 00900 00901 if ( CFndBase::m_bmSrcBlend != _bmSrc ) { 00902 CFndBase::m_bmSrcBlend = _bmSrc; 00903 m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, bModes[_bmSrc] ); 00904 } 00905 if ( CFndBase::m_bmDstBlend != _bmDst ) { 00906 CFndBase::m_bmDstBlend = _bmDst; 00907 m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, bModes[_bmDst] ); 00908 } 00909 } 00910 00916 LSE_INLINE LSVOID LSE_FCALL CDirectX9::SetFillMode( LSG_FILL_MODES _fmMode ) { 00917 static const DWORD dwValue[] = { 00918 D3DFILL_SOLID, 00919 D3DFILL_WIREFRAME, 00920 }; 00921 m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, dwValue[_fmMode] ); 00922 } 00923 00929 LSE_INLINE LSBOOL LSE_FCALL CDirectX9::BeginRender() { 00930 return SUCCEEDED( m_pd3dDevice->BeginScene() ); 00931 } 00932 00936 LSE_INLINE LSVOID LSE_FCALL CDirectX9::EndRender() { 00937 m_pd3dDevice->EndScene(); 00938 } 00939 00945 LSE_INLINE CShaderManager * LSE_FCALL CDirectX9::GetShaderManager() { 00946 return m_psmShaderMan; 00947 } 00948 00954 LSE_INLINE LSBOOL LSE_CALL CDirectX9::NonPo2() { 00955 return !(m_cCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(m_cCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL); 00956 } 00957 00963 template <typename tnType> 00964 LSE_INLINE LSVOID LSE_CALL CDirectX9::SafeRelease( tnType &_tObj ) { 00965 if ( _tObj ) { 00966 _tObj->Release(); 00967 _tObj = NULL; 00968 } 00969 } 00970 00971 } // namespace lsg 00972 00973 #endif // __LSG_DIRECTX9_H__