📄 d3dapp.cpp
字号:
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 )
m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
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
if( m_bFrameMoving )
DXUtil_Timer( TIMER_STOP );
break;
case WM_SIZE:
// Check to see if we are losing our window...
if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
m_bActive = FALSE;
else
m_bActive = TRUE;
break;
case WM_EXITSIZEMOVE:
if( m_bFrameMoving )
DXUtil_Timer( TIMER_START );
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 );
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -