|
|
HRESULT CD3DApplication::BuildDeviceList()
{
const DWORD dwNumDeviceTypes = 3;
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, 0, &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 ,D3DFMT_X8R8G8B8);
// 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,D3DFMT_X8R8G8B8, 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;
// yuexiae 抗锯齿
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;
}
}
}
}
// gth config setting
if( !g_userConfig.isLoaded )
{
if( pDevice->d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{
memcpy( &g_userConfig, &g_highQualityConfig, sizeof( gthconfig_t ) );
}
else
{
memcpy( &g_userConfig, &g_lowQualityConfig, sizeof( gthconfig_t ) );
}
}
// 秦惑档 函版
// Select any 640x480 mode for default (but prefer a 16-bit mode)
for( m=0; m<pDevice->dwNumModes; m++ )
{
unsigned int width = 1024, height = 768;
// 0 : 800x600
if( g_userConfig.resoution == 0 )
{
width = 800;
height = 600;
}
// 1 : 1024x768
else if( g_userConfig.resoution == 1 )
{
width = 1024;
height = 768;
}
// 2 : 1280x1024
else if( g_userConfig.resoution == 2 )
{
width = 1280;
height = 1024;
}
// 3 :1660x1200
else if( g_userConfig.resoution == 3 )
{
width = 1600;
height = 1200;
}
// 4: 1440x900
else if( g_userConfig.resoution == 4 )
{
width = 1440;
height = 900;
}
// 5 : 1680x1050
else if( g_userConfig.resoution == 5 )
{
width = 1680;
height = 1050;
}
if( pDevice->modes[m].Width == width && pDevice->modes[m].Height == height )
{
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_CANAUTOGENMIPMAP*/) )
{
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;
}
运行返回 D3DAPPERR_NOWINDOWABLEDEVICES
Could not find any compatible Direct3D
[em24] [em24] [em24] [em24] |
|