home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: D3DApp.cpp
- //
- // Desc: Application class for the Direct3D samples framework library.
- //
- // Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #define STRICT
- #include <windows.h>
- #include <windowsx.h>
- #include <basetsd.h>
- #include <mmsystem.h>
- #include <stdio.h>
- #include <tchar.h>
- #include <D3D8.h>
- #include "D3DApp.h"
- #include "D3DUtil.h"
- #include "DXUtil.h"
- #include "D3DRes.h"
-
-
-
-
- //-----------------------------------------------------------------------------
- // Global access to the app (needed for the global WndProc())
- //-----------------------------------------------------------------------------
- static CD3DApplication* g_pD3DApp = NULL;
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: CD3DApplication()
- // Desc: Constructor
- //-----------------------------------------------------------------------------
- CD3DApplication::CD3DApplication()
- {
- g_pD3DApp = this;
-
- m_dwNumAdapters = 0;
- m_dwAdapter = 0L;
- m_pD3D = NULL;
- m_pd3dDevice = NULL;
- m_hWnd = NULL;
- m_hWndFocus = NULL;
- m_hMenu = NULL;
- m_bActive = FALSE;
- m_bReady = FALSE;
- m_bHasFocus = FALSE;
- m_dwCreateFlags = 0L;
-
- m_bFrameMoving = TRUE;
- m_bSingleStep = FALSE;
- m_fFPS = 0.0f;
- m_strDeviceStats[0] = _T('\0');
- m_strFrameStats[0] = _T('\0');
-
- m_strWindowTitle = _T("D3D8 Application");
- m_dwCreationWidth = 400;
- m_dwCreationHeight = 300;
- m_bUseDepthBuffer = FALSE;
- m_dwMinDepthBits = 16;
- m_dwMinStencilBits = 0;
- m_bShowCursorWhenFullscreen = FALSE;
-
- // When m_bClipCursorWhenFullscreen is TRUE, the cursor is limited to
- // the device window when the app goes fullscreen. This prevents users
- // from accidentally clicking outside the app window on a multimon system.
- // This flag is turned off by default for debug builds, since it makes
- // multimon debugging difficult.
- #if defined(_DEBUG) || defined(DEBUG)
- m_bClipCursorWhenFullscreen = FALSE;
- #else
- m_bClipCursorWhenFullscreen = TRUE;
- #endif
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: WndProc()
- // Desc: Static msg handler which passes messages to the application class.
- //-----------------------------------------------------------------------------
- LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- return g_pD3DApp->MsgProc( hWnd, uMsg, wParam, lParam );
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: Create()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::Create( HINSTANCE hInstance )
- {
- HRESULT hr;
-
- // Create the Direct3D object
- m_pD3D = Direct3DCreate8( D3D_SDK_VERSION );
- if( m_pD3D == NULL )
- return DisplayErrorMsg( D3DAPPERR_NODIRECT3D, MSGERR_APPMUSTEXIT );
-
- // Build a list of Direct3D adapters, modes and devices. The
- // ConfirmDevice() callback is used to confirm that only devices that
- // meet the app's requirements are considered.
- if( FAILED( hr = BuildDeviceList() ) )
- {
- SAFE_RELEASE( m_pD3D );
- return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
- }
-
- // Unless a substitute hWnd has been specified, create a window to
- // render into
- if( m_hWnd == NULL)
- {
- // Register the windows class
- WNDCLASS wndClass = { 0, WndProc, 0, 0, hInstance,
- LoadIcon( hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON) ),
- LoadCursor( NULL, IDC_ARROW ),
- (HBRUSH)GetStockObject(WHITE_BRUSH),
- NULL, _T("D3D Window") };
- RegisterClass( &wndClass );
-
- // Set the window's initial style
- m_dwWindowStyle = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|
- WS_MINIMIZEBOX|WS_VISIBLE;
-
- // Set the window's initial width
- RECT rc;
- SetRect( &rc, 0, 0, m_dwCreationWidth, m_dwCreationHeight );
- AdjustWindowRect( &rc, m_dwWindowStyle, TRUE );
-
- // Create the render window
- m_hWnd = CreateWindow( _T("D3D Window"), m_strWindowTitle, m_dwWindowStyle,
- CW_USEDEFAULT, CW_USEDEFAULT,
- (rc.right-rc.left), (rc.bottom-rc.top), 0L,
- LoadMenu( hInstance, MAKEINTRESOURCE(IDR_MENU) ),
- hInstance, 0L );
- }
-
- // The focus window can be a specified to be a different window than the
- // device window. If not, use the device window as the focus window.
- if( m_hWndFocus == NULL )
- m_hWndFocus = m_hWnd;
-
- // Save window properties
- m_dwWindowStyle = GetWindowLong( m_hWnd, GWL_STYLE );
- GetWindowRect( m_hWnd, &m_rcWindowBounds );
- GetClientRect( m_hWnd, &m_rcWindowClient );
-
- // Initialize the application timer
- DXUtil_Timer( TIMER_START );
-
- // Initialize the app's custom scene stuff
- if( FAILED( hr = OneTimeSceneInit() ) )
- {
- SAFE_RELEASE( m_pD3D );
- return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
- }
-
- // Initialize the 3D environment for the app
- if( FAILED( hr = Initialize3DEnvironment() ) )
- {
- SAFE_RELEASE( m_pD3D );
- return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
- }
-
- // The app is ready to go
- m_bReady = TRUE;
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: SortModesCallback()
- // Desc: Callback function for sorting display modes (used by BuildDeviceList).
- //-----------------------------------------------------------------------------
- static int SortModesCallback( const VOID* arg1, const VOID* arg2 )
- {
- D3DDISPLAYMODE* p1 = (D3DDISPLAYMODE*)arg1;
- D3DDISPLAYMODE* p2 = (D3DDISPLAYMODE*)arg2;
-
- if( p1->Format > p2->Format ) return -1;
- if( p1->Format < p2->Format ) return +1;
- if( p1->Width < p2->Width ) return -1;
- if( p1->Width > p2->Width ) return +1;
- if( p1->Height < p2->Height ) return -1;
- if( p1->Height > p2->Height ) return +1;
-
- return 0;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: BuildDeviceList()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::BuildDeviceList()
- {
- const DWORD dwNumDeviceTypes = 2;
- const TCHAR* strDeviceDescs[] = { _T("HAL"), _T("REF") };
- const D3DDEVTYPE DeviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };
-
- BOOL bHALExists = FALSE;
- BOOL bHALIsWindowedCompatible = FALSE;
- BOOL bHALIsDesktopCompatible = FALSE;
- BOOL bHALIsSampleCompatible = FALSE;
-
- // Loop through all the adapters on the system (usually, there's just one
- // unless more than one graphics card is present).
- for( UINT iAdapter = 0; iAdapter < m_pD3D->GetAdapterCount(); iAdapter++ )
- {
- // Fill in adapter info
- D3DAdapterInfo* pAdapter = &m_Adapters[m_dwNumAdapters];
- m_pD3D->GetAdapterIdentifier( iAdapter, D3DENUM_NO_WHQL_LEVEL, &pAdapter->d3dAdapterIdentifier );
- m_pD3D->GetAdapterDisplayMode( iAdapter, &pAdapter->d3ddmDesktop );
- pAdapter->dwNumDevices = 0;
- pAdapter->dwCurrentDevice = 0;
-
- // Enumerate all display modes on this adapter
- D3DDISPLAYMODE modes[100];
- D3DFORMAT formats[20];
- DWORD dwNumFormats = 0;
- DWORD dwNumModes = 0;
- DWORD dwNumAdapterModes = m_pD3D->GetAdapterModeCount( iAdapter );
-
- // Add the adapter's current desktop format to the list of formats
- formats[dwNumFormats++] = pAdapter->d3ddmDesktop.Format;
-
- for( UINT iMode = 0; iMode < dwNumAdapterModes; iMode++ )
- {
- // Get the display mode attributes
- D3DDISPLAYMODE DisplayMode;
- m_pD3D->EnumAdapterModes( iAdapter, iMode, &DisplayMode );
-
- // Filter out low-resolution modes
- if( DisplayMode.Width < 640 || DisplayMode.Height < 400 )
- continue;
-
- // Check if the mode already exists (to filter out refresh rates)
- for( DWORD m=0L; m<dwNumModes; m++ )
- {
- if( ( modes[m].Width == DisplayMode.Width ) &&
- ( modes[m].Height == DisplayMode.Height ) &&
- ( modes[m].Format == DisplayMode.Format ) )
- break;
- }
-
- // If we found a new mode, add it to the list of modes
- if( m == dwNumModes )
- {
- modes[dwNumModes].Width = DisplayMode.Width;
- modes[dwNumModes].Height = DisplayMode.Height;
- modes[dwNumModes].Format = DisplayMode.Format;
- modes[dwNumModes].RefreshRate = 0;
- dwNumModes++;
-
- // Check if the mode's format already exists
- for( DWORD f=0; f<dwNumFormats; f++ )
- {
- if( DisplayMode.Format == formats[f] )
- break;
- }
-
- // If the format is new, add it to the list
- if( f== dwNumFormats )
- formats[dwNumFormats++] = DisplayMode.Format;
- }
- }
-
- // Sort the list of display modes (by format, then width, then height)
- qsort( modes, dwNumModes, sizeof(D3DDISPLAYMODE), SortModesCallback );
-
- // Add devices to adapter
- for( UINT iDevice = 0; iDevice < dwNumDeviceTypes; iDevice++ )
- {
- // Fill in device info
- D3DDeviceInfo* pDevice;
- pDevice = &pAdapter->devices[pAdapter->dwNumDevices];
- pDevice->DeviceType = DeviceTypes[iDevice];
- m_pD3D->GetDeviceCaps( iAdapter, DeviceTypes[iDevice], &pDevice->d3dCaps );
- pDevice->strDesc = strDeviceDescs[iDevice];
- pDevice->dwNumModes = 0;
- pDevice->dwCurrentMode = 0;
- pDevice->bCanDoWindowed = FALSE;
- pDevice->bWindowed = FALSE;
- pDevice->MultiSampleTypeFullscreen = D3DMULTISAMPLE_NONE;
- pDevice->MultiSampleTypeWindowed = D3DMULTISAMPLE_NONE;
-
- // Examine each format supported by the adapter to see if it will
- // work with this device and meets the needs of the application.
- BOOL bFormatConfirmed[20];
- DWORD dwBehavior[20];
- D3DFORMAT fmtDepthStencil[20];
-
- for( DWORD f=0; f<dwNumFormats; f++ )
- {
- bFormatConfirmed[f] = FALSE;
- fmtDepthStencil[f] = D3DFMT_UNKNOWN;
-
- // Skip formats that cannot be used as render targets on this device
- if( FAILED( m_pD3D->CheckDeviceType( iAdapter, pDevice->DeviceType,
- formats[f], formats[f], FALSE ) ) )
- continue;
-
- if( pDevice->DeviceType == D3DDEVTYPE_HAL )
- {
- // This system has a HAL device
- bHALExists = TRUE;
-
- if( pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED )
- {
- // HAL can run in a window for some mode
- bHALIsWindowedCompatible = TRUE;
-
- if( f == 0 )
- {
- // HAL can run in a window for the current desktop mode
- bHALIsDesktopCompatible = TRUE;
- }
- }
- }
-
- // Confirm the device/format for HW vertex processing
- if( pDevice->d3dCaps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT )
- {
- if( pDevice->d3dCaps.DevCaps&D3DDEVCAPS_PUREDEVICE )
- {
- dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING |
- D3DCREATE_PUREDEVICE;
-
- if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
- formats[f] ) ) )
- bFormatConfirmed[f] = TRUE;
- }
-
- if ( FALSE == bFormatConfirmed[f] )
- {
- dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING;
-
- if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
- formats[f] ) ) )
- bFormatConfirmed[f] = TRUE;
- }
-
- if ( FALSE == bFormatConfirmed[f] )
- {
- dwBehavior[f] = D3DCREATE_MIXED_VERTEXPROCESSING;
-
- if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
- formats[f] ) ) )
- bFormatConfirmed[f] = TRUE;
- }
- }
-
- // Confirm the device/format for SW vertex processing
- if( FALSE == bFormatConfirmed[f] )
- {
- dwBehavior[f] = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
-
- if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
- formats[f] ) ) )
- bFormatConfirmed[f] = TRUE;
- }
-
- // Find a suitable depth/stencil buffer format for this device/format
- if( bFormatConfirmed[f] && m_bUseDepthBuffer )
- {
- if( !FindDepthStencilFormat( iAdapter, pDevice->DeviceType,
- formats[f], &fmtDepthStencil[f] ) )
- {
- bFormatConfirmed[f] = FALSE;
- }
- }
- }
-
- // Add all enumerated display modes with confirmed formats to the
- // device's list of valid modes
- for( DWORD m=0L; m<dwNumModes; m++ )
- {
- for( DWORD f=0; f<dwNumFormats; f++ )
- {
- if( modes[m].Format == formats[f] )
- {
- if( bFormatConfirmed[f] == TRUE )
- {
- // Add this mode to the device's list of valid modes
- pDevice->modes[pDevice->dwNumModes].Width = modes[m].Width;
- pDevice->modes[pDevice->dwNumModes].Height = modes[m].Height;
- pDevice->modes[pDevice->dwNumModes].Format = modes[m].Format;
- pDevice->modes[pDevice->dwNumModes].dwBehavior = dwBehavior[f];
- pDevice->modes[pDevice->dwNumModes].DepthStencilFormat = fmtDepthStencil[f];
- pDevice->dwNumModes++;
-
- if( pDevice->DeviceType == D3DDEVTYPE_HAL )
- bHALIsSampleCompatible = TRUE;
- }
- }
- }
- }
-
- // Select any 640x480 mode for default (but prefer a 16-bit mode)
- for( m=0; m<pDevice->dwNumModes; m++ )
- {
- if( pDevice->modes[m].Width==640 && pDevice->modes[m].Height==480 )
- {
- pDevice->dwCurrentMode = m;
- if( pDevice->modes[m].Format == D3DFMT_R5G6B5 ||
- pDevice->modes[m].Format == D3DFMT_X1R5G5B5 ||
- pDevice->modes[m].Format == D3DFMT_A1R5G5B5 )
- {
- break;
- }
- }
- }
-
- // Check if the device is compatible with the desktop display mode
- // (which was added initially as formats[0])
- if( bFormatConfirmed[0] && (pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) )
- {
- pDevice->bCanDoWindowed = TRUE;
- pDevice->bWindowed = TRUE;
- }
-
- // If valid modes were found, keep this device
- if( pDevice->dwNumModes > 0 )
- pAdapter->dwNumDevices++;
- }
-
- // If valid devices were found, keep this adapter
- if( pAdapter->dwNumDevices > 0 )
- m_dwNumAdapters++;
- }
-
- // Return an error if no compatible devices were found
- if( 0L == m_dwNumAdapters )
- return D3DAPPERR_NOCOMPATIBLEDEVICES;
-
- // Pick a default device that can render into a window
- // (This code assumes that the HAL device comes before the REF
- // device in the device array).
- for( DWORD a=0; a<m_dwNumAdapters; a++ )
- {
- for( DWORD d=0; d < m_Adapters[a].dwNumDevices; d++ )
- {
- if( m_Adapters[a].devices[d].bWindowed )
- {
- m_Adapters[a].dwCurrentDevice = d;
- m_dwAdapter = a;
- m_bWindowed = TRUE;
-
- // Display a warning message
- if( m_Adapters[a].devices[d].DeviceType == D3DDEVTYPE_REF )
- {
- if( !bHALExists )
- DisplayErrorMsg( D3DAPPERR_NOHARDWAREDEVICE, MSGWARN_SWITCHEDTOREF );
- else if( !bHALIsSampleCompatible )
- DisplayErrorMsg( D3DAPPERR_HALNOTCOMPATIBLE, MSGWARN_SWITCHEDTOREF );
- else if( !bHALIsWindowedCompatible )
- DisplayErrorMsg( D3DAPPERR_NOWINDOWEDHAL, MSGWARN_SWITCHEDTOREF );
- else if( !bHALIsDesktopCompatible )
- DisplayErrorMsg( D3DAPPERR_NODESKTOPHAL, MSGWARN_SWITCHEDTOREF );
- else // HAL is desktop compatible, but not sample compatible
- DisplayErrorMsg( D3DAPPERR_NOHALTHISMODE, MSGWARN_SWITCHEDTOREF );
- }
-
- return S_OK;
- }
- }
- }
-
- return D3DAPPERR_NOWINDOWABLEDEVICES;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: FindDepthStencilFormat()
- // Desc: Finds a depth/stencil format for the given device that is compatible
- // with the render target format and meets the needs of the app.
- //-----------------------------------------------------------------------------
- BOOL CD3DApplication::FindDepthStencilFormat( UINT iAdapter, D3DDEVTYPE DeviceType,
- D3DFORMAT TargetFormat, D3DFORMAT* pDepthStencilFormat )
- {
- if( m_dwMinDepthBits <= 16 && m_dwMinStencilBits == 0 )
- {
- if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
- TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
- {
- if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
- TargetFormat, TargetFormat, D3DFMT_D16 ) ) )
- {
- *pDepthStencilFormat = D3DFMT_D16;
- return TRUE;
- }
- }
- }
-
- if( m_dwMinDepthBits <= 15 && m_dwMinStencilBits <= 1 )
- {
- if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
- TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D15S1 ) ) )
- {
- if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
- TargetFormat, TargetFormat, D3DFMT_D15S1 ) ) )
- {
- *pDepthStencilFormat = D3DFMT_D15S1;
- return TRUE;
- }
- }
- }
-
- if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits == 0 )
- {
- if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
- TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
- {
- if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
- TargetFormat, TargetFormat, D3DFMT_D24X8 ) ) )
- {
- *pDepthStencilFormat = D3DFMT_D24X8;
- return TRUE;
- }
- }
- }
-
- if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 8 )
- {
- if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
- TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
- {
- if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
- TargetFormat, TargetFormat, D3DFMT_D24S8 ) ) )
- {
- *pDepthStencilFormat = D3DFMT_D24S8;
- return TRUE;
- }
- }
- }
-
- if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 4 )
- {
- if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
- TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X4S4 ) ) )
- {
- if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
- TargetFormat, TargetFormat, D3DFMT_D24X4S4 ) ) )
- {
- *pDepthStencilFormat = D3DFMT_D24X4S4;
- return TRUE;
- }
- }
- }
-
- if( m_dwMinDepthBits <= 32 && m_dwMinStencilBits == 0 )
- {
- if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
- TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32 ) ) )
- {
- if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
- TargetFormat, TargetFormat, D3DFMT_D32 ) ) )
- {
- *pDepthStencilFormat = D3DFMT_D32;
- return TRUE;
- }
- }
- }
-
- return FALSE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: MsgProc()
- // Desc: Message handling function.
- //-----------------------------------------------------------------------------
- LRESULT CD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
- LPARAM lParam )
- {
- HRESULT hr;
-
- switch( uMsg )
- {
- case WM_PAINT:
- // Handle paint messages when the app is not ready
- if( m_pd3dDevice && !m_bReady )
- {
- if( m_bWindowed )
- {
- Render();
- m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
- }
- }
- break;
-
- case WM_ACTIVATEAPP:
- m_bHasFocus = (BOOL) wParam;
- break;
-
- case WM_GETMINMAXINFO:
- ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
- ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
- break;
-
- case WM_ENTERSIZEMOVE:
- // Halt frame movement while the app is sizing or moving
- Pause( TRUE );
- break;
-
- case WM_SIZE:
- // Check to see if we are losing our window...
- if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
- {
- if( m_bClipCursorWhenFullscreen && !m_bWindowed )
- ClipCursor( NULL );
- m_bActive = FALSE;
- }
- else
- {
- m_bActive = TRUE;
- }
- break;
-
- case WM_EXITSIZEMOVE:
- Pause( FALSE );
-
- if( m_bActive && m_bWindowed )
- {
- RECT rcClientOld;
- rcClientOld = m_rcWindowClient;
-
- // Update window properties
- GetWindowRect( m_hWnd, &m_rcWindowBounds );
- GetClientRect( m_hWnd, &m_rcWindowClient );
-
- if( rcClientOld.right - rcClientOld.left !=
- m_rcWindowClient.right - m_rcWindowClient.left ||
- rcClientOld.bottom - rcClientOld.top !=
- m_rcWindowClient.bottom - m_rcWindowClient.top)
- {
- // A new window size will require a new backbuffer
- // size, so the 3D structures must be changed accordingly.
- m_bReady = FALSE;
-
- m_d3dpp.BackBufferWidth = m_rcWindowClient.right - m_rcWindowClient.left;
- m_d3dpp.BackBufferHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
-
- // Resize the 3D environment
- if( FAILED( hr = Resize3DEnvironment() ) )
- {
- DisplayErrorMsg( D3DAPPERR_RESIZEFAILED, MSGERR_APPMUSTEXIT );
- return 0;
- }
-
- m_bReady = TRUE;
- }
- }
-
- break;
-
- case WM_SETCURSOR:
- // Turn off Windows cursor in fullscreen mode
- if( m_bActive && m_bReady && !m_bWindowed )
- {
- SetCursor( NULL );
- if( m_bShowCursorWhenFullscreen )
- m_pd3dDevice->ShowCursor( TRUE );
- return TRUE; // prevent Windows from setting cursor to window class cursor
- }
- break;
-
- case WM_MOUSEMOVE:
- if( m_bActive && m_bReady && m_pd3dDevice != NULL )
- {
- POINT ptCursor;
- GetCursorPos( &ptCursor );
- if( !m_bWindowed )
- ScreenToClient( m_hWnd, &ptCursor );
- m_pd3dDevice->SetCursorPosition( ptCursor.x, ptCursor.y, 0L );
- }
- break;
-
- case WM_ENTERMENULOOP:
- // Pause the app when menus are displayed
- Pause(TRUE);
- break;
-
- case WM_EXITMENULOOP:
- Pause(FALSE);
- break;
-
- case WM_CONTEXTMENU:
- // No context menus allowed in fullscreen mode
- if( m_bWindowed == FALSE )
- break;
-
- // Handle the app's context menu (via right mouse click)
- TrackPopupMenuEx( GetSubMenu( LoadMenu( 0, MAKEINTRESOURCE(IDR_POPUP) ), 0 ),
- TPM_VERTICAL, LOWORD(lParam), HIWORD(lParam), hWnd, NULL );
- break;
-
- case WM_NCHITTEST:
- // Prevent the user from selecting the menu in fullscreen mode
- if( !m_bWindowed )
- return HTCLIENT;
-
- break;
-
- case WM_POWERBROADCAST:
- switch( wParam )
- {
- #ifndef PBT_APMQUERYSUSPEND
- #define PBT_APMQUERYSUSPEND 0x0000
- #endif
- case PBT_APMQUERYSUSPEND:
- // At this point, the app should save any data for open
- // network connections, files, etc., and prepare to go into
- // a suspended mode.
- return TRUE;
-
- #ifndef PBT_APMRESUMESUSPEND
- #define PBT_APMRESUMESUSPEND 0x0007
- #endif
- case PBT_APMRESUMESUSPEND:
- // At this point, the app should recover any data, network
- // connections, files, etc., and resume running from when
- // the app was suspended.
- return TRUE;
- }
- break;
-
- case WM_SYSCOMMAND:
- // Prevent moving/sizing and power loss in fullscreen mode
- switch( wParam )
- {
- case SC_MOVE:
- case SC_SIZE:
- case SC_MAXIMIZE:
- case SC_KEYMENU:
- case SC_MONITORPOWER:
- if( FALSE == m_bWindowed )
- return 1;
- break;
- }
- break;
-
- case WM_COMMAND:
- switch( LOWORD(wParam) )
- {
- case IDM_TOGGLESTART:
- // Toggle frame movement
- m_bFrameMoving = !m_bFrameMoving;
- DXUtil_Timer( m_bFrameMoving ? TIMER_START : TIMER_STOP );
- break;
-
- case IDM_SINGLESTEP:
- // Single-step frame movement
- if( FALSE == m_bFrameMoving )
- DXUtil_Timer( TIMER_ADVANCE );
- else
- DXUtil_Timer( TIMER_STOP );
- m_bFrameMoving = FALSE;
- m_bSingleStep = TRUE;
- break;
-
- case IDM_CHANGEDEVICE:
- // Prompt the user to select a new device or mode
- if( m_bActive && m_bReady )
- {
- Pause(TRUE);
-
- if( FAILED( hr = UserSelectNewDevice() ) )
- return 0;
-
- Pause(FALSE);
- }
- return 0;
-
- case IDM_TOGGLEFULLSCREEN:
- // Toggle the fullscreen/window mode
- if( m_bActive && m_bReady )
- {
- Pause( TRUE );
-
- if( FAILED( ToggleFullscreen() ) )
- {
- DisplayErrorMsg( D3DAPPERR_RESIZEFAILED, MSGERR_APPMUSTEXIT );
- return 0;
- }
-
- Pause( FALSE );
- }
- return 0;
-
- case IDM_EXIT:
- // Recieved key/menu command to exit app
- SendMessage( hWnd, WM_CLOSE, 0, 0 );
- return 0;
- }
- break;
-
- case WM_CLOSE:
- Cleanup3DEnvironment();
- DestroyMenu( GetMenu(hWnd) );
- DestroyWindow( hWnd );
- PostQuitMessage(0);
- return 0;
- }
-
- return DefWindowProc( hWnd, uMsg, wParam, lParam );
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: Initialize3DEnvironment()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::Initialize3DEnvironment()
- {
- HRESULT hr;
-
- D3DAdapterInfo* pAdapterInfo = &m_Adapters[m_dwAdapter];
- D3DDeviceInfo* pDeviceInfo = &pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice];
- D3DModeInfo* pModeInfo = &pDeviceInfo->modes[pDeviceInfo->dwCurrentMode];
-
- // Prepare window for possible windowed/fullscreen change
- AdjustWindowForChange();
-
- // Set up the presentation parameters
- ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) );
- m_d3dpp.Windowed = pDeviceInfo->bWindowed;
- m_d3dpp.BackBufferCount = 1;
- if( pDeviceInfo->bWindowed )
- m_d3dpp.MultiSampleType = pDeviceInfo->MultiSampleTypeWindowed;
- else
- m_d3dpp.MultiSampleType = pDeviceInfo->MultiSampleTypeFullscreen;
- m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- m_d3dpp.EnableAutoDepthStencil = m_bUseDepthBuffer;
- m_d3dpp.AutoDepthStencilFormat = pModeInfo->DepthStencilFormat;
- m_d3dpp.hDeviceWindow = m_hWnd;
- if( m_bWindowed )
- {
- m_d3dpp.BackBufferWidth = m_rcWindowClient.right - m_rcWindowClient.left;
- m_d3dpp.BackBufferHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
- m_d3dpp.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format;
- }
- else
- {
- m_d3dpp.BackBufferWidth = pModeInfo->Width;
- m_d3dpp.BackBufferHeight = pModeInfo->Height;
- m_d3dpp.BackBufferFormat = pModeInfo->Format;
- }
-
- if( pDeviceInfo->d3dCaps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE )
- {
- // Warn user about null ref device that can't render anything
- DisplayErrorMsg( D3DAPPERR_NULLREFDEVICE, 0 );
- }
-
- // Create the device
- hr = m_pD3D->CreateDevice( m_dwAdapter, pDeviceInfo->DeviceType,
- m_hWndFocus, pModeInfo->dwBehavior, &m_d3dpp,
- &m_pd3dDevice );
- if( SUCCEEDED(hr) )
- {
- // When moving from fullscreen to windowed mode, it is important to
- // adjust the window size after recreating the device rather than
- // beforehand to ensure that you get the window size you want. For
- // example, when switching from 640x480 fullscreen to windowed with
- // a 1000x600 window on a 1024x768 desktop, it is impossible to set
- // the window size to 1000x600 until after the display mode has
- // changed to 1024x768, because windows cannot be larger than the
- // desktop.
- if( m_bWindowed )
- {
- SetWindowPos( m_hWnd, HWND_NOTOPMOST,
- m_rcWindowBounds.left, m_rcWindowBounds.top,
- ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
- ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
- SWP_SHOWWINDOW );
- }
-
- // Store device Caps
- m_pd3dDevice->GetDeviceCaps( &m_d3dCaps );
- m_dwCreateFlags = pModeInfo->dwBehavior;
-
- // Store device description
- if( pDeviceInfo->DeviceType == D3DDEVTYPE_REF )
- lstrcpy( m_strDeviceStats, TEXT("REF") );
- else if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
- lstrcpy( m_strDeviceStats, TEXT("HAL") );
- else if( pDeviceInfo->DeviceType == D3DDEVTYPE_SW )
- lstrcpy( m_strDeviceStats, TEXT("SW") );
-
- if( pModeInfo->dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING &&
- pModeInfo->dwBehavior & D3DCREATE_PUREDEVICE )
- {
- if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
- lstrcat( m_strDeviceStats, TEXT(" (pure hw vp)") );
- else
- lstrcat( m_strDeviceStats, TEXT(" (simulated pure hw vp)") );
- }
- else if( pModeInfo->dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING )
- {
- if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
- lstrcat( m_strDeviceStats, TEXT(" (hw vp)") );
- else
- lstrcat( m_strDeviceStats, TEXT(" (simulated hw vp)") );
- }
- else if( pModeInfo->dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING )
- {
- if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
- lstrcat( m_strDeviceStats, TEXT(" (mixed vp)") );
- else
- lstrcat( m_strDeviceStats, TEXT(" (simulated mixed vp)") );
- }
- else if( pModeInfo->dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING )
- {
- lstrcat( m_strDeviceStats, TEXT(" (sw vp)") );
- }
-
- if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
- {
- lstrcat( m_strDeviceStats, TEXT(": ") );
- lstrcat( m_strDeviceStats, pAdapterInfo->d3dAdapterIdentifier.Description );
- }
-
- // Store render target surface desc
- LPDIRECT3DSURFACE8 pBackBuffer;
- m_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
- pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
- pBackBuffer->Release();
-
- // Set up the fullscreen cursor
- if( m_bShowCursorWhenFullscreen && !m_bWindowed )
- {
- HCURSOR hCursor;
- #ifdef _WIN64
- hCursor = (HCURSOR)GetClassLongPtr( m_hWnd, GCLP_HCURSOR );
- #else
- hCursor = (HCURSOR)GetClassLong( m_hWnd, GCL_HCURSOR );
- #endif
- D3DUtil_SetDeviceCursor( m_pd3dDevice, hCursor, TRUE );
- m_pd3dDevice->ShowCursor( TRUE );
- }
-
- // Confine cursor to fullscreen window
- if( m_bClipCursorWhenFullscreen )
- {
- if (!m_bWindowed )
- {
- RECT rcWindow;
- GetWindowRect( m_hWnd, &rcWindow );
- ClipCursor( &rcWindow );
- }
- else
- {
- ClipCursor( NULL );
- }
- }
-
- // Initialize the app's device-dependent objects
- hr = InitDeviceObjects();
- if( SUCCEEDED(hr) )
- {
- hr = RestoreDeviceObjects();
- if( SUCCEEDED(hr) )
- {
- m_bActive = TRUE;
- return S_OK;
- }
- }
-
- // Cleanup before we try again
- InvalidateDeviceObjects();
- DeleteDeviceObjects();
- SAFE_RELEASE( m_pd3dDevice );
- }
-
- // If that failed, fall back to the reference rasterizer
- if( pDeviceInfo->DeviceType == D3DDEVTYPE_HAL )
- {
- // Select the default adapter
- m_dwAdapter = 0L;
- pAdapterInfo = &m_Adapters[m_dwAdapter];
-
- // Look for a software device
- for( UINT i=0L; i<pAdapterInfo->dwNumDevices; i++ )
- {
- if( pAdapterInfo->devices[i].DeviceType == D3DDEVTYPE_REF )
- {
- pAdapterInfo->dwCurrentDevice = i;
- pDeviceInfo = &pAdapterInfo->devices[i];
- m_bWindowed = pDeviceInfo->bWindowed;
- break;
- }
- }
-
- // Try again, this time with the reference rasterizer
- if( pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice].DeviceType ==
- D3DDEVTYPE_REF )
- {
- // Make sure main window isn't topmost, so error message is visible
- SetWindowPos( m_hWnd, HWND_NOTOPMOST,
- m_rcWindowBounds.left, m_rcWindowBounds.top,
- ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
- ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
- SWP_SHOWWINDOW );
- AdjustWindowForChange();
-
- // Let the user know we are switching from HAL to the reference rasterizer
- DisplayErrorMsg( hr, MSGWARN_SWITCHEDTOREF );
-
- hr = Initialize3DEnvironment();
- }
- }
-
- return hr;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::Resize3DEnvironment()
- {
- HRESULT hr;
-
- // Release all vidmem objects
- if( FAILED( hr = InvalidateDeviceObjects() ) )
- return hr;
-
- // Reset the device
- if( FAILED( hr = m_pd3dDevice->Reset( &m_d3dpp ) ) )
- return hr;
-
- // Store render target surface desc
- LPDIRECT3DSURFACE8 pBackBuffer;
- m_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
- pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
- pBackBuffer->Release();
-
- // Set up the fullscreen cursor
- if( m_bShowCursorWhenFullscreen && !m_bWindowed )
- {
- HCURSOR hCursor;
- #ifdef _WIN64
- hCursor = (HCURSOR)GetClassLongPtr( m_hWnd, GCLP_HCURSOR );
- #else
- hCursor = (HCURSOR)GetClassLong( m_hWnd, GCL_HCURSOR );
- #endif
- D3DUtil_SetDeviceCursor( m_pd3dDevice, hCursor, TRUE );
- m_pd3dDevice->ShowCursor( TRUE );
- }
-
- // Confine cursor to fullscreen window
- if( m_bClipCursorWhenFullscreen )
- {
- if (!m_bWindowed )
- {
- RECT rcWindow;
- GetWindowRect( m_hWnd, &rcWindow );
- ClipCursor( &rcWindow );
- }
- else
- {
- ClipCursor( NULL );
- }
- }
-
- // Initialize the app's device-dependent objects
- hr = RestoreDeviceObjects();
- if( FAILED(hr) )
- return hr;
-
- // If the app is paused, trigger the rendering of the current frame
- if( FALSE == m_bFrameMoving )
- {
- m_bSingleStep = TRUE;
- DXUtil_Timer( TIMER_START );
- DXUtil_Timer( TIMER_STOP );
- }
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: ToggleFullScreen()
- // Desc: Called when user toggles between fullscreen mode and windowed mode
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::ToggleFullscreen()
- {
- // Get access to current adapter, device, and mode
- D3DAdapterInfo* pAdapterInfo = &m_Adapters[m_dwAdapter];
- D3DDeviceInfo* pDeviceInfo = &pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice];
- D3DModeInfo* pModeInfo = &pDeviceInfo->modes[pDeviceInfo->dwCurrentMode];
-
- // Need device change if going windowed and the current device
- // can only be fullscreen
- if( !m_bWindowed && !pDeviceInfo->bCanDoWindowed )
- return ForceWindowed();
-
- m_bReady = FALSE;
-
- // Toggle the windowed state
- m_bWindowed = !m_bWindowed;
- pDeviceInfo->bWindowed = m_bWindowed;
-
- // Prepare window for windowed/fullscreen change
- AdjustWindowForChange();
-
- // Set up the presentation parameters
- m_d3dpp.Windowed = pDeviceInfo->bWindowed;
- if( m_bWindowed )
- m_d3dpp.MultiSampleType = pDeviceInfo->MultiSampleTypeWindowed;
- else
- m_d3dpp.MultiSampleType = pDeviceInfo->MultiSampleTypeFullscreen;
- m_d3dpp.AutoDepthStencilFormat = pModeInfo->DepthStencilFormat;
- m_d3dpp.hDeviceWindow = m_hWnd;
- if( m_bWindowed )
- {
- m_d3dpp.BackBufferWidth = m_rcWindowClient.right - m_rcWindowClient.left;
- m_d3dpp.BackBufferHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
- m_d3dpp.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format;
- }
- else
- {
- m_d3dpp.BackBufferWidth = pModeInfo->Width;
- m_d3dpp.BackBufferHeight = pModeInfo->Height;
- m_d3dpp.BackBufferFormat = pModeInfo->Format;
- }
-
- // Resize the 3D device
- if( FAILED( Resize3DEnvironment() ) )
- {
- if( m_bWindowed )
- return ForceWindowed();
- else
- return E_FAIL;
- }
-
- // When moving from fullscreen to windowed mode, it is important to
- // adjust the window size after resetting the device rather than
- // beforehand to ensure that you get the window size you want. For
- // example, when switching from 640x480 fullscreen to windowed with
- // a 1000x600 window on a 1024x768 desktop, it is impossible to set
- // the window size to 1000x600 until after the display mode has
- // changed to 1024x768, because windows cannot be larger than the
- // desktop.
- if( m_bWindowed )
- {
- SetWindowPos( m_hWnd, HWND_NOTOPMOST,
- m_rcWindowBounds.left, m_rcWindowBounds.top,
- ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
- ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
- SWP_SHOWWINDOW );
- }
-
- m_bReady = TRUE;
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: ForceWindowed()
- // Desc: Switch to a windowed mode, even if that means picking a new device
- // and/or adapter
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::ForceWindowed()
- {
- HRESULT hr;
- D3DAdapterInfo* pAdapterInfoCur = &m_Adapters[m_dwAdapter];
- D3DDeviceInfo* pDeviceInfoCur = &pAdapterInfoCur->devices[pAdapterInfoCur->dwCurrentDevice];
- BOOL bFoundDevice = FALSE;
-
- if( pDeviceInfoCur->bCanDoWindowed )
- {
- bFoundDevice = TRUE;
- }
- else
- {
- // Look for a windowable device on any adapter
- D3DAdapterInfo* pAdapterInfo;
- DWORD dwAdapter;
- D3DDeviceInfo* pDeviceInfo;
- DWORD dwDevice;
- for( dwAdapter = 0; dwAdapter < m_dwNumAdapters; dwAdapter++ )
- {
- pAdapterInfo = &m_Adapters[dwAdapter];
- for( dwDevice = 0; dwDevice < pAdapterInfo->dwNumDevices; dwDevice++ )
- {
- pDeviceInfo = &pAdapterInfo->devices[dwDevice];
- if( pDeviceInfo->bCanDoWindowed )
- {
- m_dwAdapter = dwAdapter;
- pDeviceInfoCur = pDeviceInfo;
- pAdapterInfo->dwCurrentDevice = dwDevice;
- bFoundDevice = TRUE;
- break;
- }
- }
- if( bFoundDevice )
- break;
- }
- }
-
- if( !bFoundDevice )
- return E_FAIL;
-
- pDeviceInfoCur->bWindowed = TRUE;
- m_bWindowed = TRUE;
-
- // Now destroy the current 3D device objects, then reinitialize
-
- m_bReady = FALSE;
-
- // Release all scene objects that will be re-created for the new device
- InvalidateDeviceObjects();
- DeleteDeviceObjects();
-
- // Release display objects, so a new device can be created
- if( m_pd3dDevice->Release() > 0L )
- return DisplayErrorMsg( D3DAPPERR_NONZEROREFCOUNT, MSGERR_APPMUSTEXIT );
-
- // Create the new device
- if( FAILED( hr = Initialize3DEnvironment() ) )
- return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
- m_bReady = TRUE;
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: AdjustWindowForChange()
- // Desc: Prepare the window for a possible change between windowed mode and
- // fullscreen mode. This function is virtual and thus can be overridden
- // to provide different behavior, such as switching to an entirely
- // different window for fullscreen mode (as in the MFC sample apps).
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::AdjustWindowForChange()
- {
- if( m_bWindowed )
- {
- // Set windowed-mode style
- SetWindowLong( m_hWnd, GWL_STYLE, m_dwWindowStyle );
- if( m_hMenu != NULL )
- SetMenu( m_hWnd, m_hMenu );
- }
- else
- {
- // Set fullscreen-mode style
- SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );
- m_hMenu = (HMENU)SetMenu( m_hWnd, NULL );
- }
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: UserSelectNewDevice()
- // Desc: Displays a dialog so the user can select a new adapter, device, or
- // display mode, and then recreates the 3D environment if needed
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::UserSelectNewDevice()
- {
- HRESULT hr;
-
- // Can't display dialogs in fullscreen mode
- if( m_bWindowed == FALSE )
- {
- if( FAILED( ToggleFullscreen() ) )
- {
- DisplayErrorMsg( D3DAPPERR_RESIZEFAILED, MSGERR_APPMUSTEXIT );
- return E_FAIL;
- }
- }
-
- // Prompt the user to change the mode
- if( IDOK != DialogBoxParam( (HINSTANCE)GetModuleHandle(NULL),
- MAKEINTRESOURCE(IDD_SELECTDEVICE), m_hWnd,
- SelectDeviceProc, (LPARAM)this ) )
- return S_OK;
-
- // Get access to the newly selected adapter, device, and mode
- DWORD dwDevice;
- dwDevice = m_Adapters[m_dwAdapter].dwCurrentDevice;
- m_bWindowed = m_Adapters[m_dwAdapter].devices[dwDevice].bWindowed;
-
- // Release all scene objects that will be re-created for the new device
- InvalidateDeviceObjects();
- DeleteDeviceObjects();
-
- // Release display objects, so a new device can be created
- if( m_pd3dDevice->Release() > 0L )
- return DisplayErrorMsg( D3DAPPERR_NONZEROREFCOUNT, MSGERR_APPMUSTEXIT );
-
- // Inform the display class of the change. It will internally
- // re-create valid surfaces, a d3ddevice, etc.
- if( FAILED( hr = Initialize3DEnvironment() ) )
- return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
-
- // If the app is paused, trigger the rendering of the current frame
- if( FALSE == m_bFrameMoving )
- {
- m_bSingleStep = TRUE;
- DXUtil_Timer( TIMER_START );
- DXUtil_Timer( TIMER_STOP );
- }
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: SelectDeviceProc()
- // Desc: Windows message handling function for the device select dialog
- //-----------------------------------------------------------------------------
- INT_PTR CALLBACK CD3DApplication::SelectDeviceProc( HWND hDlg, UINT msg,
- WPARAM wParam, LPARAM lParam )
- {
- // Get access to the UI controls
- HWND hwndAdapterList = GetDlgItem( hDlg, IDC_ADAPTER_COMBO );
- HWND hwndDeviceList = GetDlgItem( hDlg, IDC_DEVICE_COMBO );
- HWND hwndFullscreenModeList = GetDlgItem( hDlg, IDC_FULLSCREENMODES_COMBO );
- HWND hwndWindowedRadio = GetDlgItem( hDlg, IDC_WINDOW );
- HWND hwndFullscreenRadio = GetDlgItem( hDlg, IDC_FULLSCREEN );
- HWND hwndMultiSampleList = GetDlgItem( hDlg, IDC_MULTISAMPLE_COMBO );
- BOOL bUpdateDlgControls = FALSE;
-
- // Static state for adapter/device/mode selection
- static CD3DApplication* pd3dApp;
- static DWORD dwOldAdapter, dwNewAdapter;
- static DWORD dwOldDevice, dwNewDevice;
- static DWORD dwOldMode, dwNewMode;
- static BOOL bOldWindowed, bNewWindowed;
- static D3DMULTISAMPLE_TYPE OldMultiSampleTypeWindowed, NewMultiSampleTypeWindowed;
- static D3DMULTISAMPLE_TYPE OldMultiSampleTypeFullscreen, NewMultiSampleTypeFullscreen;
-
- // Working variables
- D3DAdapterInfo* pAdapter;
- D3DDeviceInfo* pDevice;
-
- // Handle the initialization message
- if( WM_INITDIALOG == msg )
- {
- // Old state
- pd3dApp = (CD3DApplication*)lParam;
- dwOldAdapter = pd3dApp->m_dwAdapter;
- pAdapter = &pd3dApp->m_Adapters[dwOldAdapter];
-
- dwOldDevice = pAdapter->dwCurrentDevice;
- pDevice = &pAdapter->devices[dwOldDevice];
-
- dwOldMode = pDevice->dwCurrentMode;
- bOldWindowed = pDevice->bWindowed;
- OldMultiSampleTypeWindowed = pDevice->MultiSampleTypeWindowed;
- OldMultiSampleTypeFullscreen = pDevice->MultiSampleTypeFullscreen;
-
- // New state is initially the same as the old state
- dwNewAdapter = dwOldAdapter;
- dwNewDevice = dwOldDevice;
- dwNewMode = dwOldMode;
- bNewWindowed = bOldWindowed;
- NewMultiSampleTypeWindowed = OldMultiSampleTypeWindowed;
- NewMultiSampleTypeFullscreen = OldMultiSampleTypeFullscreen;
-
- // Set flag to update dialog controls below
- bUpdateDlgControls = TRUE;
- }
-
- if( WM_COMMAND == msg )
- {
- // Get current UI state
- bNewWindowed = Button_GetCheck( hwndWindowedRadio );
-
- if( IDOK == LOWORD(wParam) )
- {
- // Handle the case when the user hits the OK button. Check if any
- // of the options were changed
- if( dwNewAdapter != dwOldAdapter || dwNewDevice != dwOldDevice ||
- dwNewMode != dwOldMode || bNewWindowed != bOldWindowed ||
- NewMultiSampleTypeWindowed != OldMultiSampleTypeWindowed ||
- NewMultiSampleTypeFullscreen != OldMultiSampleTypeFullscreen )
- {
- pd3dApp->m_dwAdapter = dwNewAdapter;
-
- pAdapter = &pd3dApp->m_Adapters[dwNewAdapter];
- pAdapter->dwCurrentDevice = dwNewDevice;
-
- pAdapter->devices[dwNewDevice].dwCurrentMode = dwNewMode;
- pAdapter->devices[dwNewDevice].bWindowed = bNewWindowed;
- pAdapter->devices[dwNewDevice].MultiSampleTypeWindowed = NewMultiSampleTypeWindowed;
- pAdapter->devices[dwNewDevice].MultiSampleTypeFullscreen = NewMultiSampleTypeFullscreen;
-
- EndDialog( hDlg, IDOK );
- }
- else
- EndDialog( hDlg, IDCANCEL );
-
- return TRUE;
- }
- else if( IDCANCEL == LOWORD(wParam) )
- {
- // Handle the case when the user hits the Cancel button
- EndDialog( hDlg, IDCANCEL );
- return TRUE;
- }
- else if( CBN_SELENDOK == HIWORD(wParam) )
- {
- if( LOWORD(wParam) == IDC_ADAPTER_COMBO )
- {
- dwNewAdapter = ComboBox_GetCurSel( hwndAdapterList );
- pAdapter = &pd3dApp->m_Adapters[dwNewAdapter];
-
- dwNewDevice = pAdapter->dwCurrentDevice;
- dwNewMode = pAdapter->devices[dwNewDevice].dwCurrentMode;
- bNewWindowed = pAdapter->devices[dwNewDevice].bWindowed;
- }
- else if( LOWORD(wParam) == IDC_DEVICE_COMBO )
- {
- pAdapter = &pd3dApp->m_Adapters[dwNewAdapter];
-
- dwNewDevice = ComboBox_GetCurSel( hwndDeviceList );
- dwNewMode = pAdapter->devices[dwNewDevice].dwCurrentMode;
- bNewWindowed = pAdapter->devices[dwNewDevice].bWindowed;
- }
- else if( LOWORD(wParam) == IDC_FULLSCREENMODES_COMBO )
- {
- dwNewMode = ComboBox_GetCurSel( hwndFullscreenModeList );
- }
- else if( LOWORD(wParam) == IDC_MULTISAMPLE_COMBO )
- {
- DWORD dwItem = ComboBox_GetCurSel( hwndMultiSampleList );
- if( bNewWindowed )
- NewMultiSampleTypeWindowed = (D3DMULTISAMPLE_TYPE)ComboBox_GetItemData( hwndMultiSampleList, dwItem );
- else
- NewMultiSampleTypeFullscreen = (D3DMULTISAMPLE_TYPE)ComboBox_GetItemData( hwndMultiSampleList, dwItem );
- }
- }
- // Keep the UI current
- bUpdateDlgControls = TRUE;
- }
-
- // Update the dialog controls
- if( bUpdateDlgControls )
- {
- // Reset the content in each of the combo boxes
- ComboBox_ResetContent( hwndAdapterList );
- ComboBox_ResetContent( hwndDeviceList );
- ComboBox_ResetContent( hwndFullscreenModeList );
- ComboBox_ResetContent( hwndMultiSampleList );
-
- pAdapter = &pd3dApp->m_Adapters[dwNewAdapter];
- pDevice = &pAdapter->devices[dwNewDevice];
-
- // Add a list of adapters to the adapter combo box
- for( DWORD a=0; a < pd3dApp->m_dwNumAdapters; a++ )
- {
- // Add device name to the combo box
- DWORD dwItem = ComboBox_AddString( hwndAdapterList,
- pd3dApp->m_Adapters[a].d3dAdapterIdentifier.Description );
-
- // Set the item data to identify this adapter
- ComboBox_SetItemData( hwndAdapterList, dwItem, a );
-
- // Set the combobox selection on the current adapater
- if( a == dwNewAdapter )
- ComboBox_SetCurSel( hwndAdapterList, dwItem );
- }
-
- // Add a list of devices to the device combo box
- for( DWORD d=0; d < pAdapter->dwNumDevices; d++ )
- {
- // Add device name to the combo box
- DWORD dwItem = ComboBox_AddString( hwndDeviceList,
- pAdapter->devices[d].strDesc );
-
- // Set the item data to identify this device
- ComboBox_SetItemData( hwndDeviceList, dwItem, d );
-
- // Set the combobox selection on the current device
- if( d == dwNewDevice )
- ComboBox_SetCurSel( hwndDeviceList, dwItem );
- }
-
- // Add a list of modes to the mode combo box
- for( DWORD m=0; m < pDevice->dwNumModes; m++ )
- {
- DWORD BitDepth = 16;
- if( pDevice->modes[m].Format == D3DFMT_X8R8G8B8 ||
- pDevice->modes[m].Format == D3DFMT_A8R8G8B8 ||
- pDevice->modes[m].Format == D3DFMT_R8G8B8 )
- {
- BitDepth = 32;
- }
-
- // Add mode desc to the combo box
- TCHAR strMode[80];
- _stprintf( strMode, _T("%ld x %ld x %ld"), pDevice->modes[m].Width,
- pDevice->modes[m].Height,
- BitDepth );
- DWORD dwItem = ComboBox_AddString( hwndFullscreenModeList, strMode );
-
- // Set the item data to identify this mode
- ComboBox_SetItemData( hwndFullscreenModeList, dwItem, m );
-
- // Set the combobox selection on the current mode
- if( m == dwNewMode )
- ComboBox_SetCurSel( hwndFullscreenModeList, dwItem );
- }
-
- // Add a list of multisample modes to the multisample combo box
- for( m=0; m <= 16; m++ )
- {
- TCHAR strDesc[50];
-
- D3DFORMAT fmt;
- if( bNewWindowed )
- fmt = pd3dApp->m_Adapters[dwNewAdapter].d3ddmDesktop.Format;
- else
- fmt = pDevice->modes[dwNewMode].Format;
-
- if ( m == 1 ) // 1 is not a valid multisample type
- continue;
-
- if( SUCCEEDED( pd3dApp->m_pD3D->CheckDeviceMultiSampleType( dwNewAdapter,
- pDevice->DeviceType, fmt, bNewWindowed, (D3DMULTISAMPLE_TYPE)m ) ) )
- {
- if( m == 0 )
- lstrcpy( strDesc, _T("none") );
- else
- wsprintf( strDesc, _T("%d samples"), m );
-
- // Add device name to the combo box
- DWORD dwItem = ComboBox_AddString( hwndMultiSampleList, strDesc );
-
- // Set the item data to identify this multisample type
- ComboBox_SetItemData( hwndMultiSampleList, dwItem, m );
-
- // Set the combobox selection on the current multisample type
- if( bNewWindowed )
- {
- if( (D3DMULTISAMPLE_TYPE)m == NewMultiSampleTypeWindowed || m == 0 )
- ComboBox_SetCurSel( hwndMultiSampleList, dwItem );
- }
- else
- {
- if( (D3DMULTISAMPLE_TYPE)m == NewMultiSampleTypeFullscreen || m == 0 )
- ComboBox_SetCurSel( hwndMultiSampleList, dwItem );
- }
- }
- }
- DWORD dwItem = ComboBox_GetCurSel( hwndMultiSampleList );
- if( bNewWindowed )
- NewMultiSampleTypeWindowed = (D3DMULTISAMPLE_TYPE)ComboBox_GetItemData( hwndMultiSampleList, dwItem );
- else
- NewMultiSampleTypeFullscreen = (D3DMULTISAMPLE_TYPE)ComboBox_GetItemData( hwndMultiSampleList, dwItem );
- EnableWindow( hwndMultiSampleList, ComboBox_GetCount( hwndMultiSampleList ) > 1);
- EnableWindow( hwndWindowedRadio, pDevice->bCanDoWindowed );
-
- if( bNewWindowed )
- {
- Button_SetCheck( hwndWindowedRadio, TRUE );
- Button_SetCheck( hwndFullscreenRadio, FALSE );
- EnableWindow( hwndFullscreenModeList, FALSE );
- }
- else
- {
- Button_SetCheck( hwndWindowedRadio, FALSE );
- Button_SetCheck( hwndFullscreenRadio, TRUE );
- EnableWindow( hwndFullscreenModeList, TRUE );
- }
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: Run()
- // Desc:
- //-----------------------------------------------------------------------------
- INT CD3DApplication::Run()
- {
- // Load keyboard accelerators
- HACCEL hAccel = LoadAccelerators( NULL, MAKEINTRESOURCE(IDR_MAIN_ACCEL) );
-
- // Now we're ready to recieve and process Windows messages.
- BOOL bGotMsg;
- MSG msg;
- msg.message = WM_NULL;
- PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
-
- while( WM_QUIT != msg.message )
- {
- // Use PeekMessage() if the app is active, so we can use idle time to
- // render the scene. Else, use GetMessage() to avoid eating CPU time.
- if( m_bActive )
- bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );
- else
- bGotMsg = GetMessage( &msg, NULL, 0U, 0U );
-
- if( bGotMsg )
- {
- // Translate and dispatch the message
- if( 0 == TranslateAccelerator( m_hWnd, hAccel, &msg ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- }
- else
- {
- // Render a frame during idle time (no messages are waiting)
- if( m_bActive && m_bReady )
- {
- if( FAILED( Render3DEnvironment() ) )
- SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
- }
- }
- }
-
- return (INT)msg.wParam;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: Render3DEnvironment()
- // Desc: Draws the scene.
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::Render3DEnvironment()
- {
- HRESULT hr;
-
- // Test the cooperative level to see if it's okay to render
- if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) )
- {
- // If the device was lost, do not render until we get it back
- if( D3DERR_DEVICELOST == hr )
- return S_OK;
-
- // Check if the device needs to be resized.
- if( D3DERR_DEVICENOTRESET == hr )
- {
- // If we are windowed, read the desktop mode and use the same format for
- // the back buffer
- if( m_bWindowed )
- {
- D3DAdapterInfo* pAdapterInfo = &m_Adapters[m_dwAdapter];
- m_pD3D->GetAdapterDisplayMode( m_dwAdapter, &pAdapterInfo->d3ddmDesktop );
- m_d3dpp.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format;
- }
-
- if( FAILED( hr = Resize3DEnvironment() ) )
- return hr;
- }
- return hr;
- }
-
- // Get the app's time, in seconds. Skip rendering if no time elapsed
- FLOAT fAppTime = DXUtil_Timer( TIMER_GETAPPTIME );
- FLOAT fElapsedAppTime = DXUtil_Timer( TIMER_GETELAPSEDTIME );
- if( ( 0.0f == fElapsedAppTime ) && m_bFrameMoving )
- return S_OK;
-
- // FrameMove (animate) the scene
- if( m_bFrameMoving || m_bSingleStep )
- {
- // Store the time for the app
- m_fTime = fAppTime;
- m_fElapsedTime = fElapsedAppTime;
-
- // Frame move the scene
- if( FAILED( hr = FrameMove() ) )
- return hr;
-
- m_bSingleStep = FALSE;
- }
-
- // Render the scene as normal
- if( FAILED( hr = Render() ) )
- return hr;
-
- // Keep track of the frame count
- {
- static FLOAT fLastTime = 0.0f;
- static DWORD dwFrames = 0L;
- FLOAT fTime = DXUtil_Timer( TIMER_GETABSOLUTETIME );
- ++dwFrames;
-
- // Update the scene stats once per second
- if( fTime - fLastTime > 1.0f )
- {
- m_fFPS = dwFrames / (fTime - fLastTime);
- fLastTime = fTime;
- dwFrames = 0L;
-
- // Get adapter's current mode so we can report
- // bit depth (back buffer depth may be unknown)
- D3DDISPLAYMODE mode;
- m_pD3D->GetAdapterDisplayMode(m_dwAdapter, &mode);
-
- _stprintf( m_strFrameStats, _T("%.02f fps (%dx%dx%d)"), m_fFPS,
- m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height,
- mode.Format==D3DFMT_X8R8G8B8?32:16 );
- D3DAdapterInfo* pAdapterInfo = &m_Adapters[m_dwAdapter];
- D3DDeviceInfo* pDeviceInfo = &pAdapterInfo->devices[pAdapterInfo->dwCurrentDevice];
- D3DModeInfo* pModeInfo = &pDeviceInfo->modes[pDeviceInfo->dwCurrentMode];
- if( m_bUseDepthBuffer )
- {
-
- switch( pModeInfo->DepthStencilFormat )
- {
- case D3DFMT_D16:
- lstrcat( m_strFrameStats, _T(" (D16)") );
- break;
- case D3DFMT_D15S1:
- lstrcat( m_strFrameStats, _T(" (D15S1)") );
- break;
- case D3DFMT_D24X8:
- lstrcat( m_strFrameStats, _T(" (D24X8)") );
- break;
- case D3DFMT_D24S8:
- lstrcat( m_strFrameStats, _T(" (D24S8)") );
- break;
- case D3DFMT_D24X4S4:
- lstrcat( m_strFrameStats, _T(" (D24X4S4)") );
- break;
- case D3DFMT_D32:
- lstrcat( m_strFrameStats, _T(" (D32)") );
- break;
- }
- }
-
- D3DMULTISAMPLE_TYPE MultiSampleType;
- if( m_bWindowed )
- MultiSampleType = pDeviceInfo->MultiSampleTypeWindowed;
- else
- MultiSampleType = pDeviceInfo->MultiSampleTypeFullscreen;
- switch( MultiSampleType )
- {
- case D3DMULTISAMPLE_2_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (2x Multisample)") );
- break;
- case D3DMULTISAMPLE_3_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (3x Multisample)") );
- break;
- case D3DMULTISAMPLE_4_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (4x Multisample)") );
- break;
- case D3DMULTISAMPLE_5_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (5x Multisample)") );
- break;
- case D3DMULTISAMPLE_6_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (6x Multisample)") );
- break;
- case D3DMULTISAMPLE_7_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (7x Multisample)") );
- break;
- case D3DMULTISAMPLE_8_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (8x Multisample)") );
- break;
- case D3DMULTISAMPLE_9_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (9x Multisample)") );
- break;
- case D3DMULTISAMPLE_10_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (10x Multisample)") );
- break;
- case D3DMULTISAMPLE_11_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (11x Multisample)") );
- break;
- case D3DMULTISAMPLE_12_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (12x Multisample)") );
- break;
- case D3DMULTISAMPLE_13_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (13x Multisample)") );
- break;
- case D3DMULTISAMPLE_14_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (14x Multisample)") );
- break;
- case D3DMULTISAMPLE_15_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (15x Multisample)") );
- break;
- case D3DMULTISAMPLE_16_SAMPLES:
- lstrcat( m_strFrameStats, _T(" (16x Multisample)") );
- break;
- }
- }
- }
-
- // Show the frame on the primary surface.
- m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: Pause()
- // Desc: Called in to toggle the pause state of the app.
- //-----------------------------------------------------------------------------
- VOID CD3DApplication::Pause( BOOL bPause )
- {
- static DWORD dwAppPausedCount = 0L;
-
- dwAppPausedCount += ( bPause ? +1 : -1 );
- m_bReady = ( dwAppPausedCount ? FALSE : TRUE );
-
- // Handle the first pause request (of many, nestable pause requests)
- if( bPause && ( 1 == dwAppPausedCount ) )
- {
- // Stop the scene from animating
- if( m_bFrameMoving )
- DXUtil_Timer( TIMER_STOP );
- }
-
- if( 0 == dwAppPausedCount )
- {
- // Restart the timers
- if( m_bFrameMoving )
- DXUtil_Timer( TIMER_START );
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: Cleanup3DEnvironment()
- // Desc: Cleanup scene objects
- //-----------------------------------------------------------------------------
- VOID CD3DApplication::Cleanup3DEnvironment()
- {
- m_bActive = FALSE;
- m_bReady = FALSE;
-
- if( m_pd3dDevice )
- {
- InvalidateDeviceObjects();
- DeleteDeviceObjects();
-
- m_pd3dDevice->Release();
- m_pD3D->Release();
-
- m_pd3dDevice = NULL;
- m_pD3D = NULL;
- }
-
- FinalCleanup();
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: DisplayErrorMsg()
- // Desc: Displays error messages in a message box
- //-----------------------------------------------------------------------------
- HRESULT CD3DApplication::DisplayErrorMsg( HRESULT hr, DWORD dwType )
- {
- TCHAR strMsg[512];
-
- switch( hr )
- {
- case D3DAPPERR_NODIRECT3D:
- _tcscpy( strMsg, _T("Could not initialize Direct3D. You may\n")
- _T("want to check that the latest version of\n")
- _T("DirectX is correctly installed on your\n")
- _T("system. Also make sure that this program\n")
- _T("was compiled with header files that match\n")
- _T("the installed DirectX DLLs.") );
- break;
-
- case D3DAPPERR_NOCOMPATIBLEDEVICES:
- _tcscpy( strMsg, _T("Could not find any compatible Direct3D\n")
- _T("devices.") );
- break;
-
- case D3DAPPERR_NOWINDOWABLEDEVICES:
- _tcscpy( strMsg, _T("This sample cannot run in a desktop\n")
- _T("window with the current display settings.\n")
- _T("Please change your desktop settings to a\n")
- _T("16- or 32-bit display mode and re-run this\n")
- _T("sample.") );
- break;
-
- case D3DAPPERR_NOHARDWAREDEVICE:
- _tcscpy( strMsg, _T("No hardware-accelerated Direct3D devices\n")
- _T("were found.") );
- break;
-
- case D3DAPPERR_HALNOTCOMPATIBLE:
- _tcscpy( strMsg, _T("This sample requires functionality that is\n")
- _T("not available on your Direct3D hardware\n")
- _T("accelerator.") );
- break;
-
- case D3DAPPERR_NOWINDOWEDHAL:
- _tcscpy( strMsg, _T("Your Direct3D hardware accelerator cannot\n")
- _T("render into a window.\n")
- _T("Press F2 while the app is running to see a\n")
- _T("list of available devices and modes.") );
- break;
-
- case D3DAPPERR_NODESKTOPHAL:
- _tcscpy( strMsg, _T("Your Direct3D hardware accelerator cannot\n")
- _T("render into a window with the current\n")
- _T("desktop display settings.\n")
- _T("Press F2 while the app is running to see a\n")
- _T("list of available devices and modes.") );
- break;
-
- case D3DAPPERR_NOHALTHISMODE:
- _tcscpy( strMsg, _T("This sample requires functionality that is\n")
- _T("not available on your Direct3D hardware\n")
- _T("accelerator with the current desktop display\n")
- _T("settings.\n")
- _T("Press F2 while the app is running to see a\n")
- _T("list of available devices and modes.") );
- break;
-
- case D3DAPPERR_MEDIANOTFOUND:
- _tcscpy( strMsg, _T("Could not load required media." ) );
- break;
-
- case D3DAPPERR_RESIZEFAILED:
- _tcscpy( strMsg, _T("Could not reset the Direct3D device." ) );
- break;
-
- case D3DAPPERR_NONZEROREFCOUNT:
- _tcscpy( strMsg, _T("A D3D object has a non-zero reference\n")
- _T("count (meaning things were not properly\n")
- _T("cleaned up).") );
- break;
-
- case D3DAPPERR_NULLREFDEVICE:
- _tcscpy( strMsg, _T("Warning: Nothing will be rendered.\n")
- _T("The reference rendering device was selected, but your\n")
- _T("computer only has a reduced-functionality reference device\n")
- _T("installed. Install the DirectX SDK to get the full\n")
- _T("reference device.\n") );
- break;
-
- case E_OUTOFMEMORY:
- _tcscpy( strMsg, _T("Not enough memory.") );
- break;
-
- case D3DERR_OUTOFVIDEOMEMORY:
- _tcscpy( strMsg, _T("Not enough video memory.") );
- break;
-
- default:
- _tcscpy( strMsg, _T("Generic application error. Enable\n")
- _T("debug output for detailed information.") );
- }
-
- if( MSGERR_APPMUSTEXIT == dwType )
- {
- _tcscat( strMsg, _T("\n\nThis sample will now exit.") );
- MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONERROR|MB_OK );
-
- // Close the window, which shuts down the app
- if( m_hWnd )
- SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
- }
- else
- {
- if( MSGWARN_SWITCHEDTOREF == dwType )
- _tcscat( strMsg, _T("\n\nSwitching to the reference rasterizer,\n")
- _T("a software device that implements the entire\n")
- _T("Direct3D feature set, but runs very slowly.") );
- MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONWARNING|MB_OK );
- }
-
- return hr;
- }
-
-
-
-
-