📄 xd3d.cpp
字号:
pdc->DevType == D3DDEVTYPE_HAL &&
pdcBest->DevType != D3DDEVTYPE_HAL;
bBest = pdc->DevType == D3DDEVTYPE_HAL &&
pdc->BackBufferFormat == pdc->DisplayFormat;
bBetter |= bBest;
if (bBetter)
{
// save it as the current best
paiBest = pai;
pdiBest = pdi;
pdcBest = pdc;
// this dc looks great -- take it
if (bBest)
goto DoneSearchingWDC;
}
}
}
}
DoneSearchingWDC:
// none found!!
if (pdcBest == NULL)
return false;
Settings.Windowed = 1;
Settings.AdapterInfos[1] = paiBest;
int l = paiBest->DisplayModes.Find(dm);
// for some bizarre multi-monitor setups in which the primary adapter's
// current dm is not available in a secondary one, there's nothing else
// we can do...
if (i > 0 && l == -1)
return false;
// index to the best dm within the ai
Settings.ndm[1] = l;
// indices to the best di and dc
if (bBest)
{
Settings.ndi[1] = j;
Settings.ndc[1] = k;
}
else
{
// retract to the 'better' di and dc
Settings.ndi[1] = (UINT)paiBest->DeviceInfos.Find(*pdiBest);
Settings.ndc[1] = (UINT)pdiBest->DeviceCombos.Find(*pdcBest);
}
return true;
}
//-----------------------------------------------------------------------------
// ChooseInitialSettings(): according to the best mode founds and app settings
//-----------------------------------------------------------------------------
HRESULT CXD3D::ChooseInitialSettings()
{
bool bFoundFullscreen = FindBestFullscreenMode(false, false);
bool bFoundWindowed = FindBestWindowedMode(false, false);
if (m_bStartFullscreen && bFoundFullscreen)
Settings.Windowed = 0;
if (!bFoundWindowed && bFoundFullscreen)
Settings.Windowed = 0;
if (!bFoundFullscreen && !bFoundWindowed)
return D3DAPPERR_NOCOMPATIBLEDEVICES;
if (!m_bStartFullscreen && !bFoundWindowed)
return D3DAPPERR_NOCOMPATIBLEDEVICES;
return S_OK;
}
//-----------------------------------------------------------------------------
// HandlePossibleSizeChange(): reset the device if the client area size has
// changed; it will update the window properties, but it will not issue a reset
// unless old and new dimensions differ; a new window size will require a new
// backbuffer size, so the 3D environment must change accordingly.
//-----------------------------------------------------------------------------
HRESULT CXD3D::HandlePossibleSizeChange()
{
if (m_bIgnoreSizeChange)
return S_OK;
HRESULT hr = S_OK;
RECT rcOld = m_rcClient;
GetClientRect(m_hWndRender, &m_rcClient);
// check for client rect changes
if (rcOld.right - rcOld.left != m_rcClient.right - m_rcClient.left ||
rcOld.bottom - rcOld.top != m_rcClient.bottom - m_rcClient.top)
{
Pause(true);
// store the new dims
m_d3dpp.BackBufferWidth = m_rcClient.right - m_rcClient.left;
m_d3dpp.BackBufferHeight = m_rcClient.bottom - m_rcClient.top;
// reset
if (m_pd3dDevice != NULL)
{
if (FAILED(hr = ResetEnvironment()))
{
if (hr != D3DERR_OUTOFVIDEOMEMORY)
hr = D3DAPPERR_RESETFAILED;
DisplayErrorMsg(hr, MSGERR_CANNOTCONTINUE);
}
}
Pause(false);
}
return hr;
}
//-----------------------------------------------------------------------------
// BuildPresentParamsFromSettings(): 'builds' presentation parameters from
// the current settings
//-----------------------------------------------------------------------------
void CXD3D::BuildPresentParamsFromSettings()
{
m_d3dpp.Windowed = Settings.Windowed;
m_d3dpp.hDeviceWindow = m_hWndRender;
m_d3dpp.BackBufferCount = 1;
m_d3dpp.EnableAutoDepthStencil = Enumeration.AppUsesDepthBuffer;
m_d3dpp.MultiSampleType = Settings.GetMSType();
m_d3dpp.MultiSampleQuality = Settings.GetMSQuality();
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_d3dpp.Flags = 0;
if (Enumeration.AppUsesDepthBuffer)
{
m_d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
m_d3dpp.AutoDepthStencilFormat = Settings.GetDSFormat();
}
if (m_bWindowed)
{
m_d3dpp.BackBufferWidth = m_rcClient.right - m_rcClient.left;
m_d3dpp.BackBufferHeight = m_rcClient.bottom - m_rcClient.top;
m_d3dpp.FullScreen_RefreshRateInHz = 0;
}
else
{
m_d3dpp.BackBufferWidth = Settings.GetDisplayMode().Width;
m_d3dpp.BackBufferHeight = Settings.GetDisplayMode().Height;
m_d3dpp.FullScreen_RefreshRateInHz = Settings.GetDisplayMode().RefreshRate;
}
m_d3dpp.BackBufferFormat = Settings.GetBackBufferFormat();
m_d3dpp.PresentationInterval = Settings.GetPresentInterval();
}
//-----------------------------------------------------------------------------
// InitializeEnvironment(): checks for a null REF device, builds presentation
// parameters from settings, instances the d3d device, sets up device stats,
// saves the backbuffer description, sets up the fullscreen cursor and finally
// inits and restores device objects. If the last step fails, it retries, but
// in windowed mode (to display a warning) and the reference rasterizer.
//-----------------------------------------------------------------------------
HRESULT CXD3D::InitializeEnvironment()
{
HRESULT hr;
AdapterInfo* pai = Settings.GetAdapterInfo();
DeviceInfo* pdi = Settings.GetDeviceInfo();
// Warn user about a null REF device that cannot render anything
if (pdi->Caps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE)
DisplayErrorMsg(D3DAPPERR_NULLREFDEVICE, 0);
// translate the VP type to a device creation behavior
switch (Settings.GetVPType())
{
case PURE_VP: m_dwCreateFlags = D3DCREATE_PUREDEVICE;
case HARD_VP: m_dwCreateFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; break;
case MIXD_VP: m_dwCreateFlags = D3DCREATE_MIXED_VERTEXPROCESSING; break;
case SOFT_VP: m_dwCreateFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; break;
default: return E_FAIL;
}
// setup the creation presentation parameters
BuildPresentParamsFromSettings();
// create the device
hr = m_pd3d->CreateDevice(pdi->AdapterOrdinal,
pdi->DevType,
m_hWndRender,
m_dwCreateFlags,
&m_d3dpp,
&m_pd3dDevice);
if (SUCCEEDED(hr))
{
// store the device's description, beginning with type;
lstrcpy(m_strDeviceStats, DEVICETYPESTRING(pdi->DevType, false));
// then VP type, including non-HAL devices simulating hardware VP and
// the pure hardware VP variant...
if ((m_dwCreateFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == 0 &&
pdi->DevType != D3DDEVTYPE_HAL)
lstrcat(m_strDeviceStats, TEXT(" simulated"));
if (m_dwCreateFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
{
if (m_dwCreateFlags & D3DCREATE_PUREDEVICE)
lstrcat(m_strDeviceStats, TEXT(" pure"));
lstrcat(m_strDeviceStats, TEXT(" hardware"));
}
else if (m_dwCreateFlags & D3DCREATE_MIXED_VERTEXPROCESSING)
lstrcat(m_strDeviceStats, TEXT(" mixed"));
else
lstrcat(m_strDeviceStats, TEXT(" software"));
lstrcat(m_strDeviceStats, TEXT(" VP"));
// ...and the adapter's description for HAL devices
if (pdi->DevType == D3DDEVTYPE_HAL)
{
lstrcat(m_strDeviceStats, TEXT(" on "));
// be sure not to overflow m_strDeviceStats when appending
const int nDescription = sizeof(pai->AdapterIdentifier.Description);
TCHAR szDescription[nDescription];
// DX Utils handle unicode somewhat gracefully...
DXUtil_ConvertAnsiStringToGenericCch(szDescription,
pai->AdapterIdentifier.Description,
nDescription);
lstrcat(szDescription, TEXT(" @ "));
// append as many characters as space is left on the stats
_tcsncat(m_strDeviceStats,
szDescription,
UBOUND(m_strDeviceStats) - lstrlen(m_strDeviceStats) - 1);
TCHAR szDims[100];
TCHAR szFmt[100];
TCHAR szDepthFmt[100];
TCHAR* szMS;
_sntprintf(szDims, 100, TEXT("%dx%d, "),
m_d3dpp.BackBufferWidth,
m_d3dpp.BackBufferHeight);
szDims[99] = TEXT('\0');
// append as many characters as space is left on the stats
_tcsncat(m_strDeviceStats, szDims,
UBOUND(m_strDeviceStats) - lstrlen(m_strDeviceStats) - 1);
D3DFORMAT fmt = Settings.GetDisplayMode().Format;
// display format (including the back buffer format if they do not match)
if (fmt == m_d3dpp.BackBufferFormat)
lstrcpyn(szFmt, D3DUtil_D3DFormatToString(fmt, false), 100);
else
_sntprintf(szFmt, 100, TEXT("%s back, %s front"),
D3DUtil_D3DFormatToString(m_d3dpp.BackBufferFormat, false),
D3DUtil_D3DFormatToString(fmt, false));
szFmt[99] = TEXT('\0');
// append as many characters as space is left on the stats
_tcsncat(m_strDeviceStats,
szFmt,
UBOUND(m_strDeviceStats) - lstrlen(m_strDeviceStats) - 1);
// depth/stencil buffer format
if (Enumeration.AppUsesDepthBuffer)
{
_sntprintf(szDepthFmt, 100, TEXT(" (%s)"),
D3DUtil_D3DFormatToString(Settings.GetDSFormat(), false));
szDepthFmt[99] = TEXT('\0');
// append as many characters as space is left on the stats
_tcsncat(m_strDeviceStats,
szDepthFmt,
UBOUND(m_strDeviceStats) - lstrlen(m_strDeviceStats) - 1);
}
// multisampling type (no. of samples or nonmaskable)
szMS = MULTISAMPLESTRING(Settings.GetMSType(), false);
// append as many characters as space is left on the stats
_tcsncat(m_strDeviceStats,
szMS,
UBOUND(m_strDeviceStats) - lstrlen(m_strDeviceStats) - 1);
}
// setup the fullscreen cursor
if (m_bShowCursor && !m_bWindowed)
{
HCURSOR hCursor = (HCURSOR)GetClassLong(m_hWndRender, GCL_HCURSOR);
D3DUtil_SetDeviceCursor(m_pd3dDevice, hCursor, true);
m_pd3dDevice->ShowCursor(true);
}
// confine the cursor to the fullscreen window
if (m_bClipCursor)
ClipCursor(m_bWindowed ? NULL : &m_rcWindow);
// initialize the app's device-dependant objects
if (FAILED(hr = InitDeviceObjects()))
DeleteDeviceObjects();
else
{
m_bDeviceObjectsInited = true;
// restore the app's device-dependant objects
if (FAILED(hr = RestoreDeviceObjects()))
InvalidateDeviceObjects();
else
{
m_bDeviceObjectsRestored = true;
return S_OK;
}
}
// if any of that failed, cleanup before we try again
CleanupEnvironment();
}
// if failure comes strictly from IDirect3D9 we'll try falling back to
// the reference rasterizer; in other words, we'll ignore the error if
// it is a 'file not found' error, because it is not Direct3D's fault,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -