📄 d3dapp.cpp
字号:
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 );
}
else
{
// Set fullscreen-mode style
SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );
}
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 OldMultiSampleType, NewMultiSampleType;
// 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;
OldMultiSampleType = pDevice->MultiSampleType;
// New state is initially the same as the old state
dwNewAdapter = dwOldAdapter;
dwNewDevice = dwOldDevice;
dwNewMode = dwOldMode;
bNewWindowed = bOldWindowed;
NewMultiSampleType = OldMultiSampleType;
// 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 ||
NewMultiSampleType != OldMultiSampleType )
{
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].MultiSampleType = NewMultiSampleType;
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 );
NewMultiSampleType = (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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -