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

📄 dx8enumeration.cpp

📁 game code对于游戏地图的编辑代码
💻 CPP
字号:
#include <TChar.h>
#include <stdio.h>
#include "DX8Prerequisites.h"
#include "DX8Enumeration.h"
#include "../../Main/QLogManager.h"

using namespace QGE::VISUAL;

//-----------------------------------------------------------------------------
// Name: SortModesCallback()
// Desc: Callback function for sorting display modes (used by BuildDeviceList).
//-----------------------------------------------------------------------------
static int SortModesCallback( const VOID* arg1, const VOID* arg2 )
{
	D3DDISPLAYMODE* p1 = (D3DDISPLAYMODE*)arg1;
	D3DDISPLAYMODE* p2 = (D3DDISPLAYMODE*)arg2;

	if( p1->Format > p2->Format )   return -1;
	if( p1->Format < p2->Format )   return +1;
	if( p1->Width  < p2->Width )    return -1;
	if( p1->Width  > p2->Width )    return +1;
	if( p1->Height < p2->Height )   return -1;
	if( p1->Height > p2->Height )   return +1;

	return 0;
}


DX8Enumeration::DX8Enumeration(LPDIRECT3D8 pd3d,Bool bDepthStencil,Bool bMixedVP,Int32 minDepthBits,Int32 minStencilBits) :
			m_pd3d(pd3d),
			m_bDepthStencil(bDepthStencil),
			m_bMixedVertexProcessing(bMixedVP),
			m_dwMinDepthBits(minDepthBits),
			m_dwMinStencilBits(minStencilBits),
			m_dwNumAdapters(0)
{
}

