⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xd3d.cpp

📁 MFC+D3D编程:在MFC单文档界面下使用D3D9.0进行编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:

						  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 + -