1 | //--------------------------------------------------------------------------------------
|
---|
2 | // File: DXUT.cpp
|
---|
3 | //
|
---|
4 | // Copyright (c) Microsoft Corporation. All rights reserved.
|
---|
5 | //--------------------------------------------------------------------------------------
|
---|
6 | #include "dxstdafx.h"
|
---|
7 | #define DXUT_MIN_WINDOW_SIZE_X 200
|
---|
8 | #define DXUT_MIN_WINDOW_SIZE_Y 200
|
---|
9 | #undef min // use __min instead inside this source file
|
---|
10 | #undef max // use __max instead inside this source file
|
---|
11 |
|
---|
12 | //--------------------------------------------------------------------------------------
|
---|
13 | // Thread safety
|
---|
14 | //--------------------------------------------------------------------------------------
|
---|
15 | CRITICAL_SECTION g_cs;
|
---|
16 | bool g_bThreadSafe = true;
|
---|
17 |
|
---|
18 |
|
---|
19 | //--------------------------------------------------------------------------------------
|
---|
20 | // Automatically enters & leaves the CS upon object creation/deletion
|
---|
21 | //--------------------------------------------------------------------------------------
|
---|
22 | class DXUTLock
|
---|
23 | {
|
---|
24 | public:
|
---|
25 | inline DXUTLock() { if( g_bThreadSafe ) EnterCriticalSection( &g_cs ); }
|
---|
26 | inline ~DXUTLock() { if( g_bThreadSafe ) LeaveCriticalSection( &g_cs ); }
|
---|
27 | };
|
---|
28 |
|
---|
29 |
|
---|
30 |
|
---|
31 | //--------------------------------------------------------------------------------------
|
---|
32 | // Helper macros to build member functions that access member variables with thread safety
|
---|
33 | //--------------------------------------------------------------------------------------
|
---|
34 | #define SET_ACCESSOR( x, y ) inline void Set##y( x t ) { DXUTLock l; m_state.m_##y = t; };
|
---|
35 | #define GET_ACCESSOR( x, y ) inline x Get##y() { DXUTLock l; return m_state.m_##y; };
|
---|
36 | #define GET_SET_ACCESSOR( x, y ) SET_ACCESSOR( x, y ) GET_ACCESSOR( x, y )
|
---|
37 |
|
---|
38 | #define SETP_ACCESSOR( x, y ) inline void Set##y( x* t ) { DXUTLock l; m_state.m_##y = *t; };
|
---|
39 | #define GETP_ACCESSOR( x, y ) inline x* Get##y() { DXUTLock l; return &m_state.m_##y; };
|
---|
40 | #define GETP_SETP_ACCESSOR( x, y ) SETP_ACCESSOR( x, y ) GETP_ACCESSOR( x, y )
|
---|
41 |
|
---|
42 |
|
---|
43 | //--------------------------------------------------------------------------------------
|
---|
44 | // Stores timer callback info
|
---|
45 | //--------------------------------------------------------------------------------------
|
---|
46 | struct DXUT_TIMER
|
---|
47 | {
|
---|
48 | LPDXUTCALLBACKTIMER pCallbackTimer;
|
---|
49 | void* pCallbackUserContext;
|
---|
50 | float fTimeoutInSecs;
|
---|
51 | float fCountdown;
|
---|
52 | bool bEnabled;
|
---|
53 | UINT nID;
|
---|
54 | };
|
---|
55 |
|
---|
56 |
|
---|
57 | //--------------------------------------------------------------------------------------
|
---|
58 | // Stores DXUT state and data access is done with thread safety (if g_bThreadSafe==true)
|
---|
59 | //--------------------------------------------------------------------------------------
|
---|
60 | class DXUTState
|
---|
61 | {
|
---|
62 | protected:
|
---|
63 | struct STATE
|
---|
64 | {
|
---|
65 | IDirect3D9* m_D3D; // the main D3D object
|
---|
66 |
|
---|
67 | IDirect3DDevice9* m_D3DDevice; // the D3D rendering device
|
---|
68 | CD3DEnumeration* m_D3DEnumeration; // CD3DEnumeration object
|
---|
69 |
|
---|
70 | DXUTDeviceSettings* m_CurrentDeviceSettings; // current device settings
|
---|
71 | D3DSURFACE_DESC m_BackBufferSurfaceDesc; // back buffer surface description
|
---|
72 | D3DCAPS9 m_Caps; // D3D caps for current device
|
---|
73 |
|
---|
74 | HWND m_HWNDFocus; // the main app focus window
|
---|
75 | HWND m_HWNDDeviceFullScreen; // the main app device window in fullscreen mode
|
---|
76 | HWND m_HWNDDeviceWindowed; // the main app device window in windowed mode
|
---|
77 | HMONITOR m_AdapterMonitor; // the monitor of the adapter
|
---|
78 | HMENU m_Menu; // handle to menu
|
---|
79 |
|
---|
80 | 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
|
---|
81 | 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
|
---|
82 | 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
|
---|
83 | 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
|
---|
84 | DWORD m_WindowedStyleAtModeChange; // window style
|
---|
85 | WINDOWPLACEMENT m_WindowedPlacement; // record of windowed HWND position/show state/etc
|
---|
86 | bool m_TopmostWhileWindowed; // if true, the windowed HWND is topmost
|
---|
87 | bool m_Minimized; // if true, the HWND is minimized
|
---|
88 | bool m_Maximized; // if true, the HWND is maximized
|
---|
89 | bool m_MinimizedWhileFullscreen; // if true, the HWND is minimized due to a focus switch away when fullscreen mode
|
---|
90 | bool m_IgnoreSizeChange; // if true, DXUT won't reset the device upon HWND size change
|
---|
91 |
|
---|
92 | double m_Time; // current time in seconds
|
---|
93 | double m_AbsoluteTime; // absolute time in seconds
|
---|
94 | float m_ElapsedTime; // time elapsed since last frame
|
---|
95 |
|
---|
96 | HINSTANCE m_HInstance; // handle to the app instance
|
---|
97 | double m_LastStatsUpdateTime; // last time the stats were updated
|
---|
98 | DWORD m_LastStatsUpdateFrames; // frames count since last time the stats were updated
|
---|
99 | float m_FPS; // frames per second
|
---|
100 | int m_CurrentFrameNumber; // the current frame number
|
---|
101 | HHOOK m_KeyboardHook; // handle to keyboard hook
|
---|
102 | bool m_AllowShortcutKeysWhenFullscreen; // if true, when fullscreen enable shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut)
|
---|
103 | bool m_AllowShortcutKeysWhenWindowed; // if true, when windowed enable shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut)
|
---|
104 | bool m_AllowShortcutKeys; // if true, then shortcut keys are currently disabled (Windows key, etc)
|
---|
105 | bool m_CallDefWindowProc; // if true, DXUTStaticWndProc will call DefWindowProc for unhandled messages. Applications rendering to a dialog may need to set this to false.
|
---|
106 | STICKYKEYS m_StartupStickyKeys; // StickyKey settings upon startup so they can be restored later
|
---|
107 | TOGGLEKEYS m_StartupToggleKeys; // ToggleKey settings upon startup so they can be restored later
|
---|
108 | FILTERKEYS m_StartupFilterKeys; // FilterKey settings upon startup so they can be restored later
|
---|
109 |
|
---|
110 | bool m_HandleDefaultHotkeys; // if true, then DXUT will handle some default hotkeys
|
---|
111 | bool m_HandleAltEnter; // if true, then DXUT will handle Alt-Enter
|
---|
112 | bool m_ShowMsgBoxOnError; // if true, then msgboxes are displayed upon errors
|
---|
113 | bool m_NoStats; // if true, then DXUTGetFrameStats() and DXUTGetDeviceStats() will return blank strings
|
---|
114 | bool m_ClipCursorWhenFullScreen; // if true, then DXUT will keep the cursor from going outside the window when full screen
|
---|
115 | bool m_ShowCursorWhenFullScreen; // if true, then DXUT will show a cursor when full screen
|
---|
116 | bool m_ConstantFrameTime; // if true, then elapsed frame time will always be 0.05f seconds which is good for debugging or automated capture
|
---|
117 | float m_TimePerFrame; // the constant time per frame in seconds, only valid if m_ConstantFrameTime==true
|
---|
118 | bool m_WireframeMode; // if true, then D3DRS_FILLMODE==D3DFILL_WIREFRAME else D3DRS_FILLMODE==D3DFILL_SOLID
|
---|
119 | bool m_AutoChangeAdapter; // if true, then the adapter will automatically change if the window is different monitor
|
---|
120 | bool m_WindowCreatedWithDefaultPositions; // if true, then CW_USEDEFAULT was used and the window should be moved to the right adapter
|
---|
121 | int m_ExitCode; // the exit code to be returned to the command line
|
---|
122 |
|
---|
123 | bool m_DXUTInited; // if true, then DXUTInit() has succeeded
|
---|
124 | bool m_WindowCreated; // if true, then DXUTCreateWindow() or DXUTSetWindow() has succeeded
|
---|
125 | bool m_DeviceCreated; // if true, then DXUTCreateDevice*() or DXUTSetDevice() has succeeded
|
---|
126 |
|
---|
127 | bool m_DXUTInitCalled; // if true, then DXUTInit() was called
|
---|
128 | bool m_WindowCreateCalled; // if true, then DXUTCreateWindow() or DXUTSetWindow() was called
|
---|
129 | bool m_DeviceCreateCalled; // if true, then DXUTCreateDevice*() or DXUTSetDevice() was called
|
---|
130 |
|
---|
131 | bool m_DeviceObjectsCreated; // if true, then DeviceCreated callback has been called (if non-NULL)
|
---|
132 | bool m_DeviceObjectsReset; // if true, then DeviceReset callback has been called (if non-NULL)
|
---|
133 | bool m_InsideDeviceCallback; // if true, then the framework is inside an app device callback
|
---|
134 | bool m_InsideMainloop; // if true, then the framework is inside the main loop
|
---|
135 | bool m_Active; // if true, then the app is the active top level window
|
---|
136 | bool m_TimePaused; // if true, then time is paused
|
---|
137 | bool m_RenderingPaused; // if true, then rendering is paused
|
---|
138 | int m_PauseRenderingCount; // pause rendering ref count
|
---|
139 | int m_PauseTimeCount; // pause time ref count
|
---|
140 | bool m_DeviceLost; // if true, then the device is lost and needs to be reset
|
---|
141 | bool m_NotifyOnMouseMove; // if true, include WM_MOUSEMOVE in mousecallback
|
---|
142 | bool m_Automation; // if true, automation is enabled
|
---|
143 | bool m_InSizeMove; // if true, app is inside a WM_ENTERSIZEMOVE
|
---|
144 | UINT m_TimerLastID; // last ID of the DXUT timer
|
---|
145 |
|
---|
146 | int m_OverrideAdapterOrdinal; // if != -1, then override to use this adapter ordinal
|
---|
147 | bool m_OverrideWindowed; // if true, then force to start windowed
|
---|
148 | bool m_OverrideFullScreen; // if true, then force to start full screen
|
---|
149 | int m_OverrideStartX; // if != -1, then override to this X position of the window
|
---|
150 | int m_OverrideStartY; // if != -1, then override to this Y position of the window
|
---|
151 | int m_OverrideWidth; // if != 0, then override to this width
|
---|
152 | int m_OverrideHeight; // if != 0, then override to this height
|
---|
153 | bool m_OverrideForceHAL; // if true, then force to HAL device (failing if one doesn't exist)
|
---|
154 | bool m_OverrideForceREF; // if true, then force to REF device (failing if one doesn't exist)
|
---|
155 | bool m_OverrideForcePureHWVP; // if true, then force to use pure HWVP (failing if device doesn't support it)
|
---|
156 | bool m_OverrideForceHWVP; // if true, then force to use HWVP (failing if device doesn't support it)
|
---|
157 | bool m_OverrideForceSWVP; // if true, then force to use SWVP
|
---|
158 | bool m_OverrideConstantFrameTime; // if true, then force to constant frame time
|
---|
159 | float m_OverrideConstantTimePerFrame; // the constant time per frame in seconds if m_OverrideConstantFrameTime==true
|
---|
160 | int m_OverrideQuitAfterFrame; // if != 0, then it will force the app to quit after that frame
|
---|
161 | int m_OverrideForceVsync; // if == 0, then it will force the app to use D3DPRESENT_INTERVAL_IMMEDIATE, if == 1 force use of D3DPRESENT_INTERVAL_DEFAULT
|
---|
162 | bool m_OverrideRelaunchMCE; // if true, then force relaunch of MCE at exit
|
---|
163 |
|
---|
164 | LPDXUTCALLBACKISDEVICEACCEPTABLE m_IsDeviceAcceptableFunc; // is device acceptable callback
|
---|
165 | LPDXUTCALLBACKMODIFYDEVICESETTINGS m_ModifyDeviceSettingsFunc; // modify device settings callback
|
---|
166 | LPDXUTCALLBACKDEVICECREATED m_DeviceCreatedFunc; // device created callback
|
---|
167 | LPDXUTCALLBACKDEVICERESET m_DeviceResetFunc; // device reset callback
|
---|
168 | LPDXUTCALLBACKDEVICELOST m_DeviceLostFunc; // device lost callback
|
---|
169 | LPDXUTCALLBACKDEVICEDESTROYED m_DeviceDestroyedFunc; // device destroyed callback
|
---|
170 | LPDXUTCALLBACKFRAMEMOVE m_FrameMoveFunc; // frame move callback
|
---|
171 | LPDXUTCALLBACKFRAMERENDER m_FrameRenderFunc; // frame render callback
|
---|
172 | LPDXUTCALLBACKKEYBOARD m_KeyboardFunc; // keyboard callback
|
---|
173 | LPDXUTCALLBACKMOUSE m_MouseFunc; // mouse callback
|
---|
174 | LPDXUTCALLBACKMSGPROC m_WindowMsgFunc; // window messages callback
|
---|
175 |
|
---|
176 | void* m_IsDeviceAcceptableFuncUserContext; // user context for is device acceptable callback
|
---|
177 | void* m_ModifyDeviceSettingsFuncUserContext; // user context for modify device settings callback
|
---|
178 | void* m_DeviceCreatedUserContext; // user context for device created callback
|
---|
179 | void* m_DeviceCreatedFuncUserContext; // user context for device created callback
|
---|
180 | void* m_DeviceResetFuncUserContext; // user context for device reset callback
|
---|
181 | void* m_DeviceLostFuncUserContext; // user context for device lost callback
|
---|
182 | void* m_DeviceDestroyedFuncUserContext; // user context for device destroyed callback
|
---|
183 | void* m_FrameMoveFuncUserContext; // user context for frame move callback
|
---|
184 | void* m_FrameRenderFuncUserContext; // user context for frame render callback
|
---|
185 | void* m_KeyboardFuncUserContext; // user context for keyboard callback
|
---|
186 | void* m_MouseFuncUserContext; // user context for mouse callback
|
---|
187 | void* m_WindowMsgFuncUserContext; // user context for window messages callback
|
---|
188 |
|
---|
189 | bool m_Keys[256]; // array of key state
|
---|
190 | bool m_MouseButtons[5]; // array of mouse states
|
---|
191 |
|
---|
192 | CGrowableArray<DXUT_TIMER>* m_TimerList; // list of DXUT_TIMER structs
|
---|
193 | WCHAR m_StaticFrameStats[256]; // static part of frames stats
|
---|
194 | WCHAR m_FPSStats[64]; // fps stats
|
---|
195 | WCHAR m_FrameStats[256]; // frame stats (fps, width, etc)
|
---|
196 | WCHAR m_DeviceStats[256]; // device stats (description, device type, etc)
|
---|
197 | WCHAR m_WindowTitle[256]; // window title
|
---|
198 | };
|
---|
199 |
|
---|
200 | STATE m_state;
|
---|
201 |
|
---|
202 | public:
|
---|
203 | DXUTState() { Create(); }
|
---|
204 | ~DXUTState() { Destroy(); }
|
---|
205 |
|
---|
206 | void Create()
|
---|
207 | {
|
---|
208 | // Make sure these are created before DXUTState so they
|
---|
209 | // destroyed last because DXUTState cleanup needs them
|
---|
210 | DXUTGetGlobalResourceCache();
|
---|
211 |
|
---|
212 | ZeroMemory( &m_state, sizeof(STATE) );
|
---|
213 | g_bThreadSafe = true;
|
---|
214 | InitializeCriticalSection( &g_cs );
|
---|
215 | m_state.m_OverrideStartX = -1;
|
---|
216 | m_state.m_OverrideStartY = -1;
|
---|
217 | m_state.m_OverrideAdapterOrdinal = -1;
|
---|
218 | m_state.m_OverrideForceVsync = -1;
|
---|
219 | m_state.m_AutoChangeAdapter = true;
|
---|
220 | m_state.m_ShowMsgBoxOnError = true;
|
---|
221 | m_state.m_AllowShortcutKeysWhenWindowed = true;
|
---|
222 | m_state.m_Active = true;
|
---|
223 | m_state.m_CallDefWindowProc = true;
|
---|
224 | }
|
---|
225 |
|
---|
226 | void Destroy()
|
---|
227 | {
|
---|
228 | DXUTShutdown();
|
---|
229 | DeleteCriticalSection( &g_cs );
|
---|
230 | }
|
---|
231 |
|
---|
232 | // Macros to define access functions for thread safe access into m_state
|
---|
233 | GET_SET_ACCESSOR( IDirect3D9*, D3D );
|
---|
234 |
|
---|
235 | GET_SET_ACCESSOR( IDirect3DDevice9*, D3DDevice );
|
---|
236 | GET_SET_ACCESSOR( CD3DEnumeration*, D3DEnumeration );
|
---|
237 | GET_SET_ACCESSOR( DXUTDeviceSettings*, CurrentDeviceSettings );
|
---|
238 | GETP_SETP_ACCESSOR( D3DSURFACE_DESC, BackBufferSurfaceDesc );
|
---|
239 | GETP_SETP_ACCESSOR( D3DCAPS9, Caps );
|
---|
240 |
|
---|
241 | GET_SET_ACCESSOR( HWND, HWNDFocus );
|
---|
242 | GET_SET_ACCESSOR( HWND, HWNDDeviceFullScreen );
|
---|
243 | GET_SET_ACCESSOR( HWND, HWNDDeviceWindowed );
|
---|
244 | GET_SET_ACCESSOR( HMONITOR, AdapterMonitor );
|
---|
245 | GET_SET_ACCESSOR( HMENU, Menu );
|
---|
246 |
|
---|
247 | GET_SET_ACCESSOR( UINT, FullScreenBackBufferWidthAtModeChange );
|
---|
248 | GET_SET_ACCESSOR( UINT, FullScreenBackBufferHeightAtModeChange );
|
---|
249 | GET_SET_ACCESSOR( UINT, WindowBackBufferWidthAtModeChange );
|
---|
250 | GET_SET_ACCESSOR( UINT, WindowBackBufferHeightAtModeChange );
|
---|
251 | GETP_SETP_ACCESSOR( WINDOWPLACEMENT, WindowedPlacement );
|
---|
252 | GET_SET_ACCESSOR( DWORD, WindowedStyleAtModeChange );
|
---|
253 | GET_SET_ACCESSOR( bool, TopmostWhileWindowed );
|
---|
254 | GET_SET_ACCESSOR( bool, Minimized );
|
---|
255 | GET_SET_ACCESSOR( bool, Maximized );
|
---|
256 | GET_SET_ACCESSOR( bool, MinimizedWhileFullscreen );
|
---|
257 | GET_SET_ACCESSOR( bool, IgnoreSizeChange );
|
---|
258 |
|
---|
259 | GET_SET_ACCESSOR( double, Time );
|
---|
260 | GET_SET_ACCESSOR( double, AbsoluteTime );
|
---|
261 | GET_SET_ACCESSOR( float, ElapsedTime );
|
---|
262 |
|
---|
263 | GET_SET_ACCESSOR( HINSTANCE, HInstance );
|
---|
264 | GET_SET_ACCESSOR( double, LastStatsUpdateTime );
|
---|
265 | GET_SET_ACCESSOR( DWORD, LastStatsUpdateFrames );
|
---|
266 | GET_SET_ACCESSOR( float, FPS );
|
---|
267 | GET_SET_ACCESSOR( int, CurrentFrameNumber );
|
---|
268 | GET_SET_ACCESSOR( HHOOK, KeyboardHook );
|
---|
269 | GET_SET_ACCESSOR( bool, AllowShortcutKeysWhenFullscreen );
|
---|
270 | GET_SET_ACCESSOR( bool, AllowShortcutKeysWhenWindowed );
|
---|
271 | GET_SET_ACCESSOR( bool, AllowShortcutKeys );
|
---|
272 | GET_SET_ACCESSOR( bool, CallDefWindowProc );
|
---|
273 | GET_SET_ACCESSOR( STICKYKEYS, StartupStickyKeys );
|
---|
274 | GET_SET_ACCESSOR( TOGGLEKEYS, StartupToggleKeys );
|
---|
275 | GET_SET_ACCESSOR( FILTERKEYS, StartupFilterKeys );
|
---|
276 |
|
---|
277 | GET_SET_ACCESSOR( bool, HandleDefaultHotkeys );
|
---|
278 | GET_SET_ACCESSOR( bool, HandleAltEnter );
|
---|
279 | GET_SET_ACCESSOR( bool, ShowMsgBoxOnError );
|
---|
280 | GET_SET_ACCESSOR( bool, NoStats );
|
---|
281 | GET_SET_ACCESSOR( bool, ClipCursorWhenFullScreen );
|
---|
282 | GET_SET_ACCESSOR( bool, ShowCursorWhenFullScreen );
|
---|
283 | GET_SET_ACCESSOR( bool, ConstantFrameTime );
|
---|
284 | GET_SET_ACCESSOR( float, TimePerFrame );
|
---|
285 | GET_SET_ACCESSOR( bool, WireframeMode );
|
---|
286 | GET_SET_ACCESSOR( bool, AutoChangeAdapter );
|
---|
287 | GET_SET_ACCESSOR( bool, WindowCreatedWithDefaultPositions );
|
---|
288 | GET_SET_ACCESSOR( int, ExitCode );
|
---|
289 |
|
---|
290 | GET_SET_ACCESSOR( bool, DXUTInited );
|
---|
291 | GET_SET_ACCESSOR( bool, WindowCreated );
|
---|
292 | GET_SET_ACCESSOR( bool, DeviceCreated );
|
---|
293 | GET_SET_ACCESSOR( bool, DXUTInitCalled );
|
---|
294 | GET_SET_ACCESSOR( bool, WindowCreateCalled );
|
---|
295 | GET_SET_ACCESSOR( bool, DeviceCreateCalled );
|
---|
296 | GET_SET_ACCESSOR( bool, InsideDeviceCallback );
|
---|
297 | GET_SET_ACCESSOR( bool, InsideMainloop );
|
---|
298 | GET_SET_ACCESSOR( bool, DeviceObjectsCreated );
|
---|
299 | GET_SET_ACCESSOR( bool, DeviceObjectsReset );
|
---|
300 | GET_SET_ACCESSOR( bool, Active );
|
---|
301 | GET_SET_ACCESSOR( bool, RenderingPaused );
|
---|
302 | GET_SET_ACCESSOR( bool, TimePaused );
|
---|
303 | GET_SET_ACCESSOR( int, PauseRenderingCount );
|
---|
304 | GET_SET_ACCESSOR( int, PauseTimeCount );
|
---|
305 | GET_SET_ACCESSOR( bool, DeviceLost );
|
---|
306 | GET_SET_ACCESSOR( bool, NotifyOnMouseMove );
|
---|
307 | GET_SET_ACCESSOR( bool, Automation );
|
---|
308 | GET_SET_ACCESSOR( bool, InSizeMove );
|
---|
309 | GET_SET_ACCESSOR( UINT, TimerLastID );
|
---|
310 |
|
---|
311 | GET_SET_ACCESSOR( int, OverrideAdapterOrdinal );
|
---|
312 | GET_SET_ACCESSOR( bool, OverrideWindowed );
|
---|
313 | GET_SET_ACCESSOR( bool, OverrideFullScreen );
|
---|
314 | GET_SET_ACCESSOR( int, OverrideStartX );
|
---|
315 | GET_SET_ACCESSOR( int, OverrideStartY );
|
---|
316 | GET_SET_ACCESSOR( int, OverrideWidth );
|
---|
317 | GET_SET_ACCESSOR( int, OverrideHeight );
|
---|
318 | GET_SET_ACCESSOR( bool, OverrideForceHAL );
|
---|
319 | GET_SET_ACCESSOR( bool, OverrideForceREF );
|
---|
320 | GET_SET_ACCESSOR( bool, OverrideForcePureHWVP );
|
---|
321 | GET_SET_ACCESSOR( bool, OverrideForceHWVP );
|
---|
322 | GET_SET_ACCESSOR( bool, OverrideForceSWVP );
|
---|
323 | GET_SET_ACCESSOR( bool, OverrideConstantFrameTime );
|
---|
324 | GET_SET_ACCESSOR( float, OverrideConstantTimePerFrame );
|
---|
325 | GET_SET_ACCESSOR( int, OverrideQuitAfterFrame );
|
---|
326 | GET_SET_ACCESSOR( int, OverrideForceVsync );
|
---|
327 | GET_SET_ACCESSOR( bool, OverrideRelaunchMCE );
|
---|
328 |
|
---|
329 | GET_SET_ACCESSOR( LPDXUTCALLBACKISDEVICEACCEPTABLE, IsDeviceAcceptableFunc );
|
---|
330 | GET_SET_ACCESSOR( LPDXUTCALLBACKMODIFYDEVICESETTINGS, ModifyDeviceSettingsFunc );
|
---|
331 | GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICECREATED, DeviceCreatedFunc );
|
---|
332 | GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICERESET, DeviceResetFunc );
|
---|
333 | GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICELOST, DeviceLostFunc );
|
---|
334 | GET_SET_ACCESSOR( LPDXUTCALLBACKDEVICEDESTROYED, DeviceDestroyedFunc );
|
---|
335 | GET_SET_ACCESSOR( LPDXUTCALLBACKFRAMEMOVE, FrameMoveFunc );
|
---|
336 | GET_SET_ACCESSOR( LPDXUTCALLBACKFRAMERENDER, FrameRenderFunc );
|
---|
337 | GET_SET_ACCESSOR( LPDXUTCALLBACKKEYBOARD, KeyboardFunc );
|
---|
338 | GET_SET_ACCESSOR( LPDXUTCALLBACKMOUSE, MouseFunc );
|
---|
339 | GET_SET_ACCESSOR( LPDXUTCALLBACKMSGPROC, WindowMsgFunc );
|
---|
340 |
|
---|
341 | GET_SET_ACCESSOR( void*, IsDeviceAcceptableFuncUserContext );
|
---|
342 | GET_SET_ACCESSOR( void*, ModifyDeviceSettingsFuncUserContext );
|
---|
343 | GET_SET_ACCESSOR( void*, DeviceCreatedFuncUserContext );
|
---|
344 | GET_SET_ACCESSOR( void*, DeviceResetFuncUserContext );
|
---|
345 | GET_SET_ACCESSOR( void*, DeviceLostFuncUserContext );
|
---|
346 | GET_SET_ACCESSOR( void*, DeviceDestroyedFuncUserContext );
|
---|
347 | GET_SET_ACCESSOR( void*, FrameMoveFuncUserContext );
|
---|
348 | GET_SET_ACCESSOR( void*, FrameRenderFuncUserContext );
|
---|
349 | GET_SET_ACCESSOR( void*, KeyboardFuncUserContext );
|
---|
350 | GET_SET_ACCESSOR( void*, MouseFuncUserContext );
|
---|
351 | GET_SET_ACCESSOR( void*, WindowMsgFuncUserContext );
|
---|
352 |
|
---|
353 | GET_SET_ACCESSOR( CGrowableArray<DXUT_TIMER>*, TimerList );
|
---|
354 | GET_ACCESSOR( bool*, Keys );
|
---|
355 | GET_ACCESSOR( bool*, MouseButtons );
|
---|
356 | GET_ACCESSOR( WCHAR*, StaticFrameStats );
|
---|
357 | GET_ACCESSOR( WCHAR*, FPSStats );
|
---|
358 | GET_ACCESSOR( WCHAR*, FrameStats );
|
---|
359 | GET_ACCESSOR( WCHAR*, DeviceStats );
|
---|
360 | GET_ACCESSOR( WCHAR*, WindowTitle );
|
---|
361 | };
|
---|
362 |
|
---|
363 |
|
---|
364 | //--------------------------------------------------------------------------------------
|
---|
365 | // Global state class
|
---|
366 | //--------------------------------------------------------------------------------------
|
---|
367 | DXUTState& GetDXUTState()
|
---|
368 | {
|
---|
369 | // Using an accessor function gives control of the construction order
|
---|
370 | static DXUTState state;
|
---|
371 | return state;
|
---|
372 | }
|
---|
373 |
|
---|
374 |
|
---|
375 | //--------------------------------------------------------------------------------------
|
---|
376 | // Internal functions forward declarations
|
---|
377 | //--------------------------------------------------------------------------------------
|
---|
378 | typedef IDirect3D9* (WINAPI* LPDIRECT3DCREATE9)(UINT SDKVersion);
|
---|
379 | typedef DECLSPEC_IMPORT UINT (WINAPI* LPTIMEBEGINPERIOD)( UINT uPeriod );
|
---|
380 | int DXUTMapButtonToArrayIndex( BYTE vButton );
|
---|
381 | void DXUTSetProcessorAffinity();
|
---|
382 | void DXUTParseCommandLine();
|
---|
383 | CD3DEnumeration* DXUTPrepareEnumerationObject( bool bEnumerate = false );
|
---|
384 | void DXUTBuildOptimalDeviceSettings( DXUTDeviceSettings* pOptimalDeviceSettings, DXUTDeviceSettings* pDeviceSettingsIn, DXUTMatchOptions* pMatchOptions );
|
---|
385 | bool DXUTDoesDeviceComboMatchPreserveOptions( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo, DXUTDeviceSettings* pDeviceSettingsIn, DXUTMatchOptions* pMatchOptions );
|
---|
386 | float DXUTRankDeviceCombo( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo, DXUTDeviceSettings* pDeviceSettingsIn, D3DDISPLAYMODE* pAdapterDesktopDisplayMode );
|
---|
387 | void DXUTBuildValidDeviceSettings( DXUTDeviceSettings* pDeviceSettings, CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo, DXUTDeviceSettings* pDeviceSettingsIn, DXUTMatchOptions* pMatchOptions );
|
---|
388 | HRESULT DXUTFindValidResolution( CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo, D3DDISPLAYMODE displayModeIn, D3DDISPLAYMODE* pBestDisplayMode );
|
---|
389 | HRESULT DXUTFindAdapterFormat( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT BackBufferFormat, BOOL Windowed, D3DFORMAT* pAdapterFormat );
|
---|
390 | HRESULT DXUTChangeDevice( DXUTDeviceSettings* pNewDeviceSettings, IDirect3DDevice9* pd3dDeviceFromApp, bool bForceRecreate, bool bClipWindowToSingleAdapter );
|
---|
391 | void DXUTUpdateDeviceSettingsWithOverrides( DXUTDeviceSettings* pNewDeviceSettings );
|
---|
392 | HRESULT DXUTCreate3DEnvironment( IDirect3DDevice9* pd3dDeviceFromApp );
|
---|
393 | HRESULT DXUTReset3DEnvironment();
|
---|
394 | void DXUTRender3DEnvironment();
|
---|
395 | void DXUTCleanup3DEnvironment( bool bReleaseSettings = true );
|
---|
396 | void DXUTUpdateFrameStats();
|
---|
397 | void DXUTUpdateDeviceStats( D3DDEVTYPE DeviceType, DWORD BehaviorFlags, D3DADAPTER_IDENTIFIER9* pAdapterIdentifier );
|
---|
398 | void DXUTUpdateStaticFrameStats();
|
---|
399 | void DXUTHandleTimers();
|
---|
400 | bool DXUTIsNextArg( WCHAR*& strCmdLine, WCHAR* strArg );
|
---|
401 | bool DXUTGetCmdParam( WCHAR*& strCmdLine, WCHAR* strFlag );
|
---|
402 | void DXUTDisplayErrorMessage( HRESULT hr );
|
---|
403 | LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
---|
404 | void DXUTCheckForWindowSizeChange();
|
---|
405 | void DXUTCheckForWindowChangingMonitors();
|
---|
406 | UINT DXUTColorChannelBits( D3DFORMAT fmt );
|
---|
407 | UINT DXUTStencilBits( D3DFORMAT fmt );
|
---|
408 | UINT DXUTDepthBits( D3DFORMAT fmt );
|
---|
409 | HRESULT DXUTGetAdapterOrdinalFromMonitor( HMONITOR hMonitor, UINT* pAdapterOrdinal );
|
---|
410 | void DXUTAllowShortcutKeys( bool bAllowKeys );
|
---|
411 | void DXUTUpdateBackBufferDesc();
|
---|
412 | void DXUTSetupCursor();
|
---|
413 | HRESULT DXUTSetDeviceCursor( IDirect3DDevice9* pd3dDevice, HCURSOR hCursor, bool bAddWatermark );
|
---|
414 |
|
---|
415 |
|
---|
416 | //--------------------------------------------------------------------------------------
|
---|
417 | // External callback setup functions
|
---|
418 | //--------------------------------------------------------------------------------------
|
---|
419 | void DXUTSetCallbackDeviceCreated( LPDXUTCALLBACKDEVICECREATED pCallbackDeviceCreated, void* pUserContext ) { GetDXUTState().SetDeviceCreatedFunc( pCallbackDeviceCreated ); GetDXUTState().SetDeviceCreatedFuncUserContext( pUserContext ); }
|
---|
420 | void DXUTSetCallbackDeviceReset( LPDXUTCALLBACKDEVICERESET pCallbackDeviceReset, void* pUserContext ) { GetDXUTState().SetDeviceResetFunc( pCallbackDeviceReset ); GetDXUTState().SetDeviceResetFuncUserContext( pUserContext ); }
|
---|
421 | void DXUTSetCallbackDeviceLost( LPDXUTCALLBACKDEVICELOST pCallbackDeviceLost, void* pUserContext ) { GetDXUTState().SetDeviceLostFunc( pCallbackDeviceLost ); GetDXUTState().SetDeviceLostFuncUserContext( pUserContext ); }
|
---|
422 | void DXUTSetCallbackDeviceDestroyed( LPDXUTCALLBACKDEVICEDESTROYED pCallbackDeviceDestroyed, void* pUserContext ) { GetDXUTState().SetDeviceDestroyedFunc( pCallbackDeviceDestroyed ); GetDXUTState().SetDeviceDestroyedFuncUserContext( pUserContext ); }
|
---|
423 | void DXUTSetCallbackDeviceChanging( LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings, void* pUserContext ) { GetDXUTState().SetModifyDeviceSettingsFunc( pCallbackModifyDeviceSettings ); GetDXUTState().SetModifyDeviceSettingsFuncUserContext( pUserContext ); }
|
---|
424 | void DXUTSetCallbackFrameMove( LPDXUTCALLBACKFRAMEMOVE pCallbackFrameMove, void* pUserContext ) { GetDXUTState().SetFrameMoveFunc( pCallbackFrameMove ); GetDXUTState().SetFrameMoveFuncUserContext( pUserContext ); }
|
---|
425 | void DXUTSetCallbackFrameRender( LPDXUTCALLBACKFRAMERENDER pCallbackFrameRender, void* pUserContext ) { GetDXUTState().SetFrameRenderFunc( pCallbackFrameRender ); GetDXUTState().SetFrameRenderFuncUserContext( pUserContext ); }
|
---|
426 | void DXUTSetCallbackKeyboard( LPDXUTCALLBACKKEYBOARD pCallbackKeyboard, void* pUserContext ) { GetDXUTState().SetKeyboardFunc( pCallbackKeyboard ); GetDXUTState().SetKeyboardFuncUserContext( pUserContext ); }
|
---|
427 | void DXUTSetCallbackMouse( LPDXUTCALLBACKMOUSE pCallbackMouse, bool bIncludeMouseMove, void* pUserContext ) { GetDXUTState().SetMouseFunc( pCallbackMouse ); GetDXUTState().SetNotifyOnMouseMove( bIncludeMouseMove ); GetDXUTState().SetMouseFuncUserContext( pUserContext ); }
|
---|
428 | void DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallbackMsgProc, void* pUserContext ) { GetDXUTState().SetWindowMsgFunc( pCallbackMsgProc ); GetDXUTState().SetWindowMsgFuncUserContext( pUserContext ); }
|
---|
429 |
|
---|
430 | //--------------------------------------------------------------------------------------
|
---|
431 | // Optionally parses the command line and sets if default hotkeys are handled
|
---|
432 | //
|
---|
433 | // Possible command line parameters are:
|
---|
434 | // -adapter:# forces app to use this adapter # (fails if the adapter doesn't exist)
|
---|
435 | // -windowed forces app to start windowed
|
---|
436 | // -fullscreen forces app to start full screen
|
---|
437 | // -forcehal forces app to use HAL (fails if HAL doesn't exist)
|
---|
438 | // -forceref forces app to use REF (fails if REF doesn't exist)
|
---|
439 | // -forcepurehwvp forces app to use pure HWVP (fails if device doesn't support it)
|
---|
440 | // -forcehwvp forces app to use HWVP (fails if device doesn't support it)
|
---|
441 | // -forceswvp forces app to use SWVP
|
---|
442 | // -forcevsync:# if # is 0, forces app to use D3DPRESENT_INTERVAL_IMMEDIATE otherwise force use of D3DPRESENT_INTERVAL_DEFAULT
|
---|
443 | // -width:# forces app to use # for width. for full screen, it will pick the closest possible supported mode
|
---|
444 | // -height:# forces app to use # for height. for full screen, it will pick the closest possible supported mode
|
---|
445 | // -startx:# forces app to use # for the x coord of the window position for windowed mode
|
---|
446 | // -starty:# forces app to use # for the y coord of the window position for windowed mode
|
---|
447 | // -constantframetime:# forces app to use constant frame time, where # is the time/frame in seconds
|
---|
448 | // -quitafterframe:x forces app to quit after # frames
|
---|
449 | // -noerrormsgboxes prevents the display of message boxes generated by the framework so the application can be run without user interaction
|
---|
450 | // -nostats prevents the display of the stats
|
---|
451 | // -relaunchmce re-launches the MCE UI after the app exits
|
---|
452 | // -automation every CDXUTDialog created will have EnableKeyboardInput(true) called, enabling UI navigation with keyboard
|
---|
453 | // This is useful when automating application testing.
|
---|
454 | //
|
---|
455 | // Hotkeys handled by default are:
|
---|
456 | // Alt-Enter toggle between full screen & windowed (hotkey always enabled)
|
---|
457 | // ESC exit app
|
---|
458 | // F3 toggle HAL/REF
|
---|
459 | // F8 toggle wire-frame mode
|
---|
460 | // Pause pause time
|
---|
461 | //--------------------------------------------------------------------------------------
|
---|
462 | HRESULT DXUTInit( bool bParseCommandLine, bool bHandleDefaultHotkeys, bool bShowMsgBoxOnError, bool bHandleAltEnter )
|
---|
463 | {
|
---|
464 | GetDXUTState().SetDXUTInitCalled( true );
|
---|
465 |
|
---|
466 | // Not always needed, but lets the app create GDI dialogs
|
---|
467 | InitCommonControls();
|
---|
468 |
|
---|
469 | // Save the current sticky/toggle/filter key settings so DXUT can restore them later
|
---|
470 | STICKYKEYS sk = {sizeof(STICKYKEYS), 0};
|
---|
471 | SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &sk, 0);
|
---|
472 | GetDXUTState().SetStartupStickyKeys( sk );
|
---|
473 |
|
---|
474 | TOGGLEKEYS tk = {sizeof(TOGGLEKEYS), 0};
|
---|
475 | SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tk, 0);
|
---|
476 | GetDXUTState().SetStartupToggleKeys( tk );
|
---|
477 |
|
---|
478 | FILTERKEYS fk = {sizeof(FILTERKEYS), 0};
|
---|
479 | SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &fk, 0);
|
---|
480 | GetDXUTState().SetStartupFilterKeys( fk );
|
---|
481 |
|
---|
482 | // Increase the accuracy of Sleep() without needing to link to winmm.lib
|
---|
483 | WCHAR wszPath[MAX_PATH+1];
|
---|
484 | if( GetSystemDirectory( wszPath, MAX_PATH+1 ) )
|
---|
485 | {
|
---|
486 | StringCchCat( wszPath, MAX_PATH, L"\\winmm.dll" );
|
---|
487 | HINSTANCE hInstWinMM = LoadLibrary( wszPath );
|
---|
488 | if( hInstWinMM )
|
---|
489 | {
|
---|
490 | LPTIMEBEGINPERIOD pTimeBeginPeriod = (LPTIMEBEGINPERIOD)GetProcAddress( hInstWinMM, "timeBeginPeriod" );
|
---|
491 | if( NULL != pTimeBeginPeriod )
|
---|
492 | pTimeBeginPeriod(1);
|
---|
493 |
|
---|
494 | FreeLibrary(hInstWinMM);
|
---|
495 | }
|
---|
496 | }
|
---|
497 |
|
---|
498 | GetDXUTState().SetShowMsgBoxOnError( bShowMsgBoxOnError );
|
---|
499 | GetDXUTState().SetHandleDefaultHotkeys( bHandleDefaultHotkeys );
|
---|
500 | GetDXUTState().SetHandleAltEnter( bHandleAltEnter );
|
---|
501 |
|
---|
502 | if( bParseCommandLine )
|
---|
503 | DXUTParseCommandLine();
|
---|
504 |
|
---|
505 | // Verify D3DX version
|
---|
506 | if( !D3DXCheckVersion( D3D_SDK_VERSION, D3DX_SDK_VERSION ) )
|
---|
507 | {
|
---|
508 | DXUTDisplayErrorMessage( DXUTERR_INCORRECTVERSION );
|
---|
509 | return DXUT_ERR( L"D3DXCheckVersion", DXUTERR_INCORRECTVERSION );
|
---|
510 | }
|
---|
511 |
|
---|
512 | // Create a Direct3D object if one has not already been created
|
---|
513 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
514 | if( pD3D == NULL )
|
---|
515 | {
|
---|
516 | // This may fail if DirectX 9 isn't installed
|
---|
517 | // This may fail if the DirectX headers are out of sync with the installed DirectX DLLs
|
---|
518 | pD3D = DXUT_Dynamic_Direct3DCreate9( D3D_SDK_VERSION );
|
---|
519 | GetDXUTState().SetD3D( pD3D );
|
---|
520 | }
|
---|
521 |
|
---|
522 | if( pD3D == NULL )
|
---|
523 | {
|
---|
524 | // If still NULL, then something went wrong
|
---|
525 | DXUTDisplayErrorMessage( DXUTERR_NODIRECT3D );
|
---|
526 | return DXUT_ERR( L"Direct3DCreate9", DXUTERR_NODIRECT3D );
|
---|
527 | }
|
---|
528 |
|
---|
529 | // Reset the timer
|
---|
530 | DXUTGetGlobalTimer()->Reset();
|
---|
531 |
|
---|
532 | GetDXUTState().SetDXUTInited( true );
|
---|
533 |
|
---|
534 | return S_OK;
|
---|
535 | }
|
---|
536 |
|
---|
537 |
|
---|
538 | //--------------------------------------------------------------------------------------
|
---|
539 | // Parses the command line for parameters. See DXUTInit() for list
|
---|
540 | //--------------------------------------------------------------------------------------
|
---|
541 | void DXUTParseCommandLine()
|
---|
542 | {
|
---|
543 | WCHAR* strCmdLine;
|
---|
544 | WCHAR strFlag[MAX_PATH];
|
---|
545 |
|
---|
546 | int nNumArgs;
|
---|
547 | WCHAR** pstrArgList = CommandLineToArgvW( GetCommandLine(), &nNumArgs );
|
---|
548 | for( int iArg=1; iArg<nNumArgs; iArg++ )
|
---|
549 | {
|
---|
550 | strCmdLine = pstrArgList[iArg];
|
---|
551 |
|
---|
552 | // Handle flag args
|
---|
553 | if( *strCmdLine == L'/' || *strCmdLine == L'-' )
|
---|
554 | {
|
---|
555 | strCmdLine++;
|
---|
556 |
|
---|
557 | if( DXUTIsNextArg( strCmdLine, L"adapter" ) )
|
---|
558 | {
|
---|
559 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
560 | {
|
---|
561 | int nAdapter = _wtoi(strFlag);
|
---|
562 | GetDXUTState().SetOverrideAdapterOrdinal( nAdapter );
|
---|
563 | continue;
|
---|
564 | }
|
---|
565 | }
|
---|
566 |
|
---|
567 | if( DXUTIsNextArg( strCmdLine, L"windowed" ) )
|
---|
568 | {
|
---|
569 | GetDXUTState().SetOverrideWindowed( true );
|
---|
570 | continue;
|
---|
571 | }
|
---|
572 |
|
---|
573 | if( DXUTIsNextArg( strCmdLine, L"fullscreen" ) )
|
---|
574 | {
|
---|
575 | GetDXUTState().SetOverrideFullScreen( true );
|
---|
576 | continue;
|
---|
577 | }
|
---|
578 |
|
---|
579 | if( DXUTIsNextArg( strCmdLine, L"forcehal" ) )
|
---|
580 | {
|
---|
581 | GetDXUTState().SetOverrideForceHAL( true );
|
---|
582 | continue;
|
---|
583 | }
|
---|
584 |
|
---|
585 | if( DXUTIsNextArg( strCmdLine, L"forceref" ) )
|
---|
586 | {
|
---|
587 | GetDXUTState().SetOverrideForceREF( true );
|
---|
588 | continue;
|
---|
589 | }
|
---|
590 |
|
---|
591 | if( DXUTIsNextArg( strCmdLine, L"forcepurehwvp" ) )
|
---|
592 | {
|
---|
593 | GetDXUTState().SetOverrideForcePureHWVP( true );
|
---|
594 | continue;
|
---|
595 | }
|
---|
596 |
|
---|
597 | if( DXUTIsNextArg( strCmdLine, L"forcehwvp" ) )
|
---|
598 | {
|
---|
599 | GetDXUTState().SetOverrideForceHWVP( true );
|
---|
600 | continue;
|
---|
601 | }
|
---|
602 |
|
---|
603 | if( DXUTIsNextArg( strCmdLine, L"forceswvp" ) )
|
---|
604 | {
|
---|
605 | GetDXUTState().SetOverrideForceSWVP( true );
|
---|
606 | continue;
|
---|
607 | }
|
---|
608 |
|
---|
609 | if( DXUTIsNextArg( strCmdLine, L"forcevsync" ) )
|
---|
610 | {
|
---|
611 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
612 | {
|
---|
613 | int nOn = _wtoi(strFlag);
|
---|
614 | GetDXUTState().SetOverrideForceVsync( nOn );
|
---|
615 | continue;
|
---|
616 | }
|
---|
617 | }
|
---|
618 |
|
---|
619 | if( DXUTIsNextArg( strCmdLine, L"width" ) )
|
---|
620 | {
|
---|
621 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
622 | {
|
---|
623 | int nWidth = _wtoi(strFlag);
|
---|
624 | GetDXUTState().SetOverrideWidth( nWidth );
|
---|
625 | continue;
|
---|
626 | }
|
---|
627 | }
|
---|
628 |
|
---|
629 | if( DXUTIsNextArg( strCmdLine, L"height" ) )
|
---|
630 | {
|
---|
631 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
632 | {
|
---|
633 | int nHeight = _wtoi(strFlag);
|
---|
634 | GetDXUTState().SetOverrideHeight( nHeight );
|
---|
635 | continue;
|
---|
636 | }
|
---|
637 | }
|
---|
638 |
|
---|
639 | if( DXUTIsNextArg( strCmdLine, L"startx" ) )
|
---|
640 | {
|
---|
641 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
642 | {
|
---|
643 | int nX = _wtoi(strFlag);
|
---|
644 | GetDXUTState().SetOverrideStartX( nX );
|
---|
645 | continue;
|
---|
646 | }
|
---|
647 | }
|
---|
648 |
|
---|
649 | if( DXUTIsNextArg( strCmdLine, L"starty" ) )
|
---|
650 | {
|
---|
651 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
652 | {
|
---|
653 | int nY = _wtoi(strFlag);
|
---|
654 | GetDXUTState().SetOverrideStartY( nY );
|
---|
655 | continue;
|
---|
656 | }
|
---|
657 | }
|
---|
658 |
|
---|
659 | if( DXUTIsNextArg( strCmdLine, L"constantframetime" ) )
|
---|
660 | {
|
---|
661 | float fTimePerFrame;
|
---|
662 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
663 | fTimePerFrame = (float)wcstod( strFlag, NULL );
|
---|
664 | else
|
---|
665 | fTimePerFrame = 0.0333f;
|
---|
666 | GetDXUTState().SetOverrideConstantFrameTime( true );
|
---|
667 | GetDXUTState().SetOverrideConstantTimePerFrame( fTimePerFrame );
|
---|
668 | DXUTSetConstantFrameTime( true, fTimePerFrame );
|
---|
669 | continue;
|
---|
670 | }
|
---|
671 |
|
---|
672 | if( DXUTIsNextArg( strCmdLine, L"quitafterframe" ) )
|
---|
673 | {
|
---|
674 | if( DXUTGetCmdParam( strCmdLine, strFlag ) )
|
---|
675 | {
|
---|
676 | int nFrame = _wtoi(strFlag);
|
---|
677 | GetDXUTState().SetOverrideQuitAfterFrame( nFrame );
|
---|
678 | continue;
|
---|
679 | }
|
---|
680 | }
|
---|
681 |
|
---|
682 | if( DXUTIsNextArg( strCmdLine, L"noerrormsgboxes" ) )
|
---|
683 | {
|
---|
684 | GetDXUTState().SetShowMsgBoxOnError( false );
|
---|
685 | continue;
|
---|
686 | }
|
---|
687 |
|
---|
688 | if( DXUTIsNextArg( strCmdLine, L"nostats" ) )
|
---|
689 | {
|
---|
690 | GetDXUTState().SetNoStats( true );
|
---|
691 | continue;
|
---|
692 | }
|
---|
693 |
|
---|
694 | if( DXUTIsNextArg( strCmdLine, L"relaunchmce" ) )
|
---|
695 | {
|
---|
696 | GetDXUTState().SetOverrideRelaunchMCE( true );
|
---|
697 | continue;
|
---|
698 | }
|
---|
699 |
|
---|
700 | if( DXUTIsNextArg( strCmdLine, L"automation" ) )
|
---|
701 | {
|
---|
702 | GetDXUTState().SetAutomation( true );
|
---|
703 | continue;
|
---|
704 | }
|
---|
705 | }
|
---|
706 |
|
---|
707 | // Unrecognized flag
|
---|
708 | StringCchCopy( strFlag, 256, strCmdLine );
|
---|
709 | WCHAR* strSpace = strFlag;
|
---|
710 | while (*strSpace && (*strSpace > L' '))
|
---|
711 | strSpace++;
|
---|
712 | *strSpace = 0;
|
---|
713 |
|
---|
714 | DXUTOutputDebugString( L"Unrecognized flag: %s", strFlag );
|
---|
715 | strCmdLine += wcslen(strFlag);
|
---|
716 | }
|
---|
717 | }
|
---|
718 |
|
---|
719 |
|
---|
720 | //--------------------------------------------------------------------------------------
|
---|
721 | // Helper function for DXUTParseCommandLine
|
---|
722 | //--------------------------------------------------------------------------------------
|
---|
723 | bool DXUTIsNextArg( WCHAR*& strCmdLine, WCHAR* strArg )
|
---|
724 | {
|
---|
725 | int nArgLen = (int) wcslen(strArg);
|
---|
726 | int nCmdLen = (int) wcslen(strCmdLine);
|
---|
727 |
|
---|
728 | if( nCmdLen >= nArgLen &&
|
---|
729 | _wcsnicmp( strCmdLine, strArg, nArgLen ) == 0 &&
|
---|
730 | (strCmdLine[nArgLen] == 0 || strCmdLine[nArgLen] == L':') )
|
---|
731 | {
|
---|
732 | strCmdLine += nArgLen;
|
---|
733 | return true;
|
---|
734 | }
|
---|
735 |
|
---|
736 | return false;
|
---|
737 | }
|
---|
738 |
|
---|
739 |
|
---|
740 | //--------------------------------------------------------------------------------------
|
---|
741 | // Helper function for DXUTParseCommandLine. Updates strCmdLine and strFlag
|
---|
742 | // Example: if strCmdLine=="-width:1024 -forceref"
|
---|
743 | // then after: strCmdLine==" -forceref" and strFlag=="1024"
|
---|
744 | //--------------------------------------------------------------------------------------
|
---|
745 | bool DXUTGetCmdParam( WCHAR*& strCmdLine, WCHAR* strFlag )
|
---|
746 | {
|
---|
747 | if( *strCmdLine == L':' )
|
---|
748 | {
|
---|
749 | strCmdLine++; // Skip ':'
|
---|
750 |
|
---|
751 | // Place NULL terminator in strFlag after current token
|
---|
752 | StringCchCopy( strFlag, 256, strCmdLine );
|
---|
753 | WCHAR* strSpace = strFlag;
|
---|
754 | while (*strSpace && (*strSpace > L' '))
|
---|
755 | strSpace++;
|
---|
756 | *strSpace = 0;
|
---|
757 |
|
---|
758 | // Update strCmdLine
|
---|
759 | strCmdLine += wcslen(strFlag);
|
---|
760 | return true;
|
---|
761 | }
|
---|
762 | else
|
---|
763 | {
|
---|
764 | strFlag[0] = 0;
|
---|
765 | return false;
|
---|
766 | }
|
---|
767 | }
|
---|
768 |
|
---|
769 |
|
---|
770 | //--------------------------------------------------------------------------------------
|
---|
771 | // Creates a window with the specified window title, icon, menu, and
|
---|
772 | // starting position. If DXUTInit() has not already been called, it will
|
---|
773 | // call it with the default parameters. Instead of calling this, you can
|
---|
774 | // call DXUTSetWindow() to use an existing window.
|
---|
775 | //--------------------------------------------------------------------------------------
|
---|
776 | HRESULT DXUTCreateWindow( const WCHAR* strWindowTitle, HINSTANCE hInstance,
|
---|
777 | HICON hIcon, HMENU hMenu, int x, int y )
|
---|
778 | {
|
---|
779 | HRESULT hr;
|
---|
780 |
|
---|
781 | // Not allowed to call this from inside the device callbacks
|
---|
782 | if( GetDXUTState().GetInsideDeviceCallback() )
|
---|
783 | return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
|
---|
784 |
|
---|
785 | GetDXUTState().SetWindowCreateCalled( true );
|
---|
786 |
|
---|
787 | if( !GetDXUTState().GetDXUTInited() )
|
---|
788 | {
|
---|
789 | // If DXUTInit() was already called and failed, then fail.
|
---|
790 | // DXUTInit() must first succeed for this function to succeed
|
---|
791 | if( GetDXUTState().GetDXUTInitCalled() )
|
---|
792 | return E_FAIL;
|
---|
793 |
|
---|
794 | // If DXUTInit() hasn't been called, then automatically call it
|
---|
795 | // with default params
|
---|
796 | hr = DXUTInit();
|
---|
797 | if( FAILED(hr) )
|
---|
798 | return hr;
|
---|
799 | }
|
---|
800 |
|
---|
801 | if( DXUTGetHWNDFocus() == NULL )
|
---|
802 | {
|
---|
803 | if( hInstance == NULL )
|
---|
804 | hInstance = (HINSTANCE)GetModuleHandle(NULL);
|
---|
805 | GetDXUTState().SetHInstance( hInstance );
|
---|
806 |
|
---|
807 | WCHAR szExePath[MAX_PATH];
|
---|
808 | GetModuleFileName( NULL, szExePath, MAX_PATH );
|
---|
809 | if( hIcon == NULL ) // If the icon is NULL, then use the first one found in the exe
|
---|
810 | hIcon = ExtractIcon( hInstance, szExePath, 0 );
|
---|
811 |
|
---|
812 | // Register the windows class
|
---|
813 | WNDCLASS wndClass;
|
---|
814 | wndClass.style = CS_DBLCLKS;
|
---|
815 | wndClass.lpfnWndProc = DXUTStaticWndProc;
|
---|
816 | wndClass.cbClsExtra = 0;
|
---|
817 | wndClass.cbWndExtra = 0;
|
---|
818 | wndClass.hInstance = hInstance;
|
---|
819 | wndClass.hIcon = hIcon;
|
---|
820 | wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
|
---|
821 | wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
---|
822 | wndClass.lpszMenuName = NULL;
|
---|
823 | wndClass.lpszClassName = L"Direct3DWindowClass";
|
---|
824 |
|
---|
825 | if( !RegisterClass( &wndClass ) )
|
---|
826 | {
|
---|
827 | DWORD dwError = GetLastError();
|
---|
828 | if( dwError != ERROR_CLASS_ALREADY_EXISTS )
|
---|
829 | return DXUT_ERR_MSGBOX( L"RegisterClass", HRESULT_FROM_WIN32(dwError) );
|
---|
830 | }
|
---|
831 |
|
---|
832 | RECT rc;
|
---|
833 | // Override the window's initial & size position if there were cmd line args
|
---|
834 | if( GetDXUTState().GetOverrideStartX() != -1 )
|
---|
835 | x = GetDXUTState().GetOverrideStartX();
|
---|
836 | if( GetDXUTState().GetOverrideStartY() != -1 )
|
---|
837 | y = GetDXUTState().GetOverrideStartY();
|
---|
838 |
|
---|
839 | GetDXUTState().SetWindowCreatedWithDefaultPositions( false );
|
---|
840 | if( x == CW_USEDEFAULT && y == CW_USEDEFAULT )
|
---|
841 | GetDXUTState().SetWindowCreatedWithDefaultPositions( true );
|
---|
842 |
|
---|
843 | // Find the window's initial size, but it might be changed later
|
---|
844 | int nDefaultWidth = 640;
|
---|
845 | int nDefaultHeight = 480;
|
---|
846 | if( GetDXUTState().GetOverrideWidth() != 0 )
|
---|
847 | nDefaultWidth = GetDXUTState().GetOverrideWidth();
|
---|
848 | if( GetDXUTState().GetOverrideHeight() != 0 )
|
---|
849 | nDefaultHeight = GetDXUTState().GetOverrideHeight();
|
---|
850 | SetRect( &rc, 0, 0, nDefaultWidth, nDefaultHeight );
|
---|
851 | AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, ( hMenu != NULL ) ? true : false );
|
---|
852 |
|
---|
853 | WCHAR* strCachedWindowTitle = GetDXUTState().GetWindowTitle();
|
---|
854 | StringCchCopy( strCachedWindowTitle, 256, strWindowTitle );
|
---|
855 |
|
---|
856 | // Create the render window
|
---|
857 | HWND hWnd = CreateWindow( L"Direct3DWindowClass", strWindowTitle, WS_OVERLAPPEDWINDOW,
|
---|
858 | x, y, (rc.right-rc.left), (rc.bottom-rc.top), 0,
|
---|
859 | hMenu, hInstance, 0 );
|
---|
860 | if( hWnd == NULL )
|
---|
861 | {
|
---|
862 | DWORD dwError = GetLastError();
|
---|
863 | return DXUT_ERR_MSGBOX( L"CreateWindow", HRESULT_FROM_WIN32(dwError) );
|
---|
864 | }
|
---|
865 |
|
---|
866 | GetDXUTState().SetWindowCreated( true );
|
---|
867 | GetDXUTState().SetHWNDFocus( hWnd );
|
---|
868 | GetDXUTState().SetHWNDDeviceFullScreen( hWnd );
|
---|
869 | GetDXUTState().SetHWNDDeviceWindowed( hWnd );
|
---|
870 | }
|
---|
871 |
|
---|
872 | return S_OK;
|
---|
873 | }
|
---|
874 |
|
---|
875 |
|
---|
876 | //--------------------------------------------------------------------------------------
|
---|
877 | // Sets a previously created window for the framework to use. If DXUTInit()
|
---|
878 | // has not already been called, it will call it with the default parameters.
|
---|
879 | // Instead of calling this, you can call DXUTCreateWindow() to create a new window.
|
---|
880 | //--------------------------------------------------------------------------------------
|
---|
881 | HRESULT DXUTSetWindow( HWND hWndFocus, HWND hWndDeviceFullScreen, HWND hWndDeviceWindowed, bool bHandleMessages )
|
---|
882 | {
|
---|
883 | HRESULT hr;
|
---|
884 |
|
---|
885 | // Not allowed to call this from inside the device callbacks
|
---|
886 | if( GetDXUTState().GetInsideDeviceCallback() )
|
---|
887 | return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
|
---|
888 |
|
---|
889 | GetDXUTState().SetWindowCreateCalled( true );
|
---|
890 |
|
---|
891 | // To avoid confusion, we do not allow any HWND to be NULL here. The
|
---|
892 | // caller must pass in valid HWND for all three parameters. The same
|
---|
893 | // HWND may be used for more than one parameter.
|
---|
894 | if( hWndFocus == NULL || hWndDeviceFullScreen == NULL || hWndDeviceWindowed == NULL )
|
---|
895 | return DXUT_ERR_MSGBOX( L"DXUTSetWindow", E_INVALIDARG );
|
---|
896 |
|
---|
897 | // If subclassing the window, set the pointer to the local window procedure
|
---|
898 | if( bHandleMessages )
|
---|
899 | {
|
---|
900 | // Switch window procedures
|
---|
901 | #ifdef _WIN64
|
---|
902 | LONG_PTR nResult = SetWindowLongPtr( hWndFocus, GWLP_WNDPROC, (LONG_PTR)DXUTStaticWndProc );
|
---|
903 | #else
|
---|
904 | LONG_PTR nResult = SetWindowLongPtr( hWndFocus, GWLP_WNDPROC, (LONG)(LONG_PTR)DXUTStaticWndProc );
|
---|
905 | #endif
|
---|
906 |
|
---|
907 | DWORD dwError = GetLastError();
|
---|
908 | if( nResult == 0 )
|
---|
909 | return DXUT_ERR_MSGBOX( L"SetWindowLongPtr", HRESULT_FROM_WIN32(dwError) );
|
---|
910 | }
|
---|
911 |
|
---|
912 | if( !GetDXUTState().GetDXUTInited() )
|
---|
913 | {
|
---|
914 | // If DXUTInit() was already called and failed, then fail.
|
---|
915 | // DXUTInit() must first succeed for this function to succeed
|
---|
916 | if( GetDXUTState().GetDXUTInitCalled() )
|
---|
917 | return E_FAIL;
|
---|
918 |
|
---|
919 | // If DXUTInit() hasn't been called, then automatically call it
|
---|
920 | // with default params
|
---|
921 | hr = DXUTInit();
|
---|
922 | if( FAILED(hr) )
|
---|
923 | return hr;
|
---|
924 | }
|
---|
925 |
|
---|
926 | WCHAR* strCachedWindowTitle = GetDXUTState().GetWindowTitle();
|
---|
927 | GetWindowText( hWndFocus, strCachedWindowTitle, 255 );
|
---|
928 | strCachedWindowTitle[255] = 0;
|
---|
929 |
|
---|
930 | HINSTANCE hInstance = (HINSTANCE) (LONG_PTR) GetWindowLongPtr( hWndFocus, GWLP_HINSTANCE );
|
---|
931 | GetDXUTState().SetHInstance( hInstance );
|
---|
932 | GetDXUTState().SetWindowCreatedWithDefaultPositions( false );
|
---|
933 | GetDXUTState().SetWindowCreated( true );
|
---|
934 | GetDXUTState().SetHWNDFocus( hWndFocus );
|
---|
935 | GetDXUTState().SetHWNDDeviceFullScreen( hWndDeviceFullScreen );
|
---|
936 | GetDXUTState().SetHWNDDeviceWindowed( hWndDeviceWindowed );
|
---|
937 |
|
---|
938 | return S_OK;
|
---|
939 | }
|
---|
940 |
|
---|
941 |
|
---|
942 | //--------------------------------------------------------------------------------------
|
---|
943 | // Creates a Direct3D device. If DXUTCreateWindow() or DXUTSetWindow() has not already
|
---|
944 | // been called, it will call DXUTCreateWindow() with the default parameters.
|
---|
945 | // Instead of calling this, you can call DXUTSetDevice() or DXUTCreateDeviceFromSettings()
|
---|
946 | //--------------------------------------------------------------------------------------
|
---|
947 | HRESULT DXUTCreateDevice( UINT AdapterOrdinal, bool bWindowed,
|
---|
948 | int nSuggestedWidth, int nSuggestedHeight,
|
---|
949 | LPDXUTCALLBACKISDEVICEACCEPTABLE pCallbackIsDeviceAcceptable,
|
---|
950 | LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings,
|
---|
951 | void* pUserContext )
|
---|
952 | {
|
---|
953 | HRESULT hr;
|
---|
954 |
|
---|
955 | // Not allowed to call this from inside the device callbacks
|
---|
956 | if( GetDXUTState().GetInsideDeviceCallback() )
|
---|
957 | return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
|
---|
958 |
|
---|
959 | // Record the function arguments in the global state
|
---|
960 | GetDXUTState().SetIsDeviceAcceptableFunc( pCallbackIsDeviceAcceptable );
|
---|
961 | GetDXUTState().SetModifyDeviceSettingsFunc( pCallbackModifyDeviceSettings );
|
---|
962 | GetDXUTState().SetIsDeviceAcceptableFuncUserContext( pUserContext );
|
---|
963 | GetDXUTState().SetModifyDeviceSettingsFuncUserContext( pUserContext );
|
---|
964 |
|
---|
965 | GetDXUTState().SetDeviceCreateCalled( true );
|
---|
966 |
|
---|
967 | // If DXUTCreateWindow() or DXUTSetWindow() has not already been called,
|
---|
968 | // then call DXUTCreateWindow() with the default parameters.
|
---|
969 | if( !GetDXUTState().GetWindowCreated() )
|
---|
970 | {
|
---|
971 | // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail.
|
---|
972 | // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed
|
---|
973 | if( GetDXUTState().GetWindowCreateCalled() )
|
---|
974 | return E_FAIL;
|
---|
975 |
|
---|
976 | // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then
|
---|
977 | // automatically call DXUTCreateWindow() with default params
|
---|
978 | hr = DXUTCreateWindow();
|
---|
979 | if( FAILED(hr) )
|
---|
980 | return hr;
|
---|
981 | }
|
---|
982 |
|
---|
983 | // Force an enumeration with the new IsDeviceAcceptable callback
|
---|
984 | DXUTPrepareEnumerationObject( true );
|
---|
985 |
|
---|
986 | DXUTMatchOptions matchOptions;
|
---|
987 | matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
|
---|
988 | matchOptions.eDeviceType = DXUTMT_IGNORE_INPUT;
|
---|
989 | matchOptions.eWindowed = DXUTMT_PRESERVE_INPUT;
|
---|
990 | matchOptions.eAdapterFormat = DXUTMT_IGNORE_INPUT;
|
---|
991 | matchOptions.eVertexProcessing = DXUTMT_IGNORE_INPUT;
|
---|
992 | if( bWindowed || (nSuggestedWidth != 0 && nSuggestedHeight != 0) )
|
---|
993 | matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
|
---|
994 | else
|
---|
995 | matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
|
---|
996 | matchOptions.eBackBufferFormat = DXUTMT_IGNORE_INPUT;
|
---|
997 | matchOptions.eBackBufferCount = DXUTMT_IGNORE_INPUT;
|
---|
998 | matchOptions.eMultiSample = DXUTMT_IGNORE_INPUT;
|
---|
999 | matchOptions.eSwapEffect = DXUTMT_IGNORE_INPUT;
|
---|
1000 | matchOptions.eDepthFormat = DXUTMT_IGNORE_INPUT;
|
---|
1001 | matchOptions.eStencilFormat = DXUTMT_IGNORE_INPUT;
|
---|
1002 | matchOptions.ePresentFlags = DXUTMT_IGNORE_INPUT;
|
---|
1003 | matchOptions.eRefreshRate = DXUTMT_IGNORE_INPUT;
|
---|
1004 | matchOptions.ePresentInterval = DXUTMT_IGNORE_INPUT;
|
---|
1005 |
|
---|
1006 | DXUTDeviceSettings deviceSettings;
|
---|
1007 | ZeroMemory( &deviceSettings, sizeof(DXUTDeviceSettings) );
|
---|
1008 | deviceSettings.AdapterOrdinal = AdapterOrdinal;
|
---|
1009 | deviceSettings.pp.Windowed = bWindowed;
|
---|
1010 | deviceSettings.pp.BackBufferWidth = nSuggestedWidth;
|
---|
1011 | deviceSettings.pp.BackBufferHeight = nSuggestedHeight;
|
---|
1012 |
|
---|
1013 | // Override with settings from the command line
|
---|
1014 | if( GetDXUTState().GetOverrideWidth() != 0 )
|
---|
1015 | deviceSettings.pp.BackBufferWidth = GetDXUTState().GetOverrideWidth();
|
---|
1016 | if( GetDXUTState().GetOverrideHeight() != 0 )
|
---|
1017 | deviceSettings.pp.BackBufferHeight = GetDXUTState().GetOverrideHeight();
|
---|
1018 |
|
---|
1019 | if( GetDXUTState().GetOverrideAdapterOrdinal() != -1 )
|
---|
1020 | deviceSettings.AdapterOrdinal = GetDXUTState().GetOverrideAdapterOrdinal();
|
---|
1021 |
|
---|
1022 | if( GetDXUTState().GetOverrideFullScreen() )
|
---|
1023 | {
|
---|
1024 | deviceSettings.pp.Windowed = FALSE;
|
---|
1025 | if( GetDXUTState().GetOverrideWidth() == 0 && GetDXUTState().GetOverrideHeight() == 0 )
|
---|
1026 | matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
|
---|
1027 | }
|
---|
1028 | if( GetDXUTState().GetOverrideWindowed() )
|
---|
1029 | deviceSettings.pp.Windowed = TRUE;
|
---|
1030 |
|
---|
1031 | if( GetDXUTState().GetOverrideForceHAL() )
|
---|
1032 | {
|
---|
1033 | deviceSettings.DeviceType = D3DDEVTYPE_HAL;
|
---|
1034 | matchOptions.eDeviceType = DXUTMT_PRESERVE_INPUT;
|
---|
1035 | }
|
---|
1036 | if( GetDXUTState().GetOverrideForceREF() )
|
---|
1037 | {
|
---|
1038 | deviceSettings.DeviceType = D3DDEVTYPE_REF;
|
---|
1039 | matchOptions.eDeviceType = DXUTMT_PRESERVE_INPUT;
|
---|
1040 | }
|
---|
1041 |
|
---|
1042 | if( GetDXUTState().GetOverrideForcePureHWVP() )
|
---|
1043 | {
|
---|
1044 | deviceSettings.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
|
---|
1045 | matchOptions.eVertexProcessing = DXUTMT_PRESERVE_INPUT;
|
---|
1046 | }
|
---|
1047 | else if( GetDXUTState().GetOverrideForceHWVP() )
|
---|
1048 | {
|
---|
1049 | deviceSettings.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
1050 | matchOptions.eVertexProcessing = DXUTMT_PRESERVE_INPUT;
|
---|
1051 | }
|
---|
1052 | else if( GetDXUTState().GetOverrideForceSWVP() )
|
---|
1053 | {
|
---|
1054 | deviceSettings.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
---|
1055 | matchOptions.eVertexProcessing = DXUTMT_PRESERVE_INPUT;
|
---|
1056 | }
|
---|
1057 |
|
---|
1058 | if( GetDXUTState().GetOverrideForceVsync() == 0 )
|
---|
1059 | {
|
---|
1060 | deviceSettings.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
---|
1061 | matchOptions.ePresentInterval = DXUTMT_PRESERVE_INPUT;
|
---|
1062 | }
|
---|
1063 | else if( GetDXUTState().GetOverrideForceVsync() == 1 )
|
---|
1064 | {
|
---|
1065 | deviceSettings.pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
---|
1066 | matchOptions.ePresentInterval = DXUTMT_PRESERVE_INPUT;
|
---|
1067 | }
|
---|
1068 |
|
---|
1069 | hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
|
---|
1070 | if( FAILED(hr) ) // the call will fail if no valid devices were found
|
---|
1071 | {
|
---|
1072 | DXUTDisplayErrorMessage( hr );
|
---|
1073 | return DXUT_ERR( L"DXUTFindValidDeviceSettings", hr );
|
---|
1074 | }
|
---|
1075 |
|
---|
1076 | // Change to a Direct3D device created from the new device settings.
|
---|
1077 | // If there is an existing device, then either reset or recreated the scene
|
---|
1078 | hr = DXUTChangeDevice( &deviceSettings, NULL, false, true );
|
---|
1079 | if( FAILED(hr) )
|
---|
1080 | return hr;
|
---|
1081 |
|
---|
1082 | return S_OK;
|
---|
1083 | }
|
---|
1084 |
|
---|
1085 |
|
---|
1086 | //--------------------------------------------------------------------------------------
|
---|
1087 | // Passes a previously created Direct3D device for use by the framework.
|
---|
1088 | // If DXUTCreateWindow() has not already been called, it will call it with the
|
---|
1089 | // default parameters. Instead of calling this, you can call DXUTCreateDevice() or
|
---|
1090 | // DXUTCreateDeviceFromSettings()
|
---|
1091 | //--------------------------------------------------------------------------------------
|
---|
1092 | HRESULT DXUTSetDevice( IDirect3DDevice9* pd3dDevice )
|
---|
1093 | {
|
---|
1094 | HRESULT hr;
|
---|
1095 |
|
---|
1096 | if( pd3dDevice == NULL )
|
---|
1097 | return DXUT_ERR_MSGBOX( L"DXUTSetDevice", E_INVALIDARG );
|
---|
1098 |
|
---|
1099 | // Not allowed to call this from inside the device callbacks
|
---|
1100 | if( GetDXUTState().GetInsideDeviceCallback() )
|
---|
1101 | return DXUT_ERR_MSGBOX( L"DXUTCreateWindow", E_FAIL );
|
---|
1102 |
|
---|
1103 | GetDXUTState().SetDeviceCreateCalled( true );
|
---|
1104 |
|
---|
1105 | // If DXUTCreateWindow() or DXUTSetWindow() has not already been called,
|
---|
1106 | // then call DXUTCreateWindow() with the default parameters.
|
---|
1107 | if( !GetDXUTState().GetWindowCreated() )
|
---|
1108 | {
|
---|
1109 | // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail.
|
---|
1110 | // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed
|
---|
1111 | if( GetDXUTState().GetWindowCreateCalled() )
|
---|
1112 | return E_FAIL;
|
---|
1113 |
|
---|
1114 | // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then
|
---|
1115 | // automatically call DXUTCreateWindow() with default params
|
---|
1116 | hr = DXUTCreateWindow();
|
---|
1117 | if( FAILED(hr) )
|
---|
1118 | return hr;
|
---|
1119 | }
|
---|
1120 |
|
---|
1121 | DXUTDeviceSettings* pDeviceSettings = new DXUTDeviceSettings;
|
---|
1122 | if( pDeviceSettings == NULL )
|
---|
1123 | return E_OUTOFMEMORY;
|
---|
1124 | ZeroMemory( pDeviceSettings, sizeof(DXUTDeviceSettings) );
|
---|
1125 |
|
---|
1126 | // Get the present params from the swap chain
|
---|
1127 | IDirect3DSurface9* pBackBuffer = NULL;
|
---|
1128 | hr = pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
|
---|
1129 | if( SUCCEEDED(hr) )
|
---|
1130 | {
|
---|
1131 | IDirect3DSwapChain9* pSwapChain = NULL;
|
---|
1132 | hr = pBackBuffer->GetContainer( IID_IDirect3DSwapChain9, (void**) &pSwapChain );
|
---|
1133 | if( SUCCEEDED(hr) )
|
---|
1134 | {
|
---|
1135 | pSwapChain->GetPresentParameters( &pDeviceSettings->pp );
|
---|
1136 | SAFE_RELEASE( pSwapChain );
|
---|
1137 | }
|
---|
1138 |
|
---|
1139 | SAFE_RELEASE( pBackBuffer );
|
---|
1140 | }
|
---|
1141 |
|
---|
1142 | D3DDEVICE_CREATION_PARAMETERS d3dCreationParams;
|
---|
1143 | pd3dDevice->GetCreationParameters( &d3dCreationParams );
|
---|
1144 |
|
---|
1145 | // Fill out the rest of the device settings struct
|
---|
1146 | pDeviceSettings->AdapterOrdinal = d3dCreationParams.AdapterOrdinal;
|
---|
1147 | pDeviceSettings->DeviceType = d3dCreationParams.DeviceType;
|
---|
1148 | DXUTFindAdapterFormat( pDeviceSettings->AdapterOrdinal, pDeviceSettings->DeviceType,
|
---|
1149 | pDeviceSettings->pp.BackBufferFormat, pDeviceSettings->pp.Windowed,
|
---|
1150 | &pDeviceSettings->AdapterFormat );
|
---|
1151 | pDeviceSettings->BehaviorFlags = d3dCreationParams.BehaviorFlags;
|
---|
1152 |
|
---|
1153 | // Change to the Direct3D device passed in
|
---|
1154 | hr = DXUTChangeDevice( pDeviceSettings, pd3dDevice, false, false );
|
---|
1155 |
|
---|
1156 | delete pDeviceSettings;
|
---|
1157 |
|
---|
1158 | if( FAILED(hr) )
|
---|
1159 | return hr;
|
---|
1160 |
|
---|
1161 | return S_OK;
|
---|
1162 | }
|
---|
1163 |
|
---|
1164 |
|
---|
1165 | //--------------------------------------------------------------------------------------
|
---|
1166 | // Tells the framework to change to a device created from the passed in device settings
|
---|
1167 | // If DXUTCreateWindow() has not already been called, it will call it with the
|
---|
1168 | // default parameters. Instead of calling this, you can call DXUTCreateDevice()
|
---|
1169 | // or DXUTSetDevice()
|
---|
1170 | //--------------------------------------------------------------------------------------
|
---|
1171 | HRESULT DXUTCreateDeviceFromSettings( DXUTDeviceSettings* pDeviceSettings, bool bPreserveInput, bool bClipWindowToSingleAdapter )
|
---|
1172 | {
|
---|
1173 | HRESULT hr;
|
---|
1174 |
|
---|
1175 | GetDXUTState().SetDeviceCreateCalled( true );
|
---|
1176 |
|
---|
1177 | // If DXUTCreateWindow() or DXUTSetWindow() has not already been called,
|
---|
1178 | // then call DXUTCreateWindow() with the default parameters.
|
---|
1179 | if( !GetDXUTState().GetWindowCreated() )
|
---|
1180 | {
|
---|
1181 | // If DXUTCreateWindow() or DXUTSetWindow() was already called and failed, then fail.
|
---|
1182 | // DXUTCreateWindow() or DXUTSetWindow() must first succeed for this function to succeed
|
---|
1183 | if( GetDXUTState().GetWindowCreateCalled() )
|
---|
1184 | return E_FAIL;
|
---|
1185 |
|
---|
1186 | // If DXUTCreateWindow() or DXUTSetWindow() hasn't been called, then
|
---|
1187 | // automatically call DXUTCreateWindow() with default params
|
---|
1188 | hr = DXUTCreateWindow();
|
---|
1189 | if( FAILED(hr) )
|
---|
1190 | return hr;
|
---|
1191 | }
|
---|
1192 |
|
---|
1193 | if( !bPreserveInput )
|
---|
1194 | {
|
---|
1195 | // If not preserving the input, then find the closest valid to it
|
---|
1196 | DXUTMatchOptions matchOptions;
|
---|
1197 | matchOptions.eAdapterOrdinal = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1198 | matchOptions.eDeviceType = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1199 | matchOptions.eWindowed = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1200 | matchOptions.eAdapterFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1201 | matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1202 | matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1203 | matchOptions.eBackBufferFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1204 | matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1205 | matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1206 | matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1207 | matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1208 | matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1209 | matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1210 | matchOptions.eRefreshRate = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1211 | matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1212 |
|
---|
1213 | hr = DXUTFindValidDeviceSettings( pDeviceSettings, pDeviceSettings, &matchOptions );
|
---|
1214 | if( FAILED(hr) ) // the call will fail if no valid devices were found
|
---|
1215 | {
|
---|
1216 | DXUTDisplayErrorMessage( hr );
|
---|
1217 | return DXUT_ERR( L"DXUTFindValidDeviceSettings", hr );
|
---|
1218 | }
|
---|
1219 | }
|
---|
1220 |
|
---|
1221 | // Change to a Direct3D device created from the new device settings.
|
---|
1222 | // If there is an existing device, then either reset or recreate the scene
|
---|
1223 | hr = DXUTChangeDevice( pDeviceSettings, NULL, false, bClipWindowToSingleAdapter );
|
---|
1224 | if( FAILED(hr) )
|
---|
1225 | return hr;
|
---|
1226 |
|
---|
1227 | return S_OK;
|
---|
1228 | }
|
---|
1229 |
|
---|
1230 |
|
---|
1231 | //--------------------------------------------------------------------------------------
|
---|
1232 | // Toggle between full screen and windowed
|
---|
1233 | //--------------------------------------------------------------------------------------
|
---|
1234 | HRESULT DXUTToggleFullScreen()
|
---|
1235 | {
|
---|
1236 | HRESULT hr;
|
---|
1237 |
|
---|
1238 | // Get the current device settings and flip the windowed state then
|
---|
1239 | // find the closest valid device settings with this change
|
---|
1240 | DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
|
---|
1241 | deviceSettings.pp.Windowed = !deviceSettings.pp.Windowed;
|
---|
1242 |
|
---|
1243 | DXUTMatchOptions matchOptions;
|
---|
1244 | matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
|
---|
1245 | matchOptions.eDeviceType = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1246 | matchOptions.eWindowed = DXUTMT_PRESERVE_INPUT;
|
---|
1247 | matchOptions.eAdapterFormat = DXUTMT_IGNORE_INPUT;
|
---|
1248 | matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1249 | matchOptions.eBackBufferFormat = DXUTMT_IGNORE_INPUT;
|
---|
1250 | matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1251 | matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1252 | matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1253 | matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1254 | matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1255 | matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1256 | matchOptions.eRefreshRate = DXUTMT_IGNORE_INPUT;
|
---|
1257 | matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1258 |
|
---|
1259 | // Go back to previous state
|
---|
1260 |
|
---|
1261 | UINT nWidth = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferWidthAtModeChange() : GetDXUTState().GetFullScreenBackBufferWidthAtModeChange();
|
---|
1262 | UINT nHeight = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferHeightAtModeChange() : GetDXUTState().GetFullScreenBackBufferHeightAtModeChange();
|
---|
1263 | if( nWidth > 0 && nHeight > 0 )
|
---|
1264 | {
|
---|
1265 | matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1266 | deviceSettings.pp.BackBufferWidth = nWidth;
|
---|
1267 | deviceSettings.pp.BackBufferHeight = nHeight;
|
---|
1268 | }
|
---|
1269 | else
|
---|
1270 | {
|
---|
1271 | // No previous data, so just switch to defaults
|
---|
1272 | matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
|
---|
1273 | }
|
---|
1274 |
|
---|
1275 | hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
|
---|
1276 | if( SUCCEEDED(hr) )
|
---|
1277 | {
|
---|
1278 | // Create a Direct3D device using the new device settings.
|
---|
1279 | // If there is an existing device, then it will either reset or recreate the scene.
|
---|
1280 | hr = DXUTChangeDevice( &deviceSettings, NULL, false, false );
|
---|
1281 |
|
---|
1282 | // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback so nothing changed
|
---|
1283 | if( FAILED(hr) && (hr != E_ABORT) )
|
---|
1284 | {
|
---|
1285 | // Failed creating device, try to switch back.
|
---|
1286 | deviceSettings.pp.Windowed = !deviceSettings.pp.Windowed;
|
---|
1287 | UINT nWidth = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferWidthAtModeChange() : GetDXUTState().GetFullScreenBackBufferWidthAtModeChange();
|
---|
1288 | UINT nHeight = ( deviceSettings.pp.Windowed ) ? GetDXUTState().GetWindowBackBufferHeightAtModeChange() : GetDXUTState().GetFullScreenBackBufferHeightAtModeChange();
|
---|
1289 | if( nWidth > 0 && nHeight > 0 )
|
---|
1290 | {
|
---|
1291 | matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1292 | deviceSettings.pp.BackBufferWidth = nWidth;
|
---|
1293 | deviceSettings.pp.BackBufferHeight = nHeight;
|
---|
1294 | }
|
---|
1295 | else
|
---|
1296 | {
|
---|
1297 | matchOptions.eResolution = DXUTMT_IGNORE_INPUT;
|
---|
1298 | }
|
---|
1299 |
|
---|
1300 | DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
|
---|
1301 |
|
---|
1302 | HRESULT hr2 = DXUTChangeDevice( &deviceSettings, NULL, false, false );
|
---|
1303 | if( FAILED(hr2) )
|
---|
1304 | {
|
---|
1305 | // If this failed, then shutdown
|
---|
1306 | DXUTShutdown();
|
---|
1307 | }
|
---|
1308 | }
|
---|
1309 | }
|
---|
1310 |
|
---|
1311 | return hr;
|
---|
1312 | }
|
---|
1313 |
|
---|
1314 |
|
---|
1315 | //--------------------------------------------------------------------------------------
|
---|
1316 | // Toggle between HAL and REF
|
---|
1317 | //--------------------------------------------------------------------------------------
|
---|
1318 | HRESULT DXUTToggleREF()
|
---|
1319 | {
|
---|
1320 | HRESULT hr;
|
---|
1321 |
|
---|
1322 | DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
|
---|
1323 | if( deviceSettings.DeviceType == D3DDEVTYPE_HAL )
|
---|
1324 | deviceSettings.DeviceType = D3DDEVTYPE_REF;
|
---|
1325 | else if( deviceSettings.DeviceType == D3DDEVTYPE_REF )
|
---|
1326 | deviceSettings.DeviceType = D3DDEVTYPE_HAL;
|
---|
1327 |
|
---|
1328 | DXUTMatchOptions matchOptions;
|
---|
1329 | matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
|
---|
1330 | matchOptions.eDeviceType = DXUTMT_PRESERVE_INPUT;
|
---|
1331 | matchOptions.eWindowed = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1332 | matchOptions.eAdapterFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1333 | matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1334 | matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1335 | matchOptions.eBackBufferFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1336 | matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1337 | matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1338 | matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1339 | matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1340 | matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1341 | matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1342 | matchOptions.eRefreshRate = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1343 | matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
|
---|
1344 |
|
---|
1345 | hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
|
---|
1346 | if( SUCCEEDED(hr) )
|
---|
1347 | {
|
---|
1348 | // Create a Direct3D device using the new device settings.
|
---|
1349 | // If there is an existing device, then it will either reset or recreate the scene.
|
---|
1350 | hr = DXUTChangeDevice( &deviceSettings, NULL, false, false );
|
---|
1351 |
|
---|
1352 | // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback so nothing changed
|
---|
1353 | if( FAILED( hr ) && (hr != E_ABORT) )
|
---|
1354 | {
|
---|
1355 | // Failed creating device, try to switch back.
|
---|
1356 | if( deviceSettings.DeviceType == D3DDEVTYPE_HAL )
|
---|
1357 | deviceSettings.DeviceType = D3DDEVTYPE_REF;
|
---|
1358 | else if( deviceSettings.DeviceType == D3DDEVTYPE_REF )
|
---|
1359 | deviceSettings.DeviceType = D3DDEVTYPE_HAL;
|
---|
1360 |
|
---|
1361 | DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
|
---|
1362 |
|
---|
1363 | HRESULT hr2 = DXUTChangeDevice( &deviceSettings, NULL, false, false );
|
---|
1364 | if( FAILED(hr2) )
|
---|
1365 | {
|
---|
1366 | // If this failed, then shutdown
|
---|
1367 | DXUTShutdown();
|
---|
1368 | }
|
---|
1369 | }
|
---|
1370 | }
|
---|
1371 |
|
---|
1372 | return hr;
|
---|
1373 | }
|
---|
1374 |
|
---|
1375 |
|
---|
1376 | //--------------------------------------------------------------------------------------
|
---|
1377 | // Internal helper function to prepare the enumeration object by creating it if it
|
---|
1378 | // didn't already exist and enumerating if desired.
|
---|
1379 | //--------------------------------------------------------------------------------------
|
---|
1380 | CD3DEnumeration* DXUTPrepareEnumerationObject( bool bEnumerate )
|
---|
1381 | {
|
---|
1382 | // Create a new CD3DEnumeration object and enumerate all devices unless its already been done
|
---|
1383 | CD3DEnumeration* pd3dEnum = GetDXUTState().GetD3DEnumeration();
|
---|
1384 | if( pd3dEnum == NULL )
|
---|
1385 | {
|
---|
1386 | pd3dEnum = DXUTGetEnumeration();
|
---|
1387 | GetDXUTState().SetD3DEnumeration( pd3dEnum );
|
---|
1388 |
|
---|
1389 | bEnumerate = true;
|
---|
1390 | }
|
---|
1391 |
|
---|
1392 | if( bEnumerate )
|
---|
1393 | {
|
---|
1394 | // Enumerate for each adapter all of the supported display modes,
|
---|
1395 | // device types, adapter formats, back buffer formats, window/full screen support,
|
---|
1396 | // depth stencil formats, multisampling types/qualities, and presentations intervals.
|
---|
1397 | //
|
---|
1398 | // For each combination of device type (HAL/REF), adapter format, back buffer format, and
|
---|
1399 | // IsWindowed it will call the app's ConfirmDevice callback. This allows the app
|
---|
1400 | // to reject or allow that combination based on its caps/etc. It also allows the
|
---|
1401 | // app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP
|
---|
1402 | // if supported otherwise it will default to SWVP, however the app can change this
|
---|
1403 | // through the ConfirmDevice callback.
|
---|
1404 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
1405 | pd3dEnum->Enumerate( pD3D, GetDXUTState().GetIsDeviceAcceptableFunc(), GetDXUTState().GetIsDeviceAcceptableFuncUserContext() );
|
---|
1406 | }
|
---|
1407 |
|
---|
1408 | return pd3dEnum;
|
---|
1409 | }
|
---|
1410 |
|
---|
1411 |
|
---|
1412 | //--------------------------------------------------------------------------------------
|
---|
1413 | // This function tries to find valid device settings based upon the input device settings
|
---|
1414 | // struct and the match options. For each device setting a match option in the
|
---|
1415 | // DXUTMatchOptions struct specifies how the function makes decisions. For example, if
|
---|
1416 | // the caller wants a HAL device with a back buffer format of D3DFMT_A2B10G10R10 but the
|
---|
1417 | // HAL device on the system does not support D3DFMT_A2B10G10R10 however a REF device is
|
---|
1418 | // installed that does, then the function has a choice to either use REF or to change to
|
---|
1419 | // a back buffer format to compatible with the HAL device. The match options lets the
|
---|
1420 | // caller control how these choices are made.
|
---|
1421 | //
|
---|
1422 | // Each match option must be one of the following types:
|
---|
1423 | // DXUTMT_IGNORE_INPUT: Uses the closest valid value to a default
|
---|
1424 | // DXUTMT_PRESERVE_INPUT: Uses the input without change, but may cause no valid device to be found
|
---|
1425 | // DXUTMT_CLOSEST_TO_INPUT: Uses the closest valid value to the input
|
---|
1426 | //
|
---|
1427 | // If pMatchOptions is NULL then, all of the match options are assumed to be DXUTMT_IGNORE_INPUT.
|
---|
1428 | // The function returns failure if no valid device settings can be found otherwise
|
---|
1429 | // the function returns success and the valid device settings are written to pOut.
|
---|
1430 | //--------------------------------------------------------------------------------------
|
---|
1431 | HRESULT DXUTFindValidDeviceSettings( DXUTDeviceSettings* pOut, DXUTDeviceSettings* pIn,
|
---|
1432 | DXUTMatchOptions* pMatchOptions )
|
---|
1433 | {
|
---|
1434 | if( pOut == NULL )
|
---|
1435 | return DXUT_ERR_MSGBOX( L"DXUTFindValidDeviceSettings", E_INVALIDARG );
|
---|
1436 |
|
---|
1437 | CD3DEnumeration* pd3dEnum = DXUTPrepareEnumerationObject( false );
|
---|
1438 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
1439 |
|
---|
1440 | // Default to DXUTMT_IGNORE_INPUT for everything unless pMatchOptions isn't NULL
|
---|
1441 | DXUTMatchOptions defaultMatchOptions;
|
---|
1442 | if( NULL == pMatchOptions )
|
---|
1443 | {
|
---|
1444 | ZeroMemory( &defaultMatchOptions, sizeof(DXUTMatchOptions) );
|
---|
1445 | pMatchOptions = &defaultMatchOptions;
|
---|
1446 | }
|
---|
1447 |
|
---|
1448 | // Build an optimal device settings structure based upon the match
|
---|
1449 | // options. If the match option is set to ignore, then a optimal default value is used.
|
---|
1450 | // The default value may not exist on the system, but later this will be taken
|
---|
1451 | // into account.
|
---|
1452 | DXUTDeviceSettings optimalDeviceSettings;
|
---|
1453 | DXUTBuildOptimalDeviceSettings( &optimalDeviceSettings, pIn, pMatchOptions );
|
---|
1454 |
|
---|
1455 | // Find the best combination of:
|
---|
1456 | // Adapter Ordinal
|
---|
1457 | // Device Type
|
---|
1458 | // Adapter Format
|
---|
1459 | // Back Buffer Format
|
---|
1460 | // Windowed
|
---|
1461 | // given what's available on the system and the match options combined with the device settings input.
|
---|
1462 | // This combination of settings is encapsulated by the CD3DEnumDeviceSettingsCombo class.
|
---|
1463 | float fBestRanking = -1.0f;
|
---|
1464 | CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo = NULL;
|
---|
1465 | D3DDISPLAYMODE adapterDesktopDisplayMode;
|
---|
1466 |
|
---|
1467 | CGrowableArray<CD3DEnumAdapterInfo*>* pAdapterList = pd3dEnum->GetAdapterInfoList();
|
---|
1468 | for( int iAdapter=0; iAdapter<pAdapterList->GetSize(); iAdapter++ )
|
---|
1469 | {
|
---|
1470 | CD3DEnumAdapterInfo* pAdapterInfo = pAdapterList->GetAt(iAdapter);
|
---|
1471 |
|
---|
1472 | // Get the desktop display mode of adapter
|
---|
1473 | pD3D->GetAdapterDisplayMode( pAdapterInfo->AdapterOrdinal, &adapterDesktopDisplayMode );
|
---|
1474 |
|
---|
1475 | // Enum all the device types supported by this adapter to find the best device settings
|
---|
1476 | for( int iDeviceInfo=0; iDeviceInfo<pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ )
|
---|
1477 | {
|
---|
1478 | CD3DEnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt(iDeviceInfo);
|
---|
1479 |
|
---|
1480 | // Enum all the device settings combinations. A device settings combination is
|
---|
1481 | // a unique set of an adapter format, back buffer format, and IsWindowed.
|
---|
1482 | for( int iDeviceCombo=0; iDeviceCombo<pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )
|
---|
1483 | {
|
---|
1484 | CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt(iDeviceCombo);
|
---|
1485 |
|
---|
1486 | // If windowed mode the adapter format has to be the same as the desktop
|
---|
1487 | // display mode format so skip any that don't match
|
---|
1488 | if (pDeviceSettingsCombo->Windowed && (pDeviceSettingsCombo->AdapterFormat != adapterDesktopDisplayMode.Format))
|
---|
1489 | continue;
|
---|
1490 |
|
---|
1491 | // Skip any combo that doesn't meet the preserve match options
|
---|
1492 | if( false == DXUTDoesDeviceComboMatchPreserveOptions( pDeviceSettingsCombo, pIn, pMatchOptions ) )
|
---|
1493 | continue;
|
---|
1494 |
|
---|
1495 | // Get a ranking number that describes how closely this device combo matches the optimal combo
|
---|
1496 | float fCurRanking = DXUTRankDeviceCombo( pDeviceSettingsCombo, &optimalDeviceSettings, &adapterDesktopDisplayMode );
|
---|
1497 |
|
---|
1498 | // If this combo better matches the input device settings then save it
|
---|
1499 | if( fCurRanking > fBestRanking )
|
---|
1500 | {
|
---|
1501 | pBestDeviceSettingsCombo = pDeviceSettingsCombo;
|
---|
1502 | fBestRanking = fCurRanking;
|
---|
1503 | }
|
---|
1504 | }
|
---|
1505 | }
|
---|
1506 | }
|
---|
1507 |
|
---|
1508 | // If no best device combination was found then fail
|
---|
1509 | if( pBestDeviceSettingsCombo == NULL )
|
---|
1510 | return DXUTERR_NOCOMPATIBLEDEVICES;
|
---|
1511 |
|
---|
1512 | // Using the best device settings combo found, build valid device settings taking heed of
|
---|
1513 | // the match options and the input device settings
|
---|
1514 | DXUTDeviceSettings validDeviceSettings;
|
---|
1515 | DXUTBuildValidDeviceSettings( &validDeviceSettings, pBestDeviceSettingsCombo, pIn, pMatchOptions );
|
---|
1516 | *pOut = validDeviceSettings;
|
---|
1517 |
|
---|
1518 | return S_OK;
|
---|
1519 | }
|
---|
1520 |
|
---|
1521 |
|
---|
1522 | //--------------------------------------------------------------------------------------
|
---|
1523 | // Internal helper function to build a device settings structure based upon the match
|
---|
1524 | // options. If the match option is set to ignore, then a optimal default value is used.
|
---|
1525 | // The default value may not exist on the system, but later this will be taken
|
---|
1526 | // into account.
|
---|
1527 | //--------------------------------------------------------------------------------------
|
---|
1528 | void DXUTBuildOptimalDeviceSettings( DXUTDeviceSettings* pOptimalDeviceSettings,
|
---|
1529 | DXUTDeviceSettings* pDeviceSettingsIn,
|
---|
1530 | DXUTMatchOptions* pMatchOptions )
|
---|
1531 | {
|
---|
1532 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
1533 | D3DDISPLAYMODE adapterDesktopDisplayMode;
|
---|
1534 |
|
---|
1535 | ZeroMemory( pOptimalDeviceSettings, sizeof(DXUTDeviceSettings) );
|
---|
1536 |
|
---|
1537 | //---------------------
|
---|
1538 | // Adapter ordinal
|
---|
1539 | //---------------------
|
---|
1540 | if( pMatchOptions->eAdapterOrdinal == DXUTMT_IGNORE_INPUT )
|
---|
1541 | pOptimalDeviceSettings->AdapterOrdinal = D3DADAPTER_DEFAULT;
|
---|
1542 | else
|
---|
1543 | pOptimalDeviceSettings->AdapterOrdinal = pDeviceSettingsIn->AdapterOrdinal;
|
---|
1544 |
|
---|
1545 | //---------------------
|
---|
1546 | // Device type
|
---|
1547 | //---------------------
|
---|
1548 | if( pMatchOptions->eDeviceType == DXUTMT_IGNORE_INPUT )
|
---|
1549 | pOptimalDeviceSettings->DeviceType = D3DDEVTYPE_HAL;
|
---|
1550 | else
|
---|
1551 | pOptimalDeviceSettings->DeviceType = pDeviceSettingsIn->DeviceType;
|
---|
1552 |
|
---|
1553 | //---------------------
|
---|
1554 | // Windowed
|
---|
1555 | //---------------------
|
---|
1556 | if( pMatchOptions->eWindowed == DXUTMT_IGNORE_INPUT )
|
---|
1557 | pOptimalDeviceSettings->pp.Windowed = TRUE;
|
---|
1558 | else
|
---|
1559 | pOptimalDeviceSettings->pp.Windowed = pDeviceSettingsIn->pp.Windowed;
|
---|
1560 |
|
---|
1561 | //---------------------
|
---|
1562 | // Adapter format
|
---|
1563 | //---------------------
|
---|
1564 | if( pMatchOptions->eAdapterFormat == DXUTMT_IGNORE_INPUT )
|
---|
1565 | {
|
---|
1566 | // If windowed, default to the desktop display mode
|
---|
1567 | // If fullscreen, default to the desktop display mode for quick mode change or
|
---|
1568 | // default to D3DFMT_X8R8G8B8 if the desktop display mode is < 32bit
|
---|
1569 | pD3D->GetAdapterDisplayMode( pOptimalDeviceSettings->AdapterOrdinal, &adapterDesktopDisplayMode );
|
---|
1570 | if( pOptimalDeviceSettings->pp.Windowed || DXUTColorChannelBits(adapterDesktopDisplayMode.Format) >= 8 )
|
---|
1571 | pOptimalDeviceSettings->AdapterFormat = adapterDesktopDisplayMode.Format;
|
---|
1572 | else
|
---|
1573 | pOptimalDeviceSettings->AdapterFormat = D3DFMT_X8R8G8B8;
|
---|
1574 | }
|
---|
1575 | else
|
---|
1576 | {
|
---|
1577 | pOptimalDeviceSettings->AdapterFormat = pDeviceSettingsIn->AdapterFormat;
|
---|
1578 | }
|
---|
1579 |
|
---|
1580 | //---------------------
|
---|
1581 | // Vertex processing
|
---|
1582 | //---------------------
|
---|
1583 | if( pMatchOptions->eVertexProcessing == DXUTMT_IGNORE_INPUT )
|
---|
1584 | pOptimalDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
1585 | else
|
---|
1586 | pOptimalDeviceSettings->BehaviorFlags = pDeviceSettingsIn->BehaviorFlags;
|
---|
1587 |
|
---|
1588 | //---------------------
|
---|
1589 | // Resolution
|
---|
1590 | //---------------------
|
---|
1591 | if( pMatchOptions->eResolution == DXUTMT_IGNORE_INPUT )
|
---|
1592 | {
|
---|
1593 | // If windowed, default to 640x480
|
---|
1594 | // If fullscreen, default to the desktop res for quick mode change
|
---|
1595 | if( pOptimalDeviceSettings->pp.Windowed )
|
---|
1596 | {
|
---|
1597 | pOptimalDeviceSettings->pp.BackBufferWidth = 640;
|
---|
1598 | pOptimalDeviceSettings->pp.BackBufferHeight = 480;
|
---|
1599 | }
|
---|
1600 | else
|
---|
1601 | {
|
---|
1602 | pD3D->GetAdapterDisplayMode( pOptimalDeviceSettings->AdapterOrdinal, &adapterDesktopDisplayMode );
|
---|
1603 | pOptimalDeviceSettings->pp.BackBufferWidth = adapterDesktopDisplayMode.Width;
|
---|
1604 | pOptimalDeviceSettings->pp.BackBufferHeight = adapterDesktopDisplayMode.Height;
|
---|
1605 | }
|
---|
1606 | }
|
---|
1607 | else
|
---|
1608 | {
|
---|
1609 | pOptimalDeviceSettings->pp.BackBufferWidth = pDeviceSettingsIn->pp.BackBufferWidth;
|
---|
1610 | pOptimalDeviceSettings->pp.BackBufferHeight = pDeviceSettingsIn->pp.BackBufferHeight;
|
---|
1611 | }
|
---|
1612 |
|
---|
1613 | //---------------------
|
---|
1614 | // Back buffer format
|
---|
1615 | //---------------------
|
---|
1616 | if( pMatchOptions->eBackBufferFormat == DXUTMT_IGNORE_INPUT )
|
---|
1617 | pOptimalDeviceSettings->pp.BackBufferFormat = pOptimalDeviceSettings->AdapterFormat; // Default to match the adapter format
|
---|
1618 | else
|
---|
1619 | pOptimalDeviceSettings->pp.BackBufferFormat = pDeviceSettingsIn->pp.BackBufferFormat;
|
---|
1620 |
|
---|
1621 | //---------------------
|
---|
1622 | // Back buffer count
|
---|
1623 | //---------------------
|
---|
1624 | if( pMatchOptions->eBackBufferCount == DXUTMT_IGNORE_INPUT )
|
---|
1625 | pOptimalDeviceSettings->pp.BackBufferCount = 2; // Default to triple buffering for perf gain
|
---|
1626 | else
|
---|
1627 | pOptimalDeviceSettings->pp.BackBufferCount = pDeviceSettingsIn->pp.BackBufferCount;
|
---|
1628 |
|
---|
1629 | //---------------------
|
---|
1630 | // Multisample
|
---|
1631 | //---------------------
|
---|
1632 | if( pMatchOptions->eMultiSample == DXUTMT_IGNORE_INPUT )
|
---|
1633 | {
|
---|
1634 | // Default to no multisampling
|
---|
1635 | pOptimalDeviceSettings->pp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
---|
1636 | pOptimalDeviceSettings->pp.MultiSampleQuality = 0;
|
---|
1637 | }
|
---|
1638 | else
|
---|
1639 | {
|
---|
1640 | pOptimalDeviceSettings->pp.MultiSampleType = pDeviceSettingsIn->pp.MultiSampleType;
|
---|
1641 | pOptimalDeviceSettings->pp.MultiSampleQuality = pDeviceSettingsIn->pp.MultiSampleQuality;
|
---|
1642 | }
|
---|
1643 |
|
---|
1644 | //---------------------
|
---|
1645 | // Swap effect
|
---|
1646 | //---------------------
|
---|
1647 | if( pMatchOptions->eSwapEffect == DXUTMT_IGNORE_INPUT )
|
---|
1648 | pOptimalDeviceSettings->pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
---|
1649 | else
|
---|
1650 | pOptimalDeviceSettings->pp.SwapEffect = pDeviceSettingsIn->pp.SwapEffect;
|
---|
1651 |
|
---|
1652 | //---------------------
|
---|
1653 | // Depth stencil
|
---|
1654 | //---------------------
|
---|
1655 | if( pMatchOptions->eDepthFormat == DXUTMT_IGNORE_INPUT &&
|
---|
1656 | pMatchOptions->eStencilFormat == DXUTMT_IGNORE_INPUT )
|
---|
1657 | {
|
---|
1658 | UINT nBackBufferBits = DXUTColorChannelBits( pOptimalDeviceSettings->pp.BackBufferFormat );
|
---|
1659 | if( nBackBufferBits >= 8 )
|
---|
1660 | pOptimalDeviceSettings->pp.AutoDepthStencilFormat = D3DFMT_D32;
|
---|
1661 | else
|
---|
1662 | pOptimalDeviceSettings->pp.AutoDepthStencilFormat = D3DFMT_D16;
|
---|
1663 | }
|
---|
1664 | else
|
---|
1665 | {
|
---|
1666 | pOptimalDeviceSettings->pp.AutoDepthStencilFormat = pDeviceSettingsIn->pp.AutoDepthStencilFormat;
|
---|
1667 | }
|
---|
1668 |
|
---|
1669 | //---------------------
|
---|
1670 | // Present flags
|
---|
1671 | //---------------------
|
---|
1672 | if( pMatchOptions->ePresentFlags == DXUTMT_IGNORE_INPUT )
|
---|
1673 | pOptimalDeviceSettings->pp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
|
---|
1674 | else
|
---|
1675 | pOptimalDeviceSettings->pp.Flags = pDeviceSettingsIn->pp.Flags;
|
---|
1676 |
|
---|
1677 | //---------------------
|
---|
1678 | // Refresh rate
|
---|
1679 | //---------------------
|
---|
1680 | if( pMatchOptions->eRefreshRate == DXUTMT_IGNORE_INPUT )
|
---|
1681 | pOptimalDeviceSettings->pp.FullScreen_RefreshRateInHz = 0;
|
---|
1682 | else
|
---|
1683 | pOptimalDeviceSettings->pp.FullScreen_RefreshRateInHz = pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz;
|
---|
1684 |
|
---|
1685 | //---------------------
|
---|
1686 | // Present interval
|
---|
1687 | //---------------------
|
---|
1688 | if( pMatchOptions->ePresentInterval == DXUTMT_IGNORE_INPUT )
|
---|
1689 | {
|
---|
1690 | // For windowed and fullscreen, default to D3DPRESENT_INTERVAL_DEFAULT
|
---|
1691 | // which will wait for the vertical retrace period to prevent tearing.
|
---|
1692 | // For benchmarking, use D3DPRESENT_INTERVAL_DEFAULT which will
|
---|
1693 | // will wait not for the vertical retrace period but may introduce tearing.
|
---|
1694 | pOptimalDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
---|
1695 | }
|
---|
1696 | else
|
---|
1697 | {
|
---|
1698 | pOptimalDeviceSettings->pp.PresentationInterval = pDeviceSettingsIn->pp.PresentationInterval;
|
---|
1699 | }
|
---|
1700 | }
|
---|
1701 |
|
---|
1702 |
|
---|
1703 | //--------------------------------------------------------------------------------------
|
---|
1704 | // Returns false for any CD3DEnumDeviceSettingsCombo that doesn't meet the preserve
|
---|
1705 | // match options against the input pDeviceSettingsIn.
|
---|
1706 | //--------------------------------------------------------------------------------------
|
---|
1707 | bool DXUTDoesDeviceComboMatchPreserveOptions( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo,
|
---|
1708 | DXUTDeviceSettings* pDeviceSettingsIn,
|
---|
1709 | DXUTMatchOptions* pMatchOptions )
|
---|
1710 | {
|
---|
1711 | //---------------------
|
---|
1712 | // Adapter ordinal
|
---|
1713 | //---------------------
|
---|
1714 | if( pMatchOptions->eAdapterOrdinal == DXUTMT_PRESERVE_INPUT &&
|
---|
1715 | (pDeviceSettingsCombo->AdapterOrdinal != pDeviceSettingsIn->AdapterOrdinal) )
|
---|
1716 | return false;
|
---|
1717 |
|
---|
1718 | //---------------------
|
---|
1719 | // Device type
|
---|
1720 | //---------------------
|
---|
1721 | if( pMatchOptions->eDeviceType == DXUTMT_PRESERVE_INPUT &&
|
---|
1722 | (pDeviceSettingsCombo->DeviceType != pDeviceSettingsIn->DeviceType) )
|
---|
1723 | return false;
|
---|
1724 |
|
---|
1725 | //---------------------
|
---|
1726 | // Windowed
|
---|
1727 | //---------------------
|
---|
1728 | if( pMatchOptions->eWindowed == DXUTMT_PRESERVE_INPUT &&
|
---|
1729 | (pDeviceSettingsCombo->Windowed != pDeviceSettingsIn->pp.Windowed) )
|
---|
1730 | return false;
|
---|
1731 |
|
---|
1732 | //---------------------
|
---|
1733 | // Adapter format
|
---|
1734 | //---------------------
|
---|
1735 | if( pMatchOptions->eAdapterFormat == DXUTMT_PRESERVE_INPUT &&
|
---|
1736 | (pDeviceSettingsCombo->AdapterFormat != pDeviceSettingsIn->AdapterFormat) )
|
---|
1737 | return false;
|
---|
1738 |
|
---|
1739 | //---------------------
|
---|
1740 | // Vertex processing
|
---|
1741 | //---------------------
|
---|
1742 | // If keep VP and input has HWVP, then skip if this combo doesn't have HWTL
|
---|
1743 | if( pMatchOptions->eVertexProcessing == DXUTMT_PRESERVE_INPUT &&
|
---|
1744 | ((pDeviceSettingsIn->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0) &&
|
---|
1745 | ((pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0) )
|
---|
1746 | return false;
|
---|
1747 |
|
---|
1748 | //---------------------
|
---|
1749 | // Resolution
|
---|
1750 | //---------------------
|
---|
1751 | // If keep resolution then check that width and height supported by this combo
|
---|
1752 | if( pMatchOptions->eResolution == DXUTMT_PRESERVE_INPUT )
|
---|
1753 | {
|
---|
1754 | bool bFound = false;
|
---|
1755 | for( int i=0; i< pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); i++ )
|
---|
1756 | {
|
---|
1757 | D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( i );
|
---|
1758 | if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
|
---|
1759 | continue; // Skip this display mode if it doesn't match the combo's adapter format
|
---|
1760 |
|
---|
1761 | if( displayMode.Width == pDeviceSettingsIn->pp.BackBufferWidth &&
|
---|
1762 | displayMode.Height == pDeviceSettingsIn->pp.BackBufferHeight )
|
---|
1763 | {
|
---|
1764 | bFound = true;
|
---|
1765 | break;
|
---|
1766 | }
|
---|
1767 | }
|
---|
1768 |
|
---|
1769 | // If the width and height are not supported by this combo, return false
|
---|
1770 | if( !bFound )
|
---|
1771 | return false;
|
---|
1772 | }
|
---|
1773 |
|
---|
1774 | //---------------------
|
---|
1775 | // Back buffer format
|
---|
1776 | //---------------------
|
---|
1777 | if( pMatchOptions->eBackBufferFormat == DXUTMT_PRESERVE_INPUT &&
|
---|
1778 | pDeviceSettingsCombo->BackBufferFormat != pDeviceSettingsIn->pp.BackBufferFormat )
|
---|
1779 | return false;
|
---|
1780 |
|
---|
1781 | //---------------------
|
---|
1782 | // Back buffer count
|
---|
1783 | //---------------------
|
---|
1784 | // No caps for the back buffer count
|
---|
1785 |
|
---|
1786 | //---------------------
|
---|
1787 | // Multisample
|
---|
1788 | //---------------------
|
---|
1789 | if( pMatchOptions->eMultiSample == DXUTMT_PRESERVE_INPUT )
|
---|
1790 | {
|
---|
1791 | bool bFound = false;
|
---|
1792 | for( int i=0; i<pDeviceSettingsCombo->multiSampleTypeList.GetSize(); i++ )
|
---|
1793 | {
|
---|
1794 | D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt(i);
|
---|
1795 | DWORD msQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt(i);
|
---|
1796 |
|
---|
1797 | if( msType == pDeviceSettingsIn->pp.MultiSampleType &&
|
---|
1798 | msQuality >= pDeviceSettingsIn->pp.MultiSampleQuality )
|
---|
1799 | {
|
---|
1800 | bFound = true;
|
---|
1801 | break;
|
---|
1802 | }
|
---|
1803 | }
|
---|
1804 |
|
---|
1805 | // If multisample type/quality not supported by this combo, then return false
|
---|
1806 | if( !bFound )
|
---|
1807 | return false;
|
---|
1808 | }
|
---|
1809 |
|
---|
1810 | //---------------------
|
---|
1811 | // Swap effect
|
---|
1812 | //---------------------
|
---|
1813 | // No caps for swap effects
|
---|
1814 |
|
---|
1815 | //---------------------
|
---|
1816 | // Depth stencil
|
---|
1817 | //---------------------
|
---|
1818 | // If keep depth stencil format then check that the depth stencil format is supported by this combo
|
---|
1819 | if( pMatchOptions->eDepthFormat == DXUTMT_PRESERVE_INPUT &&
|
---|
1820 | pMatchOptions->eStencilFormat == DXUTMT_PRESERVE_INPUT )
|
---|
1821 | {
|
---|
1822 | if( pDeviceSettingsIn->pp.AutoDepthStencilFormat != D3DFMT_UNKNOWN &&
|
---|
1823 | !pDeviceSettingsCombo->depthStencilFormatList.Contains( pDeviceSettingsIn->pp.AutoDepthStencilFormat ) )
|
---|
1824 | return false;
|
---|
1825 | }
|
---|
1826 |
|
---|
1827 | // If keep depth format then check that the depth format is supported by this combo
|
---|
1828 | if( pMatchOptions->eDepthFormat == DXUTMT_PRESERVE_INPUT &&
|
---|
1829 | pDeviceSettingsIn->pp.AutoDepthStencilFormat != D3DFMT_UNKNOWN )
|
---|
1830 | {
|
---|
1831 | bool bFound = false;
|
---|
1832 | UINT dwDepthBits = DXUTDepthBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
|
---|
1833 | for( int i=0; i<pDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
|
---|
1834 | {
|
---|
1835 | D3DFORMAT depthStencilFmt = pDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
|
---|
1836 | UINT dwCurDepthBits = DXUTDepthBits( depthStencilFmt );
|
---|
1837 | if( dwCurDepthBits - dwDepthBits == 0)
|
---|
1838 | bFound = true;
|
---|
1839 | }
|
---|
1840 |
|
---|
1841 | if( !bFound )
|
---|
1842 | return false;
|
---|
1843 | }
|
---|
1844 |
|
---|
1845 | // If keep depth format then check that the depth format is supported by this combo
|
---|
1846 | if( pMatchOptions->eStencilFormat == DXUTMT_PRESERVE_INPUT &&
|
---|
1847 | pDeviceSettingsIn->pp.AutoDepthStencilFormat != D3DFMT_UNKNOWN )
|
---|
1848 | {
|
---|
1849 | bool bFound = false;
|
---|
1850 | UINT dwStencilBits = DXUTStencilBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
|
---|
1851 | for( int i=0; i<pDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
|
---|
1852 | {
|
---|
1853 | D3DFORMAT depthStencilFmt = pDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
|
---|
1854 | UINT dwCurStencilBits = DXUTStencilBits( depthStencilFmt );
|
---|
1855 | if( dwCurStencilBits - dwStencilBits == 0)
|
---|
1856 | bFound = true;
|
---|
1857 | }
|
---|
1858 |
|
---|
1859 | if( !bFound )
|
---|
1860 | return false;
|
---|
1861 | }
|
---|
1862 |
|
---|
1863 | //---------------------
|
---|
1864 | // Present flags
|
---|
1865 | //---------------------
|
---|
1866 | // No caps for the present flags
|
---|
1867 |
|
---|
1868 | //---------------------
|
---|
1869 | // Refresh rate
|
---|
1870 | //---------------------
|
---|
1871 | // If keep refresh rate then check that the resolution is supported by this combo
|
---|
1872 | if( pMatchOptions->eRefreshRate == DXUTMT_PRESERVE_INPUT )
|
---|
1873 | {
|
---|
1874 | bool bFound = false;
|
---|
1875 | for( int i=0; i<pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); i++ )
|
---|
1876 | {
|
---|
1877 | D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( i );
|
---|
1878 | if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
|
---|
1879 | continue;
|
---|
1880 | if( displayMode.RefreshRate == pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz )
|
---|
1881 | {
|
---|
1882 | bFound = true;
|
---|
1883 | break;
|
---|
1884 | }
|
---|
1885 | }
|
---|
1886 |
|
---|
1887 | // If refresh rate not supported by this combo, then return false
|
---|
1888 | if( !bFound )
|
---|
1889 | return false;
|
---|
1890 | }
|
---|
1891 |
|
---|
1892 | //---------------------
|
---|
1893 | // Present interval
|
---|
1894 | //---------------------
|
---|
1895 | // If keep present interval then check that the present interval is supported by this combo
|
---|
1896 | if( pMatchOptions->ePresentInterval == DXUTMT_PRESERVE_INPUT &&
|
---|
1897 | !pDeviceSettingsCombo->presentIntervalList.Contains( pDeviceSettingsIn->pp.PresentationInterval ) )
|
---|
1898 | return false;
|
---|
1899 |
|
---|
1900 | return true;
|
---|
1901 | }
|
---|
1902 |
|
---|
1903 |
|
---|
1904 | //--------------------------------------------------------------------------------------
|
---|
1905 | // Returns a ranking number that describes how closely this device
|
---|
1906 | // combo matches the optimal combo based on the match options and the optimal device settings
|
---|
1907 | //--------------------------------------------------------------------------------------
|
---|
1908 | float DXUTRankDeviceCombo( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo,
|
---|
1909 | DXUTDeviceSettings* pOptimalDeviceSettings,
|
---|
1910 | D3DDISPLAYMODE* pAdapterDesktopDisplayMode )
|
---|
1911 | {
|
---|
1912 | float fCurRanking = 0.0f;
|
---|
1913 |
|
---|
1914 | // Arbitrary weights. Gives preference to the ordinal, device type, and windowed
|
---|
1915 | const float fAdapterOrdinalWeight = 1000.0f;
|
---|
1916 | const float fDeviceTypeWeight = 100.0f;
|
---|
1917 | const float fWindowWeight = 10.0f;
|
---|
1918 | const float fAdapterFormatWeight = 1.0f;
|
---|
1919 | const float fVertexProcessingWeight = 1.0f;
|
---|
1920 | const float fResolutionWeight = 1.0f;
|
---|
1921 | const float fBackBufferFormatWeight = 1.0f;
|
---|
1922 | const float fMultiSampleWeight = 1.0f;
|
---|
1923 | const float fDepthStencilWeight = 1.0f;
|
---|
1924 | const float fRefreshRateWeight = 1.0f;
|
---|
1925 | const float fPresentIntervalWeight = 1.0f;
|
---|
1926 |
|
---|
1927 | //---------------------
|
---|
1928 | // Adapter ordinal
|
---|
1929 | //---------------------
|
---|
1930 | if( pDeviceSettingsCombo->AdapterOrdinal == pOptimalDeviceSettings->AdapterOrdinal )
|
---|
1931 | fCurRanking += fAdapterOrdinalWeight;
|
---|
1932 |
|
---|
1933 | //---------------------
|
---|
1934 | // Device type
|
---|
1935 | //---------------------
|
---|
1936 | if( pDeviceSettingsCombo->DeviceType == pOptimalDeviceSettings->DeviceType )
|
---|
1937 | fCurRanking += fDeviceTypeWeight;
|
---|
1938 | // Slightly prefer HAL
|
---|
1939 | if( pDeviceSettingsCombo->DeviceType == D3DDEVTYPE_HAL )
|
---|
1940 | fCurRanking += 0.1f;
|
---|
1941 |
|
---|
1942 | //---------------------
|
---|
1943 | // Windowed
|
---|
1944 | //---------------------
|
---|
1945 | if( pDeviceSettingsCombo->Windowed == pOptimalDeviceSettings->pp.Windowed )
|
---|
1946 | fCurRanking += fWindowWeight;
|
---|
1947 |
|
---|
1948 | //---------------------
|
---|
1949 | // Adapter format
|
---|
1950 | //---------------------
|
---|
1951 | if( pDeviceSettingsCombo->AdapterFormat == pOptimalDeviceSettings->AdapterFormat )
|
---|
1952 | {
|
---|
1953 | fCurRanking += fAdapterFormatWeight;
|
---|
1954 | }
|
---|
1955 | else
|
---|
1956 | {
|
---|
1957 | int nBitDepthDelta = abs( (long) DXUTColorChannelBits(pDeviceSettingsCombo->AdapterFormat) -
|
---|
1958 | (long) DXUTColorChannelBits(pOptimalDeviceSettings->AdapterFormat) );
|
---|
1959 | float fScale = __max(0.9f - (float)nBitDepthDelta*0.2f, 0.0f);
|
---|
1960 | fCurRanking += fScale * fAdapterFormatWeight;
|
---|
1961 | }
|
---|
1962 |
|
---|
1963 | if( !pDeviceSettingsCombo->Windowed )
|
---|
1964 | {
|
---|
1965 | // Slightly prefer when it matches the desktop format or is D3DFMT_X8R8G8B8
|
---|
1966 | bool bAdapterOptimalMatch;
|
---|
1967 | if( DXUTColorChannelBits(pAdapterDesktopDisplayMode->Format) >= 8 )
|
---|
1968 | bAdapterOptimalMatch = (pDeviceSettingsCombo->AdapterFormat == pAdapterDesktopDisplayMode->Format);
|
---|
1969 | else
|
---|
1970 | bAdapterOptimalMatch = (pDeviceSettingsCombo->AdapterFormat == D3DFMT_X8R8G8B8);
|
---|
1971 |
|
---|
1972 | if( bAdapterOptimalMatch )
|
---|
1973 | fCurRanking += 0.1f;
|
---|
1974 | }
|
---|
1975 |
|
---|
1976 | //---------------------
|
---|
1977 | // Vertex processing
|
---|
1978 | //---------------------
|
---|
1979 | if( (pOptimalDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 ||
|
---|
1980 | (pOptimalDeviceSettings->BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) != 0 )
|
---|
1981 | {
|
---|
1982 | if( (pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0 )
|
---|
1983 | fCurRanking += fVertexProcessingWeight;
|
---|
1984 | }
|
---|
1985 | // Slightly prefer HW T&L
|
---|
1986 | if( (pDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0 )
|
---|
1987 | fCurRanking += 0.1f;
|
---|
1988 |
|
---|
1989 | //---------------------
|
---|
1990 | // Resolution
|
---|
1991 | //---------------------
|
---|
1992 | bool bResolutionFound = false;
|
---|
1993 | for( int idm = 0; idm < pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); idm++ )
|
---|
1994 | {
|
---|
1995 | D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( idm );
|
---|
1996 | if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
|
---|
1997 | continue;
|
---|
1998 | if( displayMode.Width == pOptimalDeviceSettings->pp.BackBufferWidth &&
|
---|
1999 | displayMode.Height == pOptimalDeviceSettings->pp.BackBufferHeight )
|
---|
2000 | bResolutionFound = true;
|
---|
2001 | }
|
---|
2002 | if( bResolutionFound )
|
---|
2003 | fCurRanking += fResolutionWeight;
|
---|
2004 |
|
---|
2005 | //---------------------
|
---|
2006 | // Back buffer format
|
---|
2007 | //---------------------
|
---|
2008 | if( pDeviceSettingsCombo->BackBufferFormat == pOptimalDeviceSettings->pp.BackBufferFormat )
|
---|
2009 | {
|
---|
2010 | fCurRanking += fBackBufferFormatWeight;
|
---|
2011 | }
|
---|
2012 | else
|
---|
2013 | {
|
---|
2014 | int nBitDepthDelta = abs( (long) DXUTColorChannelBits(pDeviceSettingsCombo->BackBufferFormat) -
|
---|
2015 | (long) DXUTColorChannelBits(pOptimalDeviceSettings->pp.BackBufferFormat) );
|
---|
2016 | float fScale = __max(0.9f - (float)nBitDepthDelta*0.2f, 0.0f);
|
---|
2017 | fCurRanking += fScale * fBackBufferFormatWeight;
|
---|
2018 | }
|
---|
2019 |
|
---|
2020 | // Check if this back buffer format is the same as
|
---|
2021 | // the adapter format since this is preferred.
|
---|
2022 | bool bAdapterMatchesBB = (pDeviceSettingsCombo->BackBufferFormat == pDeviceSettingsCombo->AdapterFormat);
|
---|
2023 | if( bAdapterMatchesBB )
|
---|
2024 | fCurRanking += 0.1f;
|
---|
2025 |
|
---|
2026 | //---------------------
|
---|
2027 | // Back buffer count
|
---|
2028 | //---------------------
|
---|
2029 | // No caps for the back buffer count
|
---|
2030 |
|
---|
2031 | //---------------------
|
---|
2032 | // Multisample
|
---|
2033 | //---------------------
|
---|
2034 | bool bMultiSampleFound = false;
|
---|
2035 | for( int i=0; i<pDeviceSettingsCombo->multiSampleTypeList.GetSize(); i++ )
|
---|
2036 | {
|
---|
2037 | D3DMULTISAMPLE_TYPE msType = pDeviceSettingsCombo->multiSampleTypeList.GetAt(i);
|
---|
2038 | DWORD msQuality = pDeviceSettingsCombo->multiSampleQualityList.GetAt(i);
|
---|
2039 |
|
---|
2040 | if( msType == pOptimalDeviceSettings->pp.MultiSampleType &&
|
---|
2041 | msQuality >= pOptimalDeviceSettings->pp.MultiSampleQuality )
|
---|
2042 | {
|
---|
2043 | bMultiSampleFound = true;
|
---|
2044 | break;
|
---|
2045 | }
|
---|
2046 | }
|
---|
2047 | if( bMultiSampleFound )
|
---|
2048 | fCurRanking += fMultiSampleWeight;
|
---|
2049 |
|
---|
2050 | //---------------------
|
---|
2051 | // Swap effect
|
---|
2052 | //---------------------
|
---|
2053 | // No caps for swap effects
|
---|
2054 |
|
---|
2055 | //---------------------
|
---|
2056 | // Depth stencil
|
---|
2057 | //---------------------
|
---|
2058 | if( pDeviceSettingsCombo->depthStencilFormatList.Contains( pOptimalDeviceSettings->pp.AutoDepthStencilFormat ) )
|
---|
2059 | fCurRanking += fDepthStencilWeight;
|
---|
2060 |
|
---|
2061 | //---------------------
|
---|
2062 | // Present flags
|
---|
2063 | //---------------------
|
---|
2064 | // No caps for the present flags
|
---|
2065 |
|
---|
2066 | //---------------------
|
---|
2067 | // Refresh rate
|
---|
2068 | //---------------------
|
---|
2069 | bool bRefreshFound = false;
|
---|
2070 | for( int idm = 0; idm < pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetSize(); idm++ )
|
---|
2071 | {
|
---|
2072 | D3DDISPLAYMODE displayMode = pDeviceSettingsCombo->pAdapterInfo->displayModeList.GetAt( idm );
|
---|
2073 | if( displayMode.Format != pDeviceSettingsCombo->AdapterFormat )
|
---|
2074 | continue;
|
---|
2075 | if( displayMode.RefreshRate == pOptimalDeviceSettings->pp.FullScreen_RefreshRateInHz )
|
---|
2076 | bRefreshFound = true;
|
---|
2077 | }
|
---|
2078 | if( bRefreshFound )
|
---|
2079 | fCurRanking += fRefreshRateWeight;
|
---|
2080 |
|
---|
2081 | //---------------------
|
---|
2082 | // Present interval
|
---|
2083 | //---------------------
|
---|
2084 | // If keep present interval then check that the present interval is supported by this combo
|
---|
2085 | if( pDeviceSettingsCombo->presentIntervalList.Contains( pOptimalDeviceSettings->pp.PresentationInterval ) )
|
---|
2086 | fCurRanking += fPresentIntervalWeight;
|
---|
2087 |
|
---|
2088 | return fCurRanking;
|
---|
2089 | }
|
---|
2090 |
|
---|
2091 |
|
---|
2092 | //--------------------------------------------------------------------------------------
|
---|
2093 | // Builds valid device settings using the match options, the input device settings, and the
|
---|
2094 | // best device settings combo found.
|
---|
2095 | //--------------------------------------------------------------------------------------
|
---|
2096 | void DXUTBuildValidDeviceSettings( DXUTDeviceSettings* pValidDeviceSettings,
|
---|
2097 | CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo,
|
---|
2098 | DXUTDeviceSettings* pDeviceSettingsIn,
|
---|
2099 | DXUTMatchOptions* pMatchOptions )
|
---|
2100 | {
|
---|
2101 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
2102 | D3DDISPLAYMODE adapterDesktopDisplayMode;
|
---|
2103 | pD3D->GetAdapterDisplayMode( pBestDeviceSettingsCombo->AdapterOrdinal, &adapterDesktopDisplayMode );
|
---|
2104 |
|
---|
2105 | // For each setting pick the best, taking into account the match options and
|
---|
2106 | // what's supported by the device
|
---|
2107 |
|
---|
2108 | //---------------------
|
---|
2109 | // Adapter Ordinal
|
---|
2110 | //---------------------
|
---|
2111 | // Just using pBestDeviceSettingsCombo->AdapterOrdinal
|
---|
2112 |
|
---|
2113 | //---------------------
|
---|
2114 | // Device Type
|
---|
2115 | //---------------------
|
---|
2116 | // Just using pBestDeviceSettingsCombo->DeviceType
|
---|
2117 |
|
---|
2118 | //---------------------
|
---|
2119 | // Windowed
|
---|
2120 | //---------------------
|
---|
2121 | // Just using pBestDeviceSettingsCombo->Windowed
|
---|
2122 |
|
---|
2123 | //---------------------
|
---|
2124 | // Adapter Format
|
---|
2125 | //---------------------
|
---|
2126 | // Just using pBestDeviceSettingsCombo->AdapterFormat
|
---|
2127 |
|
---|
2128 | //---------------------
|
---|
2129 | // Vertex processing
|
---|
2130 | //---------------------
|
---|
2131 | DWORD dwBestBehaviorFlags = 0;
|
---|
2132 | if( pMatchOptions->eVertexProcessing == DXUTMT_PRESERVE_INPUT )
|
---|
2133 | {
|
---|
2134 | dwBestBehaviorFlags = pDeviceSettingsIn->BehaviorFlags;
|
---|
2135 | }
|
---|
2136 | else if( pMatchOptions->eVertexProcessing == DXUTMT_IGNORE_INPUT )
|
---|
2137 | {
|
---|
2138 | // The framework defaults to HWVP if available otherwise use SWVP
|
---|
2139 | if ((pBestDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
|
---|
2140 | dwBestBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
2141 | else
|
---|
2142 | dwBestBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
---|
2143 | }
|
---|
2144 | else // if( pMatchOptions->eVertexProcessing == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2145 | {
|
---|
2146 | // Default to input, and fallback to SWVP if HWVP not available
|
---|
2147 | dwBestBehaviorFlags = pDeviceSettingsIn->BehaviorFlags;
|
---|
2148 | if ((pBestDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 &&
|
---|
2149 | ( (dwBestBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 ||
|
---|
2150 | (dwBestBehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) != 0) )
|
---|
2151 | {
|
---|
2152 | dwBestBehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
2153 | dwBestBehaviorFlags &= ~D3DCREATE_MIXED_VERTEXPROCESSING;
|
---|
2154 | dwBestBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
---|
2155 | }
|
---|
2156 |
|
---|
2157 | // One of these must be selected
|
---|
2158 | if( (dwBestBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) == 0 &&
|
---|
2159 | (dwBestBehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) == 0 &&
|
---|
2160 | (dwBestBehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == 0 )
|
---|
2161 | {
|
---|
2162 | if ((pBestDeviceSettingsCombo->pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
|
---|
2163 | dwBestBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
2164 | else
|
---|
2165 | dwBestBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
---|
2166 | }
|
---|
2167 | }
|
---|
2168 |
|
---|
2169 | //---------------------
|
---|
2170 | // Resolution
|
---|
2171 | //---------------------
|
---|
2172 | D3DDISPLAYMODE bestDisplayMode;
|
---|
2173 | if( pMatchOptions->eResolution == DXUTMT_PRESERVE_INPUT )
|
---|
2174 | {
|
---|
2175 | bestDisplayMode.Width = pDeviceSettingsIn->pp.BackBufferWidth;
|
---|
2176 | bestDisplayMode.Height = pDeviceSettingsIn->pp.BackBufferHeight;
|
---|
2177 | }
|
---|
2178 | else
|
---|
2179 | {
|
---|
2180 | D3DDISPLAYMODE displayModeIn;
|
---|
2181 | if( pMatchOptions->eResolution == DXUTMT_CLOSEST_TO_INPUT &&
|
---|
2182 | pDeviceSettingsIn )
|
---|
2183 | {
|
---|
2184 | displayModeIn.Width = pDeviceSettingsIn->pp.BackBufferWidth;
|
---|
2185 | displayModeIn.Height = pDeviceSettingsIn->pp.BackBufferHeight;
|
---|
2186 | }
|
---|
2187 | else // if( pMatchOptions->eResolution == DXUTMT_IGNORE_INPUT )
|
---|
2188 | {
|
---|
2189 | if( pBestDeviceSettingsCombo->Windowed )
|
---|
2190 | {
|
---|
2191 | // The framework defaults to 640x480 for windowed
|
---|
2192 | displayModeIn.Width = 640;
|
---|
2193 | displayModeIn.Height = 480;
|
---|
2194 | }
|
---|
2195 | else
|
---|
2196 | {
|
---|
2197 | // The framework defaults to desktop resolution for fullscreen to try to avoid slow mode change
|
---|
2198 | displayModeIn.Width = adapterDesktopDisplayMode.Width;
|
---|
2199 | displayModeIn.Height = adapterDesktopDisplayMode.Height;
|
---|
2200 | }
|
---|
2201 | }
|
---|
2202 |
|
---|
2203 | // Call a helper function to find the closest valid display mode to the optimal
|
---|
2204 | DXUTFindValidResolution( pBestDeviceSettingsCombo, displayModeIn, &bestDisplayMode );
|
---|
2205 | }
|
---|
2206 |
|
---|
2207 | //---------------------
|
---|
2208 | // Back Buffer Format
|
---|
2209 | //---------------------
|
---|
2210 | // Just using pBestDeviceSettingsCombo->BackBufferFormat
|
---|
2211 |
|
---|
2212 | //---------------------
|
---|
2213 | // Back buffer count
|
---|
2214 | //---------------------
|
---|
2215 | UINT bestBackBufferCount;
|
---|
2216 | if( pMatchOptions->eBackBufferCount == DXUTMT_PRESERVE_INPUT )
|
---|
2217 | {
|
---|
2218 | bestBackBufferCount = pDeviceSettingsIn->pp.BackBufferCount;
|
---|
2219 | }
|
---|
2220 | else if( pMatchOptions->eBackBufferCount == DXUTMT_IGNORE_INPUT )
|
---|
2221 | {
|
---|
2222 | // The framework defaults to triple buffering
|
---|
2223 | bestBackBufferCount = 2;
|
---|
2224 | }
|
---|
2225 | else // if( pMatchOptions->eBackBufferCount == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2226 | {
|
---|
2227 | bestBackBufferCount = pDeviceSettingsIn->pp.BackBufferCount;
|
---|
2228 | if( bestBackBufferCount > 3 )
|
---|
2229 | bestBackBufferCount = 3;
|
---|
2230 | if( bestBackBufferCount < 1 )
|
---|
2231 | bestBackBufferCount = 1;
|
---|
2232 | }
|
---|
2233 |
|
---|
2234 | //---------------------
|
---|
2235 | // Multisample
|
---|
2236 | //---------------------
|
---|
2237 | D3DMULTISAMPLE_TYPE bestMultiSampleType;
|
---|
2238 | DWORD bestMultiSampleQuality;
|
---|
2239 | if( pDeviceSettingsIn && pDeviceSettingsIn->pp.SwapEffect != D3DSWAPEFFECT_DISCARD )
|
---|
2240 | {
|
---|
2241 | // Swap effect is not set to discard so multisampling has to off
|
---|
2242 | bestMultiSampleType = D3DMULTISAMPLE_NONE;
|
---|
2243 | bestMultiSampleQuality = 0;
|
---|
2244 | }
|
---|
2245 | else
|
---|
2246 | {
|
---|
2247 | if( pMatchOptions->eMultiSample == DXUTMT_PRESERVE_INPUT )
|
---|
2248 | {
|
---|
2249 | bestMultiSampleType = pDeviceSettingsIn->pp.MultiSampleType;
|
---|
2250 | bestMultiSampleQuality = pDeviceSettingsIn->pp.MultiSampleQuality;
|
---|
2251 | }
|
---|
2252 | else if( pMatchOptions->eMultiSample == DXUTMT_IGNORE_INPUT )
|
---|
2253 | {
|
---|
2254 | // Default to no multisampling (always supported)
|
---|
2255 | bestMultiSampleType = D3DMULTISAMPLE_NONE;
|
---|
2256 | bestMultiSampleQuality = 0;
|
---|
2257 | }
|
---|
2258 | else if( pMatchOptions->eMultiSample == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2259 | {
|
---|
2260 | // Default to no multisampling (always supported)
|
---|
2261 | bestMultiSampleType = D3DMULTISAMPLE_NONE;
|
---|
2262 | bestMultiSampleQuality = 0;
|
---|
2263 |
|
---|
2264 | for( int i=0; i < pBestDeviceSettingsCombo->multiSampleTypeList.GetSize(); i++ )
|
---|
2265 | {
|
---|
2266 | D3DMULTISAMPLE_TYPE type = pBestDeviceSettingsCombo->multiSampleTypeList.GetAt(i);
|
---|
2267 | DWORD qualityLevels = pBestDeviceSettingsCombo->multiSampleQualityList.GetAt(i);
|
---|
2268 |
|
---|
2269 | // Check whether supported type is closer to the input than our current best
|
---|
2270 | if( abs(type - pDeviceSettingsIn->pp.MultiSampleType) < abs(bestMultiSampleType - pDeviceSettingsIn->pp.MultiSampleType) )
|
---|
2271 | {
|
---|
2272 | bestMultiSampleType = type;
|
---|
2273 | bestMultiSampleQuality = __min( qualityLevels-1, pDeviceSettingsIn->pp.MultiSampleQuality );
|
---|
2274 | }
|
---|
2275 | }
|
---|
2276 | }
|
---|
2277 | else
|
---|
2278 | {
|
---|
2279 | // Error case
|
---|
2280 | bestMultiSampleType = D3DMULTISAMPLE_NONE;
|
---|
2281 | bestMultiSampleQuality = 0;
|
---|
2282 | }
|
---|
2283 | }
|
---|
2284 |
|
---|
2285 | //---------------------
|
---|
2286 | // Swap effect
|
---|
2287 | //---------------------
|
---|
2288 | D3DSWAPEFFECT bestSwapEffect;
|
---|
2289 | if( pMatchOptions->eSwapEffect == DXUTMT_PRESERVE_INPUT )
|
---|
2290 | {
|
---|
2291 | bestSwapEffect = pDeviceSettingsIn->pp.SwapEffect;
|
---|
2292 | }
|
---|
2293 | else if( pMatchOptions->eSwapEffect == DXUTMT_IGNORE_INPUT )
|
---|
2294 | {
|
---|
2295 | bestSwapEffect = D3DSWAPEFFECT_DISCARD;
|
---|
2296 | }
|
---|
2297 | else // if( pMatchOptions->eSwapEffect == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2298 | {
|
---|
2299 | bestSwapEffect = pDeviceSettingsIn->pp.SwapEffect;
|
---|
2300 |
|
---|
2301 | // Swap effect has to be one of these 3
|
---|
2302 | if( bestSwapEffect != D3DSWAPEFFECT_DISCARD &&
|
---|
2303 | bestSwapEffect != D3DSWAPEFFECT_FLIP &&
|
---|
2304 | bestSwapEffect != D3DSWAPEFFECT_COPY )
|
---|
2305 | {
|
---|
2306 | bestSwapEffect = D3DSWAPEFFECT_DISCARD;
|
---|
2307 | }
|
---|
2308 | }
|
---|
2309 |
|
---|
2310 | //---------------------
|
---|
2311 | // Depth stencil
|
---|
2312 | //---------------------
|
---|
2313 | D3DFORMAT bestDepthStencilFormat;
|
---|
2314 | BOOL bestEnableAutoDepthStencil;
|
---|
2315 |
|
---|
2316 | CGrowableArray< int > depthStencilRanking;
|
---|
2317 | depthStencilRanking.SetSize( pBestDeviceSettingsCombo->depthStencilFormatList.GetSize() );
|
---|
2318 |
|
---|
2319 | UINT dwBackBufferBitDepth = DXUTColorChannelBits( pBestDeviceSettingsCombo->BackBufferFormat );
|
---|
2320 | UINT dwInputDepthBitDepth = 0;
|
---|
2321 | if( pDeviceSettingsIn )
|
---|
2322 | dwInputDepthBitDepth = DXUTDepthBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
|
---|
2323 |
|
---|
2324 | for( int i=0; i<pBestDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
|
---|
2325 | {
|
---|
2326 | D3DFORMAT curDepthStencilFmt = pBestDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
|
---|
2327 | DWORD dwCurDepthBitDepth = DXUTDepthBits( curDepthStencilFmt );
|
---|
2328 | int nRanking;
|
---|
2329 |
|
---|
2330 | if( pMatchOptions->eDepthFormat == DXUTMT_PRESERVE_INPUT )
|
---|
2331 | {
|
---|
2332 | // Need to match bit depth of input
|
---|
2333 | if(dwCurDepthBitDepth == dwInputDepthBitDepth)
|
---|
2334 | nRanking = 0;
|
---|
2335 | else
|
---|
2336 | nRanking = 10000;
|
---|
2337 | }
|
---|
2338 | else if( pMatchOptions->eDepthFormat == DXUTMT_IGNORE_INPUT )
|
---|
2339 | {
|
---|
2340 | // Prefer match of backbuffer bit depth
|
---|
2341 | nRanking = abs((int)dwCurDepthBitDepth - (int)dwBackBufferBitDepth*4);
|
---|
2342 | }
|
---|
2343 | else // if( pMatchOptions->eDepthFormat == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2344 | {
|
---|
2345 | // Prefer match of input depth format bit depth
|
---|
2346 | nRanking = abs((int)dwCurDepthBitDepth - (int)dwInputDepthBitDepth);
|
---|
2347 | }
|
---|
2348 |
|
---|
2349 | depthStencilRanking.Add( nRanking );
|
---|
2350 | }
|
---|
2351 |
|
---|
2352 | UINT dwInputStencilBitDepth = 0;
|
---|
2353 | if( pDeviceSettingsIn )
|
---|
2354 | dwInputStencilBitDepth = DXUTStencilBits( pDeviceSettingsIn->pp.AutoDepthStencilFormat );
|
---|
2355 |
|
---|
2356 | for( int i=0; i<pBestDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
|
---|
2357 | {
|
---|
2358 | D3DFORMAT curDepthStencilFmt = pBestDeviceSettingsCombo->depthStencilFormatList.GetAt(i);
|
---|
2359 | int nRanking = depthStencilRanking.GetAt(i);
|
---|
2360 | DWORD dwCurStencilBitDepth = DXUTStencilBits( curDepthStencilFmt );
|
---|
2361 |
|
---|
2362 | if( pMatchOptions->eStencilFormat == DXUTMT_PRESERVE_INPUT )
|
---|
2363 | {
|
---|
2364 | // Need to match bit depth of input
|
---|
2365 | if(dwCurStencilBitDepth == dwInputStencilBitDepth)
|
---|
2366 | nRanking += 0;
|
---|
2367 | else
|
---|
2368 | nRanking += 10000;
|
---|
2369 | }
|
---|
2370 | else if( pMatchOptions->eStencilFormat == DXUTMT_IGNORE_INPUT )
|
---|
2371 | {
|
---|
2372 | // Prefer 0 stencil bit depth
|
---|
2373 | nRanking += dwCurStencilBitDepth;
|
---|
2374 | }
|
---|
2375 | else // if( pMatchOptions->eStencilFormat == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2376 | {
|
---|
2377 | // Prefer match of input stencil format bit depth
|
---|
2378 | nRanking += abs((int)dwCurStencilBitDepth - (int)dwInputStencilBitDepth);
|
---|
2379 | }
|
---|
2380 |
|
---|
2381 | depthStencilRanking.SetAt( i, nRanking );
|
---|
2382 | }
|
---|
2383 |
|
---|
2384 | int nBestRanking = 100000;
|
---|
2385 | int nBestIndex = -1;
|
---|
2386 | for( int i=0; i<pBestDeviceSettingsCombo->depthStencilFormatList.GetSize(); i++ )
|
---|
2387 | {
|
---|
2388 | int nRanking = depthStencilRanking.GetAt(i);
|
---|
2389 | if( nRanking < nBestRanking )
|
---|
2390 | {
|
---|
2391 | nBestRanking = nRanking;
|
---|
2392 | nBestIndex = i;
|
---|
2393 | }
|
---|
2394 | }
|
---|
2395 |
|
---|
2396 | if( nBestIndex >= 0 )
|
---|
2397 | {
|
---|
2398 | bestDepthStencilFormat = pBestDeviceSettingsCombo->depthStencilFormatList.GetAt(nBestIndex);
|
---|
2399 | bestEnableAutoDepthStencil = true;
|
---|
2400 | }
|
---|
2401 | else
|
---|
2402 | {
|
---|
2403 | bestDepthStencilFormat = D3DFMT_UNKNOWN;
|
---|
2404 | bestEnableAutoDepthStencil = false;
|
---|
2405 | }
|
---|
2406 |
|
---|
2407 |
|
---|
2408 | //---------------------
|
---|
2409 | // Present flags
|
---|
2410 | //---------------------
|
---|
2411 | DWORD dwBestFlags;
|
---|
2412 | if( pMatchOptions->ePresentFlags == DXUTMT_PRESERVE_INPUT )
|
---|
2413 | {
|
---|
2414 | dwBestFlags = pDeviceSettingsIn->pp.Flags;
|
---|
2415 | }
|
---|
2416 | else if( pMatchOptions->ePresentFlags == DXUTMT_IGNORE_INPUT )
|
---|
2417 | {
|
---|
2418 | dwBestFlags = 0;
|
---|
2419 | if( bestEnableAutoDepthStencil )
|
---|
2420 | dwBestFlags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
|
---|
2421 | }
|
---|
2422 | else // if( pMatchOptions->ePresentFlags == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2423 | {
|
---|
2424 | dwBestFlags = pDeviceSettingsIn->pp.Flags;
|
---|
2425 | if( bestEnableAutoDepthStencil )
|
---|
2426 | dwBestFlags |= D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
|
---|
2427 | }
|
---|
2428 |
|
---|
2429 | //---------------------
|
---|
2430 | // Refresh rate
|
---|
2431 | //---------------------
|
---|
2432 | if( pBestDeviceSettingsCombo->Windowed )
|
---|
2433 | {
|
---|
2434 | // Must be 0 for windowed
|
---|
2435 | bestDisplayMode.RefreshRate = 0;
|
---|
2436 | }
|
---|
2437 | else
|
---|
2438 | {
|
---|
2439 | if( pMatchOptions->eRefreshRate == DXUTMT_PRESERVE_INPUT )
|
---|
2440 | {
|
---|
2441 | bestDisplayMode.RefreshRate = pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz;
|
---|
2442 | }
|
---|
2443 | else
|
---|
2444 | {
|
---|
2445 | UINT refreshRateMatch;
|
---|
2446 | if( pMatchOptions->eRefreshRate == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2447 | {
|
---|
2448 | refreshRateMatch = pDeviceSettingsIn->pp.FullScreen_RefreshRateInHz;
|
---|
2449 | }
|
---|
2450 | else // if( pMatchOptions->eRefreshRate == DXUTMT_IGNORE_INPUT )
|
---|
2451 | {
|
---|
2452 | refreshRateMatch = adapterDesktopDisplayMode.RefreshRate;
|
---|
2453 | }
|
---|
2454 |
|
---|
2455 | bestDisplayMode.RefreshRate = 0;
|
---|
2456 |
|
---|
2457 | if( refreshRateMatch != 0 )
|
---|
2458 | {
|
---|
2459 | int nBestRefreshRanking = 100000;
|
---|
2460 | CGrowableArray<D3DDISPLAYMODE>* pDisplayModeList = &pBestDeviceSettingsCombo->pAdapterInfo->displayModeList;
|
---|
2461 | for( int iDisplayMode=0; iDisplayMode<pDisplayModeList->GetSize(); iDisplayMode++ )
|
---|
2462 | {
|
---|
2463 | D3DDISPLAYMODE displayMode = pDisplayModeList->GetAt(iDisplayMode);
|
---|
2464 | if( displayMode.Format != pBestDeviceSettingsCombo->AdapterFormat ||
|
---|
2465 | displayMode.Height != bestDisplayMode.Height ||
|
---|
2466 | displayMode.Width != bestDisplayMode.Width )
|
---|
2467 | continue; // Skip display modes that don't match
|
---|
2468 |
|
---|
2469 | // Find the delta between the current refresh rate and the optimal refresh rate
|
---|
2470 | int nCurRanking = abs((int)displayMode.RefreshRate - (int)refreshRateMatch);
|
---|
2471 |
|
---|
2472 | if( nCurRanking < nBestRefreshRanking )
|
---|
2473 | {
|
---|
2474 | bestDisplayMode.RefreshRate = displayMode.RefreshRate;
|
---|
2475 | nBestRefreshRanking = nCurRanking;
|
---|
2476 |
|
---|
2477 | // Stop if perfect match found
|
---|
2478 | if( nBestRefreshRanking == 0 )
|
---|
2479 | break;
|
---|
2480 | }
|
---|
2481 | }
|
---|
2482 | }
|
---|
2483 | }
|
---|
2484 | }
|
---|
2485 |
|
---|
2486 | //---------------------
|
---|
2487 | // Present interval
|
---|
2488 | //---------------------
|
---|
2489 | UINT bestPresentInterval;
|
---|
2490 | if( pMatchOptions->ePresentInterval == DXUTMT_PRESERVE_INPUT )
|
---|
2491 | {
|
---|
2492 | bestPresentInterval = pDeviceSettingsIn->pp.PresentationInterval;
|
---|
2493 | }
|
---|
2494 | else if( pMatchOptions->ePresentInterval == DXUTMT_IGNORE_INPUT )
|
---|
2495 | {
|
---|
2496 | // For windowed and fullscreen, default to D3DPRESENT_INTERVAL_DEFAULT
|
---|
2497 | // which will wait for the vertical retrace period to prevent tearing.
|
---|
2498 | // For benchmarking, use D3DPRESENT_INTERVAL_DEFAULT which will
|
---|
2499 | // will wait not for the vertical retrace period but may introduce tearing.
|
---|
2500 | bestPresentInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
---|
2501 | }
|
---|
2502 | else // if( pMatchOptions->ePresentInterval == DXUTMT_CLOSEST_TO_INPUT )
|
---|
2503 | {
|
---|
2504 | if( pBestDeviceSettingsCombo->presentIntervalList.Contains( pDeviceSettingsIn->pp.PresentationInterval ) )
|
---|
2505 | {
|
---|
2506 | bestPresentInterval = pDeviceSettingsIn->pp.PresentationInterval;
|
---|
2507 | }
|
---|
2508 | else
|
---|
2509 | {
|
---|
2510 | bestPresentInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
---|
2511 | }
|
---|
2512 | }
|
---|
2513 |
|
---|
2514 | // Fill the device settings struct
|
---|
2515 | ZeroMemory( pValidDeviceSettings, sizeof(DXUTDeviceSettings) );
|
---|
2516 | pValidDeviceSettings->AdapterOrdinal = pBestDeviceSettingsCombo->AdapterOrdinal;
|
---|
2517 | pValidDeviceSettings->DeviceType = pBestDeviceSettingsCombo->DeviceType;
|
---|
2518 | pValidDeviceSettings->AdapterFormat = pBestDeviceSettingsCombo->AdapterFormat;
|
---|
2519 | pValidDeviceSettings->BehaviorFlags = dwBestBehaviorFlags;
|
---|
2520 | pValidDeviceSettings->pp.BackBufferWidth = bestDisplayMode.Width;
|
---|
2521 | pValidDeviceSettings->pp.BackBufferHeight = bestDisplayMode.Height;
|
---|
2522 | pValidDeviceSettings->pp.BackBufferFormat = pBestDeviceSettingsCombo->BackBufferFormat;
|
---|
2523 | pValidDeviceSettings->pp.BackBufferCount = bestBackBufferCount;
|
---|
2524 | pValidDeviceSettings->pp.MultiSampleType = bestMultiSampleType;
|
---|
2525 | pValidDeviceSettings->pp.MultiSampleQuality = bestMultiSampleQuality;
|
---|
2526 | pValidDeviceSettings->pp.SwapEffect = bestSwapEffect;
|
---|
2527 | pValidDeviceSettings->pp.hDeviceWindow = pBestDeviceSettingsCombo->Windowed ? DXUTGetHWNDDeviceWindowed() : DXUTGetHWNDDeviceFullScreen();
|
---|
2528 | pValidDeviceSettings->pp.Windowed = pBestDeviceSettingsCombo->Windowed;
|
---|
2529 | pValidDeviceSettings->pp.EnableAutoDepthStencil = bestEnableAutoDepthStencil;
|
---|
2530 | pValidDeviceSettings->pp.AutoDepthStencilFormat = bestDepthStencilFormat;
|
---|
2531 | pValidDeviceSettings->pp.Flags = dwBestFlags;
|
---|
2532 | pValidDeviceSettings->pp.FullScreen_RefreshRateInHz = bestDisplayMode.RefreshRate;
|
---|
2533 | pValidDeviceSettings->pp.PresentationInterval = bestPresentInterval;
|
---|
2534 | }
|
---|
2535 |
|
---|
2536 |
|
---|
2537 | //--------------------------------------------------------------------------------------
|
---|
2538 | // Internal helper function to find the closest allowed display mode to the optimal
|
---|
2539 | //--------------------------------------------------------------------------------------
|
---|
2540 | HRESULT DXUTFindValidResolution( CD3DEnumDeviceSettingsCombo* pBestDeviceSettingsCombo,
|
---|
2541 | D3DDISPLAYMODE displayModeIn, D3DDISPLAYMODE* pBestDisplayMode )
|
---|
2542 | {
|
---|
2543 | D3DDISPLAYMODE bestDisplayMode;
|
---|
2544 | ZeroMemory( &bestDisplayMode, sizeof(D3DDISPLAYMODE) );
|
---|
2545 |
|
---|
2546 | if( pBestDeviceSettingsCombo->Windowed )
|
---|
2547 | {
|
---|
2548 | // In windowed mode, all resolutions are valid but restritions still apply
|
---|
2549 | // on the size of the window. See DXUTChangeDevice() for details
|
---|
2550 | *pBestDisplayMode = displayModeIn;
|
---|
2551 | }
|
---|
2552 | else
|
---|
2553 | {
|
---|
2554 | int nBestRanking = 100000;
|
---|
2555 | int nCurRanking;
|
---|
2556 | CGrowableArray<D3DDISPLAYMODE>* pDisplayModeList = &pBestDeviceSettingsCombo->pAdapterInfo->displayModeList;
|
---|
2557 | for( int iDisplayMode=0; iDisplayMode<pDisplayModeList->GetSize(); iDisplayMode++ )
|
---|
2558 | {
|
---|
2559 | D3DDISPLAYMODE displayMode = pDisplayModeList->GetAt(iDisplayMode);
|
---|
2560 |
|
---|
2561 | // Skip display modes that don't match the combo's adapter format
|
---|
2562 | if( displayMode.Format != pBestDeviceSettingsCombo->AdapterFormat )
|
---|
2563 | continue;
|
---|
2564 |
|
---|
2565 | // Find the delta between the current width/height and the optimal width/height
|
---|
2566 | nCurRanking = abs((int)displayMode.Width - (int)displayModeIn.Width) +
|
---|
2567 | abs((int)displayMode.Height- (int)displayModeIn.Height);
|
---|
2568 |
|
---|
2569 | if( nCurRanking < nBestRanking )
|
---|
2570 | {
|
---|
2571 | bestDisplayMode = displayMode;
|
---|
2572 | nBestRanking = nCurRanking;
|
---|
2573 |
|
---|
2574 | // Stop if perfect match found
|
---|
2575 | if( nBestRanking == 0 )
|
---|
2576 | break;
|
---|
2577 | }
|
---|
2578 | }
|
---|
2579 |
|
---|
2580 | if( bestDisplayMode.Width == 0 )
|
---|
2581 | {
|
---|
2582 | *pBestDisplayMode = displayModeIn;
|
---|
2583 | return E_FAIL; // No valid display modes found
|
---|
2584 | }
|
---|
2585 |
|
---|
2586 | *pBestDisplayMode = bestDisplayMode;
|
---|
2587 | }
|
---|
2588 |
|
---|
2589 | return S_OK;
|
---|
2590 | }
|
---|
2591 |
|
---|
2592 |
|
---|
2593 | //--------------------------------------------------------------------------------------
|
---|
2594 | // Internal helper function to return the adapter format from the first device settings
|
---|
2595 | // combo that matches the passed adapter ordinal, device type, backbuffer format, and windowed.
|
---|
2596 | //--------------------------------------------------------------------------------------
|
---|
2597 | HRESULT DXUTFindAdapterFormat( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT BackBufferFormat,
|
---|
2598 | BOOL Windowed, D3DFORMAT* pAdapterFormat )
|
---|
2599 | {
|
---|
2600 | CD3DEnumeration* pd3dEnum = DXUTPrepareEnumerationObject();
|
---|
2601 | CD3DEnumDeviceInfo* pDeviceInfo = pd3dEnum->GetDeviceInfo( AdapterOrdinal, DeviceType );
|
---|
2602 | if( pDeviceInfo )
|
---|
2603 | {
|
---|
2604 | for( int iDeviceCombo=0; iDeviceCombo<pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )
|
---|
2605 | {
|
---|
2606 | CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt(iDeviceCombo);
|
---|
2607 | if( pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat &&
|
---|
2608 | pDeviceSettingsCombo->Windowed == Windowed )
|
---|
2609 | {
|
---|
2610 | // Return the adapter format from the first match
|
---|
2611 | *pAdapterFormat = pDeviceSettingsCombo->AdapterFormat;
|
---|
2612 | return S_OK;
|
---|
2613 | }
|
---|
2614 | }
|
---|
2615 | }
|
---|
2616 |
|
---|
2617 | *pAdapterFormat = BackBufferFormat;
|
---|
2618 | return E_FAIL;
|
---|
2619 | }
|
---|
2620 |
|
---|
2621 |
|
---|
2622 | //--------------------------------------------------------------------------------------
|
---|
2623 | // Change to a Direct3D device created from the device settings or passed in.
|
---|
2624 | // The framework will only reset if the device is similar to the previous device
|
---|
2625 | // otherwise it will cleanup the previous device (if there is one) and recreate the
|
---|
2626 | // scene using the app's device callbacks.
|
---|
2627 | //--------------------------------------------------------------------------------------
|
---|
2628 | HRESULT DXUTChangeDevice( DXUTDeviceSettings* pNewDeviceSettings, IDirect3DDevice9* pd3dDeviceFromApp, bool bForceRecreate, bool bClipWindowToSingleAdapter )
|
---|
2629 | {
|
---|
2630 | HRESULT hr;
|
---|
2631 | DXUTDeviceSettings* pOldDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
2632 |
|
---|
2633 | if( DXUTGetD3DObject() == NULL )
|
---|
2634 | return S_FALSE;
|
---|
2635 |
|
---|
2636 | // Make a copy of the pNewDeviceSettings on the heap
|
---|
2637 | DXUTDeviceSettings* pNewDeviceSettingsOnHeap = new DXUTDeviceSettings;
|
---|
2638 | if( pNewDeviceSettingsOnHeap == NULL )
|
---|
2639 | return E_OUTOFMEMORY;
|
---|
2640 | memcpy( pNewDeviceSettingsOnHeap, pNewDeviceSettings, sizeof(DXUTDeviceSettings) );
|
---|
2641 | pNewDeviceSettings = pNewDeviceSettingsOnHeap;
|
---|
2642 |
|
---|
2643 | // If the ModifyDeviceSettings callback is non-NULL, then call it to let the app
|
---|
2644 | // change the settings or reject the device change by returning false.
|
---|
2645 | LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings = GetDXUTState().GetModifyDeviceSettingsFunc();
|
---|
2646 | if( pCallbackModifyDeviceSettings )
|
---|
2647 | {
|
---|
2648 | D3DCAPS9 caps;
|
---|
2649 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
2650 | pD3D->GetDeviceCaps( pNewDeviceSettings->AdapterOrdinal, pNewDeviceSettings->DeviceType, &caps );
|
---|
2651 |
|
---|
2652 | bool bContinue = pCallbackModifyDeviceSettings( pNewDeviceSettings, &caps, GetDXUTState().GetModifyDeviceSettingsFuncUserContext() );
|
---|
2653 | if( !bContinue )
|
---|
2654 | {
|
---|
2655 | // The app rejected the device change by returning false, so just use the current device if there is one.
|
---|
2656 | if( pOldDeviceSettings == NULL )
|
---|
2657 | DXUTDisplayErrorMessage( DXUTERR_NOCOMPATIBLEDEVICES );
|
---|
2658 | SAFE_DELETE( pNewDeviceSettings );
|
---|
2659 | return E_ABORT;
|
---|
2660 | }
|
---|
2661 | if( GetDXUTState().GetD3D() == NULL )
|
---|
2662 | {
|
---|
2663 | SAFE_DELETE( pNewDeviceSettings );
|
---|
2664 | return S_FALSE;
|
---|
2665 | }
|
---|
2666 | }
|
---|
2667 |
|
---|
2668 | GetDXUTState().SetCurrentDeviceSettings( pNewDeviceSettings );
|
---|
2669 |
|
---|
2670 | DXUTPause( true, true );
|
---|
2671 |
|
---|
2672 | // When a WM_SIZE message is received, it calls DXUTCheckForWindowSizeChange().
|
---|
2673 | // A WM_SIZE message might be sent when adjusting the window, so tell
|
---|
2674 | // DXUTCheckForWindowSizeChange() to ignore size changes temporarily
|
---|
2675 | GetDXUTState().SetIgnoreSizeChange( true );
|
---|
2676 |
|
---|
2677 | // Update thread safety on/off depending on Direct3D device's thread safety
|
---|
2678 | g_bThreadSafe = ((pNewDeviceSettings->BehaviorFlags & D3DCREATE_MULTITHREADED) != 0 );
|
---|
2679 |
|
---|
2680 | // Only apply the cmd line overrides if this is the first device created
|
---|
2681 | // and DXUTSetDevice() isn't used
|
---|
2682 | if( NULL == pd3dDeviceFromApp && NULL == pOldDeviceSettings )
|
---|
2683 | {
|
---|
2684 | // Updates the device settings struct based on the cmd line args.
|
---|
2685 | // Warning: if the device doesn't support these new settings then CreateDevice() will fail.
|
---|
2686 | DXUTUpdateDeviceSettingsWithOverrides( pNewDeviceSettings );
|
---|
2687 | }
|
---|
2688 |
|
---|
2689 | // Take note if the backbuffer width & height are 0 now as they will change after pd3dDevice->Reset()
|
---|
2690 | bool bKeepCurrentWindowSize = false;
|
---|
2691 | if( pNewDeviceSettings->pp.BackBufferWidth == 0 && pNewDeviceSettings->pp.BackBufferHeight == 0 )
|
---|
2692 | bKeepCurrentWindowSize = true;
|
---|
2693 |
|
---|
2694 | //////////////////////////
|
---|
2695 | // Before reset
|
---|
2696 | /////////////////////////
|
---|
2697 | if( pNewDeviceSettings->pp.Windowed )
|
---|
2698 | {
|
---|
2699 | // Going to windowed mode
|
---|
2700 |
|
---|
2701 | if( pOldDeviceSettings && !pOldDeviceSettings->pp.Windowed )
|
---|
2702 | {
|
---|
2703 | // Going from fullscreen -> windowed
|
---|
2704 | GetDXUTState().SetFullScreenBackBufferWidthAtModeChange( pOldDeviceSettings->pp.BackBufferWidth );
|
---|
2705 | GetDXUTState().SetFullScreenBackBufferHeightAtModeChange( pOldDeviceSettings->pp.BackBufferHeight );
|
---|
2706 |
|
---|
2707 | // Restore windowed mode style
|
---|
2708 | SetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE, GetDXUTState().GetWindowedStyleAtModeChange() );
|
---|
2709 | }
|
---|
2710 |
|
---|
2711 | // If different device windows are used for windowed mode and fullscreen mode,
|
---|
2712 | // hide the fullscreen window so that it doesn't obscure the screen.
|
---|
2713 | if( DXUTGetHWNDDeviceFullScreen() != DXUTGetHWNDDeviceWindowed() )
|
---|
2714 | ShowWindow( DXUTGetHWNDDeviceFullScreen(), SW_HIDE );
|
---|
2715 |
|
---|
2716 | // If using the same window for windowed and fullscreen mode, reattach menu if one exists
|
---|
2717 | if( DXUTGetHWNDDeviceFullScreen() == DXUTGetHWNDDeviceWindowed() )
|
---|
2718 | {
|
---|
2719 | if( GetDXUTState().GetMenu() != NULL )
|
---|
2720 | SetMenu( DXUTGetHWNDDeviceWindowed(), GetDXUTState().GetMenu() );
|
---|
2721 | }
|
---|
2722 | }
|
---|
2723 | else
|
---|
2724 | {
|
---|
2725 | // Going to fullscreen mode
|
---|
2726 |
|
---|
2727 | if( pOldDeviceSettings == NULL || (pOldDeviceSettings && pOldDeviceSettings->pp.Windowed) )
|
---|
2728 | {
|
---|
2729 | // Transistioning to full screen mode from a standard window so
|
---|
2730 | // save current window position/size/style now in case the user toggles to windowed mode later
|
---|
2731 | WINDOWPLACEMENT* pwp = GetDXUTState().GetWindowedPlacement();
|
---|
2732 | ZeroMemory( pwp, sizeof(WINDOWPLACEMENT) );
|
---|
2733 | pwp->length = sizeof(WINDOWPLACEMENT);
|
---|
2734 | GetWindowPlacement( DXUTGetHWNDDeviceWindowed(), pwp );
|
---|
2735 | bool bIsTopmost = ( (GetWindowLong(DXUTGetHWNDDeviceWindowed(),GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
|
---|
2736 | GetDXUTState().SetTopmostWhileWindowed( bIsTopmost );
|
---|
2737 | DWORD dwStyle = GetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE );
|
---|
2738 | dwStyle &= ~WS_MAXIMIZE & ~WS_MINIMIZE; // remove minimize/maximize style
|
---|
2739 | GetDXUTState().SetWindowedStyleAtModeChange( dwStyle );
|
---|
2740 | if( pOldDeviceSettings )
|
---|
2741 | {
|
---|
2742 | GetDXUTState().SetWindowBackBufferWidthAtModeChange( pOldDeviceSettings->pp.BackBufferWidth );
|
---|
2743 | GetDXUTState().SetWindowBackBufferHeightAtModeChange( pOldDeviceSettings->pp.BackBufferHeight );
|
---|
2744 | }
|
---|
2745 | }
|
---|
2746 |
|
---|
2747 | // Hide the window to avoid animation of blank windows
|
---|
2748 | ShowWindow( DXUTGetHWNDDeviceFullScreen(), SW_HIDE );
|
---|
2749 |
|
---|
2750 | // Set FS window style
|
---|
2751 | SetWindowLong( DXUTGetHWNDDeviceFullScreen(), GWL_STYLE, WS_POPUP|WS_SYSMENU );
|
---|
2752 |
|
---|
2753 | // If using the same window for windowed and fullscreen mode, save and remove menu
|
---|
2754 | if( DXUTGetHWNDDeviceFullScreen() == DXUTGetHWNDDeviceWindowed() )
|
---|
2755 | {
|
---|
2756 | HMENU hMenu = GetMenu( DXUTGetHWNDDeviceFullScreen() );
|
---|
2757 | GetDXUTState().SetMenu( hMenu );
|
---|
2758 | SetMenu( DXUTGetHWNDDeviceFullScreen(), NULL );
|
---|
2759 | }
|
---|
2760 |
|
---|
2761 | WINDOWPLACEMENT wpFullscreen;
|
---|
2762 | ZeroMemory( &wpFullscreen, sizeof(WINDOWPLACEMENT) );
|
---|
2763 | wpFullscreen.length = sizeof(WINDOWPLACEMENT);
|
---|
2764 | GetWindowPlacement( DXUTGetHWNDDeviceFullScreen(), &wpFullscreen );
|
---|
2765 | if( (wpFullscreen.flags & WPF_RESTORETOMAXIMIZED) != 0 )
|
---|
2766 | {
|
---|
2767 | // Restore the window to normal if the window was maximized then minimized. This causes the
|
---|
2768 | // WPF_RESTORETOMAXIMIZED flag to be set which will cause SW_RESTORE to restore the
|
---|
2769 | // window from minimized to maxmized which isn't what we want
|
---|
2770 | wpFullscreen.flags &= ~WPF_RESTORETOMAXIMIZED;
|
---|
2771 | wpFullscreen.showCmd = SW_RESTORE;
|
---|
2772 | SetWindowPlacement( DXUTGetHWNDDeviceFullScreen(), &wpFullscreen );
|
---|
2773 | }
|
---|
2774 | }
|
---|
2775 |
|
---|
2776 | // If AdapterOrdinal and DeviceType are the same, we can just do a Reset().
|
---|
2777 | // If they've changed, we need to do a complete device tear down/rebuild.
|
---|
2778 | // Also only allow a reset if pd3dDevice is the same as the current device
|
---|
2779 | if( !bForceRecreate &&
|
---|
2780 | (pd3dDeviceFromApp == NULL || pd3dDeviceFromApp == DXUTGetD3DDevice()) &&
|
---|
2781 | DXUTGetD3DDevice() &&
|
---|
2782 | pOldDeviceSettings &&
|
---|
2783 | pOldDeviceSettings->AdapterOrdinal == pNewDeviceSettings->AdapterOrdinal &&
|
---|
2784 | pOldDeviceSettings->DeviceType == pNewDeviceSettings->DeviceType &&
|
---|
2785 | pOldDeviceSettings->BehaviorFlags == pNewDeviceSettings->BehaviorFlags )
|
---|
2786 | {
|
---|
2787 | // Reset the Direct3D device and call the app's device callbacks
|
---|
2788 | hr = DXUTReset3DEnvironment();
|
---|
2789 | if( FAILED(hr) )
|
---|
2790 | {
|
---|
2791 | if( D3DERR_DEVICELOST == hr )
|
---|
2792 | {
|
---|
2793 | // The device is lost, just mark it as so and continue on with
|
---|
2794 | // capturing the state and resizing the window/etc.
|
---|
2795 | GetDXUTState().SetDeviceLost( true );
|
---|
2796 | }
|
---|
2797 | else if( DXUTERR_RESETTINGDEVICEOBJECTS == hr ||
|
---|
2798 | DXUTERR_MEDIANOTFOUND == hr )
|
---|
2799 | {
|
---|
2800 | // Something bad happened in the app callbacks
|
---|
2801 | SAFE_DELETE( pOldDeviceSettings );
|
---|
2802 | DXUTDisplayErrorMessage( hr );
|
---|
2803 | DXUTShutdown();
|
---|
2804 | return hr;
|
---|
2805 | }
|
---|
2806 | else // DXUTERR_RESETTINGDEVICE
|
---|
2807 | {
|
---|
2808 | // Reset failed and the device wasn't lost and it wasn't the apps fault,
|
---|
2809 | // so recreate the device to try to recover
|
---|
2810 | GetDXUTState().SetCurrentDeviceSettings( pOldDeviceSettings );
|
---|
2811 | if( FAILED( DXUTChangeDevice( pNewDeviceSettings, pd3dDeviceFromApp, true, bClipWindowToSingleAdapter ) ) )
|
---|
2812 | {
|
---|
2813 | // If that fails, then shutdown
|
---|
2814 | SAFE_DELETE( pOldDeviceSettings );
|
---|
2815 | DXUTShutdown();
|
---|
2816 | return DXUTERR_CREATINGDEVICE;
|
---|
2817 | }
|
---|
2818 | else
|
---|
2819 | {
|
---|
2820 | SAFE_DELETE( pOldDeviceSettings );
|
---|
2821 | return S_OK;
|
---|
2822 | }
|
---|
2823 | }
|
---|
2824 | }
|
---|
2825 | }
|
---|
2826 | else
|
---|
2827 | {
|
---|
2828 | // Cleanup if not first device created
|
---|
2829 | if( pOldDeviceSettings )
|
---|
2830 | DXUTCleanup3DEnvironment( false );
|
---|
2831 |
|
---|
2832 | // Create the D3D device and call the app's device callbacks
|
---|
2833 | hr = DXUTCreate3DEnvironment( pd3dDeviceFromApp );
|
---|
2834 | if( FAILED(hr) )
|
---|
2835 | {
|
---|
2836 | SAFE_DELETE( pOldDeviceSettings );
|
---|
2837 | DXUTCleanup3DEnvironment();
|
---|
2838 | DXUTDisplayErrorMessage( hr );
|
---|
2839 | DXUTPause( false, false );
|
---|
2840 | GetDXUTState().SetIgnoreSizeChange( false );
|
---|
2841 | return hr;
|
---|
2842 | }
|
---|
2843 | }
|
---|
2844 |
|
---|
2845 | // Enable/disable StickKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut, and Windows key
|
---|
2846 | // to prevent accidental task switching
|
---|
2847 | DXUTAllowShortcutKeys( ( pNewDeviceSettings->pp.Windowed ) ? GetDXUTState().GetAllowShortcutKeysWhenWindowed() : GetDXUTState().GetAllowShortcutKeysWhenFullscreen() );
|
---|
2848 |
|
---|
2849 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
2850 | HMONITOR hAdapterMonitor = pD3D->GetAdapterMonitor( pNewDeviceSettings->AdapterOrdinal );
|
---|
2851 | GetDXUTState().SetAdapterMonitor( hAdapterMonitor );
|
---|
2852 |
|
---|
2853 | // Update the device stats text
|
---|
2854 | DXUTUpdateStaticFrameStats();
|
---|
2855 |
|
---|
2856 | if( pOldDeviceSettings && !pOldDeviceSettings->pp.Windowed && pNewDeviceSettings->pp.Windowed )
|
---|
2857 | {
|
---|
2858 | // Going from fullscreen -> windowed
|
---|
2859 |
|
---|
2860 | // Restore the show state, and positions/size of the window to what it was
|
---|
2861 | // It is important to adjust the window size
|
---|
2862 | // after resetting the device rather than beforehand to ensure
|
---|
2863 | // that the monitor resolution is correct and does not limit the size of the new window.
|
---|
2864 | WINDOWPLACEMENT* pwp = GetDXUTState().GetWindowedPlacement();
|
---|
2865 | SetWindowPlacement( DXUTGetHWNDDeviceWindowed(), pwp );
|
---|
2866 |
|
---|
2867 | // Also restore the z-order of window to previous state
|
---|
2868 | HWND hWndInsertAfter = GetDXUTState().GetTopmostWhileWindowed() ? HWND_TOPMOST : HWND_NOTOPMOST;
|
---|
2869 | SetWindowPos( DXUTGetHWNDDeviceWindowed(), hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOREDRAW|SWP_NOSIZE );
|
---|
2870 | }
|
---|
2871 |
|
---|
2872 | // Check to see if the window needs to be resized.
|
---|
2873 | // Handle cases where the window is minimized and maxmimized as well.
|
---|
2874 | bool bNeedToResize = false;
|
---|
2875 | if( pNewDeviceSettings->pp.Windowed && // only resize if in windowed mode
|
---|
2876 | !bKeepCurrentWindowSize ) // only resize if pp.BackbufferWidth/Height were not 0
|
---|
2877 | {
|
---|
2878 | UINT nClientWidth;
|
---|
2879 | UINT nClientHeight;
|
---|
2880 | if( IsIconic(DXUTGetHWNDDeviceWindowed()) )
|
---|
2881 | {
|
---|
2882 | // Window is currently minimized. To tell if it needs to resize,
|
---|
2883 | // get the client rect of window when its restored the
|
---|
2884 | // hard way using GetWindowPlacement()
|
---|
2885 | WINDOWPLACEMENT wp;
|
---|
2886 | ZeroMemory( &wp, sizeof(WINDOWPLACEMENT) );
|
---|
2887 | wp.length = sizeof(WINDOWPLACEMENT);
|
---|
2888 | GetWindowPlacement( DXUTGetHWNDDeviceWindowed(), &wp );
|
---|
2889 |
|
---|
2890 | if( (wp.flags & WPF_RESTORETOMAXIMIZED) != 0 && wp.showCmd == SW_SHOWMINIMIZED )
|
---|
2891 | {
|
---|
2892 | // WPF_RESTORETOMAXIMIZED means that when the window is restored it will
|
---|
2893 | // be maximized. So maximize the window temporarily to get the client rect
|
---|
2894 | // when the window is maximized. GetSystemMetrics( SM_CXMAXIMIZED ) will give this
|
---|
2895 | // information if the window is on the primary but this will work on multimon.
|
---|
2896 | ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_RESTORE );
|
---|
2897 | RECT rcClient;
|
---|
2898 | GetClientRect( DXUTGetHWNDDeviceWindowed(), &rcClient );
|
---|
2899 | nClientWidth = (UINT)(rcClient.right - rcClient.left);
|
---|
2900 | nClientHeight = (UINT)(rcClient.bottom - rcClient.top);
|
---|
2901 | ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_MINIMIZE );
|
---|
2902 | }
|
---|
2903 | else
|
---|
2904 | {
|
---|
2905 | // Use wp.rcNormalPosition to get the client rect, but wp.rcNormalPosition
|
---|
2906 | // includes the window frame so subtract it
|
---|
2907 | RECT rcFrame = {0};
|
---|
2908 | AdjustWindowRect( &rcFrame, GetDXUTState().GetWindowedStyleAtModeChange(), GetDXUTState().GetMenu() != NULL );
|
---|
2909 | LONG nFrameWidth = rcFrame.right - rcFrame.left;
|
---|
2910 | LONG nFrameHeight = rcFrame.bottom - rcFrame.top;
|
---|
2911 | nClientWidth = (UINT)(wp.rcNormalPosition.right - wp.rcNormalPosition.left - nFrameWidth);
|
---|
2912 | nClientHeight = (UINT)(wp.rcNormalPosition.bottom - wp.rcNormalPosition.top - nFrameHeight);
|
---|
2913 | }
|
---|
2914 | }
|
---|
2915 | else
|
---|
2916 | {
|
---|
2917 | // Window is restored or maximized so just get its client rect
|
---|
2918 | RECT rcClient;
|
---|
2919 | GetClientRect( DXUTGetHWNDDeviceWindowed(), &rcClient );
|
---|
2920 | nClientWidth = (UINT)(rcClient.right - rcClient.left);
|
---|
2921 | nClientHeight = (UINT)(rcClient.bottom - rcClient.top);
|
---|
2922 | }
|
---|
2923 |
|
---|
2924 | // Now that we know the client rect, compare it against the back buffer size
|
---|
2925 | // to see if the client rect is already the right size
|
---|
2926 | if( nClientWidth != pNewDeviceSettings->pp.BackBufferWidth ||
|
---|
2927 | nClientHeight != pNewDeviceSettings->pp.BackBufferHeight )
|
---|
2928 | {
|
---|
2929 | bNeedToResize = true;
|
---|
2930 | }
|
---|
2931 |
|
---|
2932 | if( bClipWindowToSingleAdapter && !IsIconic(DXUTGetHWNDDeviceWindowed()) )
|
---|
2933 | {
|
---|
2934 | // Get the rect of the monitor attached to the adapter
|
---|
2935 | MONITORINFO miAdapter;
|
---|
2936 | miAdapter.cbSize = sizeof(MONITORINFO);
|
---|
2937 | HMONITOR hAdapterMonitor = DXUTGetD3DObject()->GetAdapterMonitor( pNewDeviceSettings->AdapterOrdinal );
|
---|
2938 | DXUTGetMonitorInfo( hAdapterMonitor, &miAdapter );
|
---|
2939 | HMONITOR hWindowMonitor = DXUTMonitorFromWindow( DXUTGetHWND(), MONITOR_DEFAULTTOPRIMARY );
|
---|
2940 |
|
---|
2941 | // Get the rect of the window
|
---|
2942 | RECT rcWindow;
|
---|
2943 | GetWindowRect( DXUTGetHWNDDeviceWindowed(), &rcWindow );
|
---|
2944 |
|
---|
2945 | // Check if the window rect is fully inside the adapter's vitural screen rect
|
---|
2946 | if( (rcWindow.left < miAdapter.rcWork.left ||
|
---|
2947 | rcWindow.right > miAdapter.rcWork.right ||
|
---|
2948 | rcWindow.top < miAdapter.rcWork.top ||
|
---|
2949 | rcWindow.bottom > miAdapter.rcWork.bottom) )
|
---|
2950 | {
|
---|
2951 | if( hWindowMonitor == hAdapterMonitor && IsZoomed(DXUTGetHWNDDeviceWindowed()) )
|
---|
2952 | {
|
---|
2953 | // If the window is maximized and on the same monitor as the adapter, then
|
---|
2954 | // no need to clip to single adapter as the window is already clipped
|
---|
2955 | // even though the rcWindow rect is outside of the miAdapter.rcWork
|
---|
2956 | }
|
---|
2957 | else
|
---|
2958 | {
|
---|
2959 | bNeedToResize = true;
|
---|
2960 | }
|
---|
2961 | }
|
---|
2962 | }
|
---|
2963 | }
|
---|
2964 |
|
---|
2965 | // Only resize window if needed
|
---|
2966 | if( bNeedToResize )
|
---|
2967 | {
|
---|
2968 | // Need to resize, so if window is maximized or minimized then restore the window
|
---|
2969 | if( IsIconic(DXUTGetHWNDDeviceWindowed()) )
|
---|
2970 | ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_RESTORE );
|
---|
2971 | if( IsZoomed(DXUTGetHWNDDeviceWindowed()) ) // doing the IsIconic() check first also handles the WPF_RESTORETOMAXIMIZED case
|
---|
2972 | ShowWindow( DXUTGetHWNDDeviceWindowed(), SW_RESTORE );
|
---|
2973 |
|
---|
2974 | if( bClipWindowToSingleAdapter )
|
---|
2975 | {
|
---|
2976 | // Get the rect of the monitor attached to the adapter
|
---|
2977 | MONITORINFO miAdapter;
|
---|
2978 | miAdapter.cbSize = sizeof(MONITORINFO);
|
---|
2979 | DXUTGetMonitorInfo( DXUTGetD3DObject()->GetAdapterMonitor( pNewDeviceSettings->AdapterOrdinal ), &miAdapter );
|
---|
2980 |
|
---|
2981 | // Get the rect of the monitor attached to the window
|
---|
2982 | MONITORINFO miWindow;
|
---|
2983 | miWindow.cbSize = sizeof(MONITORINFO);
|
---|
2984 | DXUTGetMonitorInfo( DXUTMonitorFromWindow( DXUTGetHWND(), MONITOR_DEFAULTTOPRIMARY ), &miWindow );
|
---|
2985 |
|
---|
2986 | // Do something reasonable if the BackBuffer size is greater than the monitor size
|
---|
2987 | int nAdapterMonitorWidth = miAdapter.rcWork.right - miAdapter.rcWork.left;
|
---|
2988 | int nAdapterMonitorHeight = miAdapter.rcWork.bottom - miAdapter.rcWork.top;
|
---|
2989 |
|
---|
2990 | int nClientWidth = pNewDeviceSettings->pp.BackBufferWidth;
|
---|
2991 | int nClientHeight = pNewDeviceSettings->pp.BackBufferHeight;
|
---|
2992 |
|
---|
2993 | // Get the rect of the window
|
---|
2994 | RECT rcWindow;
|
---|
2995 | GetWindowRect( DXUTGetHWNDDeviceWindowed(), &rcWindow );
|
---|
2996 |
|
---|
2997 | // Make a window rect with a client rect that is the same size as the backbuffer
|
---|
2998 | RECT rcResizedWindow;
|
---|
2999 | rcResizedWindow.left = 0;
|
---|
3000 | rcResizedWindow.right = nClientWidth;
|
---|
3001 | rcResizedWindow.top = 0;
|
---|
3002 | rcResizedWindow.bottom = nClientHeight;
|
---|
3003 | AdjustWindowRect( &rcResizedWindow, GetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE ), GetDXUTState().GetMenu() != NULL );
|
---|
3004 |
|
---|
3005 | int nWindowWidth = rcResizedWindow.right - rcResizedWindow.left;
|
---|
3006 | int nWindowHeight = rcResizedWindow.bottom - rcResizedWindow.top;
|
---|
3007 |
|
---|
3008 | if( nWindowWidth > nAdapterMonitorWidth )
|
---|
3009 | nWindowWidth = (nAdapterMonitorWidth - 0);
|
---|
3010 | if( nWindowHeight > nAdapterMonitorHeight )
|
---|
3011 | nWindowHeight = (nAdapterMonitorHeight - 0);
|
---|
3012 |
|
---|
3013 | if( rcResizedWindow.left < miAdapter.rcWork.left ||
|
---|
3014 | rcResizedWindow.top < miAdapter.rcWork.top ||
|
---|
3015 | rcResizedWindow.right > miAdapter.rcWork.right ||
|
---|
3016 | rcResizedWindow.bottom > miAdapter.rcWork.bottom )
|
---|
3017 | {
|
---|
3018 | int nWindowOffsetX = (nAdapterMonitorWidth - nWindowWidth) / 2;
|
---|
3019 | int nWindowOffsetY = (nAdapterMonitorHeight - nWindowHeight) / 2;
|
---|
3020 |
|
---|
3021 | rcResizedWindow.left = miAdapter.rcWork.left + nWindowOffsetX;
|
---|
3022 | rcResizedWindow.top = miAdapter.rcWork.top + nWindowOffsetY;
|
---|
3023 | rcResizedWindow.right = miAdapter.rcWork.left + nWindowOffsetX + nWindowWidth;
|
---|
3024 | rcResizedWindow.bottom = miAdapter.rcWork.top + nWindowOffsetY + nWindowHeight;
|
---|
3025 | }
|
---|
3026 |
|
---|
3027 | // Resize the window. It is important to adjust the window size
|
---|
3028 | // after resetting the device rather than beforehand to ensure
|
---|
3029 | // that the monitor resolution is correct and does not limit the size of the new window.
|
---|
3030 | SetWindowPos( DXUTGetHWNDDeviceWindowed(), 0, rcResizedWindow.left, rcResizedWindow.top, nWindowWidth, nWindowHeight, SWP_NOZORDER );
|
---|
3031 | }
|
---|
3032 | else
|
---|
3033 | {
|
---|
3034 | // Make a window rect with a client rect that is the same size as the backbuffer
|
---|
3035 | RECT rcWindow = {0};
|
---|
3036 | rcWindow.right = (long)(pNewDeviceSettings->pp.BackBufferWidth);
|
---|
3037 | rcWindow.bottom = (long)(pNewDeviceSettings->pp.BackBufferHeight);
|
---|
3038 | AdjustWindowRect( &rcWindow, GetWindowLong( DXUTGetHWNDDeviceWindowed(), GWL_STYLE ), GetDXUTState().GetMenu() != NULL );
|
---|
3039 |
|
---|
3040 | // Resize the window. It is important to adjust the window size
|
---|
3041 | // after resetting the device rather than beforehand to ensure
|
---|
3042 | // that the monitor resolution is correct and does not limit the size of the new window.
|
---|
3043 | int cx = (int)(rcWindow.right - rcWindow.left);
|
---|
3044 | int cy = (int)(rcWindow.bottom - rcWindow.top);
|
---|
3045 | SetWindowPos( DXUTGetHWNDDeviceWindowed(), 0, 0, 0, cx, cy, SWP_NOZORDER|SWP_NOMOVE );
|
---|
3046 | }
|
---|
3047 |
|
---|
3048 | // Its possible that the new window size is not what we asked for.
|
---|
3049 | // No window can be sized larger than the desktop, so see see if the Windows OS resized the
|
---|
3050 | // window to something smaller to fit on the desktop. Also if WM_GETMINMAXINFO
|
---|
3051 | // will put a limit on the smallest/largest window size.
|
---|
3052 | RECT rcClient;
|
---|
3053 | GetClientRect( DXUTGetHWNDDeviceWindowed(), &rcClient );
|
---|
3054 | UINT nClientWidth = (UINT)(rcClient.right - rcClient.left);
|
---|
3055 | UINT nClientHeight = (UINT)(rcClient.bottom - rcClient.top);
|
---|
3056 | if( nClientWidth != pNewDeviceSettings->pp.BackBufferWidth ||
|
---|
3057 | nClientHeight != pNewDeviceSettings->pp.BackBufferHeight )
|
---|
3058 | {
|
---|
3059 | // If its different, then resize the backbuffer again. This time create a backbuffer that matches the
|
---|
3060 | // client rect of the current window w/o resizing the window.
|
---|
3061 | DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
|
---|
3062 | deviceSettings.pp.BackBufferWidth = 0;
|
---|
3063 | deviceSettings.pp.BackBufferHeight = 0;
|
---|
3064 | hr = DXUTChangeDevice( &deviceSettings, NULL, false, bClipWindowToSingleAdapter );
|
---|
3065 | if( FAILED( hr ) )
|
---|
3066 | {
|
---|
3067 | SAFE_DELETE( pOldDeviceSettings );
|
---|
3068 | DXUTCleanup3DEnvironment();
|
---|
3069 | DXUTPause( false, false );
|
---|
3070 | GetDXUTState().SetIgnoreSizeChange( false );
|
---|
3071 | return hr;
|
---|
3072 | }
|
---|
3073 | }
|
---|
3074 | }
|
---|
3075 |
|
---|
3076 | // Make the window visible
|
---|
3077 | if( !IsWindowVisible( DXUTGetHWND() ) )
|
---|
3078 | ShowWindow( DXUTGetHWND(), SW_SHOW );
|
---|
3079 |
|
---|
3080 | // Make the window visible
|
---|
3081 | if( !IsWindowVisible( DXUTGetHWND() ) )
|
---|
3082 | ShowWindow( DXUTGetHWND(), SW_SHOW );
|
---|
3083 |
|
---|
3084 | // Ensure that the display doesn't power down when fullscreen but does when windowed
|
---|
3085 | if( !DXUTIsWindowed() )
|
---|
3086 | SetThreadExecutionState( ES_DISPLAY_REQUIRED | ES_CONTINUOUS );
|
---|
3087 | else
|
---|
3088 | SetThreadExecutionState( ES_CONTINUOUS );
|
---|
3089 |
|
---|
3090 | SAFE_DELETE( pOldDeviceSettings );
|
---|
3091 | GetDXUTState().SetIgnoreSizeChange( false );
|
---|
3092 | DXUTPause( false, false );
|
---|
3093 | GetDXUTState().SetDeviceCreated( true );
|
---|
3094 |
|
---|
3095 | return S_OK;
|
---|
3096 | }
|
---|
3097 |
|
---|
3098 |
|
---|
3099 | //--------------------------------------------------------------------------------------
|
---|
3100 | // Low level keyboard hook to disable Windows key to prevent accidental task switching.
|
---|
3101 | //--------------------------------------------------------------------------------------
|
---|
3102 | LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
|
---|
3103 | {
|
---|
3104 | if (nCode < 0 || nCode != HC_ACTION) // do not process message
|
---|
3105 | return CallNextHookEx( GetDXUTState().GetKeyboardHook(), nCode, wParam, lParam);
|
---|
3106 |
|
---|
3107 | bool bEatKeystroke = false;
|
---|
3108 | KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
|
---|
3109 | switch (wParam)
|
---|
3110 | {
|
---|
3111 | case WM_KEYDOWN:
|
---|
3112 | case WM_KEYUP:
|
---|
3113 | {
|
---|
3114 | bEatKeystroke = ( !GetDXUTState().GetAllowShortcutKeys() &&
|
---|
3115 | (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN) );
|
---|
3116 | break;
|
---|
3117 | }
|
---|
3118 | }
|
---|
3119 |
|
---|
3120 | if( bEatKeystroke )
|
---|
3121 | return 1;
|
---|
3122 | else
|
---|
3123 | return CallNextHookEx( GetDXUTState().GetKeyboardHook(), nCode, wParam, lParam );
|
---|
3124 | }
|
---|
3125 |
|
---|
3126 |
|
---|
3127 |
|
---|
3128 | //--------------------------------------------------------------------------------------
|
---|
3129 | // Controls how DXUT behaves when fullscreen and windowed mode with regard to
|
---|
3130 | // shortcut keys (Windows keys, StickyKeys shortcut, ToggleKeys shortcut, FilterKeys shortcut)
|
---|
3131 | //--------------------------------------------------------------------------------------
|
---|
3132 | void DXUTSetShortcutKeySettings( bool bAllowWhenFullscreen, bool bAllowWhenWindowed )
|
---|
3133 | {
|
---|
3134 | GetDXUTState().SetAllowShortcutKeysWhenWindowed( bAllowWhenWindowed );
|
---|
3135 | GetDXUTState().SetAllowShortcutKeysWhenFullscreen( bAllowWhenFullscreen );
|
---|
3136 |
|
---|
3137 | // DXUTInit() records initial accessibility states so don't change them until then
|
---|
3138 | if( GetDXUTState().GetDXUTInited() )
|
---|
3139 | {
|
---|
3140 | if( DXUTIsWindowed() )
|
---|
3141 | DXUTAllowShortcutKeys( GetDXUTState().GetAllowShortcutKeysWhenWindowed() );
|
---|
3142 | else
|
---|
3143 | DXUTAllowShortcutKeys( GetDXUTState().GetAllowShortcutKeysWhenFullscreen() );
|
---|
3144 | }
|
---|
3145 | }
|
---|
3146 |
|
---|
3147 |
|
---|
3148 | //--------------------------------------------------------------------------------------
|
---|
3149 | // Enables/disables Windows keys, and disables or restores the StickyKeys/ToggleKeys/FilterKeys
|
---|
3150 | // shortcut to help prevent accidental task switching
|
---|
3151 | //--------------------------------------------------------------------------------------
|
---|
3152 | void DXUTAllowShortcutKeys( bool bAllowKeys )
|
---|
3153 | {
|
---|
3154 | GetDXUTState().SetAllowShortcutKeys( bAllowKeys );
|
---|
3155 |
|
---|
3156 | if( bAllowKeys )
|
---|
3157 | {
|
---|
3158 | // Restore StickyKeys/etc to original state and enable Windows key
|
---|
3159 | STICKYKEYS sk = GetDXUTState().GetStartupStickyKeys();
|
---|
3160 | TOGGLEKEYS tk = GetDXUTState().GetStartupToggleKeys();
|
---|
3161 | FILTERKEYS fk = GetDXUTState().GetStartupFilterKeys();
|
---|
3162 |
|
---|
3163 | SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &sk, 0);
|
---|
3164 | SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tk, 0);
|
---|
3165 | SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &fk, 0);
|
---|
3166 |
|
---|
3167 | // Remove the keyboard hoook when it isn't needed to prevent any slow down of other apps
|
---|
3168 | if( GetDXUTState().GetKeyboardHook() )
|
---|
3169 | {
|
---|
3170 | UnhookWindowsHookEx( GetDXUTState().GetKeyboardHook() );
|
---|
3171 | GetDXUTState().SetKeyboardHook( NULL );
|
---|
3172 | }
|
---|
3173 | }
|
---|
3174 | else
|
---|
3175 | {
|
---|
3176 | // Set low level keyboard hook if haven't already
|
---|
3177 | if( GetDXUTState().GetKeyboardHook() == NULL )
|
---|
3178 | {
|
---|
3179 | // Set the low-level hook procedure. Only works on Windows 2000 and above
|
---|
3180 | OSVERSIONINFO OSVersionInfo;
|
---|
3181 | OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo);
|
---|
3182 | GetVersionEx(&OSVersionInfo);
|
---|
3183 | if( OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && OSVersionInfo.dwMajorVersion > 4 )
|
---|
3184 | {
|
---|
3185 | HHOOK hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 );
|
---|
3186 | GetDXUTState().SetKeyboardHook( hKeyboardHook );
|
---|
3187 | }
|
---|
3188 | }
|
---|
3189 |
|
---|
3190 | // Disable StickyKeys/etc shortcuts but if the accessibility feature is on,
|
---|
3191 | // then leave the settings alone as its probably being usefully used
|
---|
3192 |
|
---|
3193 | STICKYKEYS skOff = GetDXUTState().GetStartupStickyKeys();
|
---|
3194 | if( (skOff.dwFlags & SKF_STICKYKEYSON) == 0 )
|
---|
3195 | {
|
---|
3196 | // Disable the hotkey and the confirmation
|
---|
3197 | skOff.dwFlags &= ~SKF_HOTKEYACTIVE;
|
---|
3198 | skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;
|
---|
3199 |
|
---|
3200 | SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &skOff, 0);
|
---|
3201 | }
|
---|
3202 |
|
---|
3203 | TOGGLEKEYS tkOff = GetDXUTState().GetStartupToggleKeys();
|
---|
3204 | if( (tkOff.dwFlags & TKF_TOGGLEKEYSON) == 0 )
|
---|
3205 | {
|
---|
3206 | // Disable the hotkey and the confirmation
|
---|
3207 | tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;
|
---|
3208 | tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;
|
---|
3209 |
|
---|
3210 | SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tkOff, 0);
|
---|
3211 | }
|
---|
3212 |
|
---|
3213 | FILTERKEYS fkOff = GetDXUTState().GetStartupFilterKeys();
|
---|
3214 | if( (fkOff.dwFlags & FKF_FILTERKEYSON) == 0 )
|
---|
3215 | {
|
---|
3216 | // Disable the hotkey and the confirmation
|
---|
3217 | fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;
|
---|
3218 | fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;
|
---|
3219 |
|
---|
3220 | SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &fkOff, 0);
|
---|
3221 | }
|
---|
3222 | }
|
---|
3223 | }
|
---|
3224 |
|
---|
3225 |
|
---|
3226 | //--------------------------------------------------------------------------------------
|
---|
3227 | // Updates the device settings struct based on the cmd line args.
|
---|
3228 | //--------------------------------------------------------------------------------------
|
---|
3229 | void DXUTUpdateDeviceSettingsWithOverrides( DXUTDeviceSettings* pDeviceSettings )
|
---|
3230 | {
|
---|
3231 | if( GetDXUTState().GetOverrideAdapterOrdinal() != -1 )
|
---|
3232 | pDeviceSettings->AdapterOrdinal = GetDXUTState().GetOverrideAdapterOrdinal();
|
---|
3233 |
|
---|
3234 | if( GetDXUTState().GetOverrideFullScreen() )
|
---|
3235 | pDeviceSettings->pp.Windowed = false;
|
---|
3236 | if( GetDXUTState().GetOverrideWindowed() )
|
---|
3237 | pDeviceSettings->pp.Windowed = true;
|
---|
3238 |
|
---|
3239 | if( GetDXUTState().GetOverrideForceREF() )
|
---|
3240 | pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
|
---|
3241 | else if( GetDXUTState().GetOverrideForceHAL() )
|
---|
3242 | pDeviceSettings->DeviceType = D3DDEVTYPE_HAL;
|
---|
3243 |
|
---|
3244 | if( GetDXUTState().GetOverrideWidth() != 0 )
|
---|
3245 | pDeviceSettings->pp.BackBufferWidth = GetDXUTState().GetOverrideWidth();
|
---|
3246 | if( GetDXUTState().GetOverrideHeight() != 0 )
|
---|
3247 | pDeviceSettings->pp.BackBufferHeight = GetDXUTState().GetOverrideHeight();
|
---|
3248 |
|
---|
3249 | if( GetDXUTState().GetOverrideForcePureHWVP() )
|
---|
3250 | {
|
---|
3251 | pDeviceSettings->BehaviorFlags &= ~D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
---|
3252 | pDeviceSettings->BehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
3253 | pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
|
---|
3254 | }
|
---|
3255 | else if( GetDXUTState().GetOverrideForceHWVP() )
|
---|
3256 | {
|
---|
3257 | pDeviceSettings->BehaviorFlags &= ~D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
---|
3258 | pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
|
---|
3259 | pDeviceSettings->BehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
3260 | }
|
---|
3261 | else if( GetDXUTState().GetOverrideForceSWVP() )
|
---|
3262 | {
|
---|
3263 | pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
---|
3264 | pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
|
---|
3265 | pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
---|
3266 | }
|
---|
3267 | }
|
---|
3268 |
|
---|
3269 |
|
---|
3270 | //--------------------------------------------------------------------------------------
|
---|
3271 | // Creates the 3D environment
|
---|
3272 | //--------------------------------------------------------------------------------------
|
---|
3273 | HRESULT DXUTCreate3DEnvironment( IDirect3DDevice9* pd3dDeviceFromApp )
|
---|
3274 | {
|
---|
3275 | HRESULT hr = S_OK;
|
---|
3276 |
|
---|
3277 | IDirect3DDevice9* pd3dDevice = NULL;
|
---|
3278 | DXUTDeviceSettings* pNewDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
3279 |
|
---|
3280 | // Only create a Direct3D device if one hasn't been supplied by the app
|
---|
3281 | if( pd3dDeviceFromApp == NULL )
|
---|
3282 | {
|
---|
3283 | // Try to create the device with the chosen settings
|
---|
3284 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
3285 | hr = pD3D->CreateDevice( pNewDeviceSettings->AdapterOrdinal, pNewDeviceSettings->DeviceType,
|
---|
3286 | DXUTGetHWNDFocus(), pNewDeviceSettings->BehaviorFlags,
|
---|
3287 | &pNewDeviceSettings->pp, &pd3dDevice );
|
---|
3288 | if( hr == D3DERR_DEVICELOST )
|
---|
3289 | {
|
---|
3290 | GetDXUTState().SetDeviceLost( true );
|
---|
3291 | return S_OK;
|
---|
3292 | }
|
---|
3293 | else if( FAILED(hr) )
|
---|
3294 | {
|
---|
3295 | DXUT_ERR( L"CreateDevice", hr );
|
---|
3296 | return DXUTERR_CREATINGDEVICE;
|
---|
3297 | }
|
---|
3298 | }
|
---|
3299 | else
|
---|
3300 | {
|
---|
3301 | pd3dDeviceFromApp->AddRef();
|
---|
3302 | pd3dDevice = pd3dDeviceFromApp;
|
---|
3303 | }
|
---|
3304 |
|
---|
3305 | GetDXUTState().SetD3DDevice( pd3dDevice );
|
---|
3306 |
|
---|
3307 | // If switching to REF, set the exit code to 11. If switching to HAL and exit code was 11, then set it back to 0.
|
---|
3308 | if( pNewDeviceSettings->DeviceType == D3DDEVTYPE_REF && GetDXUTState().GetExitCode() == 0 )
|
---|
3309 | GetDXUTState().SetExitCode(11);
|
---|
3310 | else if( pNewDeviceSettings->DeviceType == D3DDEVTYPE_HAL && GetDXUTState().GetExitCode() == 11 )
|
---|
3311 | GetDXUTState().SetExitCode(0);
|
---|
3312 |
|
---|
3313 | // Update back buffer desc before calling app's device callbacks
|
---|
3314 | DXUTUpdateBackBufferDesc();
|
---|
3315 |
|
---|
3316 | // Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state)
|
---|
3317 | DXUTSetupCursor();
|
---|
3318 |
|
---|
3319 | // Update GetDXUTState()'s copy of D3D caps
|
---|
3320 | D3DCAPS9* pd3dCaps = GetDXUTState().GetCaps();
|
---|
3321 | DXUTGetD3DDevice()->GetDeviceCaps( pd3dCaps );
|
---|
3322 |
|
---|
3323 | // Update the device stats text
|
---|
3324 | CD3DEnumeration* pd3dEnum = DXUTPrepareEnumerationObject();
|
---|
3325 | CD3DEnumAdapterInfo* pAdapterInfo = pd3dEnum->GetAdapterInfo( pNewDeviceSettings->AdapterOrdinal );
|
---|
3326 | DXUTUpdateDeviceStats( pNewDeviceSettings->DeviceType,
|
---|
3327 | pNewDeviceSettings->BehaviorFlags,
|
---|
3328 | &pAdapterInfo->AdapterIdentifier );
|
---|
3329 |
|
---|
3330 | // Call the resource cache created function
|
---|
3331 | hr = DXUTGetGlobalResourceCache().OnCreateDevice( pd3dDevice );
|
---|
3332 | if( FAILED(hr) )
|
---|
3333 | return DXUT_ERR( L"OnCreateDevice", ( hr == DXUTERR_MEDIANOTFOUND ) ? DXUTERR_MEDIANOTFOUND : DXUTERR_CREATINGDEVICEOBJECTS );
|
---|
3334 |
|
---|
3335 | // Call the app's device created callback if non-NULL
|
---|
3336 | const D3DSURFACE_DESC* pbackBufferSurfaceDesc = DXUTGetBackBufferSurfaceDesc();
|
---|
3337 | GetDXUTState().SetInsideDeviceCallback( true );
|
---|
3338 | LPDXUTCALLBACKDEVICECREATED pCallbackDeviceCreated = GetDXUTState().GetDeviceCreatedFunc();
|
---|
3339 | hr = S_OK;
|
---|
3340 | if( pCallbackDeviceCreated != NULL )
|
---|
3341 | hr = pCallbackDeviceCreated( DXUTGetD3DDevice(), pbackBufferSurfaceDesc, GetDXUTState().GetDeviceCreatedFuncUserContext() );
|
---|
3342 | GetDXUTState().SetInsideDeviceCallback( false );
|
---|
3343 | if( DXUTGetD3DDevice() == NULL ) // Handle DXUTShutdown from inside callback
|
---|
3344 | return E_FAIL;
|
---|
3345 | if( FAILED(hr) )
|
---|
3346 | {
|
---|
3347 | DXUT_ERR( L"DeviceCreated callback", hr );
|
---|
3348 | return ( hr == DXUTERR_MEDIANOTFOUND ) ? DXUTERR_MEDIANOTFOUND : DXUTERR_CREATINGDEVICEOBJECTS;
|
---|
3349 | }
|
---|
3350 | GetDXUTState().SetDeviceObjectsCreated( true );
|
---|
3351 |
|
---|
3352 | // Call the resource cache device reset function
|
---|
3353 | hr = DXUTGetGlobalResourceCache().OnResetDevice( pd3dDevice );
|
---|
3354 | if( FAILED(hr) )
|
---|
3355 | return DXUT_ERR( L"OnResetDevice", DXUTERR_RESETTINGDEVICEOBJECTS );
|
---|
3356 |
|
---|
3357 | // Call the app's device reset callback if non-NULL
|
---|
3358 | GetDXUTState().SetInsideDeviceCallback( true );
|
---|
3359 | LPDXUTCALLBACKDEVICERESET pCallbackDeviceReset = GetDXUTState().GetDeviceResetFunc();
|
---|
3360 | hr = S_OK;
|
---|
3361 | if( pCallbackDeviceReset != NULL )
|
---|
3362 | hr = pCallbackDeviceReset( DXUTGetD3DDevice(), pbackBufferSurfaceDesc, GetDXUTState().GetDeviceResetFuncUserContext() );
|
---|
3363 | GetDXUTState().SetInsideDeviceCallback( false );
|
---|
3364 | if( DXUTGetD3DDevice() == NULL ) // Handle DXUTShutdown from inside callback
|
---|
3365 | return E_FAIL;
|
---|
3366 | if( FAILED(hr) )
|
---|
3367 | {
|
---|
3368 | DXUT_ERR( L"DeviceReset callback", hr );
|
---|
3369 | return ( hr == DXUTERR_MEDIANOTFOUND ) ? DXUTERR_MEDIANOTFOUND : DXUTERR_RESETTINGDEVICEOBJECTS;
|
---|
3370 | }
|
---|
3371 | GetDXUTState().SetDeviceObjectsReset( true );
|
---|
3372 |
|
---|
3373 | return S_OK;
|
---|
3374 | }
|
---|
3375 |
|
---|
3376 |
|
---|
3377 | //--------------------------------------------------------------------------------------
|
---|
3378 | // Resets the 3D environment by:
|
---|
3379 | // - Calls the device lost callback
|
---|
3380 | // - Resets the device
|
---|
3381 | // - Stores the back buffer description
|
---|
3382 | // - Sets up the full screen Direct3D cursor if requested
|
---|
3383 | // - Calls the device reset callback
|
---|
3384 | //--------------------------------------------------------------------------------------
|
---|
3385 | HRESULT DXUTReset3DEnvironment()
|
---|
3386 | {
|
---|
3387 | HRESULT hr;
|
---|
3388 |
|
---|
3389 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
3390 | assert( pd3dDevice != NULL );
|
---|
3391 |
|
---|
3392 | // Call the app's device lost callback
|
---|
3393 | if( GetDXUTState().GetDeviceObjectsReset() == true )
|
---|
3394 | {
|
---|
3395 | GetDXUTState().SetInsideDeviceCallback( true );
|
---|
3396 | LPDXUTCALLBACKDEVICELOST pCallbackDeviceLost = GetDXUTState().GetDeviceLostFunc();
|
---|
3397 | if( pCallbackDeviceLost != NULL )
|
---|
3398 | pCallbackDeviceLost( GetDXUTState().GetDeviceLostFuncUserContext() );
|
---|
3399 | GetDXUTState().SetDeviceObjectsReset( false );
|
---|
3400 | GetDXUTState().SetInsideDeviceCallback( false );
|
---|
3401 |
|
---|
3402 | // Call the resource cache device lost function
|
---|
3403 | DXUTGetGlobalResourceCache().OnLostDevice();
|
---|
3404 | }
|
---|
3405 |
|
---|
3406 | // Reset the device
|
---|
3407 | DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
3408 | hr = pd3dDevice->Reset( &pDeviceSettings->pp );
|
---|
3409 | if( FAILED(hr) )
|
---|
3410 | {
|
---|
3411 | if( hr == D3DERR_DEVICELOST )
|
---|
3412 | return D3DERR_DEVICELOST; // Reset could legitimately fail if the device is lost
|
---|
3413 | else
|
---|
3414 | return DXUT_ERR( L"Reset", DXUTERR_RESETTINGDEVICE );
|
---|
3415 | }
|
---|
3416 |
|
---|
3417 | // Update back buffer desc before calling app's device callbacks
|
---|
3418 | DXUTUpdateBackBufferDesc();
|
---|
3419 |
|
---|
3420 | // Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state)
|
---|
3421 | DXUTSetupCursor();
|
---|
3422 |
|
---|
3423 | hr = DXUTGetGlobalResourceCache().OnResetDevice( pd3dDevice );
|
---|
3424 | if( FAILED(hr) )
|
---|
3425 | return DXUT_ERR( L"OnResetDevice", DXUTERR_RESETTINGDEVICEOBJECTS );
|
---|
3426 |
|
---|
3427 | // Call the app's OnDeviceReset callback
|
---|
3428 | GetDXUTState().SetInsideDeviceCallback( true );
|
---|
3429 | const D3DSURFACE_DESC* pbackBufferSurfaceDesc = DXUTGetBackBufferSurfaceDesc();
|
---|
3430 | LPDXUTCALLBACKDEVICERESET pCallbackDeviceReset = GetDXUTState().GetDeviceResetFunc();
|
---|
3431 | hr = S_OK;
|
---|
3432 | if( pCallbackDeviceReset != NULL )
|
---|
3433 | hr = pCallbackDeviceReset( pd3dDevice, pbackBufferSurfaceDesc, GetDXUTState().GetDeviceResetFuncUserContext() );
|
---|
3434 | GetDXUTState().SetInsideDeviceCallback( false );
|
---|
3435 | if( FAILED(hr) )
|
---|
3436 | {
|
---|
3437 | // If callback failed, cleanup
|
---|
3438 | DXUT_ERR( L"DeviceResetCallback", hr );
|
---|
3439 | if( hr != DXUTERR_MEDIANOTFOUND )
|
---|
3440 | hr = DXUTERR_RESETTINGDEVICEOBJECTS;
|
---|
3441 |
|
---|
3442 | GetDXUTState().SetInsideDeviceCallback( true );
|
---|
3443 | LPDXUTCALLBACKDEVICELOST pCallbackDeviceLost = GetDXUTState().GetDeviceLostFunc();
|
---|
3444 | if( pCallbackDeviceLost != NULL )
|
---|
3445 | pCallbackDeviceLost( GetDXUTState().GetDeviceLostFuncUserContext() );
|
---|
3446 | GetDXUTState().SetInsideDeviceCallback( false );
|
---|
3447 |
|
---|
3448 | DXUTGetGlobalResourceCache().OnLostDevice();
|
---|
3449 | return hr;
|
---|
3450 | }
|
---|
3451 |
|
---|
3452 | // Success
|
---|
3453 | GetDXUTState().SetDeviceObjectsReset( true );
|
---|
3454 |
|
---|
3455 | return S_OK;
|
---|
3456 | }
|
---|
3457 |
|
---|
3458 |
|
---|
3459 | //--------------------------------------------------------------------------------------
|
---|
3460 | // Pauses time or rendering. Keeps a ref count so pausing can be layered
|
---|
3461 | //--------------------------------------------------------------------------------------
|
---|
3462 | void DXUTPause( bool bPauseTime, bool bPauseRendering )
|
---|
3463 | {
|
---|
3464 | int nPauseTimeCount = GetDXUTState().GetPauseTimeCount();
|
---|
3465 | nPauseTimeCount += ( bPauseTime ? +1 : -1 );
|
---|
3466 | if( nPauseTimeCount < 0 )
|
---|
3467 | nPauseTimeCount = 0;
|
---|
3468 | GetDXUTState().SetPauseTimeCount( nPauseTimeCount );
|
---|
3469 |
|
---|
3470 | int nPauseRenderingCount = GetDXUTState().GetPauseRenderingCount();
|
---|
3471 | nPauseRenderingCount += ( bPauseRendering ? +1 : -1 );
|
---|
3472 | if( nPauseRenderingCount < 0 )
|
---|
3473 | nPauseRenderingCount = 0;
|
---|
3474 | GetDXUTState().SetPauseRenderingCount( nPauseRenderingCount );
|
---|
3475 |
|
---|
3476 | if( nPauseTimeCount > 0 )
|
---|
3477 | {
|
---|
3478 | // Stop the scene from animating
|
---|
3479 | DXUTGetGlobalTimer()->Stop();
|
---|
3480 | }
|
---|
3481 | else
|
---|
3482 | {
|
---|
3483 | // Restart the timer
|
---|
3484 | DXUTGetGlobalTimer()->Start();
|
---|
3485 | }
|
---|
3486 |
|
---|
3487 | GetDXUTState().SetRenderingPaused( nPauseRenderingCount > 0 );
|
---|
3488 | GetDXUTState().SetTimePaused( nPauseTimeCount > 0 );
|
---|
3489 | }
|
---|
3490 |
|
---|
3491 |
|
---|
3492 | //--------------------------------------------------------------------------------------
|
---|
3493 | // Checks if the window client rect has changed and if it has, then reset the device
|
---|
3494 | //--------------------------------------------------------------------------------------
|
---|
3495 | void DXUTCheckForWindowSizeChange()
|
---|
3496 | {
|
---|
3497 | // Skip the check for various reasons
|
---|
3498 | if( GetDXUTState().GetIgnoreSizeChange() ||
|
---|
3499 | !GetDXUTState().GetDeviceCreated() ||
|
---|
3500 | !GetDXUTState().GetCurrentDeviceSettings()->pp.Windowed )
|
---|
3501 | return;
|
---|
3502 |
|
---|
3503 | RECT rcCurrentClient;
|
---|
3504 | GetClientRect( DXUTGetHWND(), &rcCurrentClient );
|
---|
3505 |
|
---|
3506 | if( (UINT)rcCurrentClient.right != GetDXUTState().GetCurrentDeviceSettings()->pp.BackBufferWidth ||
|
---|
3507 | (UINT)rcCurrentClient.bottom != GetDXUTState().GetCurrentDeviceSettings()->pp.BackBufferHeight )
|
---|
3508 | {
|
---|
3509 | // A new window size will require a new backbuffer size
|
---|
3510 | // size, so the device must be reset and the D3D structures updated accordingly.
|
---|
3511 |
|
---|
3512 | // Tell DXUTChangeDevice and D3D to size according to the HWND's client rect
|
---|
3513 | DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
|
---|
3514 | deviceSettings.pp.BackBufferWidth = 0;
|
---|
3515 | deviceSettings.pp.BackBufferHeight = 0;
|
---|
3516 | DXUTChangeDevice( &deviceSettings, NULL, false, false );
|
---|
3517 | }
|
---|
3518 | }
|
---|
3519 |
|
---|
3520 |
|
---|
3521 | //--------------------------------------------------------------------------------------
|
---|
3522 | // Handles app's message loop and rendering when idle. If DXUTCreateDevice*() or DXUTSetDevice()
|
---|
3523 | // has not already been called, it will call DXUTCreateWindow() with the default parameters.
|
---|
3524 | //--------------------------------------------------------------------------------------
|
---|
3525 | HRESULT DXUTMainLoop( HACCEL hAccel )
|
---|
3526 | {
|
---|
3527 | HRESULT hr;
|
---|
3528 |
|
---|
3529 | // Not allowed to call this from inside the device callbacks or reenter
|
---|
3530 | if( GetDXUTState().GetInsideDeviceCallback() || GetDXUTState().GetInsideMainloop() )
|
---|
3531 | {
|
---|
3532 | if( (GetDXUTState().GetExitCode() == 0) || (GetDXUTState().GetExitCode() == 11) )
|
---|
3533 | GetDXUTState().SetExitCode(1);
|
---|
3534 | return DXUT_ERR_MSGBOX( L"DXUTMainLoop", E_FAIL );
|
---|
3535 | }
|
---|
3536 |
|
---|
3537 | GetDXUTState().SetInsideMainloop( true );
|
---|
3538 |
|
---|
3539 | // If DXUTCreateDevice*() or DXUTSetDevice() has not already been called,
|
---|
3540 | // then call DXUTCreateDevice() with the default parameters.
|
---|
3541 | if( !GetDXUTState().GetDeviceCreated() )
|
---|
3542 | {
|
---|
3543 | if( GetDXUTState().GetDeviceCreateCalled() )
|
---|
3544 | {
|
---|
3545 | if( (GetDXUTState().GetExitCode() == 0) || (GetDXUTState().GetExitCode() == 11) )
|
---|
3546 | GetDXUTState().SetExitCode(1);
|
---|
3547 | return E_FAIL; // DXUTCreateDevice() must first succeed for this function to succeed
|
---|
3548 | }
|
---|
3549 |
|
---|
3550 | hr = DXUTCreateDevice();
|
---|
3551 | if( FAILED(hr) )
|
---|
3552 | {
|
---|
3553 | if( (GetDXUTState().GetExitCode() == 0) || (GetDXUTState().GetExitCode() == 11) )
|
---|
3554 | GetDXUTState().SetExitCode(1);
|
---|
3555 | return hr;
|
---|
3556 | }
|
---|
3557 | }
|
---|
3558 |
|
---|
3559 | HWND hWnd = DXUTGetHWND();
|
---|
3560 |
|
---|
3561 | // DXUTInit() must have been called and succeeded for this function to proceed
|
---|
3562 | // DXUTCreateWindow() or DXUTSetWindow() must have been called and succeeded for this function to proceed
|
---|
3563 | // DXUTCreateDevice() or DXUTCreateDeviceFromSettings() or DXUTSetDevice() must have been called and succeeded for this function to proceed
|
---|
3564 | if( !GetDXUTState().GetDXUTInited() || !GetDXUTState().GetWindowCreated() || !GetDXUTState().GetDeviceCreated() )
|
---|
3565 | {
|
---|
3566 | if( (GetDXUTState().GetExitCode() == 0) || (GetDXUTState().GetExitCode() == 11) )
|
---|
3567 | GetDXUTState().SetExitCode(1);
|
---|
3568 | return DXUT_ERR_MSGBOX( L"DXUTMainLoop", E_FAIL );
|
---|
3569 | }
|
---|
3570 |
|
---|
3571 | // Now we're ready to receive and process Windows messages.
|
---|
3572 | bool bGotMsg;
|
---|
3573 | MSG msg;
|
---|
3574 | msg.message = WM_NULL;
|
---|
3575 | PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
|
---|
3576 |
|
---|
3577 | while( WM_QUIT != msg.message )
|
---|
3578 | {
|
---|
3579 | // Use PeekMessage() so we can use idle time to render the scene.
|
---|
3580 | bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
|
---|
3581 |
|
---|
3582 | if( bGotMsg )
|
---|
3583 | {
|
---|
3584 | // Translate and dispatch the message
|
---|
3585 | if( hAccel == NULL || hWnd == NULL ||
|
---|
3586 | 0 == TranslateAccelerator( hWnd, hAccel, &msg ) )
|
---|
3587 | {
|
---|
3588 | TranslateMessage( &msg );
|
---|
3589 | DispatchMessage( &msg );
|
---|
3590 | }
|
---|
3591 | }
|
---|
3592 | else
|
---|
3593 | {
|
---|
3594 | // Render a frame during idle time (no messages are waiting)
|
---|
3595 | DXUTRender3DEnvironment();
|
---|
3596 | }
|
---|
3597 | }
|
---|
3598 |
|
---|
3599 | // Cleanup the accelerator table
|
---|
3600 | if( hAccel != NULL )
|
---|
3601 | DestroyAcceleratorTable( hAccel );
|
---|
3602 |
|
---|
3603 | GetDXUTState().SetInsideMainloop( false );
|
---|
3604 |
|
---|
3605 | return S_OK;
|
---|
3606 | }
|
---|
3607 |
|
---|
3608 |
|
---|
3609 | //--------------------------------------------------------------------------------------
|
---|
3610 | // Render the 3D environment by:
|
---|
3611 | // - Checking if the device is lost and trying to reset it if it is
|
---|
3612 | // - Get the elapsed time since the last frame
|
---|
3613 | // - Calling the app's framemove and render callback
|
---|
3614 | // - Calling Present()
|
---|
3615 | //--------------------------------------------------------------------------------------
|
---|
3616 | void DXUTRender3DEnvironment()
|
---|
3617 | {
|
---|
3618 | HRESULT hr;
|
---|
3619 |
|
---|
3620 | if( GetDXUTState().GetDeviceLost() || DXUTIsRenderingPaused() || !DXUTIsActive() )
|
---|
3621 | {
|
---|
3622 | // Window is minimized or paused so yield CPU time to other processes
|
---|
3623 | Sleep( 50 );
|
---|
3624 | }
|
---|
3625 |
|
---|
3626 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
3627 | if( NULL == pd3dDevice )
|
---|
3628 | {
|
---|
3629 | if( GetDXUTState().GetDeviceLost() )
|
---|
3630 | {
|
---|
3631 | DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
|
---|
3632 | DXUTChangeDevice( &deviceSettings, NULL, false, true );
|
---|
3633 | }
|
---|
3634 |
|
---|
3635 | return;
|
---|
3636 | }
|
---|
3637 |
|
---|
3638 | if( GetDXUTState().GetDeviceLost() && !GetDXUTState().GetRenderingPaused() )
|
---|
3639 | {
|
---|
3640 | // Test the cooperative level to see if it's okay to render
|
---|
3641 | if( FAILED( hr = pd3dDevice->TestCooperativeLevel() ) )
|
---|
3642 | {
|
---|
3643 | if( D3DERR_DEVICELOST == hr )
|
---|
3644 | {
|
---|
3645 | // The device has been lost but cannot be reset at this time.
|
---|
3646 | // So wait until it can be reset.
|
---|
3647 | return;
|
---|
3648 | }
|
---|
3649 |
|
---|
3650 | // If we are windowed, read the desktop format and
|
---|
3651 | // ensure that the Direct3D device is using the same format
|
---|
3652 | // since the user could have changed the desktop bitdepth
|
---|
3653 | if( DXUTIsWindowed() )
|
---|
3654 | {
|
---|
3655 | D3DDISPLAYMODE adapterDesktopDisplayMode;
|
---|
3656 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
3657 | DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
3658 | pD3D->GetAdapterDisplayMode( pDeviceSettings->AdapterOrdinal, &adapterDesktopDisplayMode );
|
---|
3659 | if( pDeviceSettings->AdapterFormat != adapterDesktopDisplayMode.Format )
|
---|
3660 | {
|
---|
3661 | DXUTMatchOptions matchOptions;
|
---|
3662 | matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
|
---|
3663 | matchOptions.eDeviceType = DXUTMT_PRESERVE_INPUT;
|
---|
3664 | matchOptions.eWindowed = DXUTMT_PRESERVE_INPUT;
|
---|
3665 | matchOptions.eAdapterFormat = DXUTMT_PRESERVE_INPUT;
|
---|
3666 | matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3667 | matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3668 | matchOptions.eBackBufferFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3669 | matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3670 | matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3671 | matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3672 | matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3673 | matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3674 | matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3675 | matchOptions.eRefreshRate = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3676 | matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
|
---|
3677 |
|
---|
3678 | DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
|
---|
3679 | deviceSettings.AdapterFormat = adapterDesktopDisplayMode.Format;
|
---|
3680 |
|
---|
3681 | hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
|
---|
3682 | if( FAILED(hr) ) // the call will fail if no valid devices were found
|
---|
3683 | {
|
---|
3684 | DXUTDisplayErrorMessage( DXUTERR_NOCOMPATIBLEDEVICES );
|
---|
3685 | DXUTShutdown();
|
---|
3686 | }
|
---|
3687 |
|
---|
3688 | // Change to a Direct3D device created from the new device settings.
|
---|
3689 | // If there is an existing device, then either reset or recreate the scene
|
---|
3690 | hr = DXUTChangeDevice( &deviceSettings, NULL, false, false );
|
---|
3691 | if( FAILED(hr) )
|
---|
3692 | {
|
---|
3693 | // If this fails, try to go fullscreen and if this fails also shutdown.
|
---|
3694 | if( FAILED(DXUTToggleFullScreen()) )
|
---|
3695 | DXUTShutdown();
|
---|
3696 | }
|
---|
3697 |
|
---|
3698 | return;
|
---|
3699 | }
|
---|
3700 | }
|
---|
3701 |
|
---|
3702 | // Try to reset the device
|
---|
3703 | if( FAILED( hr = DXUTReset3DEnvironment() ) )
|
---|
3704 | {
|
---|
3705 | if( D3DERR_DEVICELOST == hr )
|
---|
3706 | {
|
---|
3707 | // The device was lost again, so continue waiting until it can be reset.
|
---|
3708 | return;
|
---|
3709 | }
|
---|
3710 | else if( DXUTERR_RESETTINGDEVICEOBJECTS == hr ||
|
---|
3711 | DXUTERR_MEDIANOTFOUND == hr )
|
---|
3712 | {
|
---|
3713 | DXUTDisplayErrorMessage( hr );
|
---|
3714 | DXUTShutdown();
|
---|
3715 | return;
|
---|
3716 | }
|
---|
3717 | else
|
---|
3718 | {
|
---|
3719 | // Reset failed, but the device wasn't lost so something bad happened,
|
---|
3720 | // so recreate the device to try to recover
|
---|
3721 | DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
3722 | if( FAILED( DXUTChangeDevice( pDeviceSettings, NULL, true, false ) ) )
|
---|
3723 | {
|
---|
3724 | DXUTShutdown();
|
---|
3725 | return;
|
---|
3726 | }
|
---|
3727 | }
|
---|
3728 | }
|
---|
3729 | }
|
---|
3730 |
|
---|
3731 | GetDXUTState().SetDeviceLost( false );
|
---|
3732 | }
|
---|
3733 |
|
---|
3734 | // Get the app's time, in seconds. Skip rendering if no time elapsed
|
---|
3735 | double fTime, fAbsTime; float fElapsedTime;
|
---|
3736 | DXUTGetGlobalTimer()->GetTimeValues( &fTime, &fAbsTime, &fElapsedTime );
|
---|
3737 |
|
---|
3738 | // Store the time for the app
|
---|
3739 | if( GetDXUTState().GetConstantFrameTime() )
|
---|
3740 | {
|
---|
3741 | fElapsedTime = GetDXUTState().GetTimePerFrame();
|
---|
3742 | fTime = DXUTGetTime() + fElapsedTime;
|
---|
3743 | }
|
---|
3744 |
|
---|
3745 | GetDXUTState().SetTime( fTime );
|
---|
3746 | GetDXUTState().SetAbsoluteTime( fAbsTime );
|
---|
3747 | GetDXUTState().SetElapsedTime( fElapsedTime );
|
---|
3748 |
|
---|
3749 | // Update the FPS stats
|
---|
3750 | DXUTUpdateFrameStats();
|
---|
3751 |
|
---|
3752 | DXUTHandleTimers();
|
---|
3753 |
|
---|
3754 | // Animate the scene by calling the app's frame move callback
|
---|
3755 | LPDXUTCALLBACKFRAMEMOVE pCallbackFrameMove = GetDXUTState().GetFrameMoveFunc();
|
---|
3756 | if( pCallbackFrameMove != NULL )
|
---|
3757 | {
|
---|
3758 | pCallbackFrameMove( pd3dDevice, fTime, fElapsedTime, GetDXUTState().GetFrameMoveFuncUserContext() );
|
---|
3759 | pd3dDevice = DXUTGetD3DDevice();
|
---|
3760 | if( NULL == pd3dDevice ) // Handle DXUTShutdown from inside callback
|
---|
3761 | return;
|
---|
3762 | }
|
---|
3763 |
|
---|
3764 | if( !GetDXUTState().GetRenderingPaused() )
|
---|
3765 | {
|
---|
3766 | // Render the scene by calling the app's render callback
|
---|
3767 | LPDXUTCALLBACKFRAMERENDER pCallbackFrameRender = GetDXUTState().GetFrameRenderFunc();
|
---|
3768 | if( pCallbackFrameRender != NULL )
|
---|
3769 | {
|
---|
3770 | pCallbackFrameRender( pd3dDevice, fTime, fElapsedTime, GetDXUTState().GetFrameRenderFuncUserContext() );
|
---|
3771 | pd3dDevice = DXUTGetD3DDevice();
|
---|
3772 | if( NULL == pd3dDevice ) // Handle DXUTShutdown from inside callback
|
---|
3773 | return;
|
---|
3774 | }
|
---|
3775 |
|
---|
3776 | #if defined(DEBUG) || defined(_DEBUG)
|
---|
3777 | // The back buffer should always match the client rect
|
---|
3778 | // if the Direct3D backbuffer covers the entire window
|
---|
3779 | RECT rcClient;
|
---|
3780 | GetClientRect( DXUTGetHWND(), &rcClient );
|
---|
3781 | if( !IsIconic( DXUTGetHWND() ) )
|
---|
3782 | {
|
---|
3783 | GetClientRect( DXUTGetHWND(), &rcClient );
|
---|
3784 | assert( DXUTGetBackBufferSurfaceDesc()->Width == (UINT)rcClient.right );
|
---|
3785 | assert( DXUTGetBackBufferSurfaceDesc()->Height == (UINT)rcClient.bottom );
|
---|
3786 | }
|
---|
3787 | #endif
|
---|
3788 |
|
---|
3789 | // Show the frame on the primary surface.
|
---|
3790 | hr = pd3dDevice->Present( NULL, NULL, NULL, NULL );
|
---|
3791 | if( FAILED(hr) )
|
---|
3792 | {
|
---|
3793 | if( D3DERR_DEVICELOST == hr )
|
---|
3794 | {
|
---|
3795 | GetDXUTState().SetDeviceLost( true );
|
---|
3796 | }
|
---|
3797 | else if( D3DERR_DRIVERINTERNALERROR == hr )
|
---|
3798 | {
|
---|
3799 | // When D3DERR_DRIVERINTERNALERROR is returned from Present(),
|
---|
3800 | // the application can do one of the following:
|
---|
3801 | //
|
---|
3802 | // - End, with the pop-up window saying that the application cannot continue
|
---|
3803 | // because of problems in the display adapter and that the user should
|
---|
3804 | // contact the adapter manufacturer.
|
---|
3805 | //
|
---|
3806 | // - Attempt to restart by calling IDirect3DDevice9::Reset, which is essentially the same
|
---|
3807 | // path as recovering from a lost device. If IDirect3DDevice9::Reset fails with
|
---|
3808 | // D3DERR_DRIVERINTERNALERROR, the application should end immediately with the message
|
---|
3809 | // that the user should contact the adapter manufacturer.
|
---|
3810 | //
|
---|
3811 | // The framework attempts the path of resetting the device
|
---|
3812 | //
|
---|
3813 | GetDXUTState().SetDeviceLost( true );
|
---|
3814 | }
|
---|
3815 | }
|
---|
3816 | }
|
---|
3817 |
|
---|
3818 | // Update current frame #
|
---|
3819 | int nFrame = GetDXUTState().GetCurrentFrameNumber();
|
---|
3820 | nFrame++;
|
---|
3821 | GetDXUTState().SetCurrentFrameNumber( nFrame );
|
---|
3822 |
|
---|
3823 | // Check to see if the app should shutdown due to cmdline
|
---|
3824 | if( GetDXUTState().GetOverrideQuitAfterFrame() != 0 )
|
---|
3825 | {
|
---|
3826 | if( nFrame > GetDXUTState().GetOverrideQuitAfterFrame() )
|
---|
3827 | DXUTShutdown();
|
---|
3828 | }
|
---|
3829 |
|
---|
3830 | return;
|
---|
3831 | }
|
---|
3832 |
|
---|
3833 |
|
---|
3834 | //--------------------------------------------------------------------------------------
|
---|
3835 | // Updates the string which describes the device
|
---|
3836 | //--------------------------------------------------------------------------------------
|
---|
3837 | void DXUTUpdateDeviceStats( D3DDEVTYPE DeviceType, DWORD BehaviorFlags, D3DADAPTER_IDENTIFIER9* pAdapterIdentifier )
|
---|
3838 | {
|
---|
3839 | if( GetDXUTState().GetNoStats() )
|
---|
3840 | return;
|
---|
3841 |
|
---|
3842 | // Store device description
|
---|
3843 | WCHAR* pstrDeviceStats = GetDXUTState().GetDeviceStats();
|
---|
3844 | if( DeviceType == D3DDEVTYPE_REF )
|
---|
3845 | StringCchCopy( pstrDeviceStats, 256, L"REF" );
|
---|
3846 | else if( DeviceType == D3DDEVTYPE_HAL )
|
---|
3847 | StringCchCopy( pstrDeviceStats, 256, L"HAL" );
|
---|
3848 | else if( DeviceType == D3DDEVTYPE_SW )
|
---|
3849 | StringCchCopy( pstrDeviceStats, 256, L"SW" );
|
---|
3850 |
|
---|
3851 | if( BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING &&
|
---|
3852 | BehaviorFlags & D3DCREATE_PUREDEVICE )
|
---|
3853 | {
|
---|
3854 | if( DeviceType == D3DDEVTYPE_HAL )
|
---|
3855 | StringCchCat( pstrDeviceStats, 256, L" (pure hw vp)" );
|
---|
3856 | else
|
---|
3857 | StringCchCat( pstrDeviceStats, 256, L" (simulated pure hw vp)" );
|
---|
3858 | }
|
---|
3859 | else if( BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING )
|
---|
3860 | {
|
---|
3861 | if( DeviceType == D3DDEVTYPE_HAL )
|
---|
3862 | StringCchCat( pstrDeviceStats, 256, L" (hw vp)" );
|
---|
3863 | else
|
---|
3864 | StringCchCat( pstrDeviceStats, 256, L" (simulated hw vp)" );
|
---|
3865 | }
|
---|
3866 | else if( BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING )
|
---|
3867 | {
|
---|
3868 | if( DeviceType == D3DDEVTYPE_HAL )
|
---|
3869 | StringCchCat( pstrDeviceStats, 256, L" (mixed vp)" );
|
---|
3870 | else
|
---|
3871 | StringCchCat( pstrDeviceStats, 256, L" (simulated mixed vp)" );
|
---|
3872 | }
|
---|
3873 | else if( BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING )
|
---|
3874 | {
|
---|
3875 | StringCchCat( pstrDeviceStats, 256, L" (sw vp)" );
|
---|
3876 | }
|
---|
3877 |
|
---|
3878 | if( DeviceType == D3DDEVTYPE_HAL )
|
---|
3879 | {
|
---|
3880 | // Be sure not to overflow m_strDeviceStats when appending the adapter
|
---|
3881 | // description, since it can be long.
|
---|
3882 | StringCchCat( pstrDeviceStats, 256, L": " );
|
---|
3883 |
|
---|
3884 | // Try to get a unique description from the CD3DEnumDeviceSettingsCombo
|
---|
3885 | DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
3886 | CD3DEnumeration* pd3dEnum = DXUTPrepareEnumerationObject();
|
---|
3887 | CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pd3dEnum->GetDeviceSettingsCombo( pDeviceSettings->AdapterOrdinal, pDeviceSettings->DeviceType, pDeviceSettings->AdapterFormat, pDeviceSettings->pp.BackBufferFormat, pDeviceSettings->pp.Windowed );
|
---|
3888 | if( pDeviceSettingsCombo )
|
---|
3889 | {
|
---|
3890 | StringCchCat( pstrDeviceStats, 256, pDeviceSettingsCombo->pAdapterInfo->szUniqueDescription );
|
---|
3891 | }
|
---|
3892 | else
|
---|
3893 | {
|
---|
3894 | const int cchDesc = sizeof(pAdapterIdentifier->Description);
|
---|
3895 | WCHAR szDescription[cchDesc];
|
---|
3896 | MultiByteToWideChar( CP_ACP, 0, pAdapterIdentifier->Description, -1, szDescription, cchDesc );
|
---|
3897 | szDescription[cchDesc-1] = 0;
|
---|
3898 | StringCchCat( pstrDeviceStats, 256, szDescription );
|
---|
3899 | }
|
---|
3900 | }
|
---|
3901 | }
|
---|
3902 |
|
---|
3903 |
|
---|
3904 | //--------------------------------------------------------------------------------------
|
---|
3905 | // Updates the frames/sec stat once per second
|
---|
3906 | //--------------------------------------------------------------------------------------
|
---|
3907 | void DXUTUpdateFrameStats()
|
---|
3908 | {
|
---|
3909 | if( GetDXUTState().GetNoStats() )
|
---|
3910 | return;
|
---|
3911 |
|
---|
3912 | // Keep track of the frame count
|
---|
3913 | double fLastTime = GetDXUTState().GetLastStatsUpdateTime();
|
---|
3914 | DWORD dwFrames = GetDXUTState().GetLastStatsUpdateFrames();
|
---|
3915 | double fAbsTime = GetDXUTState().GetAbsoluteTime();
|
---|
3916 | dwFrames++;
|
---|
3917 | GetDXUTState().SetLastStatsUpdateFrames( dwFrames );
|
---|
3918 |
|
---|
3919 | // Update the scene stats once per second
|
---|
3920 | if( fAbsTime - fLastTime > 1.0f )
|
---|
3921 | {
|
---|
3922 | float fFPS = (float) (dwFrames / (fAbsTime - fLastTime));
|
---|
3923 | GetDXUTState().SetFPS( fFPS );
|
---|
3924 | GetDXUTState().SetLastStatsUpdateTime( fAbsTime );
|
---|
3925 | GetDXUTState().SetLastStatsUpdateFrames( 0 );
|
---|
3926 |
|
---|
3927 | WCHAR* pstrFPS = GetDXUTState().GetFPSStats();
|
---|
3928 | StringCchPrintf( pstrFPS, 64, L"%0.2f fps ", fFPS );
|
---|
3929 | }
|
---|
3930 | }
|
---|
3931 |
|
---|
3932 |
|
---|
3933 | //--------------------------------------------------------------------------------------
|
---|
3934 | // Updates the static part of the frame stats so it doesn't have be generated every frame
|
---|
3935 | //--------------------------------------------------------------------------------------
|
---|
3936 | void DXUTUpdateStaticFrameStats()
|
---|
3937 | {
|
---|
3938 | if( GetDXUTState().GetNoStats() )
|
---|
3939 | return;
|
---|
3940 |
|
---|
3941 | DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
3942 | if( NULL == pDeviceSettings )
|
---|
3943 | return;
|
---|
3944 | CD3DEnumeration* pd3dEnum = DXUTPrepareEnumerationObject();
|
---|
3945 | if( NULL == pd3dEnum )
|
---|
3946 | return;
|
---|
3947 |
|
---|
3948 | CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pd3dEnum->GetDeviceSettingsCombo( pDeviceSettings->AdapterOrdinal, pDeviceSettings->DeviceType, pDeviceSettings->AdapterFormat, pDeviceSettings->pp.BackBufferFormat, pDeviceSettings->pp.Windowed );
|
---|
3949 | if( NULL == pDeviceSettingsCombo )
|
---|
3950 | return;
|
---|
3951 |
|
---|
3952 | WCHAR strFmt[100];
|
---|
3953 | D3DPRESENT_PARAMETERS* pPP = &pDeviceSettings->pp;
|
---|
3954 |
|
---|
3955 | if( pDeviceSettingsCombo->AdapterFormat == pDeviceSettingsCombo->BackBufferFormat )
|
---|
3956 | {
|
---|
3957 | StringCchCopy( strFmt, 100, DXUTD3DFormatToString( pDeviceSettingsCombo->AdapterFormat, false ) );
|
---|
3958 | }
|
---|
3959 | else
|
---|
3960 | {
|
---|
3961 | StringCchPrintf( strFmt, 100, L"backbuf %s, adapter %s",
|
---|
3962 | DXUTD3DFormatToString( pDeviceSettingsCombo->BackBufferFormat, false ),
|
---|
3963 | DXUTD3DFormatToString( pDeviceSettingsCombo->AdapterFormat, false ) );
|
---|
3964 | }
|
---|
3965 |
|
---|
3966 | WCHAR strDepthFmt[100];
|
---|
3967 | if( pPP->EnableAutoDepthStencil )
|
---|
3968 | {
|
---|
3969 | StringCchPrintf( strDepthFmt, 100, L" (%s)", DXUTD3DFormatToString( pPP->AutoDepthStencilFormat, false ) );
|
---|
3970 | }
|
---|
3971 | else
|
---|
3972 | {
|
---|
3973 | // No depth buffer
|
---|
3974 | strDepthFmt[0] = 0;
|
---|
3975 | }
|
---|
3976 |
|
---|
3977 | WCHAR strMultiSample[100];
|
---|
3978 | switch( pPP->MultiSampleType )
|
---|
3979 | {
|
---|
3980 | case D3DMULTISAMPLE_NONMASKABLE: StringCchCopy( strMultiSample, 100, L" (Nonmaskable Multisample)" ); break;
|
---|
3981 | case D3DMULTISAMPLE_NONE: StringCchCopy( strMultiSample, 100, L"" ); break;
|
---|
3982 | default: StringCchPrintf( strMultiSample, 100, L" (%dx Multisample)", pPP->MultiSampleType ); break;
|
---|
3983 | }
|
---|
3984 |
|
---|
3985 | WCHAR* pstrStaticFrameStats = GetDXUTState().GetStaticFrameStats();
|
---|
3986 | StringCchPrintf( pstrStaticFrameStats, 256, L"%%sVsync %s (%dx%d), %s%s%s",
|
---|
3987 | ( pPP->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE ) ? L"off" : L"on",
|
---|
3988 | pPP->BackBufferWidth, pPP->BackBufferHeight,
|
---|
3989 | strFmt, strDepthFmt, strMultiSample );
|
---|
3990 | }
|
---|
3991 |
|
---|
3992 |
|
---|
3993 | //--------------------------------------------------------------------------------------
|
---|
3994 | LPCWSTR DXUTGetFrameStats( bool bShowFPS )
|
---|
3995 | {
|
---|
3996 | WCHAR* pstrFrameStats = GetDXUTState().GetFrameStats();
|
---|
3997 | WCHAR* pstrFPS = ( bShowFPS ) ? GetDXUTState().GetFPSStats() : L"";
|
---|
3998 | StringCchPrintf( pstrFrameStats, 256, GetDXUTState().GetStaticFrameStats(), pstrFPS );
|
---|
3999 | return pstrFrameStats;
|
---|
4000 | }
|
---|
4001 |
|
---|
4002 |
|
---|
4003 | //--------------------------------------------------------------------------------------
|
---|
4004 | // Handles window messages
|
---|
4005 | //--------------------------------------------------------------------------------------
|
---|
4006 | LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
---|
4007 | {
|
---|
4008 | // Consolidate the keyboard messages and pass them to the app's keyboard callback
|
---|
4009 | if( uMsg == WM_KEYDOWN ||
|
---|
4010 | uMsg == WM_SYSKEYDOWN ||
|
---|
4011 | uMsg == WM_KEYUP ||
|
---|
4012 | uMsg == WM_SYSKEYUP )
|
---|
4013 | {
|
---|
4014 | bool bKeyDown = (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN);
|
---|
4015 | DWORD dwMask = (1 << 29);
|
---|
4016 | bool bAltDown = ( (lParam & dwMask) != 0 );
|
---|
4017 |
|
---|
4018 | bool* bKeys = GetDXUTState().GetKeys();
|
---|
4019 | bKeys[ (BYTE) (wParam & 0xFF) ] = bKeyDown;
|
---|
4020 |
|
---|
4021 | LPDXUTCALLBACKKEYBOARD pCallbackKeyboard = GetDXUTState().GetKeyboardFunc();
|
---|
4022 | if( pCallbackKeyboard )
|
---|
4023 | pCallbackKeyboard( (UINT)wParam, bKeyDown, bAltDown, GetDXUTState().GetKeyboardFuncUserContext() );
|
---|
4024 | }
|
---|
4025 |
|
---|
4026 | // Consolidate the mouse button messages and pass them to the app's mouse callback
|
---|
4027 | if( uMsg == WM_LBUTTONDOWN ||
|
---|
4028 | uMsg == WM_LBUTTONUP ||
|
---|
4029 | uMsg == WM_LBUTTONDBLCLK ||
|
---|
4030 | uMsg == WM_MBUTTONDOWN ||
|
---|
4031 | uMsg == WM_MBUTTONUP ||
|
---|
4032 | uMsg == WM_MBUTTONDBLCLK ||
|
---|
4033 | uMsg == WM_RBUTTONDOWN ||
|
---|
4034 | uMsg == WM_RBUTTONUP ||
|
---|
4035 | uMsg == WM_RBUTTONDBLCLK ||
|
---|
4036 | uMsg == WM_XBUTTONDOWN ||
|
---|
4037 | uMsg == WM_XBUTTONUP ||
|
---|
4038 | uMsg == WM_XBUTTONDBLCLK ||
|
---|
4039 | uMsg == WM_MOUSEWHEEL ||
|
---|
4040 | (GetDXUTState().GetNotifyOnMouseMove() && uMsg == WM_MOUSEMOVE) )
|
---|
4041 | {
|
---|
4042 | int xPos = (short)LOWORD(lParam);
|
---|
4043 | int yPos = (short)HIWORD(lParam);
|
---|
4044 |
|
---|
4045 | if( uMsg == WM_MOUSEWHEEL )
|
---|
4046 | {
|
---|
4047 | // WM_MOUSEWHEEL passes screen mouse coords
|
---|
4048 | // so convert them to client coords
|
---|
4049 | POINT pt;
|
---|
4050 | pt.x = xPos; pt.y = yPos;
|
---|
4051 | ScreenToClient( hWnd, &pt );
|
---|
4052 | xPos = pt.x; yPos = pt.y;
|
---|
4053 | }
|
---|
4054 |
|
---|
4055 | int nMouseWheelDelta = 0;
|
---|
4056 | if( uMsg == WM_MOUSEWHEEL )
|
---|
4057 | nMouseWheelDelta = (short) HIWORD(wParam);
|
---|
4058 |
|
---|
4059 | int nMouseButtonState = LOWORD(wParam);
|
---|
4060 | bool bLeftButton = ((nMouseButtonState & MK_LBUTTON) != 0);
|
---|
4061 | bool bRightButton = ((nMouseButtonState & MK_RBUTTON) != 0);
|
---|
4062 | bool bMiddleButton = ((nMouseButtonState & MK_MBUTTON) != 0);
|
---|
4063 | bool bSideButton1 = ((nMouseButtonState & MK_XBUTTON1) != 0);
|
---|
4064 | bool bSideButton2 = ((nMouseButtonState & MK_XBUTTON2) != 0);
|
---|
4065 |
|
---|
4066 | bool* bMouseButtons = GetDXUTState().GetMouseButtons();
|
---|
4067 | bMouseButtons[0] = bLeftButton;
|
---|
4068 | bMouseButtons[1] = bMiddleButton;
|
---|
4069 | bMouseButtons[2] = bRightButton;
|
---|
4070 | bMouseButtons[3] = bSideButton1;
|
---|
4071 | bMouseButtons[4] = bSideButton2;
|
---|
4072 |
|
---|
4073 | LPDXUTCALLBACKMOUSE pCallbackMouse = GetDXUTState().GetMouseFunc();
|
---|
4074 | if( pCallbackMouse )
|
---|
4075 | pCallbackMouse( bLeftButton, bRightButton, bMiddleButton, bSideButton1, bSideButton2, nMouseWheelDelta, xPos, yPos, GetDXUTState().GetMouseFuncUserContext() );
|
---|
4076 | }
|
---|
4077 |
|
---|
4078 | // Pass all messages to the app's MsgProc callback, and don't
|
---|
4079 | // process further messages if the apps says not to.
|
---|
4080 | LPDXUTCALLBACKMSGPROC pCallbackMsgProc = GetDXUTState().GetWindowMsgFunc();
|
---|
4081 | if( pCallbackMsgProc )
|
---|
4082 | {
|
---|
4083 | bool bNoFurtherProcessing = false;
|
---|
4084 | LRESULT nResult = pCallbackMsgProc( hWnd, uMsg, wParam, lParam, &bNoFurtherProcessing, GetDXUTState().GetWindowMsgFuncUserContext() );
|
---|
4085 | if( bNoFurtherProcessing )
|
---|
4086 | return nResult;
|
---|
4087 | }
|
---|
4088 |
|
---|
4089 | switch( uMsg )
|
---|
4090 | {
|
---|
4091 | case WM_PAINT:
|
---|
4092 | {
|
---|
4093 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
4094 |
|
---|
4095 | // Handle paint messages when the app is paused
|
---|
4096 | if( pd3dDevice && DXUTIsRenderingPaused() &&
|
---|
4097 | GetDXUTState().GetDeviceObjectsCreated() && GetDXUTState().GetDeviceObjectsReset() )
|
---|
4098 | {
|
---|
4099 | HRESULT hr;
|
---|
4100 | double fTime = DXUTGetTime();
|
---|
4101 | float fElapsedTime = DXUTGetElapsedTime();
|
---|
4102 |
|
---|
4103 | LPDXUTCALLBACKFRAMERENDER pCallbackFrameRender = GetDXUTState().GetFrameRenderFunc();
|
---|
4104 | if( pCallbackFrameRender != NULL )
|
---|
4105 | pCallbackFrameRender( pd3dDevice, fTime, fElapsedTime, GetDXUTState().GetFrameRenderFuncUserContext() );
|
---|
4106 |
|
---|
4107 | hr = pd3dDevice->Present( NULL, NULL, NULL, NULL );
|
---|
4108 | if( D3DERR_DEVICELOST == hr )
|
---|
4109 | {
|
---|
4110 | GetDXUTState().SetDeviceLost( true );
|
---|
4111 | }
|
---|
4112 | else if( D3DERR_DRIVERINTERNALERROR == hr )
|
---|
4113 | {
|
---|
4114 | // When D3DERR_DRIVERINTERNALERROR is returned from Present(),
|
---|
4115 | // the application can do one of the following:
|
---|
4116 | //
|
---|
4117 | // - End, with the pop-up window saying that the application cannot continue
|
---|
4118 | // because of problems in the display adapter and that the user should
|
---|
4119 | // contact the adapter manufacturer.
|
---|
4120 | //
|
---|
4121 | // - Attempt to restart by calling IDirect3DDevice9::Reset, which is essentially the same
|
---|
4122 | // path as recovering from a lost device. If IDirect3DDevice9::Reset fails with
|
---|
4123 | // D3DERR_DRIVERINTERNALERROR, the application should end immediately with the message
|
---|
4124 | // that the user should contact the adapter manufacturer.
|
---|
4125 | //
|
---|
4126 | // The framework attempts the path of resetting the device
|
---|
4127 | //
|
---|
4128 | GetDXUTState().SetDeviceLost( true );
|
---|
4129 | }
|
---|
4130 | }
|
---|
4131 | break;
|
---|
4132 | }
|
---|
4133 |
|
---|
4134 | case WM_SIZE:
|
---|
4135 | if( SIZE_MINIMIZED == wParam )
|
---|
4136 | {
|
---|
4137 | DXUTPause( true, true ); // Pause while we're minimized
|
---|
4138 |
|
---|
4139 | GetDXUTState().SetMinimized( true );
|
---|
4140 | GetDXUTState().SetMaximized( false );
|
---|
4141 | }
|
---|
4142 | else
|
---|
4143 | {
|
---|
4144 | RECT rcCurrentClient;
|
---|
4145 | GetClientRect( DXUTGetHWND(), &rcCurrentClient );
|
---|
4146 | if( rcCurrentClient.top == 0 && rcCurrentClient.bottom == 0 )
|
---|
4147 | {
|
---|
4148 | // Rapidly clicking the task bar to minimize and restore a window
|
---|
4149 | // can cause a WM_SIZE message with SIZE_RESTORED when
|
---|
4150 | // the window has actually become minimized due to rapid change
|
---|
4151 | // so just ignore this message
|
---|
4152 | }
|
---|
4153 | else if( SIZE_MAXIMIZED == wParam )
|
---|
4154 | {
|
---|
4155 | if( GetDXUTState().GetMinimized() )
|
---|
4156 | DXUTPause( false, false ); // Unpause since we're no longer minimized
|
---|
4157 | GetDXUTState().SetMinimized( false );
|
---|
4158 | GetDXUTState().SetMaximized( true );
|
---|
4159 | DXUTCheckForWindowSizeChange();
|
---|
4160 | DXUTCheckForWindowChangingMonitors();
|
---|
4161 | }
|
---|
4162 | else if( SIZE_RESTORED == wParam )
|
---|
4163 | {
|
---|
4164 | if( GetDXUTState().GetMaximized() )
|
---|
4165 | {
|
---|
4166 | GetDXUTState().SetMaximized( false );
|
---|
4167 | DXUTCheckForWindowSizeChange();
|
---|
4168 | DXUTCheckForWindowChangingMonitors();
|
---|
4169 | }
|
---|
4170 | else if( GetDXUTState().GetMinimized() )
|
---|
4171 | {
|
---|
4172 | DXUTPause( false, false ); // Unpause since we're no longer minimized
|
---|
4173 | GetDXUTState().SetMinimized( false );
|
---|
4174 | DXUTCheckForWindowSizeChange();
|
---|
4175 | DXUTCheckForWindowChangingMonitors();
|
---|
4176 | }
|
---|
4177 | else if( GetDXUTState().GetInSizeMove() )
|
---|
4178 | {
|
---|
4179 | // If we're neither maximized nor minimized, the window size
|
---|
4180 | // is changing by the user dragging the window edges. In this
|
---|
4181 | // case, we don't reset the device yet -- we wait until the
|
---|
4182 | // user stops dragging, and a WM_EXITSIZEMOVE message comes.
|
---|
4183 | }
|
---|
4184 | else
|
---|
4185 | {
|
---|
4186 | // This WM_SIZE come from resizing the window via an API like SetWindowPos() so
|
---|
4187 | // resize and reset the device now.
|
---|
4188 | DXUTCheckForWindowSizeChange();
|
---|
4189 | DXUTCheckForWindowChangingMonitors();
|
---|
4190 | }
|
---|
4191 | }
|
---|
4192 | }
|
---|
4193 | break;
|
---|
4194 |
|
---|
4195 | case WM_GETMINMAXINFO:
|
---|
4196 | ((MINMAXINFO*)lParam)->ptMinTrackSize.x = DXUT_MIN_WINDOW_SIZE_X;
|
---|
4197 | ((MINMAXINFO*)lParam)->ptMinTrackSize.y = DXUT_MIN_WINDOW_SIZE_Y;
|
---|
4198 | break;
|
---|
4199 |
|
---|
4200 | case WM_ENTERSIZEMOVE:
|
---|
4201 | // Halt frame movement while the app is sizing or moving
|
---|
4202 | DXUTPause( true, true );
|
---|
4203 | GetDXUTState().SetInSizeMove( true );
|
---|
4204 | break;
|
---|
4205 |
|
---|
4206 | case WM_EXITSIZEMOVE:
|
---|
4207 | DXUTPause( false, false );
|
---|
4208 | DXUTCheckForWindowSizeChange();
|
---|
4209 | DXUTCheckForWindowChangingMonitors();
|
---|
4210 | GetDXUTState().SetInSizeMove( false );
|
---|
4211 | break;
|
---|
4212 |
|
---|
4213 | case WM_MOUSEMOVE:
|
---|
4214 | if( DXUTIsActive() && !DXUTIsWindowed() )
|
---|
4215 | {
|
---|
4216 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
4217 | if( pd3dDevice )
|
---|
4218 | {
|
---|
4219 | POINT ptCursor;
|
---|
4220 | GetCursorPos( &ptCursor );
|
---|
4221 | pd3dDevice->SetCursorPosition( ptCursor.x, ptCursor.y, 0 );
|
---|
4222 | }
|
---|
4223 | }
|
---|
4224 | break;
|
---|
4225 |
|
---|
4226 | case WM_SETCURSOR:
|
---|
4227 | if( DXUTIsActive() && !DXUTIsWindowed() )
|
---|
4228 | {
|
---|
4229 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
4230 | if( pd3dDevice && GetDXUTState().GetShowCursorWhenFullScreen() )
|
---|
4231 | pd3dDevice->ShowCursor( true );
|
---|
4232 | return true; // prevent Windows from setting cursor to window class cursor
|
---|
4233 | }
|
---|
4234 | break;
|
---|
4235 |
|
---|
4236 | case WM_ACTIVATEAPP:
|
---|
4237 | if( wParam == TRUE && !DXUTIsActive() ) // Handle only if previously not active
|
---|
4238 | {
|
---|
4239 | GetDXUTState().SetActive( true );
|
---|
4240 |
|
---|
4241 | // The GetMinimizedWhileFullscreen() varible is used instead of !DXUTIsWindowed()
|
---|
4242 | // to handle the rare case toggling to windowed mode while the fullscreen application
|
---|
4243 | // is minimized and thus making the pause count wrong
|
---|
4244 | if( GetDXUTState().GetMinimizedWhileFullscreen() )
|
---|
4245 | {
|
---|
4246 | DXUTPause( false, false ); // Unpause since we're no longer minimized
|
---|
4247 | GetDXUTState().SetMinimizedWhileFullscreen( false );
|
---|
4248 | }
|
---|
4249 |
|
---|
4250 | // Upon returning to this app, potentially disable shortcut keys
|
---|
4251 | // (Windows key, accessibility shortcuts)
|
---|
4252 | DXUTAllowShortcutKeys( ( DXUTIsWindowed() ) ? GetDXUTState().GetAllowShortcutKeysWhenWindowed() :
|
---|
4253 | GetDXUTState().GetAllowShortcutKeysWhenFullscreen() );
|
---|
4254 |
|
---|
4255 | }
|
---|
4256 | else if( wParam == FALSE && DXUTIsActive() ) // Handle only if previously active
|
---|
4257 | {
|
---|
4258 | GetDXUTState().SetActive( false );
|
---|
4259 |
|
---|
4260 | // Disable any controller rumble when de-activating app
|
---|
4261 | DXUTStopRumbleOnAllControllers();
|
---|
4262 |
|
---|
4263 | if( !DXUTIsWindowed() )
|
---|
4264 | {
|
---|
4265 | // Going from full screen to a minimized state
|
---|
4266 | ClipCursor( NULL ); // don't limit the cursor anymore
|
---|
4267 | DXUTPause( true, true ); // Pause while we're minimized (take care not to pause twice by handling this message twice)
|
---|
4268 | GetDXUTState().SetMinimizedWhileFullscreen( true );
|
---|
4269 | }
|
---|
4270 |
|
---|
4271 | // Restore shortcut keys (Windows key, accessibility shortcuts) to original state
|
---|
4272 | //
|
---|
4273 | // This is important to call here if the shortcuts are disabled,
|
---|
4274 | // because if this is not done then the Windows key will continue to
|
---|
4275 | // be disabled while this app is running which is very bad.
|
---|
4276 | // If the app crashes, the Windows key will return to normal.
|
---|
4277 | DXUTAllowShortcutKeys( true );
|
---|
4278 | }
|
---|
4279 | break;
|
---|
4280 |
|
---|
4281 | case WM_ENTERMENULOOP:
|
---|
4282 | // Pause the app when menus are displayed
|
---|
4283 | DXUTPause( true, true );
|
---|
4284 | break;
|
---|
4285 |
|
---|
4286 | case WM_EXITMENULOOP:
|
---|
4287 | DXUTPause( false, false );
|
---|
4288 | break;
|
---|
4289 |
|
---|
4290 | case WM_MENUCHAR:
|
---|
4291 | // A menu is active and the user presses a key that does not correspond to any mnemonic or accelerator key
|
---|
4292 | // So just ignore and don't beep
|
---|
4293 | return MAKELRESULT(0,MNC_CLOSE);
|
---|
4294 | break;
|
---|
4295 |
|
---|
4296 | case WM_NCHITTEST:
|
---|
4297 | // Prevent the user from selecting the menu in full screen mode
|
---|
4298 | if( !DXUTIsWindowed() )
|
---|
4299 | return HTCLIENT;
|
---|
4300 | break;
|
---|
4301 |
|
---|
4302 | case WM_POWERBROADCAST:
|
---|
4303 | switch( wParam )
|
---|
4304 | {
|
---|
4305 | #ifndef PBT_APMQUERYSUSPEND
|
---|
4306 | #define PBT_APMQUERYSUSPEND 0x0000
|
---|
4307 | #endif
|
---|
4308 | case PBT_APMQUERYSUSPEND:
|
---|
4309 | // At this point, the app should save any data for open
|
---|
4310 | // network connections, files, etc., and prepare to go into
|
---|
4311 | // a suspended mode. The app can use the MsgProc callback
|
---|
4312 | // to handle this if desired.
|
---|
4313 | return true;
|
---|
4314 |
|
---|
4315 | #ifndef PBT_APMRESUMESUSPEND
|
---|
4316 | #define PBT_APMRESUMESUSPEND 0x0007
|
---|
4317 | #endif
|
---|
4318 | case PBT_APMRESUMESUSPEND:
|
---|
4319 | // At this point, the app should recover any data, network
|
---|
4320 | // connections, files, etc., and resume running from when
|
---|
4321 | // the app was suspended. The app can use the MsgProc callback
|
---|
4322 | // to handle this if desired.
|
---|
4323 |
|
---|
4324 | // QPC may lose consistency when suspending, so reset the timer
|
---|
4325 | // upon resume.
|
---|
4326 | DXUTGetGlobalTimer()->Reset();
|
---|
4327 | GetDXUTState().SetLastStatsUpdateTime( 0 );
|
---|
4328 | return true;
|
---|
4329 | }
|
---|
4330 | break;
|
---|
4331 |
|
---|
4332 | case WM_SYSCOMMAND:
|
---|
4333 | // Prevent moving/sizing in full screen mode
|
---|
4334 | switch( wParam )
|
---|
4335 | {
|
---|
4336 | case SC_MOVE:
|
---|
4337 | case SC_SIZE:
|
---|
4338 | case SC_MAXIMIZE:
|
---|
4339 | case SC_KEYMENU:
|
---|
4340 | if( !DXUTIsWindowed() )
|
---|
4341 | return 0;
|
---|
4342 | break;
|
---|
4343 | }
|
---|
4344 | break;
|
---|
4345 |
|
---|
4346 | case WM_SYSKEYDOWN:
|
---|
4347 | {
|
---|
4348 | switch( wParam )
|
---|
4349 | {
|
---|
4350 | case VK_RETURN:
|
---|
4351 | {
|
---|
4352 | if( GetDXUTState().GetHandleAltEnter() )
|
---|
4353 | {
|
---|
4354 | // Toggle full screen upon alt-enter
|
---|
4355 | DWORD dwMask = (1 << 29);
|
---|
4356 | if( (lParam & dwMask) != 0 ) // Alt is down also
|
---|
4357 | {
|
---|
4358 | // Toggle the full screen/window mode
|
---|
4359 | DXUTPause( true, true );
|
---|
4360 | DXUTToggleFullScreen();
|
---|
4361 | DXUTPause( false, false );
|
---|
4362 | return 0;
|
---|
4363 | }
|
---|
4364 | }
|
---|
4365 | }
|
---|
4366 | }
|
---|
4367 | break;
|
---|
4368 | }
|
---|
4369 |
|
---|
4370 | case WM_KEYDOWN:
|
---|
4371 | {
|
---|
4372 | if( GetDXUTState().GetHandleDefaultHotkeys() )
|
---|
4373 | {
|
---|
4374 | switch( wParam )
|
---|
4375 | {
|
---|
4376 | case VK_F3:
|
---|
4377 | {
|
---|
4378 | DXUTPause( true, true );
|
---|
4379 | DXUTToggleREF();
|
---|
4380 | DXUTPause( false, false );
|
---|
4381 | break;
|
---|
4382 | }
|
---|
4383 |
|
---|
4384 | case VK_F8:
|
---|
4385 | {
|
---|
4386 | bool bWireFrame = GetDXUTState().GetWireframeMode();
|
---|
4387 | bWireFrame = !bWireFrame;
|
---|
4388 | GetDXUTState().SetWireframeMode( bWireFrame );
|
---|
4389 |
|
---|
4390 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
4391 | if( pd3dDevice )
|
---|
4392 | pd3dDevice->SetRenderState( D3DRS_FILLMODE, (bWireFrame) ? D3DFILL_WIREFRAME : D3DFILL_SOLID );
|
---|
4393 | break;
|
---|
4394 | }
|
---|
4395 |
|
---|
4396 | case VK_ESCAPE:
|
---|
4397 | {
|
---|
4398 | // Received key to exit app
|
---|
4399 | SendMessage( hWnd, WM_CLOSE, 0, 0 );
|
---|
4400 | }
|
---|
4401 |
|
---|
4402 | case VK_PAUSE:
|
---|
4403 | {
|
---|
4404 | bool bTimePaused = DXUTIsTimePaused();
|
---|
4405 | bTimePaused = !bTimePaused;
|
---|
4406 | if( bTimePaused )
|
---|
4407 | DXUTPause( true, false );
|
---|
4408 | else
|
---|
4409 | DXUTPause( false, false );
|
---|
4410 | break;
|
---|
4411 | }
|
---|
4412 | }
|
---|
4413 | }
|
---|
4414 | break;
|
---|
4415 | }
|
---|
4416 |
|
---|
4417 | case WM_CLOSE:
|
---|
4418 | {
|
---|
4419 | HMENU hMenu;
|
---|
4420 | hMenu = GetMenu(hWnd);
|
---|
4421 | if( hMenu != NULL )
|
---|
4422 | DestroyMenu( hMenu );
|
---|
4423 | DestroyWindow( hWnd );
|
---|
4424 | UnregisterClass( L"Direct3DWindowClass", NULL );
|
---|
4425 | GetDXUTState().SetHWNDFocus( NULL );
|
---|
4426 | GetDXUTState().SetHWNDDeviceFullScreen( NULL );
|
---|
4427 | GetDXUTState().SetHWNDDeviceWindowed( NULL );
|
---|
4428 | return 0;
|
---|
4429 | }
|
---|
4430 |
|
---|
4431 | case WM_DESTROY:
|
---|
4432 | PostQuitMessage(0);
|
---|
4433 | break;
|
---|
4434 | }
|
---|
4435 |
|
---|
4436 | // Don't allow the F10 key to act as a shortcut to the menu bar
|
---|
4437 | // by not passing these messages to the DefWindowProc only when
|
---|
4438 | // there's no menu present
|
---|
4439 | if( !GetDXUTState().GetCallDefWindowProc() || GetDXUTState().GetMenu() == NULL && (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP) && wParam == VK_F10 )
|
---|
4440 | return 0;
|
---|
4441 | else
|
---|
4442 | return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
---|
4443 | }
|
---|
4444 |
|
---|
4445 |
|
---|
4446 | //--------------------------------------------------------------------------------------
|
---|
4447 | // Resets the state associated with DXUT
|
---|
4448 | //--------------------------------------------------------------------------------------
|
---|
4449 | void DXUTResetFrameworkState()
|
---|
4450 | {
|
---|
4451 | GetDXUTState().Destroy();
|
---|
4452 | GetDXUTState().Create();
|
---|
4453 | }
|
---|
4454 |
|
---|
4455 |
|
---|
4456 | //--------------------------------------------------------------------------------------
|
---|
4457 | // Closes down the window. When the window closes, it will cleanup everything
|
---|
4458 | //--------------------------------------------------------------------------------------
|
---|
4459 | void DXUTShutdown( int nExitCode )
|
---|
4460 | {
|
---|
4461 | HWND hWnd = DXUTGetHWND();
|
---|
4462 | if( hWnd != NULL )
|
---|
4463 | SendMessage( hWnd, WM_CLOSE, 0, 0 );
|
---|
4464 |
|
---|
4465 | GetDXUTState().SetExitCode(nExitCode);
|
---|
4466 |
|
---|
4467 | DXUTCleanup3DEnvironment( true );
|
---|
4468 |
|
---|
4469 | // Restore shortcut keys (Windows key, accessibility shortcuts) to original state
|
---|
4470 | // This is important to call here if the shortcuts are disabled,
|
---|
4471 | // because accessibility setting changes are permanent.
|
---|
4472 | // This means that if this is not done then the accessibility settings
|
---|
4473 | // might not be the same as when the app was started.
|
---|
4474 | // If the app crashes without restoring the settings, this is also true so it
|
---|
4475 | // would be wise to backup/restore the settings from a file so they can be
|
---|
4476 | // restored when the crashed app is run again.
|
---|
4477 | DXUTAllowShortcutKeys( true );
|
---|
4478 |
|
---|
4479 | GetDXUTState().SetD3DEnumeration( NULL );
|
---|
4480 |
|
---|
4481 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
4482 | SAFE_RELEASE( pD3D );
|
---|
4483 | GetDXUTState().SetD3D( NULL );
|
---|
4484 |
|
---|
4485 | if( GetDXUTState().GetOverrideRelaunchMCE() )
|
---|
4486 | DXUTReLaunchMediaCenter();
|
---|
4487 | }
|
---|
4488 |
|
---|
4489 |
|
---|
4490 | //--------------------------------------------------------------------------------------
|
---|
4491 | // Cleans up the 3D environment by:
|
---|
4492 | // - Calls the device lost callback
|
---|
4493 | // - Calls the device destroyed callback
|
---|
4494 | // - Releases the D3D device
|
---|
4495 | //--------------------------------------------------------------------------------------
|
---|
4496 | void DXUTCleanup3DEnvironment( bool bReleaseSettings )
|
---|
4497 | {
|
---|
4498 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
4499 | if( pd3dDevice != NULL )
|
---|
4500 | {
|
---|
4501 | GetDXUTState().SetInsideDeviceCallback( true );
|
---|
4502 |
|
---|
4503 | // Call the app's device lost callback
|
---|
4504 | if( GetDXUTState().GetDeviceObjectsReset() == true )
|
---|
4505 | {
|
---|
4506 | LPDXUTCALLBACKDEVICELOST pCallbackDeviceLost = GetDXUTState().GetDeviceLostFunc();
|
---|
4507 | if( pCallbackDeviceLost != NULL )
|
---|
4508 | pCallbackDeviceLost( GetDXUTState().GetDeviceLostFuncUserContext() );
|
---|
4509 | GetDXUTState().SetDeviceObjectsReset( false );
|
---|
4510 |
|
---|
4511 | // Call the resource cache device lost function
|
---|
4512 | DXUTGetGlobalResourceCache().OnLostDevice();
|
---|
4513 | }
|
---|
4514 |
|
---|
4515 | // Call the app's device destroyed callback
|
---|
4516 | if( GetDXUTState().GetDeviceObjectsCreated() == true )
|
---|
4517 | {
|
---|
4518 | LPDXUTCALLBACKDEVICEDESTROYED pCallbackDeviceDestroyed = GetDXUTState().GetDeviceDestroyedFunc();
|
---|
4519 | if( pCallbackDeviceDestroyed != NULL )
|
---|
4520 | pCallbackDeviceDestroyed( GetDXUTState().GetDeviceDestroyedFuncUserContext() );
|
---|
4521 | GetDXUTState().SetDeviceObjectsCreated( false );
|
---|
4522 |
|
---|
4523 | // Call the resource cache device destory function
|
---|
4524 | DXUTGetGlobalResourceCache().OnDestroyDevice();
|
---|
4525 | }
|
---|
4526 |
|
---|
4527 | GetDXUTState().SetInsideDeviceCallback( false );
|
---|
4528 |
|
---|
4529 | // Release the D3D device and in debug configs, displays a message box if there
|
---|
4530 | // are unrelease objects.
|
---|
4531 | if( pd3dDevice )
|
---|
4532 | {
|
---|
4533 | if( pd3dDevice->Release() > 0 )
|
---|
4534 | {
|
---|
4535 | DXUTDisplayErrorMessage( DXUTERR_NONZEROREFCOUNT );
|
---|
4536 | DXUT_ERR( L"DXUTCleanup3DEnvironment", DXUTERR_NONZEROREFCOUNT );
|
---|
4537 | }
|
---|
4538 | }
|
---|
4539 | GetDXUTState().SetD3DDevice( NULL );
|
---|
4540 |
|
---|
4541 | if( bReleaseSettings )
|
---|
4542 | {
|
---|
4543 | DXUTDeviceSettings* pOldDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
4544 | SAFE_DELETE(pOldDeviceSettings);
|
---|
4545 | GetDXUTState().SetCurrentDeviceSettings( NULL );
|
---|
4546 | }
|
---|
4547 |
|
---|
4548 | D3DSURFACE_DESC* pbackBufferSurfaceDesc = GetDXUTState().GetBackBufferSurfaceDesc();
|
---|
4549 | ZeroMemory( pbackBufferSurfaceDesc, sizeof(D3DSURFACE_DESC) );
|
---|
4550 |
|
---|
4551 | D3DCAPS9* pd3dCaps = GetDXUTState().GetCaps();
|
---|
4552 | ZeroMemory( pd3dCaps, sizeof(D3DCAPS9) );
|
---|
4553 |
|
---|
4554 | GetDXUTState().SetDeviceCreated( false );
|
---|
4555 | }
|
---|
4556 | }
|
---|
4557 |
|
---|
4558 |
|
---|
4559 | //--------------------------------------------------------------------------------------
|
---|
4560 | // Stores back buffer surface desc in GetDXUTState().GetBackBufferSurfaceDesc()
|
---|
4561 | //--------------------------------------------------------------------------------------
|
---|
4562 | void DXUTUpdateBackBufferDesc()
|
---|
4563 | {
|
---|
4564 | HRESULT hr;
|
---|
4565 | IDirect3DSurface9* pBackBuffer;
|
---|
4566 | hr = GetDXUTState().GetD3DDevice()->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
|
---|
4567 | D3DSURFACE_DESC* pBBufferSurfaceDesc = GetDXUTState().GetBackBufferSurfaceDesc();
|
---|
4568 | ZeroMemory( pBBufferSurfaceDesc, sizeof(D3DSURFACE_DESC) );
|
---|
4569 | if( SUCCEEDED(hr) )
|
---|
4570 | {
|
---|
4571 | pBackBuffer->GetDesc( pBBufferSurfaceDesc );
|
---|
4572 | SAFE_RELEASE( pBackBuffer );
|
---|
4573 | }
|
---|
4574 | }
|
---|
4575 |
|
---|
4576 |
|
---|
4577 | //--------------------------------------------------------------------------------------
|
---|
4578 | // Starts a user defined timer callback
|
---|
4579 | //--------------------------------------------------------------------------------------
|
---|
4580 | HRESULT DXUTSetTimer( LPDXUTCALLBACKTIMER pCallbackTimer, float fTimeoutInSecs, UINT* pnIDEvent, void* pCallbackUserContext )
|
---|
4581 | {
|
---|
4582 | if( pCallbackTimer == NULL )
|
---|
4583 | return DXUT_ERR_MSGBOX( L"DXUTSetTimer", E_INVALIDARG );
|
---|
4584 |
|
---|
4585 | HRESULT hr;
|
---|
4586 | DXUT_TIMER DXUTTimer;
|
---|
4587 | DXUTTimer.pCallbackTimer = pCallbackTimer;
|
---|
4588 | DXUTTimer.pCallbackUserContext = pCallbackUserContext;
|
---|
4589 | DXUTTimer.fTimeoutInSecs = fTimeoutInSecs;
|
---|
4590 | DXUTTimer.fCountdown = fTimeoutInSecs;
|
---|
4591 | DXUTTimer.bEnabled = true;
|
---|
4592 | DXUTTimer.nID = GetDXUTState().GetTimerLastID() + 1;
|
---|
4593 | GetDXUTState().SetTimerLastID( DXUTTimer.nID );
|
---|
4594 |
|
---|
4595 | CGrowableArray<DXUT_TIMER>* pTimerList = GetDXUTState().GetTimerList();
|
---|
4596 | if( pTimerList == NULL )
|
---|
4597 | {
|
---|
4598 | pTimerList = new CGrowableArray<DXUT_TIMER>;
|
---|
4599 | if( pTimerList == NULL )
|
---|
4600 | return E_OUTOFMEMORY;
|
---|
4601 | GetDXUTState().SetTimerList( pTimerList );
|
---|
4602 | }
|
---|
4603 |
|
---|
4604 | if( FAILED( hr = pTimerList->Add( DXUTTimer ) ) )
|
---|
4605 | return hr;
|
---|
4606 |
|
---|
4607 | if( pnIDEvent )
|
---|
4608 | *pnIDEvent = DXUTTimer.nID;
|
---|
4609 |
|
---|
4610 | return S_OK;
|
---|
4611 | }
|
---|
4612 |
|
---|
4613 |
|
---|
4614 | //--------------------------------------------------------------------------------------
|
---|
4615 | // Stops a user defined timer callback
|
---|
4616 | //--------------------------------------------------------------------------------------
|
---|
4617 | HRESULT DXUTKillTimer( UINT nIDEvent )
|
---|
4618 | {
|
---|
4619 | CGrowableArray<DXUT_TIMER>* pTimerList = GetDXUTState().GetTimerList();
|
---|
4620 | if( pTimerList == NULL )
|
---|
4621 | return S_FALSE;
|
---|
4622 |
|
---|
4623 | bool bFound = false;
|
---|
4624 |
|
---|
4625 | for( int i=0; i<pTimerList->GetSize(); i++ )
|
---|
4626 | {
|
---|
4627 | DXUT_TIMER DXUTTimer = pTimerList->GetAt(i);
|
---|
4628 | if( DXUTTimer.nID == nIDEvent )
|
---|
4629 | {
|
---|
4630 | DXUTTimer.bEnabled = false;
|
---|
4631 | pTimerList->SetAt(i, DXUTTimer);
|
---|
4632 | bFound = true;
|
---|
4633 | break;
|
---|
4634 | }
|
---|
4635 | }
|
---|
4636 |
|
---|
4637 | if( !bFound )
|
---|
4638 | return DXUT_ERR_MSGBOX( L"DXUTKillTimer", E_INVALIDARG );
|
---|
4639 |
|
---|
4640 | return S_OK;
|
---|
4641 | }
|
---|
4642 |
|
---|
4643 |
|
---|
4644 | //--------------------------------------------------------------------------------------
|
---|
4645 | // Internal helper function to handle calling the user defined timer callbacks
|
---|
4646 | //--------------------------------------------------------------------------------------
|
---|
4647 | void DXUTHandleTimers()
|
---|
4648 | {
|
---|
4649 | float fElapsedTime = DXUTGetElapsedTime();
|
---|
4650 |
|
---|
4651 | CGrowableArray<DXUT_TIMER>* pTimerList = GetDXUTState().GetTimerList();
|
---|
4652 | if( pTimerList == NULL )
|
---|
4653 | return;
|
---|
4654 |
|
---|
4655 | // Walk through the list of timer callbacks
|
---|
4656 | for( int i=0; i<pTimerList->GetSize(); i++ )
|
---|
4657 | {
|
---|
4658 | DXUT_TIMER DXUTTimer = pTimerList->GetAt(i);
|
---|
4659 | if( DXUTTimer.bEnabled )
|
---|
4660 | {
|
---|
4661 | DXUTTimer.fCountdown -= fElapsedTime;
|
---|
4662 |
|
---|
4663 | // Call the callback if count down expired
|
---|
4664 | if( DXUTTimer.fCountdown < 0 )
|
---|
4665 | {
|
---|
4666 | DXUTTimer.pCallbackTimer( i, DXUTTimer.pCallbackUserContext );
|
---|
4667 | DXUTTimer.fCountdown = DXUTTimer.fTimeoutInSecs;
|
---|
4668 | }
|
---|
4669 | pTimerList->SetAt(i, DXUTTimer);
|
---|
4670 | }
|
---|
4671 | }
|
---|
4672 | }
|
---|
4673 |
|
---|
4674 |
|
---|
4675 | //--------------------------------------------------------------------------------------
|
---|
4676 | // External state access functions
|
---|
4677 | //--------------------------------------------------------------------------------------
|
---|
4678 | IDirect3D9* DXUTGetD3DObject() { return GetDXUTState().GetD3D(); }
|
---|
4679 | IDirect3DDevice9* DXUTGetD3DDevice() { return GetDXUTState().GetD3DDevice(); }
|
---|
4680 | const D3DSURFACE_DESC* DXUTGetBackBufferSurfaceDesc() { return GetDXUTState().GetBackBufferSurfaceDesc(); }
|
---|
4681 | const D3DCAPS9* DXUTGetDeviceCaps() { return GetDXUTState().GetCaps(); }
|
---|
4682 | HINSTANCE DXUTGetHINSTANCE() { return GetDXUTState().GetHInstance(); }
|
---|
4683 | HWND DXUTGetHWND() { return DXUTIsWindowed() ? GetDXUTState().GetHWNDDeviceWindowed() : GetDXUTState().GetHWNDDeviceFullScreen(); }
|
---|
4684 | HWND DXUTGetHWNDFocus() { return GetDXUTState().GetHWNDFocus(); }
|
---|
4685 | HWND DXUTGetHWNDDeviceFullScreen() { return GetDXUTState().GetHWNDDeviceFullScreen(); }
|
---|
4686 | HWND DXUTGetHWNDDeviceWindowed() { return GetDXUTState().GetHWNDDeviceWindowed(); }
|
---|
4687 | RECT DXUTGetWindowClientRect() { RECT rc; GetClientRect( DXUTGetHWND(), &rc ); return rc; }
|
---|
4688 | RECT DXUTGetWindowClientRectAtModeChange() { RECT rc = { 0, 0, GetDXUTState().GetWindowBackBufferWidthAtModeChange(), GetDXUTState().GetWindowBackBufferHeightAtModeChange() }; return rc; }
|
---|
4689 | RECT DXUTGetFullsceenClientRectAtModeChange() { RECT rc = { 0, 0, GetDXUTState().GetFullScreenBackBufferWidthAtModeChange(), GetDXUTState().GetFullScreenBackBufferHeightAtModeChange() }; return rc; }
|
---|
4690 | double DXUTGetTime() { return GetDXUTState().GetTime(); }
|
---|
4691 | float DXUTGetElapsedTime() { return GetDXUTState().GetElapsedTime(); }
|
---|
4692 | float DXUTGetFPS() { return GetDXUTState().GetFPS(); }
|
---|
4693 | LPCWSTR DXUTGetWindowTitle() { return GetDXUTState().GetWindowTitle(); }
|
---|
4694 | LPCWSTR DXUTGetDeviceStats() { return GetDXUTState().GetDeviceStats(); }
|
---|
4695 | bool DXUTIsRenderingPaused() { return GetDXUTState().GetPauseRenderingCount() > 0; }
|
---|
4696 | bool DXUTIsTimePaused() { return GetDXUTState().GetPauseTimeCount() > 0; }
|
---|
4697 | bool DXUTIsActive() { return GetDXUTState().GetActive(); }
|
---|
4698 | int DXUTGetExitCode() { return GetDXUTState().GetExitCode(); }
|
---|
4699 | bool DXUTGetShowMsgBoxOnError() { return GetDXUTState().GetShowMsgBoxOnError(); }
|
---|
4700 | bool DXUTGetAutomation() { return GetDXUTState().GetAutomation(); }
|
---|
4701 | bool DXUTGetHandleDefaultHotkeys() { return GetDXUTState().GetHandleDefaultHotkeys(); }
|
---|
4702 | bool DXUTIsKeyDown( BYTE vKey )
|
---|
4703 | {
|
---|
4704 | bool* bKeys = GetDXUTState().GetKeys();
|
---|
4705 | if( vKey >= 0xA0 && vKey <= 0xA5 ) // VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU, VK_RMENU
|
---|
4706 | return GetAsyncKeyState( vKey ) != 0; // these keys only are tracked via GetAsyncKeyState()
|
---|
4707 | else if( vKey >= 0x01 && vKey <= 0x06 && vKey != 0x03 ) // mouse buttons (VK_*BUTTON)
|
---|
4708 | return DXUTIsMouseButtonDown(vKey);
|
---|
4709 | else
|
---|
4710 | return bKeys[vKey];
|
---|
4711 | }
|
---|
4712 | bool DXUTIsMouseButtonDown( BYTE vButton )
|
---|
4713 | {
|
---|
4714 | bool* bMouseButtons = GetDXUTState().GetMouseButtons();
|
---|
4715 | int nIndex = DXUTMapButtonToArrayIndex(vButton);
|
---|
4716 | return bMouseButtons[nIndex];
|
---|
4717 | }
|
---|
4718 | void DXUTSetMultimonSettings( bool bAutoChangeAdapter )
|
---|
4719 | {
|
---|
4720 | GetDXUTState().SetAutoChangeAdapter( bAutoChangeAdapter );
|
---|
4721 | }
|
---|
4722 | void DXUTSetCursorSettings( bool bShowCursorWhenFullScreen, bool bClipCursorWhenFullScreen )
|
---|
4723 | {
|
---|
4724 | GetDXUTState().SetClipCursorWhenFullScreen(bClipCursorWhenFullScreen);
|
---|
4725 | GetDXUTState().SetShowCursorWhenFullScreen(bShowCursorWhenFullScreen);
|
---|
4726 | DXUTSetupCursor();
|
---|
4727 | }
|
---|
4728 | void DXUTSetWindowSettings( bool bCallDefWindowProc )
|
---|
4729 | {
|
---|
4730 | GetDXUTState().SetCallDefWindowProc( bCallDefWindowProc );
|
---|
4731 | }
|
---|
4732 | void DXUTSetConstantFrameTime( bool bEnabled, float fTimePerFrame )
|
---|
4733 | {
|
---|
4734 | if( GetDXUTState().GetOverrideConstantFrameTime() )
|
---|
4735 | {
|
---|
4736 | bEnabled = GetDXUTState().GetOverrideConstantFrameTime();
|
---|
4737 | fTimePerFrame = GetDXUTState().GetOverrideConstantTimePerFrame();
|
---|
4738 | }
|
---|
4739 | GetDXUTState().SetConstantFrameTime(bEnabled);
|
---|
4740 | GetDXUTState().SetTimePerFrame(fTimePerFrame);
|
---|
4741 | }
|
---|
4742 |
|
---|
4743 |
|
---|
4744 | //--------------------------------------------------------------------------------------
|
---|
4745 | // Return if windowed in the current device. If no device exists yet, then returns false
|
---|
4746 | //--------------------------------------------------------------------------------------
|
---|
4747 | bool DXUTIsWindowed()
|
---|
4748 | {
|
---|
4749 | DXUTDeviceSettings* pDeviceSettings = GetDXUTState().GetCurrentDeviceSettings();
|
---|
4750 | if(pDeviceSettings)
|
---|
4751 | return (pDeviceSettings->pp.Windowed != 0);
|
---|
4752 | else
|
---|
4753 | return false;
|
---|
4754 | }
|
---|
4755 |
|
---|
4756 |
|
---|
4757 | //--------------------------------------------------------------------------------------
|
---|
4758 | // Return the present params of the current device. If no device exists yet, then
|
---|
4759 | // return blank present params
|
---|
4760 | //--------------------------------------------------------------------------------------
|
---|
4761 | D3DPRESENT_PARAMETERS DXUTGetPresentParameters()
|
---|
4762 | {
|
---|
4763 | DXUTDeviceSettings* pDS = GetDXUTState().GetCurrentDeviceSettings();
|
---|
4764 | if( pDS )
|
---|
4765 | {
|
---|
4766 | return pDS->pp;
|
---|
4767 | }
|
---|
4768 | else
|
---|
4769 | {
|
---|
4770 | D3DPRESENT_PARAMETERS pp;
|
---|
4771 | ZeroMemory( &pp, sizeof(D3DPRESENT_PARAMETERS) );
|
---|
4772 | return pp;
|
---|
4773 | }
|
---|
4774 | }
|
---|
4775 |
|
---|
4776 |
|
---|
4777 | //--------------------------------------------------------------------------------------
|
---|
4778 | // Return the device settings of the current device. If no device exists yet, then
|
---|
4779 | // return blank device settings
|
---|
4780 | //--------------------------------------------------------------------------------------
|
---|
4781 | DXUTDeviceSettings DXUTGetDeviceSettings()
|
---|
4782 | {
|
---|
4783 | DXUTDeviceSettings* pDS = GetDXUTState().GetCurrentDeviceSettings();
|
---|
4784 | if( pDS )
|
---|
4785 | {
|
---|
4786 | return *pDS;
|
---|
4787 | }
|
---|
4788 | else
|
---|
4789 | {
|
---|
4790 | DXUTDeviceSettings ds;
|
---|
4791 | ZeroMemory( &ds, sizeof(DXUTDeviceSettings) );
|
---|
4792 | return ds;
|
---|
4793 | }
|
---|
4794 | }
|
---|
4795 |
|
---|
4796 | #ifndef SM_REMOTESESSION // needs WINVER >= 0x0500
|
---|
4797 | #define SM_REMOTESESSION 0x1000
|
---|
4798 | #endif
|
---|
4799 |
|
---|
4800 |
|
---|
4801 | //--------------------------------------------------------------------------------------
|
---|
4802 | // Display an custom error msg box
|
---|
4803 | //--------------------------------------------------------------------------------------
|
---|
4804 | void DXUTDisplayErrorMessage( HRESULT hr )
|
---|
4805 | {
|
---|
4806 | WCHAR strBuffer[512];
|
---|
4807 |
|
---|
4808 | int nExitCode;
|
---|
4809 | bool bFound = true;
|
---|
4810 | switch( hr )
|
---|
4811 | {
|
---|
4812 | case DXUTERR_NODIRECT3D: nExitCode = 2; StringCchCopy( strBuffer, 512, L"Could not initialize Direct3D. You may want to check that the latest version of DirectX is correctly installed on your system. Also make sure that this program was compiled with header files that match the installed DirectX DLLs." ); break;
|
---|
4813 | case DXUTERR_INCORRECTVERSION: nExitCode = 10; StringCchCopy( strBuffer, 512, L"Incorrect version of Direct3D and/or D3DX." ); break;
|
---|
4814 | case DXUTERR_MEDIANOTFOUND: nExitCode = 4; StringCchCopy( strBuffer, 512, L"Could not find required media. Ensure that the DirectX SDK is correctly installed." ); break;
|
---|
4815 | case DXUTERR_NONZEROREFCOUNT: nExitCode = 5; StringCchCopy( strBuffer, 512, L"The D3D device has a non-zero reference count, meaning some objects were not released." ); break;
|
---|
4816 | case DXUTERR_CREATINGDEVICE: nExitCode = 6; StringCchCopy( strBuffer, 512, L"Failed creating the Direct3D device." ); break;
|
---|
4817 | case DXUTERR_RESETTINGDEVICE: nExitCode = 7; StringCchCopy( strBuffer, 512, L"Failed resetting the Direct3D device." ); break;
|
---|
4818 | case DXUTERR_CREATINGDEVICEOBJECTS: nExitCode = 8; StringCchCopy( strBuffer, 512, L"Failed creating Direct3D device objects." ); break;
|
---|
4819 | case DXUTERR_RESETTINGDEVICEOBJECTS: nExitCode = 9; StringCchCopy( strBuffer, 512, L"Failed resetting Direct3D device objects." ); break;
|
---|
4820 | case DXUTERR_NOCOMPATIBLEDEVICES:
|
---|
4821 | nExitCode = 3;
|
---|
4822 | if( GetSystemMetrics(SM_REMOTESESSION) != 0 )
|
---|
4823 | StringCchCopy( strBuffer, 512, L"Direct3D does not work over a remote session." );
|
---|
4824 | else
|
---|
4825 | StringCchCopy( strBuffer, 512, L"Could not find any compatible Direct3D devices." );
|
---|
4826 | break;
|
---|
4827 | default: bFound = false; nExitCode = 1;break;
|
---|
4828 | }
|
---|
4829 |
|
---|
4830 | GetDXUTState().SetExitCode(nExitCode);
|
---|
4831 |
|
---|
4832 | bool bShowMsgBoxOnError = GetDXUTState().GetShowMsgBoxOnError();
|
---|
4833 | if( bFound && bShowMsgBoxOnError )
|
---|
4834 | {
|
---|
4835 | if( DXUTGetWindowTitle()[0] == 0 )
|
---|
4836 | MessageBox( DXUTGetHWND(), strBuffer, L"DirectX Application", MB_ICONERROR|MB_OK );
|
---|
4837 | else
|
---|
4838 | MessageBox( DXUTGetHWND(), strBuffer, DXUTGetWindowTitle(), MB_ICONERROR|MB_OK );
|
---|
4839 | }
|
---|
4840 | }
|
---|
4841 |
|
---|
4842 |
|
---|
4843 | //--------------------------------------------------------------------------------------
|
---|
4844 | // Display error msg box to help debug
|
---|
4845 | //--------------------------------------------------------------------------------------
|
---|
4846 | HRESULT WINAPI DXUTTrace( const CHAR* strFile, DWORD dwLine, HRESULT hr,
|
---|
4847 | const WCHAR* strMsg, bool bPopMsgBox )
|
---|
4848 | {
|
---|
4849 | bool bShowMsgBoxOnError = GetDXUTState().GetShowMsgBoxOnError();
|
---|
4850 | if( bPopMsgBox && bShowMsgBoxOnError == false )
|
---|
4851 | bPopMsgBox = false;
|
---|
4852 |
|
---|
4853 | return DXTrace( strFile, dwLine, hr, strMsg, bPopMsgBox );
|
---|
4854 | }
|
---|
4855 |
|
---|
4856 |
|
---|
4857 | //--------------------------------------------------------------------------------------
|
---|
4858 | // Checks to see if the HWND changed monitors, and if it did it creates a device
|
---|
4859 | // from the monitor's adapter and recreates the scene.
|
---|
4860 | //--------------------------------------------------------------------------------------
|
---|
4861 | void DXUTCheckForWindowChangingMonitors()
|
---|
4862 | {
|
---|
4863 | // Skip this check for various reasons
|
---|
4864 | if( !GetDXUTState().GetAutoChangeAdapter() ||
|
---|
4865 | GetDXUTState().GetIgnoreSizeChange() ||
|
---|
4866 | !GetDXUTState().GetDeviceCreated() ||
|
---|
4867 | !GetDXUTState().GetCurrentDeviceSettings()->pp.Windowed )
|
---|
4868 | {
|
---|
4869 | return;
|
---|
4870 | }
|
---|
4871 |
|
---|
4872 | HRESULT hr;
|
---|
4873 | HMONITOR hWindowMonitor = DXUTMonitorFromWindow( DXUTGetHWND(), MONITOR_DEFAULTTOPRIMARY );
|
---|
4874 | HMONITOR hAdapterMonitor = GetDXUTState().GetAdapterMonitor();
|
---|
4875 | if( hWindowMonitor != hAdapterMonitor )
|
---|
4876 | {
|
---|
4877 | UINT newOrdinal;
|
---|
4878 | if( SUCCEEDED( DXUTGetAdapterOrdinalFromMonitor( hWindowMonitor, &newOrdinal ) ) )
|
---|
4879 | {
|
---|
4880 | // Find the closest valid device settings with the new ordinal
|
---|
4881 | DXUTDeviceSettings deviceSettings = DXUTGetDeviceSettings();
|
---|
4882 | deviceSettings.AdapterOrdinal = newOrdinal;
|
---|
4883 |
|
---|
4884 | DXUTMatchOptions matchOptions;
|
---|
4885 | matchOptions.eAdapterOrdinal = DXUTMT_PRESERVE_INPUT;
|
---|
4886 | matchOptions.eDeviceType = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4887 | matchOptions.eWindowed = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4888 | matchOptions.eAdapterFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4889 | matchOptions.eVertexProcessing = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4890 | matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4891 | matchOptions.eBackBufferFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4892 | matchOptions.eBackBufferCount = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4893 | matchOptions.eMultiSample = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4894 | matchOptions.eSwapEffect = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4895 | matchOptions.eDepthFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4896 | matchOptions.eStencilFormat = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4897 | matchOptions.ePresentFlags = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4898 | matchOptions.eRefreshRate = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4899 | matchOptions.ePresentInterval = DXUTMT_CLOSEST_TO_INPUT;
|
---|
4900 |
|
---|
4901 | hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
|
---|
4902 | if( SUCCEEDED(hr) )
|
---|
4903 | {
|
---|
4904 | // Create a Direct3D device using the new device settings.
|
---|
4905 | // If there is an existing device, then it will either reset or recreate the scene.
|
---|
4906 | hr = DXUTChangeDevice( &deviceSettings, NULL, false, false );
|
---|
4907 |
|
---|
4908 | // If hr == E_ABORT, this means the app rejected the device settings in the ModifySettingsCallback
|
---|
4909 | if( hr == E_ABORT )
|
---|
4910 | {
|
---|
4911 | // so nothing changed and keep from attempting to switch adapters next time
|
---|
4912 | GetDXUTState().SetAutoChangeAdapter( false );
|
---|
4913 | }
|
---|
4914 | else if( FAILED(hr) )
|
---|
4915 | {
|
---|
4916 | DXUTShutdown();
|
---|
4917 | DXUTPause( false, false );
|
---|
4918 | return;
|
---|
4919 | }
|
---|
4920 | }
|
---|
4921 | }
|
---|
4922 | }
|
---|
4923 | }
|
---|
4924 |
|
---|
4925 |
|
---|
4926 | //--------------------------------------------------------------------------------------
|
---|
4927 | // Look for an adapter ordinal that is tied to a HMONITOR
|
---|
4928 | //--------------------------------------------------------------------------------------
|
---|
4929 | HRESULT DXUTGetAdapterOrdinalFromMonitor( HMONITOR hMonitor, UINT* pAdapterOrdinal )
|
---|
4930 | {
|
---|
4931 | *pAdapterOrdinal = 0;
|
---|
4932 |
|
---|
4933 | CD3DEnumeration* pd3dEnum = DXUTPrepareEnumerationObject();
|
---|
4934 | IDirect3D9* pD3D = DXUTGetD3DObject();
|
---|
4935 |
|
---|
4936 | CGrowableArray<CD3DEnumAdapterInfo*>* pAdapterList = pd3dEnum->GetAdapterInfoList();
|
---|
4937 | for( int iAdapter=0; iAdapter<pAdapterList->GetSize(); iAdapter++ )
|
---|
4938 | {
|
---|
4939 | CD3DEnumAdapterInfo* pAdapterInfo = pAdapterList->GetAt(iAdapter);
|
---|
4940 | HMONITOR hAdapterMonitor = pD3D->GetAdapterMonitor( pAdapterInfo->AdapterOrdinal );
|
---|
4941 | if( hAdapterMonitor == hMonitor )
|
---|
4942 | {
|
---|
4943 | *pAdapterOrdinal = pAdapterInfo->AdapterOrdinal;
|
---|
4944 | return S_OK;
|
---|
4945 | }
|
---|
4946 | }
|
---|
4947 |
|
---|
4948 | return E_FAIL;
|
---|
4949 | }
|
---|
4950 |
|
---|
4951 |
|
---|
4952 | //--------------------------------------------------------------------------------------
|
---|
4953 | // Internal function to map MK_* to an array index
|
---|
4954 | //--------------------------------------------------------------------------------------
|
---|
4955 | int DXUTMapButtonToArrayIndex( BYTE vButton )
|
---|
4956 | {
|
---|
4957 | switch( vButton )
|
---|
4958 | {
|
---|
4959 | case MK_LBUTTON: return 0;
|
---|
4960 | case VK_MBUTTON:
|
---|
4961 | case MK_MBUTTON: return 1;
|
---|
4962 | case MK_RBUTTON: return 2;
|
---|
4963 | case VK_XBUTTON1:
|
---|
4964 | case MK_XBUTTON1: return 3;
|
---|
4965 | case VK_XBUTTON2:
|
---|
4966 | case MK_XBUTTON2: return 4;
|
---|
4967 | }
|
---|
4968 |
|
---|
4969 | return 0;
|
---|
4970 | }
|
---|
4971 |
|
---|
4972 |
|
---|
4973 | //--------------------------------------------------------------------------------------
|
---|
4974 | // Setup cursor based on current settings (window/fullscreen mode, show cursor state, clip cursor state)
|
---|
4975 | //--------------------------------------------------------------------------------------
|
---|
4976 | void DXUTSetupCursor()
|
---|
4977 | {
|
---|
4978 | // Show the cursor again if returning to fullscreen
|
---|
4979 | IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
|
---|
4980 | if( !DXUTIsWindowed() && pd3dDevice )
|
---|
4981 | {
|
---|
4982 | if( GetDXUTState().GetShowCursorWhenFullScreen() )
|
---|
4983 | {
|
---|
4984 | SetCursor( NULL ); // Turn off Windows cursor in full screen mode
|
---|
4985 | HCURSOR hCursor = (HCURSOR)(ULONG_PTR)GetClassLongPtr( DXUTGetHWNDDeviceFullScreen(), GCLP_HCURSOR );
|
---|
4986 | DXUTSetDeviceCursor( pd3dDevice, hCursor, false );
|
---|
4987 | DXUTGetD3DDevice()->ShowCursor( true );
|
---|
4988 | }
|
---|
4989 | else
|
---|
4990 | {
|
---|
4991 | SetCursor( NULL ); // Turn off Windows cursor in full screen mode
|
---|
4992 | DXUTGetD3DDevice()->ShowCursor( false );
|
---|
4993 | }
|
---|
4994 | }
|
---|
4995 |
|
---|
4996 | // Clip cursor if requested
|
---|
4997 | if( !DXUTIsWindowed() && GetDXUTState().GetClipCursorWhenFullScreen() )
|
---|
4998 | {
|
---|
4999 | // Confine cursor to full screen window
|
---|
5000 | RECT rcWindow;
|
---|
5001 | GetWindowRect( DXUTGetHWNDDeviceFullScreen(), &rcWindow );
|
---|
5002 | ClipCursor( &rcWindow );
|
---|
5003 | }
|
---|
5004 | else
|
---|
5005 | {
|
---|
5006 | ClipCursor( NULL );
|
---|
5007 | }
|
---|
5008 | }
|
---|
5009 |
|
---|
5010 | //--------------------------------------------------------------------------------------
|
---|
5011 | // Gives the D3D device a cursor with image and hotspot from hCursor.
|
---|
5012 | //--------------------------------------------------------------------------------------
|
---|
5013 | HRESULT DXUTSetDeviceCursor( IDirect3DDevice9* pd3dDevice, HCURSOR hCursor, bool bAddWatermark )
|
---|
5014 | {
|
---|
5015 | HRESULT hr = E_FAIL;
|
---|
5016 | ICONINFO iconinfo;
|
---|
5017 | bool bBWCursor;
|
---|
5018 | LPDIRECT3DSURFACE9 pCursorSurface = NULL;
|
---|
5019 | HDC hdcColor = NULL;
|
---|
5020 | HDC hdcMask = NULL;
|
---|
5021 | HDC hdcScreen = NULL;
|
---|
5022 | BITMAP bm;
|
---|
5023 | DWORD dwWidth;
|
---|
5024 | DWORD dwHeightSrc;
|
---|
5025 | DWORD dwHeightDest;
|
---|
5026 | COLORREF crColor;
|
---|
5027 | COLORREF crMask;
|
---|
5028 | UINT x;
|
---|
5029 | UINT y;
|
---|
5030 | BITMAPINFO bmi;
|
---|
5031 | COLORREF* pcrArrayColor = NULL;
|
---|
5032 | COLORREF* pcrArrayMask = NULL;
|
---|
5033 | DWORD* pBitmap;
|
---|
5034 | HGDIOBJ hgdiobjOld;
|
---|
5035 |
|
---|
5036 | ZeroMemory( &iconinfo, sizeof(iconinfo) );
|
---|
5037 | if( !GetIconInfo( hCursor, &iconinfo ) )
|
---|
5038 | goto End;
|
---|
5039 |
|
---|
5040 | if (0 == GetObject((HGDIOBJ)iconinfo.hbmMask, sizeof(BITMAP), (LPVOID)&bm))
|
---|
5041 | goto End;
|
---|
5042 | dwWidth = bm.bmWidth;
|
---|
5043 | dwHeightSrc = bm.bmHeight;
|
---|
5044 |
|
---|
5045 | if( iconinfo.hbmColor == NULL )
|
---|
5046 | {
|
---|
5047 | bBWCursor = TRUE;
|
---|
5048 | dwHeightDest = dwHeightSrc / 2;
|
---|
5049 | }
|
---|
5050 | else
|
---|
5051 | {
|
---|
5052 | bBWCursor = FALSE;
|
---|
5053 | dwHeightDest = dwHeightSrc;
|
---|
5054 | }
|
---|
5055 |
|
---|
5056 | // Create a surface for the fullscreen cursor
|
---|
5057 | if( FAILED( hr = pd3dDevice->CreateOffscreenPlainSurface( dwWidth, dwHeightDest,
|
---|
5058 | D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCursorSurface, NULL ) ) )
|
---|
5059 | {
|
---|
5060 | goto End;
|
---|
5061 | }
|
---|
5062 |
|
---|
5063 | pcrArrayMask = new DWORD[dwWidth * dwHeightSrc];
|
---|
5064 |
|
---|
5065 | ZeroMemory(&bmi, sizeof(bmi));
|
---|
5066 | bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
---|
5067 | bmi.bmiHeader.biWidth = dwWidth;
|
---|
5068 | bmi.bmiHeader.biHeight = dwHeightSrc;
|
---|
5069 | bmi.bmiHeader.biPlanes = 1;
|
---|
5070 | bmi.bmiHeader.biBitCount = 32;
|
---|
5071 | bmi.bmiHeader.biCompression = BI_RGB;
|
---|
5072 |
|
---|
5073 | hdcScreen = GetDC( NULL );
|
---|
5074 | hdcMask = CreateCompatibleDC( hdcScreen );
|
---|
5075 | if( hdcMask == NULL )
|
---|
5076 | {
|
---|
5077 | hr = E_FAIL;
|
---|
5078 | goto End;
|
---|
5079 | }
|
---|
5080 | hgdiobjOld = SelectObject(hdcMask, iconinfo.hbmMask);
|
---|
5081 | GetDIBits(hdcMask, iconinfo.hbmMask, 0, dwHeightSrc,
|
---|
5082 | pcrArrayMask, &bmi, DIB_RGB_COLORS);
|
---|
5083 | SelectObject(hdcMask, hgdiobjOld);
|
---|
5084 |
|
---|
5085 | if (!bBWCursor)
|
---|
5086 | {
|
---|
5087 | pcrArrayColor = new DWORD[dwWidth * dwHeightDest];
|
---|
5088 | hdcColor = CreateCompatibleDC( hdcScreen );
|
---|
5089 | if( hdcColor == NULL )
|
---|
5090 | {
|
---|
5091 | hr = E_FAIL;
|
---|
5092 | goto End;
|
---|
5093 | }
|
---|
5094 | SelectObject(hdcColor, iconinfo.hbmColor);
|
---|
5095 | GetDIBits(hdcColor, iconinfo.hbmColor, 0, dwHeightDest,
|
---|
5096 | pcrArrayColor, &bmi, DIB_RGB_COLORS);
|
---|
5097 | }
|
---|
5098 |
|
---|
5099 | // Transfer cursor image into the surface
|
---|
5100 | D3DLOCKED_RECT lr;
|
---|
5101 | pCursorSurface->LockRect( &lr, NULL, 0 );
|
---|
5102 | pBitmap = (DWORD*)lr.pBits;
|
---|
5103 | for( y = 0; y < dwHeightDest; y++ )
|
---|
5104 | {
|
---|
5105 | for( x = 0; x < dwWidth; x++ )
|
---|
5106 | {
|
---|
5107 | if (bBWCursor)
|
---|
5108 | {
|
---|
5109 | crColor = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
|
---|
5110 | crMask = pcrArrayMask[dwWidth*(dwHeightSrc-1-y) + x];
|
---|
5111 | }
|
---|
5112 | else
|
---|
5113 | {
|
---|
5114 | crColor = pcrArrayColor[dwWidth*(dwHeightDest-1-y) + x];
|
---|
5115 | crMask = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
|
---|
5116 | }
|
---|
5117 | if (crMask == 0)
|
---|
5118 | pBitmap[dwWidth*y + x] = 0xff000000 | crColor;
|
---|
5119 | else
|
---|
5120 | pBitmap[dwWidth*y + x] = 0x00000000;
|
---|
5121 |
|
---|
5122 | // It may be helpful to make the D3D cursor look slightly
|
---|
5123 | // different from the Windows cursor so you can distinguish
|
---|
5124 | // between the two when developing/testing code. When
|
---|
5125 | // bAddWatermark is TRUE, the following code adds some
|
---|
5126 | // small grey "D3D" characters to the upper-left corner of
|
---|
5127 | // the D3D cursor image.
|
---|
5128 | if( bAddWatermark && x < 12 && y < 5 )
|
---|
5129 | {
|
---|
5130 | // 11.. 11.. 11.. .... CCC0
|
---|
5131 | // 1.1. ..1. 1.1. .... A2A0
|
---|
5132 | // 1.1. .1.. 1.1. .... A4A0
|
---|
5133 | // 1.1. ..1. 1.1. .... A2A0
|
---|
5134 | // 11.. 11.. 11.. .... CCC0
|
---|
5135 |
|
---|
5136 | const WORD wMask[5] = { 0xccc0, 0xa2a0, 0xa4a0, 0xa2a0, 0xccc0 };
|
---|
5137 | if( wMask[y] & (1 << (15 - x)) )
|
---|
5138 | {
|
---|
5139 | pBitmap[dwWidth*y + x] |= 0xff808080;
|
---|
5140 | }
|
---|
5141 | }
|
---|
5142 | }
|
---|
5143 | }
|
---|
5144 | pCursorSurface->UnlockRect();
|
---|
5145 |
|
---|
5146 | // Set the device cursor
|
---|
5147 | if( FAILED( hr = pd3dDevice->SetCursorProperties( iconinfo.xHotspot,
|
---|
5148 | iconinfo.yHotspot, pCursorSurface ) ) )
|
---|
5149 | {
|
---|
5150 | goto End;
|
---|
5151 | }
|
---|
5152 |
|
---|
5153 | hr = S_OK;
|
---|
5154 |
|
---|
5155 | End:
|
---|
5156 | if( iconinfo.hbmMask != NULL )
|
---|
5157 | DeleteObject( iconinfo.hbmMask );
|
---|
5158 | if( iconinfo.hbmColor != NULL )
|
---|
5159 | DeleteObject( iconinfo.hbmColor );
|
---|
5160 | if( hdcScreen != NULL )
|
---|
5161 | ReleaseDC( NULL, hdcScreen );
|
---|
5162 | if( hdcColor != NULL )
|
---|
5163 | DeleteDC( hdcColor );
|
---|
5164 | if( hdcMask != NULL )
|
---|
5165 | DeleteDC( hdcMask );
|
---|
5166 | SAFE_DELETE_ARRAY( pcrArrayColor );
|
---|
5167 | SAFE_DELETE_ARRAY( pcrArrayMask );
|
---|
5168 | SAFE_RELEASE( pCursorSurface );
|
---|
5169 | return hr;
|
---|
5170 | }
|
---|
5171 |
|
---|
5172 |
|
---|
5173 |
|
---|