HRESULT DX8Enumeration::BuildDeviceList()
{
	if( m_pd3d==NULL )
		return E_FAIL;
	const DWORD dwNumDeviceType = 2;
	const TCHAR* strDeviceDes[] = { _T("HAL"),_T("REF") };
	const D3DDEVTYPE DeviceTypes[] ={ D3DDEVTYPE_HAL, D3DDEVTYPE_REF };

	BOOL bHAL_Exists = FALSE;
	BOOL bHAL_Windowed_Compatible = FALSE;
	BOOL bHAL_Desktop_Compatible = FALSE;
	BOOL bHAL_Sample_Compatible = FALSE;

	for( UINT iAdapterCount=0; iAdapterCount<m_pd3d->GetAdapterCount();++iAdapterCount )
	{
		//填冲Adapter结构
		D3DAdapterInfo* pAdapter = &m_Adapters[m_dwNumAdapters];
		m_pd3d->GetAdapterIdentifier(iAdapterCount,D3DENUM_NO_WHQL_LEVEL,&pAdapter->d3dAdapterIdentifier);
		m_pd3d->GetAdapterDisplayMode(iAdapterCount,&pAdapter->d3ddmDesktop);
		pAdapter->dwNumDevices = 0;
		pAdapter->dwCurrentDevice = 0;
		//枚举所有显示模式
		D3DDISPLAYMODE modes[100];
		D3DFORMAT formats[20];
		DWORD dwNumModes = 0;
		DWORD dwNumFormats = 0;
		DWORD dwNumAdpaterModes = m_pd3d->GetAdapterModeCount(iAdapterCount);

		formats[dwNumFormats] = pAdapter->d3ddmDesktop.Format;

		//枚举该Adapter的所有模式
		for( UINT iModeCount=0;iModeCount<dwNumAdpaterModes;++iModeCount)
		{
			//枚举显示模式
			D3DDISPLAYMODE DisplayMode;
			m_pd3d->EnumAdapterModes(iAdapterCount,iModeCount,&DisplayMode);
			//去除分辨率太低的模式
			if( DisplayMode.Width <600 || DisplayMode.Height <400 )
				continue;
			//判断是否重复
			for( DWORD i=0;i<dwNumModes;++i )
			{
				if( (modes[i].Width == DisplayMode.Width) &&
                    (modes[i].Height == DisplayMode.Height) &&
					(modes[i].Format == DisplayMode.Format) )
					break;
			}
			if( i == dwNumModes ) //找到新模式
			{
				modes[dwNumModes].Width = DisplayMode.Width;
				modes[dwNumModes].Height = DisplayMode.Height;
				modes[dwNumModes].Format = DisplayMode.Format;
				modes[dwNumModes].RefreshRate = DisplayMode.RefreshRate;
				dwNumModes++;
				//判断该模式的Format是否已存在
				for( DWORD j=0;j<dwNumFormats;++j)
				{
					if( formats[j] == DisplayMode.Format )
						break;
				}
				if( j==dwNumFormats ) //找到新模式
				{
					formats[dwNumFormats++] = DisplayMode.Format;
				}
			}
		}
		//排序
		qsort(modes,dwNumModes,sizeof(D3DDISPLAYMODE),SortModesCallback);

		//将Device添加到Adpater,HAL or REF
		for( UINT iDeviceCount=0; iDeviceCount<dwNumDeviceType;++iDeviceCount)
		{
			//填充DeviceInfo结构
			D3DDeviceInfo* pDevice = &pAdapter->devices[pAdapter->dwNumDevices];
			pDevice->DeviceType = DeviceTypes[iDeviceCount];
			m_pd3d->GetDeviceCaps(iAdapterCount,pDevice->DeviceType,&pDevice->d3dCaps);
			pDevice->strDesc = strDeviceDes[iDeviceCount];
			pDevice->dwNumModes = 0;
			pDevice->dwCurrentMode = 0;
			pDevice->bCanDoWindowed =FALSE;
			pDevice->bWindowed = FALSE;
			pDevice->MultiSampleTypeFullscreen = D3DMULTISAMPLE_NONE;
			pDevice->MultiSampleTypeWindowed   = D3DMULTISAMPLE_NONE;

			//检查所有的Formats是否可以在该DeviceType(HAL or REF)下正常工作
			BOOL bFormatsConfirmed[20];
			DWORD dwBehavior[20];
			D3DFORMAT fmtDepthStencil[20];
			for( DWORD i=0;i<dwNumFormats;++i)
			{
				bFormatsConfirmed[i] = FALSE;
				fmtDepthStencil[i] = D3DFMT_UNKNOWN;
				//如果不能工作,跳过
				if( FAILED( m_pd3d->CheckDeviceType(iAdapterCount,
					pDevice->DeviceType,formats[i],formats[i],FALSE)) )
					continue;
                if( pDevice->DeviceType == D3DDEVTYPE_HAL )
					bHAL_Exists = TRUE;
				if( pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED )
				{
					bHAL_Windowed_Compatible = TRUE;
					if( i==0 )	//第一个是Desktop的Format
					{
						bHAL_Desktop_Compatible = true;
					}
				}
				//最后判断顶点渲染模式
				if( pDevice->d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )		//使用HARDWARE_VP
				{
					if( m_bMixedVertexProcessing )
					{
						dwBehavior[i] = D3DCREATE_MIXED_VERTEXPROCESSING;
						bFormatsConfirmed[i] = TRUE;
					}
					else 
					{
						if( pDevice->d3dCaps.DevCaps & D3DDEVCAPS_PUREDEVICE )
						{
							dwBehavior[i] = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
							bFormatsConfirmed[i] = TRUE;
						}
						else
						{
							dwBehavior[i] = D3DCREATE_HARDWARE_VERTEXPROCESSING;
							bFormatsConfirmed[i] = TRUE;
						}
					}
				}
				else	//使用SOFTWARE_VP
				{
					dwBehavior[i] = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
					bFormatsConfirmed[i] = TRUE;
				}
				//设置合适的Depth/Stencil Buffer
				if( m_bDepthStencil )
				{
					if( !FindDepthStencilFormat( iAdapterCount, pDevice->DeviceType,
						formats[i], &fmtDepthStencil[i] ) )
					{
						bFormatsConfirmed[i] = FALSE;
					}
				}
			}
			//将所有有效的Display Modes和Formats填充入Device中的列表
			for( DWORD j=0;j<dwNumModes;++j )
			{
				for( DWORD k=0;k<dwNumFormats;++k )
				{
					if( modes[j].Format == formats[k] )
					{
						if( bFormatsConfirmed[k] )
						{
							pDevice->modes[pDevice->dwNumModes].Width = modes[j].Width;
							pDevice->modes[pDevice->dwNumModes].Height = modes[j].Height;
							pDevice->modes[pDevice->dwNumModes].dwBehavior = dwBehavior[k];
							pDevice->modes[pDevice->dwNumModes].DepthStencilFormat = fmtDepthStencil[k];
							pDevice->modes[pDevice->dwNumModes].Format = modes[j].Format;
							pDevice->dwNumModes++;

							if( pDevice->DeviceType == D3DDEVTYPE_HAL )
								bHAL_Sample_Compatible = TRUE;
						}
					}
				}
			}
			//寻找640*480作为默认
			for( DWORD k=0;k<pDevice->dwNumModes;++k )
			{
				if( pDevice->modes[k].Width ==640 && pDevice->modes[k].Height== 480 )
				{
					pDevice->dwCurrentMode = k;
					if( pDevice->modes[k].Format == D3DFMT_R5G6B5 ||
						pDevice->modes[k].Format == D3DFMT_X1R5G5B5 ||
						pDevice->modes[k].Format == D3DFMT_A1R5G5B5 )
					{
						break;
					}
				}
			}
			//可在窗口模式下
			if( bFormatsConfirmed[0] && (pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) )
			{
				pDevice->bCanDoWindowed = TRUE;
				pDevice->bWindowed      = TRUE;
			}
			//该DeviceType模式有效
			if( pDevice->dwNumModes >0 )
				pAdapter->dwNumDevices++;
		}
		if( pAdapter->dwNumDevices >0 )
			++m_dwNumAdapters;
		//记录
#ifdef QDEBUG
		Char buf[512];
		sprintf(buf,"Find Adapter:%s;Device[HAL]->Modes:%d;Device[REF]->Modes:%d",
			pAdapter->d3dAdapterIdentifier.Description,pAdapter->devices[0].dwNumModes,pAdapter->devices[1].dwNumModes);
		LOGBOREME(buf);
#endif
	}
	//无效
	if( 0L == m_dwNumAdapters )
		return D3DAPPERR_NOCOMPATIBLEDEVICES;
	//选择第一个作为默认
	m_CurrentAdapter = 0;

	return S_OK;
}

BOOL  DX8Enumeration::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;
}


inline D3DAdapterInfo& DX8Enumeration::GetAdapter(Int32 idx) const
{
	return (D3DAdapterInfo&)m_Adapters[idx];
}

inline Int32 DX8Enumeration::GetAdapterNum() const
{
	return m_dwNumAdapters;
}

inline D3DAdapterInfo& DX8Enumeration::GetCurrentAdapter() const
{
	return (D3DAdapterInfo&)m_Adapters[m_CurrentAdapter];
}

inline Int32 DX8Enumeration::GetCurrentAdapterIdx() const 
{
	return m_CurrentAdapter;
}
inline void DX8Enumeration::SetCurrentAdapterIdx(Int32 idx)
{
	if( idx < m_dwNumAdapters )
		m_CurrentAdapter = idx;
}

inline Bool DX8Enumeration::IsUseDepthStencilBuffer()
{
	return m_bDepthStencil;
}

inline void DX8Enumeration::UseDepthStencilBuffer(Bool use)
{
	m_bDepthStencil = use;
}

inline Bool DX8Enumeration::IsMixedVertexProcessing()
{
	return m_bMixedVertexProcessing;
}

inline void DX8Enumeration::UseMixedVertexProcessing(Bool use)
{
	m_bMixedVertexProcessing = use;
}

⌨️ 快捷键说明

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