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

📄 xd3d.cpp

📁 MFC+D3D编程:在MFC单文档界面下使用D3D9.0进行编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// XD3D.cpp: custom Direct3D (CXD3D) Implementation file
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "XD3D.h"

//-----------------------------------------------------------------------------
// CXD3D Constructor
//-----------------------------------------------------------------------------
CXD3D::CXD3D()
{
	m_bActive					= false;
	
	m_bStartFullscreen			= false;    
	
	m_bShowCursor = true;
	m_bClipCursor = true;
	
	m_bWindowed					= true;
	m_bIgnoreSizeChange			= false;
	
	m_bDeviceLost				= false;
	m_bDeviceObjectsInited		= false;
	m_bDeviceObjectsRestored	= false;
	
	m_fTime			= 0.0f;
	m_fElapsedTime	= 0.0f;
	m_fFPS			= 0.0f;
	
	m_strDeviceStats[0] = _T('\0');
	m_strFrameStats[0]  = _T('\0');

	m_hWndRender        = NULL;
	m_hWndFocus         = NULL;
	
	m_pd3d              = NULL;
	m_pd3dDevice        = NULL;
	
	m_dwCreateFlags     = 0L;
	
	Pause(true); // until we're ready to render
}

//-----------------------------------------------------------------------------
// CreateD3D(): provided m_hWnd has been initialised, it instantiates the d3d
// object, chooses initial d3d settings and initializes the d3d stuff.
//-----------------------------------------------------------------------------
HRESULT CXD3D::CreateD3D()
{		
	HRESULT hr;

	// check for a window to render to
    if (m_hWndRender == NULL)
        return DisplayErrorMsg(D3DAPPERR_NOWINDOW, MSGERR_CANNOTCONTINUE);
	
	// instantiate a D3D Object
    if ((m_pd3d = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
        return DisplayErrorMsg(D3DAPPERR_NODIRECT3D, MSGERR_CANNOTCONTINUE);

    // build a list of D3D adapters, modes and devices
	if (FAILED(hr = Enumeration.Enumerate(m_pd3d)))
	{
        SAFE_RELEASE(m_pd3d);
        
		return DisplayErrorMsg(hr, MSGERR_CANNOTCONTINUE);
    }

    // use the device window as the focus window, unless otherwise specified
    if (m_hWndFocus == NULL) m_hWndFocus = m_hWndRender;

    // save some window properties into class members
    m_dwWindowStyle = GetWindowLong(m_hWndRender, GWL_STYLE);
    
	GetWindowRect(m_hWndRender, &m_rcWindow);
    GetClientRect(m_hWndRender, &m_rcClient);

    // choose the best settings to render
	if (FAILED(hr = ChooseInitialSettings()))
	{
        SAFE_RELEASE(m_pd3d);
    
		return DisplayErrorMsg(hr, MSGERR_CANNOTCONTINUE);
    }

    // initialize the timer
    DXUtil_Timer(TIMER_START);

    // initialize the app's custom (pre-device creation) stuff
    if (FAILED(hr = OneTimeSceneInit()))
    {
        SAFE_RELEASE(m_pd3d);
        
		return DisplayErrorMsg(hr, MSGERR_CANNOTCONTINUE);
    }

    // initialize the 3D environment, creating the device
    if (FAILED(hr = InitializeEnvironment()))
	{
		SAFE_RELEASE(m_pd3d);
        
		return DisplayErrorMsg(hr, MSGERR_CANNOTCONTINUE);
    }

    // D3D is ready to go so unpause it
    Pause(false);

    return S_OK;
}

//-----------------------------------------------------------------------------
// FindBestFullscreenMode(): Adjust settings with the best available fullscreen
// mode, subject to the HAL and REF constraints; returns false if no such mode
// can be found.
//-----------------------------------------------------------------------------
bool CXD3D::FindBestFullscreenMode(bool bHAL, bool bREF)
{
	// for fullscreen, default to the first HAL device combo that supports the
	// current desktop display mode, to any display mode if HAL is incompatible
	// with the desktop mode, or to a non-HAL if no HAL is available
	D3DDISPLAYMODE dmDesktop;
	D3DDISPLAYMODE dmDesktopBest;
	D3DDISPLAYMODE dmBest;
	
	// fortunately for us, D3DFMT_UNKNOWN == 0
	ZeroMemory(&dmDesktopBest, sizeof(D3DDISPLAYMODE));
	ZeroMemory(&dmBest, sizeof(D3DDISPLAYMODE));
	
	// 'best' storage
	AdapterInfo* paiBest = NULL;
	DeviceInfo*  pdiBest = NULL;
	DeviceCombo* pdcBest = NULL;

	// iterators
	AdapterInfo* pai;
	DeviceInfo*  pdi;
	DeviceCombo* pdc;
				
	// success flags
	bool bBetter, bBest;

	UINT i, j, k;

	// traverse the adpater infos
	for (i = 0; i < Enumeration.AdapterInfos.Length(); i++)
	{
		pai = &Enumeration.AdapterInfos[i];
		
		// get the current display mode of each adapter
		m_pd3d->GetAdapterDisplayMode(pai->AdapterOrdinal, &dmDesktop);
		
		// traverse device infos on each adapter info
		for (j = 0; j < pai->DeviceInfos.Length(); j++)
		{			
			pdi = &pai->DeviceInfos[j];
			
			// skip devices with other than the requested type
			if (bHAL && pdi->DevType != D3DDEVTYPE_HAL)
				continue;
			
			if (bREF && pdi->DevType != D3DDEVTYPE_REF)
				continue;
			
			// traverse device combos for each device info
			for (k = 0; k < pdi->DeviceCombos.Length(); k++)
			{
				pdc = &pdi->DeviceCombos[k];
				
				// skip the windowed combos
				if (pdc->Windowed)
					continue;
				
				// this device combo is 'better' than the current best if:
				//  (a) there's no best yet;
				//  (b) it's a HAL and the current best is not;
				//  (c) it's a HAL matching the desktop's format, while the
				//      current best does not;
				//  (d) it's a HAL and both the display and backbuffer formats
				//      match the desktop's, in which case it is also the best

				bBetter = pdcBest == NULL ||
						  
						  pdc->DevType     == D3DDEVTYPE_HAL &&
						  pdcBest->DevType != D3DDEVTYPE_HAL ||
						  
						  pdc->DevType           == D3DDEVTYPE_HAL &&
						  pdc->DisplayFormat     == dmDesktop.Format &&
						  pdcBest->DisplayFormat != dmDesktop.Format;
						  
				bBest = pdc->DevType          == D3DDEVTYPE_HAL &&
						pdc->DisplayFormat    == dmDesktop.Format &&
						pdc->BackBufferFormat == dmDesktop.Format;

				bBetter |= bBest;

				if (bBetter)
				{
					// make it the best so far
					dmDesktopBest = dmDesktop;
					paiBest = pai;
					pdiBest = pdi;
					pdcBest = pdc;
					
					// this one looks great -- take it
					if (bBest)
						goto DoneSearchingFDC;
				}
			}
		}
	}

DoneSearchingFDC:

	// no suitable dc found!
	if (pdcBest == NULL)
		return false;
	
	// now we need to find a display mode on the best ai that uses the best
	// dc's display format and is as close to the best desktop display mode
	// as possible	
	D3DDISPLAYMODE dm;
		
	for (i = 0; i < paiBest->DisplayModes.Length(); i++)
	{
		dm = paiBest->DisplayModes[i];
		
		// formats must match
		if (dm.Format != dmDesktopBest.Format)
			continue;
		
		// compare other properties
		if (dm.Width	   == dmDesktopBest.Width &&
			dm.Height	   == dmDesktopBest.Height && 
			dm.RefreshRate == dmDesktopBest.RefreshRate)
		{
			// perfect match, break out
			dmBest = dm;
			break;
		}
		else if (dm.Width      == dmDesktopBest.Width &&
			     dm.Height     == dmDesktopBest.Height && 
			     dm.RefreshRate > dmBest.RefreshRate)
		{
			// faster
			dmBest = dm;
		}
		else if (dm.Width == dmDesktopBest.Width)
		{
			// same width
			dmBest = dm;
		}
		else if (dmBest.Width == 0)
		{
			// we don't have anything better yet
			dmBest = dm;
		}
	}
	
	// save these settings
	Settings.Windowed = 0;	
	Settings.AdapterInfos[0] = paiBest;

	// index to the best dm within the ai
	Settings.ndm[0] = paiBest->DisplayModes.Find(dm);

	// indices to the best di and dc
	if (bBest)
	{
		Settings.ndi[0] = j;
		Settings.ndc[0] = k;
	}
	else
	{
		// retract to the 'better' di and dc
		Settings.ndi[0] = (UINT)paiBest->DeviceInfos.Find(*pdiBest);
		Settings.ndc[0] = (UINT)pdiBest->DeviceCombos.Find(*pdcBest);
	}
	
	return true;
}

//-----------------------------------------------------------------------------
// FindBestWindowedMode(): adjusts settings with best available windowed mode,
// subject to the HAL and REF constraints; returns false if no such mode can be
// found.
//-----------------------------------------------------------------------------
bool CXD3D::FindBestWindowedMode(bool bHAL, bool bREF)
{
	// get the display mode of the primary adapter, which is assumed to be
	// where the window will appear
	D3DDISPLAYMODE dm;
	
	m_pd3d->GetAdapterDisplayMode(0, &dm);
	
	// 'best' storage
	AdapterInfo* paiBest = NULL;
	DeviceInfo*  pdiBest = NULL;
	DeviceCombo* pdcBest = NULL;

	// iterators
	AdapterInfo* pai;
	DeviceInfo*  pdi;
	DeviceCombo* pdc;	

	// success flags
	bool bBetter, bBest;

	UINT i, j, k;
	
	// traverse the enumerated adapters information
	for (i = 0; i < Enumeration.AdapterInfos.Length(); i++)
	{
		pai = &Enumeration.AdapterInfos[i];
		
		// for each adapter, traverse the device infos
		for (j = 0; j < pai->DeviceInfos.Length(); j++)
		{
			pdi = &pai->DeviceInfos[j];
			
			// skip according to the requirements
			if (bHAL && pdi->DevType != D3DDEVTYPE_HAL)
				continue;
			
			if (bREF && pdi->DevType != D3DDEVTYPE_REF)
				continue;
			
			// traverse device combos for this device
			for (k = 0; k < pdi->DeviceCombos.Length(); k++)
			{
				pdc = &pdi->DeviceCombos[k];
				
				// skip the non-windowed or distinct format combos
				if (!pdc->Windowed)
					continue;
				
				if (pdc->DisplayFormat != dm.Format)
					continue;
				
				// this device combo is better than the current best if:
				//  (a) there's no best yet;
				//  (b) it's a HAL and the current best is not;
				//  (c) it's a HAL with matching backbuffer and display
				//      formats, in which case is also the best
				bBetter = pdcBest == NULL ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -