DXUT.cpp
资源名称:Direct3D.rar [点击查看]
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:227k
源码类别:
DirextX编程
开发平台:
Visual C++
- //--------------------------------------------------------------------------------------
- // File: DXUT.cpp
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //--------------------------------------------------------------------------------------
- #include "dxstdafx.h"
- #define DXUT_MIN_WINDOW_SIZE_X 200
- #define DXUT_MIN_WINDOW_SIZE_Y 200
- #undef min // use __min instead inside this source file
- #undef max // use __max instead inside this source file
- //--------------------------------------------------------------------------------------
- // Thread safety
- //--------------------------------------------------------------------------------------
- CRITICAL_SECTION g_cs;
- bool g_bThreadSafe = true;
- //--------------------------------------------------------------------------------------
- // Automatically enters & leaves the CS upon object creation/deletion
- //--------------------------------------------------------------------------------------
- class DXUTLock
- {
- public:
- inline DXUTLock() { if( g_bThreadSafe ) EnterCriticalSection( &g_cs ); }
- inline ~DXUTLock() { if( g_bThreadSafe ) LeaveCriticalSection( &g_cs ); }
- };
- //--------------------------------------------------------------------------------------
- // Helper macros to build member functions that access member variables with thread safety
- //--------------------------------------------------------------------------------------
- #define SET_ACCESSOR( x, y ) inline void Set##y( x t ) { DXUTLock l; m_state.m_##y = t; };
- #define GET_ACCESSOR( x, y ) inline x Get##y() { DXUTLock l; return m_state.m_##y; };
- #define GET_SET_ACCESSOR( x, y ) SET_ACCESSOR( x, y ) GET_ACCESSOR( x, y )
- #define SETP_ACCESSOR( x, y ) inline void Set##y( x* t ) { DXUTLock l; m_state.m_##y = *t; };
- #define GETP_ACCESSOR( x, y ) inline x* Get##y() { DXUTLock l; return &m_state.m_##y; };
- #define GETP_SETP_ACCESSOR( x, y ) SETP_ACCESSOR( x, y ) GETP_ACCESSOR( x, y )
- //--------------------------------------------------------------------------------------
- // Stores timer callback info
- //--------------------------------------------------------------------------------------
- struct DXUT_TIMER
- {
- LPDXUTCALLBACKTIMER pCallbackTimer;
- void* pCallbackUserContext;
- float fTimeoutInSecs;
- float fCountdown;
- bool bEnabled;
- UINT nID;
- };
- //--------------------------------------------------------------------------------------
- // Stores DXUT state and data access is done with thread safety (if g_bThreadSafe==true)
- //--------------------------------------------------------------------------------------
- class DXUTState
- {
- protected:
- struct STATE
- {
- IDirect3D9* m_D3D; // the main D3D object
- IDirect3DDevice9* m_D3DDevice; // the D3D rendering device
- CD3DEnumeration* m_D3DEnumeration; // CD3DEnumeration object
- DXUTDeviceSettings* m_CurrentDeviceSettings; // current device settings
- D3DSURFACE_DESC m_BackBufferSurfaceDesc; // back buffer surface description
- D3DCAPS9 m_Caps; // D3D caps for current device
- HWND m_HWNDFocus; // the main app focus window
- HWND m_HWNDDeviceFullScreen; // the main app device window in fullscreen mode
- HWND m_HWNDDeviceWindowed; // the main app device window in windowed mode
- HMONITOR m_AdapterMonitor; // the monitor of the adapter
- HMENU m_Menu; // handle to menu
- UINT m_FullScreenBackBufferWidthAtModeChange; // back buffer size of fullscreen mode right before switching to windowed mode. Used to restore to same resolution when toggling back to fullscreen
- UINT m_FullScreenBackBufferHeightAtModeChange; // back buffer size of fullscreen mode right before switching to windowed mode. Used to restore to same resolution when toggling back to fullscreen
- UINT m_WindowBackBufferWidthAtModeChange; // back buffer size of windowed mode right before switching to fullscreen mode. Used to restore to same resolution when toggling back to windowed mode
- UINT m_WindowBackBufferHeightAtModeChange; // back buffer size of windowed mode right before switching to fullscreen mode. Used to restore to same resolution when toggling back to windowed mode
- DWORD m_WindowedStyleAtModeChange; // window style
- WINDOWPLACEMENT m_WindowedPlacement; // record of windowed HWND position/show state/etc
- bool m_TopmostWhileWindowed; // if true, the windowed HWND is topmost
- bool m_Minimized; // if true, the HWND is minimized
- bool m_Maximized; // if true, the HWND is maximized
- bool m_MinimizedWhileFullscreen; // if true, the HWND is minimized due to a focus switch away when fullscreen mode
- bool m_IgnoreSizeChange; // if true, DXUT won't reset the device upon HWND size change
- double m_Time; // current time in seconds
- double m_AbsoluteTime; // absolute time in seconds
- float m_ElapsedTime; // time elapsed since last frame
- HINSTANCE m_HInstance; // handle to the app instance
- double m_LastStatsUpdateTime; // last time the stats were updated
- DWORD m_LastStatsUpdateFrames; // frames count since last time the stats were updated
- float m_FPS; // frames per second
- int m_CurrentFrameNumber; // the current frame number
- HHOOK m_KeyboardHook; // handle to keyboard hook
- bool m_AllowShortcutKeysWhenFullscreen; // if true, when fullscreen enable shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut)
- bool m_AllowShortcutKeysWhenWindowed; // if true, when windowed enable shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut)
- bool m_AllowShortcutKeys; // if true, then shortcut keys are currently disabled (Windows key, etc)
- bool m_CallDefWindowProc; // if true, DXUTStaticWndProc will call DefWindowProc for unhandled messages. Applications rendering to a dialog may need to set this to false.
- STICKYKEYS m_StartupStickyKeys; // StickyKey settings upon startup so they can be restored later
- TOGGLEKEYS m_StartupToggleKeys; // ToggleKey settings upon startup so they can be restored later
- FILTERKEYS m_StartupFilterKeys; // FilterKey settings upon startup so they can be restored later
- bool m_HandleDefaultHotkeys; // if true, then DXUT will handle some default hotkeys
- bool m_HandleAltEnter; // if true, then DXUT will handle Alt-Enter
- bool m_ShowMsgBoxOnError; // if true, then msgboxes are displayed upon errors
- bool m_NoStats; // if true, then DXUTGetFrameStats() and DXUTGetDeviceStats() will return blank strings
- bool m_ClipCursorWhenFullScreen; // if true, then DXUT will keep the cursor from going outside the window when full screen
- bool m_ShowCursorWhenFullScreen; // if true, then DXUT will show a cursor when full screen
- bool m_ConstantFrameTime; // if true, then elapsed frame time will always be 0.05f seconds which is good for debugging or automated capture
- float m_TimePerFrame; // the constant time per frame in seconds, only valid if m_ConstantFrameTime==true
- bool m_WireframeMode; // if true, then D3DRS_FILLMODE==D3DFILL_WIREFRAME else D3DRS_FILLMODE==D3DFILL_SOLID
- bool m_AutoChangeAdapter; // if true, then the adapter will automatically change if the window is different monitor
- bool m_WindowCreatedWithDefaultPositions; // if true, then CW_USEDEFAULT was used and the window should be moved to the right adapter
- int m_ExitCode; // the exit code to be returned to the command line
- bool m_DXUTInited; // if true, then DXUTInit() has succeeded
- bool m_WindowCreated; // if true, then DXUTCreateWindow() or DXUTSetWindow() has succeeded
- bool m_DeviceCreated; // if true, then DXUTCreateDevice*() or DXUTSetDevice() has succeeded
- bool m_DXUTInitCalled; // if true, then DXUTInit() was called
- bool m_WindowCreateCalled; // if true, then DXUTCreateWindow() or DXUTSetWindow() was called
- bool m_DeviceCreateCalled; // if true, then DXUTCreateDevice*() or DXUTSetDevice() was called
- bool m_DeviceObjectsCreated; // if true, then DeviceCreated callback has been called (if non-NULL)
- bool m_DeviceObjectsReset; // if true, then DeviceReset callback has been called (if non-NULL)
- bool m_InsideDeviceCallback; // if true, then the framework is inside an app device callback
- bool m_InsideMainloop; // if true, then the framework is inside the main loop
- bool m_Active; // if true, then the app is the active top level window
- bool m_TimePaused; // if true, then time is paused
- bool m_RenderingPaused; // if true, then rendering is paused
- int m_PauseRenderingCount; // pause rendering ref count
- int m_PauseTimeCount; // pause time ref count
- bool m_DeviceLost; // if true, then the device is lost and needs to be reset
- bool m_NotifyOnMouseMove; // if true, include WM_MOUSEMOVE in mousecallback
- bool m_Automation; // if true, automation is enabled
- bool m_InSizeMove; // if true, app is inside a WM_ENTERSIZEMOVE
- UINT m_TimerLastID; // last ID of the DXUT timer
- int m_OverrideAdapterOrdinal; // if != -1, then override to use this adapter ordinal
- bool m_OverrideWindowed; // if true, then force to start windowed
- bool m_OverrideFullScreen; // if true, then force to start full screen
- int m_OverrideStartX; // if != -1, then override to this X position of the window
- int m_OverrideStartY; // if != -1, then override to this Y position of the window
- int m_OverrideWidth; // if != 0, then override to this width
- int m_OverrideHeight; // if != 0, then override to this height
- bool m_OverrideForceHAL; // if true, then force to HAL device (failing if one doesn't exist)
- bool m_OverrideForceREF; // if true, then force to REF device (failing if one doesn't exist)
- bool m_OverrideForcePureHWVP; // if true, then force to use pure HWVP (failing if device doesn't support it)
- bool m_OverrideForceHWVP; // if true, then force to use HWVP (failing if device doesn't support it)
- bool m_OverrideForceSWVP; // if true, then force to use SWVP
- bool m_OverrideConstantFrameTime; // if true, then force to constant frame time
- float m_OverrideConstantTimePerFrame; // the constant time per frame in seconds if m_OverrideConstantFrameTime==true
- int m_OverrideQuitAfterFrame; // if != 0, then it will force the app to quit after that frame
- int m_OverrideForceVsync; // if == 0, then it will force the app to use D3DPRESENT_INTERVAL_IMMEDIATE, if == 1 force use of D3DPRESENT_INTERVAL_DEFAULT
- bool m_OverrideRelaunchMCE; // if true, then force relaunch of MCE at exit
- LPDXUTCALLBACKISDEVICEACCEPTABLE m_IsDeviceAcceptableFunc; // is device acceptable callback
- LPDXUTCALLBACKMODIFYDEVICESETTINGS m_ModifyDeviceSettingsFunc; // modify device settings callback
- LPDXUTCALLBACKDEVICECREATED m_DeviceCreatedFunc; // device created callback
- LPDXUTCALLBACKDEVICERESET m_DeviceResetFunc; // device reset callback
- LPDXUTCALLBACKDEVICELOST m_DeviceLostFunc; // device lost callback
- LPDXUTCALLBACKDEVICEDESTROYED m_DeviceDestroyedFunc; // device destroyed callback
- LPDXUTCALLBACKFRAMEMOVE m_FrameMoveFunc; // frame move callback
- LPDXUTCALLBACKFRAMERENDER m_FrameRenderFunc; // frame render callback
- LPDXUTCALLBACKKEYBOARD m_KeyboardFunc; // keyboard callback
- LPDXUTCALLBACKMOUSE m_MouseFunc; // mouse callback
- LPDXUTCALLBACKMSGPROC m_WindowMsgFunc; // window messages callback
- void* m_IsDeviceAcceptableFuncUserContext; // user context for is device acceptable callback
- void* m_ModifyDeviceSettingsFuncUserContext; // user context for modify device settings callback
- void* m_DeviceCreatedUserContext; // user context for device created callback
- void* m_DeviceCreatedFuncUserContext; // user context for device created callback
- void* m_DeviceResetFuncUserContext; // user context for device reset callback
- void* m_DeviceLostFuncUserContext; // user context for device lost callback
- void* m_DeviceDestroyedFuncUserContext; // user context for device destroyed callback
- void* m_FrameMoveFuncUserContext; // user context for frame move callback
- void* m_FrameRenderFuncUserContext; // user context for frame render callback
- void* m_KeyboardFuncUserContext; // user context for keyboard callback
- void* m_MouseFuncUserContext; // user context for mouse callback
- void* m_WindowMsgFuncUserContext; // user context for window messages callback
- bool m_Keys[256]; // array of key state
- bool m_MouseButtons[5]; // array of mouse states
- CGrowableArray<DXUT_TIMER>* m_TimerList; // list of DXUT_TIMER structs
- WCHAR m_StaticFrameStats[256]; // static part of frames stats
- WCHAR m_FPSStats[64]; // fps stats
- WCHAR m_FrameStats[256]; // frame stats (fps, width, etc)
- WCHAR m_DeviceStats[256]; // device stats (description, device type, etc)
- WCHAR m_WindowTitle[256]; // window title
- };
- STATE m_state;
- public:
- DXUTState() { Create(); }
- ~DXUTState() { Destroy(); }
- void Create()
- {
- // Make sure these are created before DXUTState so they
- // destroyed last because DXUTState cleanup needs them
- DXUTGetGlobalResourceCache();
- ZeroMemory( &m_state, sizeof(STATE) );
- g_bThreadSafe = true;
- InitializeCriticalSection( &g_cs );
- m_state.m_OverrideStartX = -1;
- m_state.m_OverrideStartY = -1;
- m_state.m_OverrideAdapterOrdinal = -1;
- m_state.m_OverrideForceVsync = -1;
- m_state.m_AutoChangeAdapter = true;
- m_state.m_ShowMsgBoxOnError = true;
- m_state.m_AllowShortcutKeysWhenWindowed = true;
- m_state.m_Active = true;
- m_state.m_CallDefWindowProc = true;
- }
- void Destroy()
- {
- DXUTShutdown();
- DeleteCriticalSection( &g_cs );
- }
- // Macros to define access functions for thread safe access into m_state
- GET_SET_ACCESSOR( IDirect3D9*, D3D );
- GET_SET_ACCESSOR( IDirect3DDevice9*, D3DDevice );
- GET_SET_ACCESSOR( CD3DEnumeration*, D3DEnumeration );
- GET_SET_ACCESSOR( DXUTDeviceSettings*, CurrentDeviceSettings );
- GETP_SETP_ACCESSOR( D3DSURFACE_DESC, BackBufferSurfaceDesc );
- GETP_SETP_ACCESSOR( D3DCAPS9, Caps );
- GET_SET_ACCESSOR( HWND, HWNDFocus );
- GET_SET_ACCESSOR( HWND, HWNDDeviceFullScreen );
- GET_SET_ACCESSOR( HWND, HWNDDeviceWindowed );
- GET_SET_ACCESSOR( HMONITOR, AdapterMonitor );
- GET_SET_ACCESSOR( HMENU, Menu );
- GET_SET_ACCESSOR( UINT, FullScreenBackBufferWidthAtModeChange );
- GET_SET_ACCESSOR( UINT, FullScreenBackBufferHeightAtModeChange );
- GET_SET_ACCESSOR( UINT, WindowBackBufferWidthAtModeChange );
- GET_SET_ACCESSOR( UINT, WindowBackBufferHeightAtModeChange );
- GETP_SETP_ACCESSOR( WINDOWPLACEMENT, WindowedPlacement );
- GET_SET_ACCESSOR( DWORD, WindowedStyleAtModeChange );
- GET_SET_ACCESSOR( bool, TopmostWhileWindowed );
- GET_SET_ACCESSOR( bool, Minimized );
- GET_SET_ACCESSOR( bool, Maximized );
- GET_SET_ACCESSOR( bool, MinimizedWhileFullscreen );
- GET_SET_ACCESSOR( bool, IgnoreSizeChange );
- GET_SET_ACCESSOR( double, Time );
- GET_SET_ACCESSOR( double, AbsoluteTime );
- GET_SET_ACCESSOR( float, ElapsedTime );
- GET_SET_ACCESSOR( HINSTANCE, HInstance );
- GET_SET_ACCESSOR( double, LastStatsUpdateTime );
- GET_SET_ACCESSOR( DWORD, LastStatsUpdateFrames );
- GET_SET_ACCESSOR( float, FPS );
- GET_SET_ACCESSOR( int, CurrentFrameNumber );
- GET_SET_ACCESSOR( HHOOK, KeyboardHook );
- GET_SET_ACCESSOR( bool, AllowShortcutKeysWhenFullscreen );
- GET_SET_ACCESSOR( bool, AllowShortcutKeysWhenWindowed );
- GET_SET_ACCESSOR( bool, AllowShortcutKeys );
- GET_SET_ACCESSOR( bool, CallDefWindowProc );
- GET_SET_ACCESSOR( STICKYKEYS, StartupStickyKeys );
- GET_SET_ACCESSOR( TOGGLEKEYS, StartupToggleKeys );
- GET_SET_ACCESSOR( FILTERKEYS, StartupFilterKeys );
- GET_SET_ACCESSOR( bool, HandleDefaultHotkeys );
- GET_SET_ACCESSOR( bool, HandleAltEnter );
- GET_SET_ACCESSOR( bool, ShowMsgBoxOnError );
- GET_SET_ACCESSOR( bool, NoStats );
- GET_SET_ACCESSOR( bool, ClipCursorWhenFullScreen );
- GET_SET_ACCESSOR( bool, ShowCursorWhenFullScreen );
- GET_SET_ACCESSOR( bool, ConstantFrameTime );
- GET_SET_ACCESSOR( float, TimePerFrame );
- GET_SET_ACCESSOR( bool, WireframeMode );
- GET_SET_ACCESSOR( bool, AutoChangeAdapter );
- GET_SET_ACCESSOR( bool, WindowCreatedWithDefaultPositions );
- GET_SET_ACCESSOR( int, ExitCode );
- GET_SET_ACCESSOR( bool, DXUTInited );
- GET_SET_ACCESSOR( bool, WindowCreated );
- GET_SET_ACCESSOR( bool, DeviceCreated );
- GET_SET_ACCESSOR( bool, DXUTInitCalled );
- GET_SET_ACCESSOR( bool, WindowCreateCalled );
- GET_SET_ACCESSOR( bool, DeviceCreateCalled );
- GET_SET_ACCESSOR( bool, InsideDeviceCallback );
- GET_SET_ACCESSOR( bool, InsideMainloop );
- GET_SET_ACCESSOR( bool, DeviceObjectsCreated );
- GET_SET_ACCESSOR( bool, DeviceObjectsReset );
- GET_SET_ACCESSOR( bool, Active );
- GET_SET_ACCESSOR( bool, RenderingPaused );
- GET_SET_ACCESSOR( bool, TimePaused );
- GET_SET_ACCESSOR( int, PauseRenderingCount );
- GET_SET_ACCESSOR( int, PauseTimeCount );
- GET_SET_ACCESSOR( bool, DeviceLost );
- GET_SET_ACCESSOR( bool, NotifyOnMouseMove );
- GET_SET_ACCESSOR( bool, Automation );
- GET_SET_ACCESSOR( bool, InSizeMove );
- GET_SET_ACCESSOR( UINT, TimerLastID );
- GET_SET_ACCESSOR( int, OverrideAdapterOrdinal );
- GET_SET_ACCESSOR( bool, OverrideWindowed );
- GET_SET_ACCESSOR( bool, OverrideFullScreen );
- GET_SET_ACCESSOR( int, OverrideStartX );
- GET_SET_ACCESSOR( int, OverrideStartY );
- GET_SET_ACCESSOR( int, OverrideWidth );
- GET_SET_ACCESSOR( int, OverrideHeight );
- GET_SET_ACCESSOR( bool, OverrideForceHAL );
- GET_SET_ACCESSOR( bool, OverrideForceREF );
- GET_SET_ACCESSOR( bool, OverrideForcePureHWVP );
- GET_SET_ACCESSOR( bool, OverrideForceHWVP );
- GET_SET_ACCESSOR( bool, OverrideForceSWVP );
- GET_SET_ACCESSOR( bool, OverrideConstantFrameTime );
- GET_SET_ACCESSOR( float, OverrideConstantTimePerFrame );
- GET_SET_ACCESSOR( int, OverrideQuitAfterFrame );
- GET_SET_ACCESSOR( int, OverrideForceVsync );
- GET_SET_ACCESSOR( bool, OverrideRelaunchMCE );
- GET_SET_ACCESSOR( LPDXUTCALLBACKISDEVICEACCEPTABLE, IsDeviceAcceptableFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKMODIFYDEVICESETTINGS, ModifyDeviceSettingsFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICECREATED, DeviceCreatedFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICERESET, DeviceResetFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICELOST, DeviceLostFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICEDESTROYED, DeviceDestroyedFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKFRAMEMOVE, FrameMoveFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKFRAMERENDER, FrameRenderFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKKEYBOARD, KeyboardFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKMOUSE, MouseFunc );
- GET_SET_ACCESSOR( LPDXUTCALLBACKMSGPROC, WindowMsgFunc );
- GET_SET_ACCESSOR( void*, IsDeviceAcceptableFuncUserContext );
- GET_SET_ACCESSOR( void*, ModifyDeviceSettingsFuncUserContext );
- GET_SET_ACCESSOR( void*, DeviceCreatedFuncUserContext );
- GET_SET_ACCESSOR( void*, DeviceResetFuncUserContext );
- GET_SET_ACCESSOR( void*, DeviceLostFuncUserContext );
- GET_SET_ACCESSOR( void*, DeviceDestroyedFuncUserContext );
- GET_SET_ACCESSOR( void*, FrameMoveFuncUserContext );
- GET_SET_ACCESSOR( void*, FrameRenderFuncUserContext );
- GET_SET_ACCESSOR( void*, KeyboardFuncUserContext );
- GET_SET_ACCESSOR( void*, MouseFuncUserContext );
- GET_SET_ACCESSOR( void*, WindowMsgFuncUserContext );
- GET_SET_ACCESSOR( CGrowableArray<DXUT_TIMER>*, TimerList );
- GET_ACCESSOR( bool*, Keys );
- GET_ACCESSOR( bool*, MouseButtons );
- GET_ACCESSOR( WCHAR*, StaticFrameStats );
- GET_ACCESSOR( WCHAR*, FPSStats );
- GET_ACCESSOR( WCHAR*, FrameStats );
- GET_ACCESSOR( WCHAR*, DeviceStats );
- GET_ACCESSOR( WCHAR*, WindowTitle );
- };
- //--------------------------------------------------------------------------------------
- // Global state class
- //--------------------------------------------------------------------------------------
- DXUTState& GetDXUTState()
- {
- // Using an accessor function gives control of the construction order
- static DXUTState state;
- return state;
- }
- //--------------------------------------------------------------------------------------
- // Internal functions forward declarations
- //--------------------------------------------------------------------------------------
- typedef IDirect3D9* (WINAPI* LPDIRECT3DCREATE9)(UINT SDKVersion);
- typedef DECLSPEC_IMPORT UINT (WINAPI* LPTIMEBEGINPERIOD)( UINT uPeriod );
- int DXUTMapButtonToArrayIndex( BYTE vButton );
- void DXUTSetProcessorAffinity();
- void DXUTParseCommandLine();
- CD3DEnumeration* DXUTPrepareEnumerationObject( bool bEnumerate = false );
- void DXUTBuildOptimalDeviceSettings( DXUTDeviceSettings* pOptimalDeviceSettings, DXUTDeviceSettings* pDeviceSettingsIn, DXUTMatchOptions* pMatchOptions );
- bool DXUTDoesDeviceComboMatchPreserveOptions( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo, DXUTDeviceSettings* pDeviceSettingsIn, DXUTMatchOptions* pMatchOptions );
- float DXUTRankDeviceCombo( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo, DXUTDeviceSettings* pDeviceSettingsIn, D3DDISPLAYMODE* pAdapterDesktopDisplayMode );
- void DXUTBuildValidDeviceSettings( DXUTDeviceSettings* pDeviceSettings, CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo, DXUTDeviceSettings* pDeviceSettingsIn, DXUTMatchOptions* pMatchOptions );
- HRESULT DXUTFindValidResolution( CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo, D3DDISPLAYMODE displayModeIn, D3DDISPLAYMODE* pBestDisplayMode );
- HRESULT DXUTFindAdapterFormat( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT BackBufferFormat, BOOL Windowed, D3DFORMAT* pAdapterFormat );
- HRESULT DXUTChangeDevice( DXUTDeviceSettings* pNewDeviceSettings, IDirect3DDevice9* pd3dDeviceFromApp, bool bForceRecreate, bool bClipWindowToSingleAdapter );
- void DXUTUpdateDeviceSettingsWithOverrides( DXUTDeviceSettings* pNewDeviceSettings );
- HRESULT DXUTCreate3DEnvironment( IDirect3DDevice9* pd3dDeviceFromApp );
- HRESULT DXUTReset3DEnvironment();
- void DXUTRender3DEnvironment();
- void DXUTCleanup3DEnvironment( bool bReleaseSettings = true );
- void DXUTUpdateFrameStats();
- void DXUTUpdateDeviceStats( D3DDEVTYPE DeviceType, DWORD BehaviorFlags, D3DADAPTER_IDENTIFIER9* pAdapterIdentifier );
- void DXUTUpdateStaticFrameStats();
- void DXUTHandleTimers();
- bool DXUTIsNextArg( WCHAR*& strCmdLine, WCHAR* strArg );
- bool DXUTGetCmdParam( WCHAR*& strCmdLine, WCHAR* strFlag );
- void DXUTDisplayErrorMessage( HRESULT hr );
- LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
- void DXUTCheckForWindowSizeChange();
- void DXUTCheckForWindowChangingMonitors();
- UINT DXUTColorChannelBits( D3DFORMAT fmt );
- UINT DXUTStencilBits( D3DFORMAT fmt );
- UINT DXUTDepthBits( D3DFORMAT fmt );
- HRESULT DXUTGetAdapterOrdinalFromMonitor( HMONITOR hMonitor, UINT* pAdapterOrdinal );
- void DXUTAllowShortcutKeys( bool bAllowKeys );
- void DXUTUpdateBackBufferDesc();
- void DXUTSetupCursor();
- HRESULT DXUTSetDeviceCursor( IDirect3DDevice9* pd3dDevice, HCURSOR hCursor, bool bAddWatermark );
- //--------------------------------------------------------------------------------------
- // External callback setup functions
- //--------------------------------------------------------------------------------------
- void DXUTSetCallbackDeviceCreated( LPDXUTCALLBACKDEVICECREATED pCallbackDeviceCreated, void* pUserContext ) { GetDXUTState().SetDeviceCreatedFunc( pCallbackDeviceCreated ); GetDXUTState().SetDeviceCreatedFuncUserContext( pUserContext ); }
- void DXUTSetCallbackDeviceReset( LPDXUTCALLBACKDEVICERESET pCallbackDeviceReset, void* pUserContext ) { GetDXUTState().SetDeviceResetFunc( pCallbackDeviceReset ); GetDXUTState().SetDeviceResetFuncUserContext( pUserContext ); }
- void DXUTSetCallbackDeviceLost( LPDXUTCALLBACKDEVICELOST pCallbackDeviceLost, void* pUserContext ) { GetDXUTState().SetDeviceLostFunc( pCallbackDeviceLost ); GetDXUTState().SetDeviceLostFuncUserContext( pUserContext ); }
- void DXUTSetCallbackDeviceDestroyed( LPDXUTCALLBACKDEVICEDESTROYED pCallbackDeviceDestroyed, void* pUserContext ) { GetDXUTState().SetDeviceDestroyedFunc( pCallbackDeviceDestroyed ); GetDXUTState().SetDeviceDestroyedFuncUserContext( pUserContext ); }
- void DXUTSetCallbackDeviceChanging( LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings, void* pUserContext ) { GetDXUTState().SetModifyDeviceSettingsFunc( pCallbackModifyDeviceSettings ); GetDXUTState().SetModifyDeviceSettingsFuncUserContext( pUserContext ); }
- void DXUTSetCallbackFrameMove( LPDXUTCALLBACKFRAMEMOVE pCallbackFrameMove, void* pUserContext ) { GetDXUTState().SetFrameMoveFunc( pCallbackFrameMove ); GetDXUTState().SetFrameMoveFuncUserContext( pUserContext ); }
- void DXUTSetCallbackFrameRender( LPDXUTCALLBACKFRAMERENDER pCallbackFrameRender, void* pUserContext ) { GetDXUTState().SetFrameRenderFunc( pCallbackFrameRender ); GetDXUTState().SetFrameRenderFuncUserContext( pUserContext ); }
- void DXUTSetCallbackKeyboard( LPDXUTCALLBACKKEYBOARD pCallbackKeyboard, void* pUserContext ) { GetDXUTState().SetKeyboardFunc( pCallbackKeyboard ); GetDXUTState().SetKeyboardFuncUserContext( pUserContext ); }
- void DXUTSetCallbackMouse( LPDXUTCALLBACKMOUSE pCallbackMouse, bool bIncludeMouseMove, void* pUserContext ) { GetDXUTState().SetMouseFunc( pCallbackMouse ); GetDXUTState().SetNotifyOnMouseMove( bIncludeMouseMove ); GetDXUTState().SetMouseFuncUserContext( pUserContext ); }
- void DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallbackMsgProc, void* pUserContext ) { GetDXUTState().SetWindowMsgFunc( pCallbackMsgProc ); GetDXUTState().SetWindowMsgFuncUserContext( pUserContext ); }
- //--------------------------------------------------------------------------------------
- // Optionally parses the command line and sets if default hotkeys are handled
- //
- // Possible command line parameters are:
- // -adapter:# forces app to use this adapter # (fails if the adapter doesn't exist)
- // -windowed forces app to start windowed
- // -fullscreen forces app to start full screen
- // -forcehal forces app to use HAL (fails if HAL doesn't exist)
- // -forceref forces app to use REF (fails if REF doesn't exist)
- // -forcepurehwvp forces app to use pure HWVP (fails if device doesn't support it)
- // -forcehwvp forces app to use HWVP (fails if device doesn't support it)
- // -forceswvp forces app to use SWVP
- // -forcevsync:# if # is 0, forces app to use D3DPRESENT_INTERVAL_IMMEDIATE otherwise force use of D3DPRESENT_INTERVAL_DEFAULT
- // -width:# forces app to use # for width. for full screen, it will pick the closest possible supported mode
- // -height:# forces app to use # for height. for full screen, it will pick the closest possible supported mode
- // -startx:# forces app to use # for the x coord of the window position for windowed mode
- // -starty:# forces app to use # for the y coord of the window position for windowed mode
- // -constantframetime:# forces app to use constant frame time, where # is the time/frame in seconds
- // -quitafterframe:x forces app to quit after # frames
- // -noerrormsgboxes prevents the display of message boxes generated by the framework so the application can be run without user interaction
- // -nostats prevents the display of the stats
- // -relaunchmce re-launches the MCE UI after the app exits
- // -automation every CDXUTDialog created will have EnableKeyboardInput(true) called, enabling UI navigation with keyboard
- // This is useful when automating application testing.
- //
- // Hotkeys handled by default are:
- // Alt-Enter toggle between full screen & windowed (hotkey always enabled)
- // ESC exit app
- // F3 toggle HAL/REF
- // F8 toggle wire-frame mode
- // Pause pause time
- //--------------------------------------------------------------------------------------
- HRESULT DXUTInit( bool bParseCommandLine, bool bHandleDefaultHotkeys, bool bShowMsgBoxOnError, bool bHandleAltEnter )
- {
- GetDXUTState().SetDXUTInitCalled( true );
- // Not always needed, but lets the app create GDI dialogs
- InitCommonControls();
- // Save the current sticky/toggle/filter key settings so DXUT can restore them later
- STICKYKEYS sk = {sizeof(STICKYKEYS), 0};
- SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &sk, 0);
- GetDXUTState().SetStartupStickyKeys( sk );
- TOGGLEKEYS tk = {sizeof(TOGGLEKEYS), 0};
- SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tk, 0);
- GetDXUTState().SetStartupToggleKeys( tk );
- FILTERKEYS fk = {sizeof(FILTERKEYS), 0};
- SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &fk, 0);
- GetDXUTState().SetStartupFilterKeys( fk );
- // Increase the accuracy of Sleep() without needing to link to winmm.lib
- WCHAR wszPath[MAX_PATH+1];
- if( GetSystemDirectory( wszPath, MAX_PATH+1 ) )
- {
- StringCchCat( wszPath, MAX_PATH, L"\winmm.dll" );
- HINSTANCE hInstWinMM = LoadLibrary( wszPath );
- if( hInstWinMM )
- {
- LPTIMEBEGINPERIOD pTimeBeginPeriod = (LPTIMEBEGINPERIOD)GetProcAddress( hInstWinMM, "timeBeginPeriod" );
- if( NULL != pTimeBeginPeriod )
- pTimeBeginPeriod(1);
- FreeLibrary(hInstWinMM);
- }
- }
- GetDXUTState().SetShowMsgBoxOnError( bShowMsgBoxOnError );
- GetDXUTState().SetHandleDefaultHotkeys( bHandleDefaultHotkeys );
- GetDXUTState().SetHandleAltEnter( bHandleAltEnter );
- if( bParseCommandLine )
- DXUTParseCommandLine();
- // Verify D3DX version
- if( !D3DXCheckVersion( D3D_SDK_VERSION, D3DX_SDK_VERSION ) )
- {
- DXUTDisplayErrorMessage( DXUTERR_INCORRECTVERSION );
- return DXUT_ERR( L"D3DXCheckVersion", DXUTERR_INCORRECTVERSION );
- }
- // Create a Direct3D object if one has not already been created
- IDirect3D9* pD3D = DXUTGetD3DObject();
- if( pD3D == NULL )
- {
- // This may fail if DirectX 9 isn't installed
- // This may fail if the DirectX headers are out of sync with the installed DirectX DLLs
- pD3D = DXUT_Dynamic_Direct3DCreate9( D3D_SDK_VERSION );
- GetDXUTState().SetD3D( pD3D );
- }
- if( pD3D == NULL )
- {
- // If still NULL, then something went wrong
- DXUTDisplayErrorMessage( DXUTERR_NODIRECT3D );
- return DXUT_ERR( L"Direct3DCreate9", DXUTERR_NODIRECT3D );
- }
- // Reset the timer
- DXUTGetGlobalTimer()->Reset();
- GetDXUTState().SetDXUTInited( true );
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- // Parses the command line for parameters. See DXUTInit() for list
- //--------------------------------------------------------------------------------------
- void DXUTParseCommandLine()
- {
- WCHAR* strCmdLine;
- WCHAR strFlag[MAX_PATH];
- int nNumArgs;
- WCHAR** pstrArgList = CommandLineToArgvW( GetCommandLine(), &nNumArgs );
- for( int iArg=1; iArg<nNumArgs; iArg++ )
- {
- strCmdLine = pstrArgList[iArg];
- // Handle flag args
- if( *strCmdLine == L'/' || *strCmdLine == L'-' )
- {
- strCmdLine++;
- if( DXUTIsNextArg( strCmdLine, L"adapter" ) )
- {
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- {
- int nAdapter = _wtoi(strFlag);
- GetDXUTState().SetOverrideAdapterOrdinal( nAdapter );
- continue;
- }
- }
- if( DXUTIsNextArg( strCmdLine, L"windowed" ) )
- {
- GetDXUTState().SetOverrideWindowed( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"fullscreen" ) )
- {
- GetDXUTState().SetOverrideFullScreen( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"forcehal" ) )
- {
- GetDXUTState().SetOverrideForceHAL( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"forceref" ) )
- {
- GetDXUTState().SetOverrideForceREF( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"forcepurehwvp" ) )
- {
- GetDXUTState().SetOverrideForcePureHWVP( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"forcehwvp" ) )
- {
- GetDXUTState().SetOverrideForceHWVP( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"forceswvp" ) )
- {
- GetDXUTState().SetOverrideForceSWVP( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"forcevsync" ) )
- {
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- {
- int nOn = _wtoi(strFlag);
- GetDXUTState().SetOverrideForceVsync( nOn );
- continue;
- }
- }
- if( DXUTIsNextArg( strCmdLine, L"width" ) )
- {
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- {
- int nWidth = _wtoi(strFlag);
- GetDXUTState().SetOverrideWidth( nWidth );
- continue;
- }
- }
- if( DXUTIsNextArg( strCmdLine, L"height" ) )
- {
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- {
- int nHeight = _wtoi(strFlag);
- GetDXUTState().SetOverrideHeight( nHeight );
- continue;
- }
- }
- if( DXUTIsNextArg( strCmdLine, L"startx" ) )
- {
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- {
- int nX = _wtoi(strFlag);
- GetDXUTState().SetOverrideStartX( nX );
- continue;
- }
- }
- if( DXUTIsNextArg( strCmdLine, L"starty" ) )
- {
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- {
- int nY = _wtoi(strFlag);
- GetDXUTState().SetOverrideStartY( nY );
- continue;
- }
- }
- if( DXUTIsNextArg( strCmdLine, L"constantframetime" ) )
- {
- float fTimePerFrame;
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- fTimePerFrame = (float)wcstod( strFlag, NULL );
- else
- fTimePerFrame = 0.0333f;
- GetDXUTState().SetOverrideConstantFrameTime( true );
- GetDXUTState().SetOverrideConstantTimePerFrame( fTimePerFrame );
- DXUTSetConstantFrameTime( true, fTimePerFrame );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"quitafterframe" ) )
- {
- if( DXUTGetCmdParam( strCmdLine, strFlag ) )
- {
- int nFrame = _wtoi(strFlag);
- GetDXUTState().SetOverrideQuitAfterFrame( nFrame );
- continue;
- }
- }
- if( DXUTIsNextArg( strCmdLine, L"noerrormsgboxes" ) )
- {
- GetDXUTState().SetShowMsgBoxOnError( false );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"nostats" ) )
- {
- GetDXUTState().SetNoStats( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"relaunchmce" ) )
- {
- GetDXUTState().SetOverrideRelaunchMCE( true );
- continue;
- }
- if( DXUTIsNextArg( strCmdLine, L"automation" ) )
- {
- GetDXUTState().SetAutomation( true );
- continue;
- }
- }
- // Unrecognized flag
- StringCchCopy( strFlag, 256, strCmdLine );
- WCHAR* strSpace = strFlag;
- while (*strSpace && (*strSpace > L' '))
- strSpace++;
- *strSpace = 0;
- DXUTOutputDebugString( L"Unrecognized flag: %s", strFlag );
- strCmdLine += wcslen(strFlag);
- }
- }
- //--------------------------------------------------------------------------------------
- // Helper function for DXUTParseCommandLine
- //--------------------------------------------------------------------------------------
- bool DXUTIsNextArg( WCHAR*& strCmdLine, WCHAR* strArg )
- {
- int nArgLen = (int) wcslen(strArg);
- int nCmdLen = (int) wcslen(strCmdLine);
- if( nCmdLen >= nArgLen &&
- _wcsnicmp( strCmdLine, strArg, nArgLen ) == 0 &&
- (strCmdLine[nArgLen] == 0 || strCmdLine[nArgLen] == L':') )
- {
- strCmdLine += nArgLen;
- return true;
- }
- return false;
- }
- //--------------------------------------------------------------------------------------
- // Helper function for DXUTParseCommandLine. Updates strCmdLine and strFlag
- // Example: if strCmdLine=="-width:1024 -forceref"
- // then after: strCmdLine==" -forceref" and strFlag=="1024"
- //--------------------------------------------------------------------------------------
- bool DXUTGetCmdParam( WCHAR*& strCmdLine, WCHAR* strFlag )
- {
- if( *strCmdLine == L':' )
- {
- strCmdLine++; // Skip ':'
- // Place NULL terminator in strFlag after current token
- StringCchCopy( strFlag, 256, strCmdLine );
- WCHAR* strSpace = strFlag;
- while (*strSpace && (*strSpace > L' '))
- strSpace++;
- *strSpace = 0;
- // Update strCmdLine
- strCmdLine += wcslen(strFlag);
- return true;
- }
- else
- {
- strFlag[0] = 0;
- return false;
- }
- }
- //--------------------------------------------------------------------------------------
- // Creates a window with the specified window title, icon, menu, and
- // starting position. If DXUTInit() has not already been called, it will
- // call it with the default parameters. Instead of calling this, you can
- // call DXUTSetWindow() to use an existing window.
- //--------------------------------------------------------------------------------------
- HRESULT DXUTCreateWindow( const WCHAR* strWindowTitle, HINSTANCE hInstance,
- HICON hIcon, HMENU hMenu, int x, int y )
- {
- HRESULT hr;
- // Not allowed to call this from inside the device callbacks
- if( GetDXUTState().GetInsideDeviceCallback() )
- return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
- GetDXUTState().SetWindowCreateCalled( true );
- if( !GetDXUTState().GetDXUTInited() )
- {
- // If DXUTInit() was already called and failed, then fail.
- // DXUTInit() must first succeed for this function to succeed
- if( GetDXUTState().GetDXUTInitCalled() )
- return E_FAIL;
- // If DXUTInit() hasn't been called, then automatically call it
- // with default params
- hr = DXUTInit();
- if( FAILED(hr) )
- return hr;
- }
- if( DXUTGetHWNDFocus() == NULL )
- {
- if( hInstance == NULL )
- hInstance = (HINSTANCE)GetModuleHandle(NULL);
- GetDXUTState().SetHInstance( hInstance );
- WCHAR szExePath[MAX_PATH];
- GetModuleFileName( NULL, szExePath, MAX_PATH );
- if( hIcon == NULL ) // If the icon is NULL, then use the first one found in the exe
- hIcon = ExtractIcon( hInstance, szExePath, 0 );
- // Register the windows class
- WNDCLASS wndClass;
- wndClass.style = CS_DBLCLKS;
- wndClass.lpfnWndProc = DXUTStaticWndProc;
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- wndClass.hInstance = hInstance;
- wndClass.hIcon = hIcon;
- wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
- wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wndClass.lpszMenuName = NULL;
- wndClass.lpszClassName = L"Direct3DWindowClass";
- if( !RegisterClass( &wndClass ) )
- {
- DWORD dwError = GetLastError();
- if( dwError != ERROR_CLASS_ALREADY_EXISTS )
- return DXUT_ERR_MSGBOX( L"RegisterClass", HRESULT_FROM_WIN32(dwError) );
- }
- RECT rc;
- // Override the window's initial & size position if there were cmd line args
- if( GetDXUTState().GetOverrideStartX() != -1 )
- x = GetDXUTState().GetOverrideStartX();
- if( GetDXUTState().GetOverrideStartY() != -1 )
- y = GetDXUTState().GetOverrideStartY();
- GetDXUTState().SetWindowCreatedWithDefaultPositions( false );
- if( x == CW_USEDEFAULT && y == CW_USEDEFAULT )
- GetDXUTState().SetWindowCreatedWithDefaultPositions( true );
- // Find the window's initial size, but it might be changed later
- int nDefaultWidth = 640;
- int nDefaultHeight = 480;
- if( GetDXUTState().GetOverrideWidth() != 0 )
- nDefaultWidth = GetDXUTState().GetOverrideWidth();
- if( GetDXUTState().GetOverrideHeight() != 0 )
- nDefaultHeight = GetDXUTState().GetOverrideHeight();
- SetRect( &rc, 0, 0, nDefaultWidth, nDefaultHeight );
- AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, ( hMenu != NULL ) ? true : false );
- WCHAR* strCachedWindowTitle = GetDXUTState().GetWindowTitle();
- StringCchCopy( strCachedWindowTitle, 256, strWindowTitle );
- // Create the render window
- HWND hWnd = CreateWindow( L"Direct3DWindowClass", strWindowTitle, WS_OVERLAPPEDWINDOW,
- x, y, (rc.right-rc.left), (rc.bottom-rc.top), 0,
- hMenu, hInstance, 0 );
- if( hWnd == NULL )
- {
- DWORD dwError = GetLastError();
- return DXUT_ERR_MSGBOX( L"CreateWindow", HRESULT_FROM_WIN32(dwError) );
- }
- GetDXUTState().SetWindowCreated( true );
- GetDXUTState().SetHWNDFocus( hWnd );
- GetDXUTState().SetHWNDDeviceFullScreen( hWnd );
- GetDXUTState().SetHWNDDeviceWindowed( hWnd );
- }
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- // Sets a previously created window for the framework to use. If DXUTInit()
- // has not already been called, it will call it with the default parameters.
- // Instead of calling this, you can call DXUTCreateWindow() to create a new window.
- //--------------------------------------------------------------------------------------
- HRESULT DXUTSetWindow( HWND hWndFocus, HWND hWndDeviceFullScreen, HWND hWndDeviceWindowed, bool bHandleMessages )
- {
- HRESULT hr;
- // Not allowed to call this from inside the device callbacks
- if( GetDXUTState().GetInsideDeviceCallback() )
- return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
- GetDXUTState().SetWindowCreateCalled( true );
- // To avoid confusion, we do not allow any HWND to be NULL here. The
- // caller must pass in valid HWND for all three parameters. The same
- // HWND may be used for more than one parameter.
- if( hWndFocus == NULL || hWndDeviceFullScreen == NULL || hWndDeviceWindowed == NULL )
- return DXUT_ERR_MSGBOX( L"DXUTSetWindow", E_INVALIDARG );
- // If subclassing the window, set the pointer to the local window procedure
- if( bHandleMessages )
- {
- // Switch window procedures
- #ifdef _WIN64
- LONG_PTR nResult = SetWindowLongPtr( hWndFocus, GWLP_WNDPROC, (LONG_PTR)DXUTStaticWndProc );
- #else
- LONG_PTR nResult = SetWindowLongPtr( hWndFocus, GWLP_WNDPROC, (LONG)(LONG_PTR)DXUTStaticWndProc );
- #endif
- DWORD dwError = GetLastError();
- if( nResult == 0 )
- return DXUT_ERR_MSGBOX( L"SetWindowLongPtr", HRESULT_FROM_WIN32(dwError) );
- }
- if( !GetDXUTState().GetDXUTInited() )
- {
- // If DXUTInit() was already called and failed, then fail.
- // DXUTInit() must first succeed for this function to succeed
- if( GetDXUTState().GetDXUTInitCalled() )
- return E_FAIL;
- // If DXUTInit() hasn't been called, then automatically call it
- // with default params
- hr = DXUTInit();
- if( FAILED(hr) )
- return hr;
- }
- WCHAR* strCachedWindowTitle = GetDXUTState().GetWindowTitle();
- GetWindowText( hWndFocus, strCachedWindowTitle, 255 );
- strCachedWindowTitle[255] = 0;
- HINSTANCE hInstance = (HINSTANCE) (LONG_PTR) GetWindowLongPtr( hWndFocus, GWLP_HINSTANCE );
- GetDXUTState().SetHInstance( hInstance );
- GetDXUTState().SetWindowCreatedWithDefaultPositions( false );
- GetDXUTState().SetWindowCreated( true );
- GetDXUTState().SetHWNDFocus( hWndFocus );
- GetDXUTState().SetHWNDDeviceFullScreen( hWndDeviceFullScreen );
- GetDXUTState().SetHWNDDeviceWindowed( hWndDeviceWindowed );
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- // Creates a Direct3D device. If DXUTCreateWindow() or DXUTSetWindow() has not already
- // been called, it will call DXUTCreateWindow() with the default parameters.
- // Instead of calling this, you can call DXUTSetDevice() or DXUTCreateDeviceFromSettings()
- //--------------------------------------------------------------------------------------
- HRESULT DXUTCreateDevice( UINT AdapterOrdinal, bool bWindowed,
- int nSuggestedWidth, int nSuggestedHeight,
- LPDXUTCALLBACKISDEVICEACCEPTABLE pCallbackIsDeviceAcceptable,
- LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings,
- void* pUserContext )
- {
- HRESULT hr;
- // Not allowed to call this from inside the device callbacks
- if( GetDXUTState().GetInsideDeviceCallback() )
- return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
- // Record the function arguments in the global state
- GetDXUTState().SetIsDeviceAcceptableFunc( pCallbackIsDeviceAcceptable );
- GetDXUTState().SetModifyDeviceSettingsFunc( pCallbackModifyDeviceSettings );
- GetDXUTState().SetIsDeviceAcceptableFuncUserContext( pUserContext );
- GetDXUTState().SetModifyDeviceSettingsFuncUserContext( pUserContext );
- GetDXUTState().SetDeviceCreateCalled( true );
- // If DXUTCreateWindow() or DXUTSetWindow() has not already been called,
- // then call DXUTCreateWindow() with the default parameters.
- if( !GetDXUTState().GetWindowCreated() )
- {
- // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail.
- // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed
- if( GetDXUTState().GetWindowCreateCalled() )
- return E_FAIL;
- // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then
- // automatically call DXUTCreateWindow() with default params
- hr = DXUTCreateWindow();
- if( FAILED(hr) )
- return hr;
- }
- // Force an enumeration with the new IsDeviceAcceptable callback
- DXUTPrepareEnumerationObject( true );
- DXUTMatchOptions matchOptions;
- matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
- matchOptions.eDeviceType = DXUTMT_IGNORE_INPUT;
- matchOptions.eWindowed = DXUTMT_PRESERVE_INPUT;
- matchOptions.eAdapterFormat = DXUTMT_IGNORE_INPUT;
- matchOptions.eVertexProcessing = DXUTMT_IGNORE_INPUT;
- if( bWindowed || (nSuggestedWidth != 0 && nSuggestedHeight != 0) )
- matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
- else
- matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
- matchOptions.eBackBufferFormat = DXUTMT_IGNORE_INPUT;
- matchOptions.eBackBufferCount = DXUTMT_IGNORE_INPUT;
- matchOptions.eMultiSample = DXUTMT_IGNORE_INPUT;
- matchOptions.eSwapEffect = DXUTMT_IGNORE_INPUT;
- matchOptions.eDepthFormat = DXUTMT_IGNORE_INPUT;
- matchOptions.eStencilFormat = DXUTMT_IGNORE_INPUT;
- matchOptions.ePresentFlags = DXUTMT_IGNORE_INPUT;
- matchOptions.eRefreshRate = DXUTMT_IGNORE_INPUT;
- matchOptions.ePresentInterval = DXUTMT_IGNORE_INPUT;
- DXUTDeviceSettings deviceSettings;
- ZeroMemory( &deviceSettings, sizeof(DXUTDeviceSettings) );
- deviceSettings.AdapterOrdinal = AdapterOrdinal;
- deviceSettings.pp.Windowed = bWindowed;
- deviceSettings.pp.BackBufferWidth = nSuggestedWidth;
- deviceSettings.pp.BackBufferHeight = nSuggestedHeight;
- // Override with settings from the command line
- if( GetDXUTState().GetOverrideWidth() != 0 )
- deviceSettings.pp.BackBufferWidth = GetDXUTState().GetOverrideWidth();
- if( GetDXUTState().GetOverrideHeight() != 0 )
- deviceSettings.pp.BackBufferHeight = GetDXUTState().GetOverrideHeight();
- if( GetDXUTState().GetOverrideAdapterOrdinal() != -1 )
- deviceSettings.AdapterOrdinal = GetDXUTState().GetOverrideAdapterOrdinal();
- if( GetDXUTState().GetOverrideFullScreen() )
- {
- deviceSettings.pp.Windowed = FALSE;
- if( GetDXUTState().GetOverrideWidth() == 0 && GetDXUTState().GetOverrideHeight() == 0 )
- matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
- }
- if( GetDXUTState().GetOverrideWindowed() )
- deviceSettings.pp.Windowed = TRUE;
- if( GetDXUTState().GetOverrideForceHAL() )
- {
- deviceSettings.DeviceType = D3DDEVTYPE_HAL;
- matchOptions.eDeviceType = DXUTMT_PRESERVE_INPUT;
- }
- if( GetDXUTState().GetOverrideForceREF() )
- {
- deviceSettings.DeviceType = D3DDEVTYPE_REF;
- matchOptions.eDeviceType = DXUTMT_PRESERVE_INPUT;
- }
- if( GetDXUTState().GetOverrideForcePureHWVP() )
- {
- deviceSettings.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
- matchOptions.eVertexProcessing = DXUTMT_PRESERVE_INPUT;
- }
- else if( GetDXUTState().GetOverrideForceHWVP() )
- {
- deviceSettings.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
- matchOptions.eVertexProcessing = DXUTMT_PRESERVE_INPUT;
- }
- else if( GetDXUTState().GetOverrideForceSWVP() )
- {
- deviceSettings.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- matchOptions.eVertexProcessing = DXUTMT_PRESERVE_INPUT;
- }
- if( GetDXUTState().GetOverrideForceVsync() == 0 )
- {
- deviceSettings.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
- matchOptions.ePresentInterval = DXUTMT_PRESERVE_INPUT;
- }
- else if( GetDXUTState().GetOverrideForceVsync() == 1 )
- {
- deviceSettings.pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
- matchOptions.ePresentInterval = DXUTMT_PRESERVE_INPUT;
- }
- hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
- if( FAILED(hr) ) // the call will fail if no valid devices were found
- {
- DXUTDisplayErrorMessage( hr );
- return DXUT_ERR( L"DXUTFindValidDeviceSettings", hr );
- }
- // Change to a Direct3D device created from the new device settings.
- // If there is an existing device, then either reset or recreated the scene
- hr = DXUTChangeDevice( &deviceSettings, NULL, false, true );
- if( FAILED(hr) )
- return hr;
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- // Passes a previously created Direct3D device for use by the framework.
- // If DXUTCreateWindow() has not already been called, it will call it with the
- // default parameters. Instead of calling this, you can call DXUTCreateDevice() or
- // DXUTCreateDeviceFromSettings()
- //--------------------------------------------------------------------------------------
- HRESULT DXUTSetDevice( IDirect3DDevice9* pd3dDevice )
- {
- HRESULT hr;
- if( pd3dDevice == NULL )
- return DXUT_ERR_MSGBOX( L"DXUTSetDevice", E_INVALIDARG );
- // Not allowed to call this from inside the device callbacks
- if( GetDXUTState().GetInsideDeviceCallback() )
- return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
- GetDXUTState().SetDeviceCreateCalled( true );
- // If DXUTCreateWindow() or DXUTSetWindow() has not already been called,
- // then call DXUTCreateWindow() with the default parameters.
- if( !GetDXUTState().GetWindowCreated() )
- {
- // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail.
- // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed
- if( GetDXUTState().GetWindowCreateCalled() )
- return E_FAIL;
- // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then
- // automatically call DXUTCreateWindow() with default params
- hr = DXUTCreateWindow();
- if( FAILED(hr) )
- return hr;
- }
- DXUTDeviceSettings* pDeviceSettings = new DXUTDeviceSettings;
- if( pDeviceSettings == NULL )
- return E_OUTOFMEMORY;
- ZeroMemory( pDeviceSettings, sizeof(DXUTDeviceSettings) );
- // Get the present params from the swap chain
- IDirect3DSurface9* pBackBuffer = NULL;
- hr = pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
- if( SUCCEEDED(hr) )
- {
- IDirect3DSwapChain9* pSwapChain = NULL;
- hr = pBackBuffer->GetContainer( IID_IDirect3DSwapChain9, (void**) &pSwapChain );
- if( SUCCEEDED(hr) )
- {
- pSwapChain->GetPresentParameters( &pDeviceSettings->pp );
- SAFE_RELEASE( pSwapChain );
- }
- SAFE_RELEASE( pBackBuffer );
- }
- D3DDEVICE_CREATION_PARAMETERS d3dCreationParams;
- pd3dDevice->GetCreationParameters( &d3dCreationParams );
- // Fill out the rest of the device settings struct
- pDeviceSettings->AdapterOrdinal = d3dCreationParams.AdapterOrdinal;
- pDeviceSettings->DeviceType = d3dCreationParams.DeviceType;
- DXUTFindAdapterFormat( pDeviceSettings->AdapterOrdinal, pDeviceSettings->DeviceType,
- pDeviceSettings->pp.BackBufferFormat, pDeviceSettings->pp.Windowed,
- &pDeviceSettings->AdapterFormat );
- pDeviceSettings->BehaviorFlags = d3dCreationParams.BehaviorFlags;
- // Change to the Direct3D device passed in
- hr = DXUTChangeDevice( pDeviceSettings, pd3dDevice, false, false );
- delete pDeviceSettings;
- if( FAILED(hr) )
- return hr;
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- // Tells the framework to change to a device created from the passed in device settings
- // If DXUTCreateWindow() has not already been called, it will call it with the
- // default parameters. Instead of calling this, you can call DXUTCreateDevice()
- // or DXUTSetDevice()
- //--------------------------------------------------------------------------------------
- HRESULT DXUTCreateDeviceFromSettings( DXUTDeviceSettings* pDeviceSettings, bool bPreserveInput, bool bClipWindowToSingleAdapter )
- {
- HRESULT hr;
- GetDXUTState().SetDeviceCreateCalled( true );
- // If DXUTCreateWindow() or DXUTSetWindow() has not already been called,
- // then call DXUTCreateWindow() with the default parameters.
- if( !GetDXUTState().GetWindowCreated() )
- {
- // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail.
- // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed
- if( GetDXUTState().GetWindowCreateCalled() )
- return E_FAIL;
- // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then
- // automatically call DXUTCreateWindow() with default params
- hr = DXUTCreateWindow();
- if( FAILED(hr) )
- return hr;
- }
- if( !bPreserveInput )
- {
- // If not preserving the input, then find the closest valid to it
- DXUTMatchOptions matchOptions;
- matchOptions.eAdapterOrdinal = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eDeviceType = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eWindowed = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eAdapterFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eBackBufferFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eRefreshRate = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
- hr = DXUTFindValidDeviceSettings( pDeviceSettings, pDeviceSettings, &matchOptions );
- if( FAILED(hr) ) // the call will fail if no valid devices were found
- {
- DXUTDisplayErrorMessage( hr );
- return DXUT_ERR( L"DXUTFindValidDeviceSettings", hr );
- }
- }
- // Change to a Direct3D device created from the new device settings.
- // If there is an existing device, then either reset or recreate the scene
- hr = DXUTChangeDevice( pDeviceSettings, NULL, false, bClipWindowToSingleAdapter );
- if( FAILED(hr) )
- return hr;
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- // Toggle between full screen and windowed
- //--------------------------------------------------------------------------------------
- HRESULT DXUTToggleFullScreen()
- {
- HRESULT hr;
- // Get the current device settings and flip the windowed state then
- // find the closest valid device settings with this change
- DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
- deviceSettings.pp.Windowed = !deviceSettings.pp.Windowed;
- DXUTMatchOptions matchOptions;
- matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
- matchOptions.eDeviceType = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eWindowed = DXUTMT_PRESERVE_INPUT;
- matchOptions.eAdapterFormat = DXUTMT_IGNORE_INPUT;
- matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eBackBufferFormat = DXUTMT_IGNORE_INPUT;
- matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eRefreshRate = DXUTMT_IGNORE_INPUT;
- matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
- // Go back to previous state
- UINT nWidth = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferWidthAtModeChange() : GetDXUTState().GetFullScreenBackBufferWidthAtModeChange();
- UINT nHeight = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferHeightAtModeChange() : GetDXUTState().GetFullScreenBackBufferHeightAtModeChange();
- if( nWidth > 0 && nHeight > 0 )
- {
- matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
- deviceSettings.pp.BackBufferWidth = nWidth;
- deviceSettings.pp.BackBufferHeight = nHeight;
- }
- else
- {
- // No previous data, so just switch to defaults
- matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
- }
- hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
- if( SUCCEEDED(hr) )
- {
- // Create a Direct3D device using the new device settings.
- // If there is an existing device, then it will either reset or recreate the scene.
- hr = DXUTChangeDevice( &deviceSettings, NULL, false, false );
- // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback so nothing changed
- if( FAILED(hr) && (hr != E_ABORT) )
- {
- // Failed creating device, try to switch back.
- deviceSettings.pp.Windowed = !deviceSettings.pp.Windowed;
- UINT nWidth = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferWidthAtModeChange() : GetDXUTState().GetFullScreenBackBufferWidthAtModeChange();
- UINT nHeight = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferHeightAtModeChange() : GetDXUTState().GetFullScreenBackBufferHeightAtModeChange();
- if( nWidth > 0 && nHeight > 0 )
- {
- matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
- deviceSettings.pp.BackBufferWidth = nWidth;
- deviceSettings.pp.BackBufferHeight = nHeight;
- }
- else
- {
- matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
- }
- DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
- HRESULT hr2 = DXUTChangeDevice( &deviceSettings, NULL, false, false );
- if( FAILED(hr2) )
- {
- // If this failed, then shutdown
- DXUTShutdown();
- }
- }
- }
- return hr;
- }
- //--------------------------------------------------------------------------------------
- // Toggle between HAL and REF
- //--------------------------------------------------------------------------------------
- HRESULT DXUTToggleREF()
- {
- HRESULT hr;
- DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
- if( deviceSettings.DeviceType == D3DDEVTYPE_HAL )
- deviceSettings.DeviceType = D3DDEVTYPE_REF;
- else if( deviceSettings.DeviceType == D3DDEVTYPE_REF )
- deviceSettings.DeviceType = D3DDEVTYPE_HAL;
- DXUTMatchOptions matchOptions;
- matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
- matchOptions.eDeviceType = DXUTMT_PRESERVE_INPUT;
- matchOptions.eWindowed = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eAdapterFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eBackBufferFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.eRefreshRate = DXUTMT_CLOSEST_TO_INPUT;
- matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
- hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
- if( SUCCEEDED(hr) )
- {
- // Create a Direct3D device using the new device settings.
- // If there is an existing device, then it will either reset or recreate the scene.
- hr = DXUTChangeDevice( &deviceSettings, NULL, false, false );
- // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback so nothing changed
- if( FAILED( hr ) && (hr != E_ABORT) )
- {
- // Failed creating device, try to switch back.
- if( deviceSettings.DeviceType == D3DDEVTYPE_HAL )
- deviceSettings.DeviceType = D3DDEVTYPE_REF;
- else if( deviceSettings.DeviceType == D3DDEVTYPE_REF )
- deviceSettings.DeviceType = D3DDEVTYPE_HAL;
- DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
- HRESULT hr2 = DXUTChangeDevice( &deviceSettings, NULL, false, false );
- if( FAILED(hr2) )
- {
- // If this failed, then shutdown
- DXUTShutdown();
- }
- }
- }
- return hr;
- }
- //--------------------------------------------------------------------------------------
- // Internal helper function to prepare the enumeration object by creating it if it
- // didn't already exist and enumerating if desired.
- //--------------------------------------------------------------------------------------
- CD3DEnumeration* DXUTPrepareEnumerationObject( bool bEnumerate )
- {
- // Create a new CD3DEnumeration object and enumerate all devices unless its already been done
- CD3DEnumeration* pd3dEnum = GetDXUTState().GetD3DEnumeration();
- if( pd3dEnum == NULL )
- {
- pd3dEnum = DXUTGetEnumeration();
- GetDXUTState().SetD3DEnumeration( pd3dEnum );
- bEnumerate = true;
- }
- if( bEnumerate )
- {
- // Enumerate for each adapter all of the supported display modes,
- // device types, adapter formats, back buffer formats, window/full screen support,
- // depth stencil formats, multisampling types/qualities, and presentations intervals.
- //
- // For each combination of device type (HAL/REF), adapter format, back buffer format, and
- // IsWindowed it will call the app's ConfirmDevice callback. This allows the app
- // to reject or allow that combination based on its caps/etc. It also allows the
- // app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP
- // if supported otherwise it will default to SWVP, however the app can change this
- // through the ConfirmDevice callback.
- IDirect3D9* pD3D = DXUTGetD3DObject();
- pd3dEnum->Enumerate( pD3D, GetDXUTState().GetIsDeviceAcceptableFunc(), GetDXUTState().GetIsDeviceAcceptableFuncUserContext() );
- }
- return pd3dEnum;
- }
- //--------------------------------------------------------------------------------------
- // This function tries to find valid device settings based upon the input device settings
- // struct and the match options. For each device setting a match option in the
- // DXUTMatchOptions struct specifies how the function makes decisions. For example, if
- // the caller wants a HAL device with a back buffer format of D3DFMT_A2B10G10R10 but the
- // HAL device on the system does not support D3DFMT_A2B10G10R10 however a REF device is
- // installed that does, then the function has a choice to either use REF or to change to
- // a back buffer format to compatible with the HAL device. The match options lets the
- // caller control how these choices are made.
- //
- // Each match option must be one of the following types:
- // DXUTMT_IGNORE_INPUT: Uses the closest valid value to a default
- // DXUTMT_PRESERVE_INPUT: Uses the input without change, but may cause no valid device to be found
- // DXUTMT_CLOSEST_TO_INPUT: Uses the closest valid value to the input
- //
- // If pMatchOptions is NULL then, all of the match options are assumed to be DXUTMT_IGNORE_INPUT.
- // The function returns failure if no valid device settings can be found otherwise
- // the function returns success and the valid device settings are written to pOut.
- //--------------------------------------------------------------------------------------
- HRESULT DXUTFindValidDeviceSettings( DXUTDeviceSettings* pOut, DXUTDeviceSettings* pIn,
- DXUTMatchOptions* pMatchOptions )
- {
- if( pOut == NULL )
- return DXUT_ERR_MSGBOX( L"DXUTFindValidDeviceSettings", E_INVALIDARG );
- CD3DEnumeration* pd3dEnum = DXUTPrepareEnumerationObject( false );
- IDirect3D9* pD3D = DXUTGetD3DObject();
- // Default to DXUTMT_IGNORE_INPUT for everything unless pMatchOptions isn't NULL
- DXUTMatchOptions defaultMatchOptions;
- if( NULL == pMatchOptions )
- {
- ZeroMemory( &defaultMatchOptions, sizeof(DXUTMatchOptions) );
- pMatchOptions = &defaultMatchOptions;
- }
- // Build an optimal device settings structure based upon the match
- // options. If the match option is set to ignore, then a optimal default value is used.
- // The default value may not exist on the system, but later this will be taken
- // into account.
- DXUTDeviceSettings optimalDeviceSettings;
- DXUTBuildOptimalDeviceSettings( &optimalDeviceSettings, pIn, pMatchOptions );
- // Find the best combination of:
- // Adapter Ordinal
- // Device Type
- // Adapter Format
- // Back Buffer Format
- // Windowed
- // given what's available on the system and the match options combined with the device settings input.
- // This combination of settings is encapsulated by the CD3DEnumDeviceSettingsCombo class.
- float fBestRanking = -1.0f;
- CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo = NULL;
- D3DDISPLAYMODE adapterDesktopDisplayMode;
- CGrowableArray<CD3DEnumAdapterInfo*>* pAdapterList = pd3dEnum->GetAdapterInfoList();
- for( int iAdapter=0; iAdapter<pAdapterList->GetSize(); iAdapter++ )
- {
- CD3DEnumAdapterInfo* pAdapterInfo = pAdapterList->GetAt(iAdapter);
- // Get the desktop display mode of adapter
- pD3D->GetAdapterDisplayMode( pAdapterInfo->AdapterOrdinal, &adapterDesktopDisplayMode );
- // Enum all the device types supported by this adapter to find the best device settings
- for( int iDeviceInfo=0; iDeviceInfo<pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ )
- {
- CD3DEnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt(iDeviceInfo);
- // Enum all the device settings combinations. A device settings combination is
- // a unique set of an adapter format, back buffer format, and IsWindowed.
- for( int iDeviceCombo=0; iDeviceCombo<pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )
- {
- CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt(iDeviceCombo);
- // If windowed mode the adapter format has to be the same as the desktop
- // display mode format so skip any that don't match
- if (pDeviceSettingsCombo->Windowed && (pDeviceSettingsCombo->AdapterFormat != adapterDesktopDisplayMode.Format))
- continue;
- // Skip any combo that doesn't meet the preserve match options
- if( false == DXUTDoesDeviceComboMatchPreserveOptions( pDeviceSettingsCombo, pIn, pMatchOptions ) )
- continue;
- // Get a ranking number that describes how closely this device combo matches the optimal combo
- float fCurRanking = DXUTRankDeviceCombo( pDeviceSettingsCombo, &optimalDeviceSettings, &adapterDesktopDisplayMode );
- // If this combo better matches the input device settings then save it
- if( fCurRanking > fBestRanking )
- {
- pBestDeviceSettingsCombo = pDeviceSettingsCombo;
- fBestRanking = fCurRanking;
- }
- }
- }
- }
- // If no best device combination was found then fail
- if( pBestDeviceSettingsCombo == NULL )
- return DXUTERR_NOCOMPATIBLEDEVICES;
- // Using the best device settings combo found, build valid device settings taking heed of
- // the match options and the input device settings
- DXUTDeviceSettings validDeviceSettings;
- DXUTBuildValidDeviceSettings( &validDeviceSettings, pBestDeviceSettingsCombo, pIn, pMatchOptions );
- *pOut = validDeviceSettings;
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- // Internal helper function to build a device settings structure based upon the match
- // options. If the match option is set to ignore, then a optimal default value is used.
- // The default value may not exist on the system, but later this will be taken
- // into account.
- //--------------------------------------------------------------------------------------
- void DXUTBuildOptimalDeviceSettings( DXUTDeviceSettings* pOptimalDeviceSettings,
- DXUTDeviceSettings* pDeviceSettingsIn,
- DXUTMatchOptions* pMatchOptions )
- {
- IDirect3D9* pD3D = DXUTGetD3DObject();
- D3DDISPLAYMODE adapterDesktopDisplayMode;
- ZeroMemory( pOptimalDeviceSettings, sizeof(DXUTDeviceSettings) );
- //---------------------
- // Adapter ordinal
- //---------------------
- if( pMatchOptions->eAdapterOrdinal == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->AdapterOrdinal = D3DADAPTER_DEFAULT;
- else
- pOptimalDeviceSettings->AdapterOrdinal = pDeviceSettingsIn->AdapterOrdinal;
- //---------------------
- // Device type
- //---------------------
- if( pMatchOptions->eDeviceType == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->DeviceType = D3DDEVTYPE_HAL;
- else
- pOptimalDeviceSettings->DeviceType = pDeviceSettingsIn->DeviceType;
- //---------------------
- // Windowed
- //---------------------
- if( pMatchOptions->eWindowed == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->pp.Windowed = TRUE;
- else
- pOptimalDeviceSettings->pp.Windowed = pDeviceSettingsIn->pp.Windowed;
- //---------------------
- // Adapter format
- //---------------------
- if( pMatchOptions->eAdapterFormat == DXUTMT_IGNORE_INPUT )
- {
- // If windowed, default to the desktop display mode
- // If fullscreen, default to the desktop display mode for quick mode change or
- // default to D3DFMT_X8R8G8B8 if the desktop display mode is < 32bit
- pD3D->GetAdapterDisplayMode( pOptimalDeviceSettings->AdapterOrdinal, &adapterDesktopDisplayMode );
- if( pOptimalDeviceSettings->pp.Windowed || DXUTColorChannelBits(adapterDesktopDisplayMode.Format) >= 8 )
- pOptimalDeviceSettings->AdapterFormat = adapterDesktopDisplayMode.Format;
- else
- pOptimalDeviceSettings->AdapterFormat = D3DFMT_X8R8G8B8;
- }
- else
- {
- pOptimalDeviceSettings->AdapterFormat = pDeviceSettingsIn->AdapterFormat;
- }
- //---------------------
- // Vertex processing
- //---------------------
- if( pMatchOptions->eVertexProcessing == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
- else
- pOptimalDeviceSettings->BehaviorFlags = pDeviceSettingsIn->BehaviorFlags;
- //---------------------
- // Resolution
- //---------------------
- if( pMatchOptions->eResolution == DXUTMT_IGNORE_INPUT )
- {
- // If windowed, default to 640x480
- // If fullscreen, default to the desktop res for quick mode change
- if( pOptimalDeviceSettings->pp.Windowed )
- {
- pOptimalDeviceSettings->pp.BackBufferWidth = 640;
- pOptimalDeviceSettings->pp.BackBufferHeight = 480;
- }
- else
- {
- pD3D->GetAdapterDisplayMode( pOptimalDeviceSettings->AdapterOrdinal, &adapterDesktopDisplayMode );
- pOptimalDeviceSettings->pp.BackBufferWidth = adapterDesktopDisplayMode.Width;
- pOptimalDeviceSettings->pp.BackBufferHeight = adapterDesktopDisplayMode.Height;
- }
- }
- else
- {
- pOptimalDeviceSettings->pp.BackBufferWidth = pDeviceSettingsIn->pp.BackBufferWidth;
- pOptimalDeviceSettings->pp.BackBufferHeight = pDeviceSettingsIn->pp.BackBufferHeight;
- }
- //---------------------
- // Back buffer format
- //---------------------
- if( pMatchOptions->eBackBufferFormat == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->pp.BackBufferFormat = pOptimalDeviceSettings->AdapterFormat; // Default to match the adapter format
- else
- pOptimalDeviceSettings->pp.BackBufferFormat = pDeviceSettingsIn->pp.BackBufferFormat;
- //---------------------
- // Back buffer count
- //---------------------
- if( pMatchOptions->eBackBufferCount == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->pp.BackBufferCount = 2; // Default to triple buffering for perf gain
- else
- pOptimalDeviceSettings->pp.BackBufferCount = pDeviceSettingsIn->pp.BackBufferCount;
- //---------------------
- // Multisample
- //---------------------
- if( pMatchOptions->eMultiSample == DXUTMT_IGNORE_INPUT )
- {
- // Default to no multisampling
- pOptimalDeviceSettings->pp.MultiSampleType = D3DMULTISAMPLE_NONE;
- pOptimalDeviceSettings->pp.MultiSampleQuality = 0;
- }
- else
- {
- pOptimalDeviceSettings->pp.MultiSampleType = pDeviceSettingsIn->pp.MultiSampleType;
- pOptimalDeviceSettings->pp.MultiSampleQuality = pDeviceSettingsIn->pp.MultiSampleQuality;
- }
- //---------------------
- // Swap effect
- //---------------------
- if( pMatchOptions->eSwapEffect == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- else
- pOptimalDeviceSettings->pp.SwapEffect = pDeviceSettingsIn->pp.SwapEffect;
- //---------------------
- // Depth stencil
- //---------------------
- if( pMatchOptions->eDepthFormat == DXUTMT_IGNORE_INPUT &&
- pMatchOptions->eStencilFormat == DXUTMT_IGNORE_INPUT )
- {
- UINT nBackBufferBits = DXUTColorChannelBits( pOptimalDeviceSettings->pp.BackBufferFormat );
- if( nBackBufferBits >= 8 )
- pOptimalDeviceSettings->pp.AutoDepthStencilFormat = D3DFMT_D32;
- else
- pOptimalDeviceSettings->pp.AutoDepthStencilFormat = D3DFMT_D16;
- }
- else
- {
- pOptimalDeviceSettings->pp.AutoDepthStencilFormat = pDeviceSettingsIn->pp.AutoDepthStencilFormat;
- }
- //---------------------
- // Present flags
- //---------------------
- if( pMatchOptions->ePresentFlags == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->pp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
- else
- pOptimalDeviceSettings->pp.Flags = pDeviceSettingsIn->pp.Flags;
- //---------------------
- // Refresh rate
- //---------------------
- if( pMatchOptions->eRefreshRate == DXUTMT_IGNORE_INPUT )
- pOptimalDeviceSettings->pp.FullScreen_RefreshRateInHz = 0;
- else
- pOptimalDeviceSettings->pp.FullScreen_RefreshRateInHz = pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz;
- //---------------------
- // Present interval
- //---------------------
- if( pMatchOptions->ePresentInterval == DXUTMT_IGNORE_INPUT )
- {
- // For windowed and fullscreen, default to D3DPRESENT_INTERVAL_DEFAULT
- // which will wait for the vertical retrace period to prevent tearing.
- // For benchmarking, use D3DPRESENT_INTERVAL_DEFAULT which will
- // will wait not for the vertical retrace period but may introduce tearing.
- pOptimalDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
- }
- else
- {
- pOptimalDeviceSettings->pp.PresentationInterval = pDeviceSettingsIn->pp.PresentationInterval;
- }
- }
- //--------------------------------------------------------------------------------------
- // Returns false for any CD3DEnumDeviceSettingsCombo that doesn't meet the preserve
- // match options against the input pDeviceSettingsIn.
- //--------------------------------------------------------------------------------------
- bool DXUTDoesDeviceComboMatchPreserveOptions( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo,
- DXUTDeviceSettings* pDeviceSettingsIn,
- DXUTMatchOptions* pMatchOptions )
- {
- //---------------------
- // Adapter ordinal
- //---------------------
- if( pMatchOptions->eAdapterOrdinal == DXUTMT_PRESERVE_INPUT &&
- (pDeviceSettingsCombo->AdapterOrdinal != pDeviceSettingsIn->AdapterOrdinal) )
- return false;
- //---------------------
- // Device type
- //---------------------
- if( pMatchOptions->eDeviceType == DXUTMT_PRESERVE_INPUT &&
- (pDeviceSettingsCombo->DeviceType != pDeviceSettingsIn->DeviceType) )
- return false;
- //---------------------
- // Windowed
- //---------------------
- if( pMatchOptions->eWindowed == DXUTMT_PRESERVE_INPUT &&
- (pDeviceSettingsCombo->Windowed != pDeviceSettingsIn->pp.Windowed) )
- return false;
- //---------------------
- // Adapter format
- //---------------------
- if( pMatchOptions->eAdapterFormat == DXUTMT_PRESERVE_INPUT &&
- (pDeviceSettingsCombo->AdapterFormat != pDeviceSettingsIn->AdapterFormat) )
- return false;
- //---------------------
- // Vertex processing
- //---------------------
- // If keep VP and input has HWVP, then skip if this combo doesn't have HWTL
- if( pMatchOptions->eVertexProcessing == DXUTMT_PRESERVE_INPUT &&
- ((pDeviceSettingsIn->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0) &&
- ((pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0) )
- return false;
- //---------------------
- // Resolution
- //---------------------
- // If keep resolution then check that width and height supported by this combo
- if( pMatchOptions->eResolution == DXUTMT_PRESERVE_INPUT )
- {
- bool bFound = false;
- for( int i=0; i< pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); i++ )
- {
- D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( i );
- if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
- continue; // Skip this display mode if it doesn't match the combo's adapter format
- if( displayMode.Width == pDeviceSettingsIn->pp.BackBufferWidth &&
- displayMode.Height == pDeviceSettingsIn->pp.BackBufferHeight )
- {
- bFound = true;
- break;
- }
- }
- // If the width and height are not supported by this combo, return false
- if( !bFound )
- return false;
- }
- //---------------------
- // Back buffer format
- //---------------------
- if( pMatchOptions->eBackBufferFormat == DXUTMT_PRESERVE_INPUT &&
- pDeviceSettingsCombo->BackBufferFormat != pDeviceSettingsIn->pp.BackBufferFormat )
- return false;
- //---------------------
- // Back buffer count
- //---------------------
- // No caps for the back buffer count
- //---------------------
- // Multisample
- //---------------------
- if( pMatchOptions->eMultiSample == DXUTMT_PRESERVE_INPUT )
- {
- bool bFound = false;
- for( int i=0; i<pDeviceSettingsCombo->multiSampleTypeList.GetSize(); i++ )
- {
- D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt(i);
- DWORD msQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt(i);
- if( msType == pDeviceSettingsIn->pp.MultiSampleType &&
- msQuality >= pDeviceSettingsIn->pp.MultiSampleQuality )
- {
- bFound = true;
- break;
- }
- }
- // If multisample type/quality not supported by this combo, then return false
- if( !bFound )
- return false;
- }
- //---------------------
- // Swap effect
- //---------------------
- // No caps for swap effects
- //---------------------
- // Depth stencil
- //---------------------
- // If keep depth stencil format then check that the depth stencil format is supported by this combo
- if( pMatchOptions->eDepthFormat == DXUTMT_PRESERVE_INPUT &&
- pMatchOptions->eStencilFormat == DXUTMT_PRESERVE_INPUT )
- {
- if( pDeviceSettingsIn->pp.AutoDepthStencilFormat != D3DFMT_UNKNOWN &&
- !pDeviceSettingsCombo->depthStencilFormatList.Contains( pDeviceSettingsIn->pp.AutoDepthStencilFormat ) )
- return false;
- }
- // If keep depth format then check that the depth format is supported by this combo
- if( pMatchOptions->eDepthFormat == DXUTMT_PRESERVE_INPUT &&
- pDeviceSettingsIn->pp.AutoDepthStencilFormat != D3DFMT_UNKNOWN )
- {
- bool bFound = false;
- UINT dwDepthBits = DXUTDepthBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
- for( int i=0; i<pDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
- {
- D3DFORMAT depthStencilFmt = pDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
- UINT dwCurDepthBits = DXUTDepthBits( depthStencilFmt );
- if( dwCurDepthBits - dwDepthBits == 0)
- bFound = true;
- }
- if( !bFound )
- return false;
- }
- // If keep depth format then check that the depth format is supported by this combo
- if( pMatchOptions->eStencilFormat == DXUTMT_PRESERVE_INPUT &&
- pDeviceSettingsIn->pp.AutoDepthStencilFormat != D3DFMT_UNKNOWN )
- {
- bool bFound = false;
- UINT dwStencilBits = DXUTStencilBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
- for( int i=0; i<pDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
- {
- D3DFORMAT depthStencilFmt = pDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
- UINT dwCurStencilBits = DXUTStencilBits( depthStencilFmt );
- if( dwCurStencilBits - dwStencilBits == 0)
- bFound = true;
- }
- if( !bFound )
- return false;
- }
- //---------------------
- // Present flags
- //---------------------
- // No caps for the present flags
- //---------------------
- // Refresh rate
- //---------------------
- // If keep refresh rate then check that the resolution is supported by this combo
- if( pMatchOptions->eRefreshRate == DXUTMT_PRESERVE_INPUT )
- {
- bool bFound = false;
- for( int i=0; i<pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); i++ )
- {
- D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( i );
- if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
- continue;
- if( displayMode.RefreshRate == pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz )
- {
- bFound = true;
- break;
- }
- }
- // If refresh rate not supported by this combo, then return false
- if( !bFound )
- return false;
- }
- //---------------------
- // Present interval
- //---------------------
- // If keep present interval then check that the present interval is supported by this combo
- if( pMatchOptions->ePresentInterval == DXUTMT_PRESERVE_INPUT &&
- !pDeviceSettingsCombo->presentIntervalList.Contains( pDeviceSettingsIn->pp.PresentationInterval ) )
- return false;
- return true;
- }
- //--------------------------------------------------------------------------------------
- // Returns a ranking number that describes how closely this device
- // combo matches the optimal combo based on the match options and the optimal device settings
- //--------------------------------------------------------------------------------------
- float DXUTRankDeviceCombo( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo,
- DXUTDeviceSettings* pOptimalDeviceSettings,
- D3DDISPLAYMODE* pAdapterDesktopDisplayMode )
- {
- float fCurRanking = 0.0f;
- // Arbitrary weights. Gives preference to the ordinal, device type, and windowed
- const float fAdapterOrdinalWeight = 1000.0f;
- const float fDeviceTypeWeight = 100.0f;
- const float fWindowWeight = 10.0f;
- const float fAdapterFormatWeight = 1.0f;
- const float fVertexProcessingWeight = 1.0f;
- const float fResolutionWeight = 1.0f;
- const float fBackBufferFormatWeight = 1.0f;
- const float fMultiSampleWeight = 1.0f;
- const float fDepthStencilWeight = 1.0f;
- const float fRefreshRateWeight = 1.0f;
- const float fPresentIntervalWeight = 1.0f;
- //---------------------
- // Adapter ordinal
- //---------------------
- if( pDeviceSettingsCombo->AdapterOrdinal == pOptimalDeviceSettings->AdapterOrdinal )
- fCurRanking += fAdapterOrdinalWeight;
- //---------------------
- // Device type
- //---------------------
- if( pDeviceSettingsCombo->DeviceType == pOptimalDeviceSettings->DeviceType )
- fCurRanking += fDeviceTypeWeight;
- // Slightly prefer HAL
- if( pDeviceSettingsCombo->DeviceType == D3DDEVTYPE_HAL )
- fCurRanking += 0.1f;
- //---------------------
- // Windowed
- //---------------------
- if( pDeviceSettingsCombo->Windowed == pOptimalDeviceSettings->pp.Windowed )
- fCurRanking += fWindowWeight;
- //---------------------
- // Adapter format
- //---------------------
- if( pDeviceSettingsCombo->AdapterFormat == pOptimalDeviceSettings->AdapterFormat )
- {
- fCurRanking += fAdapterFormatWeight;
- }
- else
- {
- int nBitDepthDelta = abs( (long) DXUTColorChannelBits(pDeviceSettingsCombo->AdapterFormat) -
- (long) DXUTColorChannelBits(pOptimalDeviceSettings->AdapterFormat) );
- float fScale = __max(0.9f - (float)nBitDepthDelta*0.2f, 0.0f);
- fCurRanking += fScale * fAdapterFormatWeight;
- }
- if( !pDeviceSettingsCombo->Windowed )
- {
- // Slightly prefer when it matches the desktop format or is D3DFMT_X8R8G8B8
- bool bAdapterOptimalMatch;
- if( DXUTColorChannelBits(pAdapterDesktopDisplayMode->Format) >= 8 )
- bAdapterOptimalMatch = (pDeviceSettingsCombo->AdapterFormat == pAdapterDesktopDisplayMode->Format);
- else
- bAdapterOptimalMatch = (pDeviceSettingsCombo->AdapterFormat == D3DFMT_X8R8G8B8);
- if( bAdapterOptimalMatch )
- fCurRanking += 0.1f;
- }
- //---------------------
- // Vertex processing
- //---------------------
- if( (pOptimalDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 ||
- (pOptimalDeviceSettings->BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) != 0 )
- {
- if( (pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0 )
- fCurRanking += fVertexProcessingWeight;
- }
- // Slightly prefer HW T&L
- if( (pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0 )
- fCurRanking += 0.1f;
- //---------------------
- // Resolution
- //---------------------
- bool bResolutionFound = false;
- for( int idm = 0; idm < pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); idm++ )
- {
- D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( idm );
- if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
- continue;
- if( displayMode.Width == pOptimalDeviceSettings->pp.BackBufferWidth &&
- displayMode.Height == pOptimalDeviceSettings->pp.BackBufferHeight )
- bResolutionFound = true;
- }
- if( bResolutionFound )
- fCurRanking += fResolutionWeight;
- //---------------------
- // Back buffer format
- //---------------------
- if( pDeviceSettingsCombo->BackBufferFormat == pOptimalDeviceSettings->pp.BackBufferFormat )
- {
- fCurRanking += fBackBufferFormatWeight;
- }
- else
- {
- int nBitDepthDelta = abs( (long) DXUTColorChannelBits(pDeviceSettingsCombo->BackBufferFormat) -
- (long) DXUTColorChannelBits(pOptimalDeviceSettings->pp.BackBufferFormat) );
- float fScale = __max(0.9f - (float)nBitDepthDelta*0.2f, 0.0f);
- fCurRanking += fScale * fBackBufferFormatWeight;
- }
- // Check if this back buffer format is the same as
- // the adapter format since this is preferred.
- bool bAdapterMatchesBB = (pDeviceSettingsCombo->BackBufferFormat == pDeviceSettingsCombo->AdapterFormat);
- if( bAdapterMatchesBB )
- fCurRanking += 0.1f;
- //---------------------
- // Back buffer count
- //---------------------
- // No caps for the back buffer count
- //---------------------
- // Multisample
- //---------------------
- bool bMultiSampleFound = false;
- for( int i=0; i<pDeviceSettingsCombo->multiSampleTypeList.GetSize(); i++ )
- {
- D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt(i);
- DWORD msQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt(i);
- if( msType == pOptimalDeviceSettings->pp.MultiSampleType &&
- msQuality >= pOptimalDeviceSettings->pp.MultiSampleQuality )
- {
- bMultiSampleFound = true;
- break;
- }
- }
- if( bMultiSampleFound )
- fCurRanking += fMultiSampleWeight;
- //---------------------
- // Swap effect
- //---------------------
- // No caps for swap effects
- //---------------------
- // Depth stencil
- //---------------------
- if( pDeviceSettingsCombo->depthStencilFormatList.Contains( pOptimalDeviceSettings->pp.AutoDepthStencilFormat ) )
- fCurRanking += fDepthStencilWeight;
- //---------------------
- // Present flags
- //---------------------
- // No caps for the present flags
- //---------------------
- // Refresh rate
- //---------------------
- bool bRefreshFound = false;
- for( int idm = 0; idm < pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); idm++ )
- {
- D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( idm );
- if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
- continue;
- if( displayMode.RefreshRate == pOptimalDeviceSettings->pp.FullScreen_RefreshRateInHz )
- bRefreshFound = true;
- }
- if( bRefreshFound )
- fCurRanking += fRefreshRateWeight;
- //---------------------
- // Present interval
- //---------------------
- // If keep present interval then check that the present interval is supported by this combo
- if( pDeviceSettingsCombo->presentIntervalList.Contains( pOptimalDeviceSettings->pp.PresentationInterval ) )
- fCurRanking += fPresentIntervalWeight;
- return fCurRanking;
- }
- //--------------------------------------------------------------------------------------
- // Builds valid device settings using the match options, the input device settings, and the
- // best device settings combo found.
- //--------------------------------------------------------------------------------------
- void DXUTBuildValidDeviceSettings( DXUTDeviceSettings* pValidDeviceSettings,
- CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo,
- DXUTDeviceSettings* pDeviceSettingsIn,
- DXUTMatchOptions* pMatchOptions )
- {
- IDirect3D9* pD3D = DXUTGetD3DObject();
- D3DDISPLAYMODE adapterDesktopDisplayMode;
- pD3D->GetAdapterDisplayMode( pBestDeviceSettingsCombo->AdapterOrdinal, &adapterDesktopDisplayMode );
- // For each setting pick the best, taking into account the match options and
- // what's supported by the device
- //---------------------
- // Adapter Ordinal
- //---------------------
- // Just using pBestDeviceSettingsCombo->AdapterOrdinal
- //---------------------
- // Device Type
- //---------------------
- // Just using pBestDeviceSettingsCombo->DeviceType
- //---------------------
- // Windowed
- //---------------------
- // Just using pBestDeviceSettingsCombo->Windowed
- //---------------------
- // Adapter Format
- //---------------------
- // Just using pBestDeviceSettingsCombo->AdapterFormat
- //---------------------
- // Vertex processing
- //---------------------
- DWORD dwBestBehaviorFlags = 0;
- if( pMatchOptions->eVertexProcessing == DXUTMT_PRESERVE_INPUT )
- {
- dwBestBehaviorFlags = pDeviceSettingsIn->BehaviorFlags;
- }
- else if( pMatchOptions->eVertexProcessing == DXUTMT_IGNORE_INPUT )
- {
- // The framework defaults to HWVP if available otherwise use SWVP
- if ((pBestDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
- dwBestBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
- else
- dwBestBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- }
- else // if( pMatchOptions->eVertexProcessing == DXUTMT_CLOSEST_TO_INPUT )
- {
- // Default to input, and fallback to SWVP if HWVP not available
- dwBestBehaviorFlags = pDeviceSettingsIn->BehaviorFlags;
- if ((pBestDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 &&
- ( (dwBestBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 ||
- (dwBestBehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) != 0) )
- {
- dwBestBehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
- dwBestBehaviorFlags &= ~D3DCREATE_MIXED_VERTEXPROCESSING;
- dwBestBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- }
- // One of these must be selected
- if( (dwBestBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) == 0 &&
- (dwBestBehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) == 0 &&
- (dwBestBehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == 0 )
- {
- if ((pBestDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
- dwBestBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
- else
- dwBestBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- }
- }
- //---------------------
- // Resolution
- //---------------------
- D3DDISPLAYMODE bestDisplayMode;
- if( pMatchOptions->eResolution == DXUTMT_PRESERVE_INPUT )
- {
- bestDisplayMode.Width = pDeviceSettingsIn->pp.BackBufferWidth;
- bestDisplayMode.Height = pDeviceSettingsIn->pp.BackBufferHeight;
- }
- else
- {
- D3DDISPLAYMODE displayModeIn;
- if( pMatchOptions->eResolution == DXUTMT_CLOSEST_TO_INPUT &&
- pDeviceSettingsIn )
- {
- displayModeIn.Width = pDeviceSettingsIn->pp.BackBufferWidth;
- displayModeIn.Height = pDeviceSettingsIn->pp.BackBufferHeight;
- }
- else // if( pMatchOptions->eResolution == DXUTMT_IGNORE_INPUT )
- {
- if( pBestDeviceSettingsCombo->Windowed )
- {
- // The framework defaults to 640x480 for windowed
- displayModeIn.Width = 640;
- displayModeIn.Height = 480;
- }
- else
- {
- // The framework defaults to desktop resolution for fullscreen to try to avoid slow mode change
- displayModeIn.Width = adapterDesktopDisplayMode.Width;
- displayModeIn.Height = adapterDesktopDisplayMode.Height;
- }
- }
- // Call a helper function to find the closest valid display mode to the optimal
- DXUTFindValidResolution( pBestDeviceSettingsCombo, displayModeIn, &bestDisplayMode );
- }
- //---------------------
- // Back Buffer Format
- //---------------------
- // Just using pBestDeviceSettingsCombo->BackBufferFormat
- //---------------------
- // Back buffer count
- //---------------------
- UINT bestBackBufferCount;
- if( pMatchOptions->eBackBufferCount == DXUTMT_PRESERVE_INPUT )
- {
- bestBackBufferCount = pDeviceSettingsIn->pp.BackBufferCount;
- }
- else if( pMatchOptions->eBackBufferCount == DXUTMT_IGNORE_INPUT )
- {
- // The framework defaults to triple buffering
- bestBackBufferCount = 2;
- }
- else // if( pMatchOptions->eBackBufferCount == DXUTMT_CLOSEST_TO_INPUT )
- {
- bestBackBufferCount = pDeviceSettingsIn->pp.BackBufferCount;
- if( bestBackBufferCount > 3 )
- bestBackBufferCount = 3;
- if( bestBackBufferCount < 1 )
- bestBackBufferCount = 1;
- }
- //---------------------
- // Multisample
- //---------------------
- D3DMULTISAMPLE_TYPE bestMultiSampleType;
- DWORD bestMultiSampleQuality;
- if( pDeviceSettingsIn && pDeviceSettingsIn->pp.SwapEffect != D3DSWAPEFFECT_DISCARD )
- {
- // Swap effect is not set to discard so multisampling has to off
- bestMultiSampleType = D3DMULTISAMPLE_NONE;
- bestMultiSampleQuality = 0;
- }
- else
- {
- if( pMatchOptions->eMultiSample == DXUTMT_PRESERVE_INPUT )
- {
- bestMultiSampleType = pDeviceSettingsIn->pp.MultiSampleType;
- bestMultiSampleQuality = pDeviceSettingsIn->pp.MultiSampleQuality;
- }
- else if( pMatchOptions->eMultiSample == DXUTMT_IGNORE_INPUT )
- {
- // Default to no multisampling (always supported)
- bestMultiSampleType = D3DMULTISAMPLE_NONE;
- bestMultiSampleQuality = 0;
- }
- else if( pMatchOptions->eMultiSample == DXUTMT_CLOSEST_TO_INPUT )
- {
- // Default to no multisampling (always supported)
- bestMultiSampleType = D3DMULTISAMPLE_NONE;
- bestMultiSampleQuality = 0;
- for( int i=0; i < pBestDeviceSettingsCombo->multiSampleTypeList.GetSize(); i++ )
- {
- D3DMULTISAMPLE_TYPE type = pBestDeviceSettingsCombo->multiSampleTypeList.GetAt(i);
- DWORD qualityLevels = pBestDeviceSettingsCombo->multiSampleQualityList.GetAt(i);
- // Check whether supported type is closer to the input than our current best
- if( abs(type - pDeviceSettingsIn->pp.MultiSampleType) < abs(bestMultiSampleType - pDeviceSettingsIn->pp.MultiSampleType) )
- {
- bestMultiSampleType = type;
- bestMultiSampleQuality = __min( qualityLevels-1, pDeviceSettingsIn->pp.MultiSampleQuality );
- }
- }
- }
- else
- {
- // Error case
- bestMultiSampleType = D3DMULTISAMPLE_NONE;
- bestMultiSampleQuality = 0;
- }
- }
- //---------------------
- // Swap effect
- //---------------------
- D3DSWAPEFFECT bestSwapEffect;
- if( pMatchOptions->eSwapEffect == DXUTMT_PRESERVE_INPUT )
- {
- bestSwapEffect = pDeviceSettingsIn->pp.SwapEffect;
- }
- else if( pMatchOptions->eSwapEffect == DXUTMT_IGNORE_INPUT )
- {
- bestSwapEffect = D3DSWAPEFFECT_DISCARD;
- }
- else // if( pMatchOptions->eSwapEffect == DXUTMT_CLOSEST_TO_INPUT )
- {
- bestSwapEffect = pDeviceSettingsIn->pp.SwapEffect;
- // Swap effect has to be one of these 3
- if( bestSwapEffect != D3DSWAPEFFECT_DISCARD &&
- bestSwapEffect != D3DSWAPEFFECT_FLIP &&
- bestSwapEffect != D3DSWAPEFFECT_COPY )
- {
- bestSwapEffect = D3DSWAPEFFECT_DISCARD;
- }
- }
- //---------------------
- // Depth stencil
- //---------------------
- D3DFORMAT bestDepthStencilFormat;
- BOOL bestEnableAutoDepthStencil;
- CGrowableArray< int > depthStencilRanking;
- depthStencilRanking.SetSize( pBestDeviceSettingsCombo->depthStencilFormatList.GetSize() );
- UINT dwBackBufferBitDepth = DXUTColorChannelBits( pBestDeviceSettingsCombo->BackBufferFormat );
- UINT dwInputDepthBitDepth = 0;
- if( pDeviceSettingsIn )
- dwInputDepthBitDepth = DXUTDepthBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
- for( int i=0; i<pBestDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
- {
- D3DFORMAT curDepthStencilFmt = pBestDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
- DWORD dwCurDepthBitDepth = DXUTDepthBits( curDepthStencilFmt );
- int nRanking;
- if( pMatchOptions->eDepthFormat == DXUTMT_PRESERVE_INPUT )
- {
- // Need to match bit depth of input
- if(dwCurDepthBitDepth == dwInputDepthBitDepth)
- nRanking = 0;
- else
- nRanking = 10000;
- }
- else if( pMatchOptions->eDepthFormat == DXUTMT_IGNORE_INPUT )
- {
- // Prefer match of backbuffer bit depth
- nRanking = abs((int)dwCurDepthBitDepth - (int)dwBackBufferBitDepth*4);
- }
- else // if( pMatchOptions->eDepthFormat == DXUTMT_CLOSEST_TO_INPUT )
- {
- // Prefer match of input depth format bit depth
- nRanking = abs((int)dwCurDepthBitDepth - (int)dwInputDepthBitDepth);
- }
- depthStencilRanking.Add( nRanking );
- }
- UINT dwInputStencilBitDepth = 0;
- if( pDeviceSettingsIn )
- dwInputStencilBitDepth = DXUTStencilBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
- for( int i=0; i<pBestDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
- {
- D3DFORMAT curDepthStencilFmt = pBestDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
- int nRanking = depthStencilRanking.GetAt(i);
- DWORD dwCurStencilBitDepth = DXUTStencilBits( curDepthStencilFmt );
- if( pMatchOptions->eStencilFormat == DXUTMT_PRESERVE_INPUT )
- {
- // Need to match bit depth of input
- if(dwCurStencilBitDepth == dwInputStencilBitDepth)
- nRanking += 0;
- else
- nRanking += 10000;
- }
- else if( pMatchOptions->eStencilFormat == DXUTMT_IGNORE_INPUT )
- {
- // Prefer 0 stencil bit depth
- nRanking += dwCurStencilBitDepth;
- }
- else // if( pMatchOptions->eStencilFormat == DXUTMT_CLOSEST_TO_INPUT )
- {
- // Prefer match of input stencil format bit depth
- nRanking += abs((int)dwCurStencilBitDepth - (int)dwInputStencilBitDepth);
- }
- depthStencilRanking.SetAt( i, nRanking );
- }
- int nBestRanking = 100000;
- int nBestIndex = -1;
- for( int i=0; i<pBestDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
- {
- int nRanking = depthStencilRanking.GetAt(i);
- if( nRanking < nBestRanking )
- {
- nBestRanking = nRanking;
- nBestIndex = i;
- }
- }
- if( nBestIndex >= 0 )
- {
- bestDepthStencilFormat = pBestDeviceSettingsCombo->depthStencilFormatList.GetAt(nBestIndex);
- bestEnableAutoDepthStencil = true;
- }
- else
- {
- bestDepthStencilFormat = D3DFMT_UNKNOWN;
- bestEnableAutoDepthStencil = false;
- }
- //---------------------
- // Present flags
- //---------------------
- DWORD dwBestFlags;
- if( pMatchOptions->ePresentFlags == DXUTMT_PRESERVE_INPUT )
- {
- dwBestFlags = pDeviceSettingsIn->pp.Flags;
- }
- else if( pMatchOptions->ePresentFlags == DXUTMT_IGNORE_INPUT )
- {
- dwBestFlags = 0;
- if( bestEnableAutoDepthStencil )
- dwBestFlags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
- }
- else // if( pMatchOptions->ePresentFlags == DXUTMT_CLOSEST_TO_INPUT )
- {
- dwBestFlags = pDeviceSettingsIn->pp.Flags;
- if( bestEnableAutoDepthStencil )
- dwBestFlags |= D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
- }
- //---------------------
- // Refresh rate
- //---------------------
- if( pBestDeviceSettingsCombo->Windowed )
- {
- // Must be 0 for windowed
- bestDisplayMode.RefreshRate = 0;
- }
- else
- {
- if( pMatchOptions->eRefreshRate == DXUTMT_PRESERVE_INPUT )
- {
- bestDisplayMode.RefreshRate = pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz;
- }
- else
- {
- UINT refreshRateMatch;
- if( pMatchOptions->eRefreshRate == DXUTMT_CLOSEST_TO_INPUT )
- {
- refreshRateMatch = pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz;
- }
- else // if( pMatchOptions->eRefreshRate == DXUTMT_IGNORE_INPUT )
- {
- refreshRateMatch = adapterDesktopDisplayMode.RefreshRate;
- }
- bestDisplayMode.RefreshRate = 0;
- if( refreshRateMatch != 0 )
- {
- int nBestRefreshRanking = 100000;
- CGrowableArray<D3DDISPLAYMODE>* pDisplayModeList = &pBestDeviceSettingsCombo->pAdapterInfo->displayModeList;
- for( int iDisplayMode=0; iDisplayMode<pDisplayModeList->GetSize(); iDisplayMode++ )
- {
- D3DDISPLAYMODE displayMode = pDisplayModeList->GetAt(iDisplayMode);
- if( displayMode.Format != pBestDeviceSettingsCombo->AdapterFormat ||
- displayMode.Height != bestDisplayMode.Height ||
- displayMode.Width != bestDisplayMode.Width )
- continue; // Skip display modes that don't match
- // Find the delta between the current refresh rate and the optimal refresh rate
- int nCurRanking = abs((int)displayMode.RefreshRate - (int)refreshRateMatch);
- if( nCurRanking < nBestRefreshRanking )
- {
- bestDisplayMode.RefreshRate = displayMode.RefreshRate;
- nBestRefreshRanking = nCurRanking;
- // Stop if perfect match found
- if( nBestRefreshRanking == 0 )
- break;
- }
- }
- }
- }
- }
- //---------------------
- // Present interval
- //---------------------
- UINT bestPresentInterval;
- if( pMatchOptions->ePresentInterval == DXUTMT_PRESERVE_INPUT )
- {
- bestPresentInterval = pDeviceSettingsIn->pp.PresentationInterval;
- }
- else if( pMatchOptions->ePresentInterval == DXUTMT_IGNORE_INPUT )
- {
- // For windowed and fullscreen, default to D3DPRESENT_INTERVAL_DEFAULT
- // which will wait for the vertical retrace period to prevent tearing.
- // For benchmarking, use D3DPRESENT_INTERVAL_DEFAULT which will
- // will wait not for the vertical retrace period but may introduce tearing.
- bestPresentInterval = D3DPRESENT_INTERVAL_DEFAULT;
- }
- else // if( pMatchOptions->ePresentInterval == DXUTMT_CLOSEST_TO_INPUT )
- {
- if( pBestDeviceSettingsCombo->presentIntervalList.Contains( pDeviceSettingsIn->pp.PresentationInterval ) )
- {
- bestPresentInterval = pDeviceSettingsIn->pp.PresentationInterval;
- }
- else
- {
- bestPresentInterval = D3DPRESENT_INTERVAL_DEFAULT;
- }
- }
- // Fill the device settings struct
- ZeroMemory( pValidDeviceSettings, sizeof(DXUTDeviceSettings) );
- pValidDeviceSettings->AdapterOrdinal = pBestDeviceSettingsCombo->AdapterOrdinal;
- pValidDeviceSettings->DeviceType = pBestDeviceSettingsCombo->DeviceType;
- pValidDeviceSettings->AdapterFormat = pBestDeviceSettingsCombo->AdapterFormat;
- pValidDeviceSettings->BehaviorFlags = dwBestBehaviorFlags;
- pValidDeviceSettings->pp.BackBufferWidth = bestDisplayMode.Width;
- pValidDeviceSettings->pp.BackBufferHeight = bestDisplayMode.Height;
- pValidDeviceSettings->pp.BackBufferFormat = pBestDeviceSettingsCombo->BackBufferFormat;
- pValidDeviceSettings->pp.BackBufferCount = bestBackBufferCount;
- pValidDeviceSettings->pp.MultiSampleType = bestMultiSampleType;
- pValidDeviceSettings->pp.MultiSampleQuality = bestMultiSampleQuality;
- pValidDeviceSettings->pp.SwapEffect = bestSwapEffect;
- pValidDeviceSettings->pp.hDeviceWindow = pBestDeviceSettingsCombo->Windowed ? DXUTGetHWNDDeviceWindowed() : DXUTGetHWNDDeviceFullScreen();
- pValidDeviceSettings->pp.Windowed = pBestDeviceSettingsCombo->Windowed;
- pValidDeviceSettings->pp.EnableAutoDepthStencil = bestEnableAutoDepthStencil;
- pValidDeviceSettings->pp.AutoDepthStencilFormat = bestDepthStencilFormat;
- pValidDeviceSettings->pp.Flags = dwBestFlags;
- pValidDeviceSettings->pp.FullScreen_RefreshRateInHz = bestDisplayMode.RefreshRate;
- pValidDeviceSettings->pp.PresentationInterval = bestPresentInterval;
- }
- //--------------------------------------------------------------------------------------
- // Internal helper function to find the closest allowed display mode to the optimal
- //--------------------------------------------------------------------------------------
- HRESULT DXUTFindValidResolution( CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo,
- D3DDISPLAYMODE displayModeIn, D3DDISPLAYMODE* pBestDisplayMode )
- {
- D3DDISPLAYMODE bestDisplayMode;
- ZeroMemory( &bestDisplayMode, sizeof(D3DDISPLAYMODE) );
- if( pBestDeviceSettingsCombo->Windowed )
- {
- // In windowed mode, all resolutions are valid but restritions still apply
- // on the size of the window. See DXUTChangeDevice() for details
- *pBestDisplayMode = displayModeIn;
- }
- else
- {
- int nBestRanking = 100000;
- int nCurRanking;
- CGrowableArray<D3DDISPLAYMODE>* pDisplayModeList = &pBestDeviceSettingsCombo->pAdapterInfo->displayModeList;
- for( int iDisplayMode=0; iDisplayMode<pDisplayModeList->GetSize(); iDisplayMode++ )
- {
- D3DDISPLAYMODE displayMode = pDisplayModeList->GetAt(iDisplayMode);
- // Skip display modes that don't match the combo's adapter format
- if( displayMode.Format != pBestDeviceSettingsCombo->AdapterFormat )
- continue;
- // Find the delta between the current width/height and the optimal width/height
- nCurRanking = abs((int)displayMode.Width - (int)displayModeIn.Width) +
- abs((int)displayMode.Height- (int)displayModeIn.Height);
- if( nCurRanking < nBestRanking )
- {
- bestDisplayMode = displayMode;
- nBestRanking = nCurRanking;
- // Stop if perfect match found
- if( nBestRanking == 0 )
- break;
- }
- }
- if( bestDisplayMode.Width == 0 )
- {
- *pBestDisplayMode = displayModeIn;
- return E_FAIL; // No valid display modes found
- }
- *pBestDisplayMode = bestDisplayMode;
- }