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

📄 d3denumeration.cpp

📁 java实现的简单的分形树。简单易学!是学习分形知识的很好的例子。其java语法简单
💻 CPP
字号:
// --------------------------------------------------------------------------
// Dingus project - a collection of subsystems for game/graphics applications
// --------------------------------------------------------------------------
#include "stdafx.h"

#include "D3DEnumeration.h"

using namespace dingus;


//---------------------------------------------------------------------------

/**
 *  Returns number of color channel bits for D3DFORMAT.
 */
static int gGetColorChannelBits( D3DFORMAT fmt ) {
	switch( fmt ) {
	case D3DFMT_A2B10G10R10:
	case D3DFMT_A2R10G10B10:
		return 10;
	case D3DFMT_R8G8B8:
	case D3DFMT_A8R8G8B8:
	case D3DFMT_X8R8G8B8:
		return 8;
	case D3DFMT_R5G6B5:
	case D3DFMT_X1R5G5B5:
	case D3DFMT_A1R5G5B5:
		return 5;
	case D3DFMT_A4R4G4B4:
	case D3DFMT_X4R4G4B4:
		return 4;
	case D3DFMT_R3G3B2:
	case D3DFMT_A8R3G3B2:
		return 2;
	default:
		return 0;
	}
};


//---------------------------------------------------------------------------

/**
 *  Returns number of alpha channel bits for D3DFORMAT.
 */
static int gGetAlphaChannelBits( D3DFORMAT fmt ) {
	switch( fmt ) {
	case D3DFMT_R8G8B8:
	case D3DFMT_X8R8G8B8:
	case D3DFMT_R5G6B5:
	case D3DFMT_X1R5G5B5:
	case D3DFMT_R3G3B2:
	case D3DFMT_X4R4G4B4:
		return 0;
	case D3DFMT_A8R8G8B8:
	case D3DFMT_A8R3G3B2:
		return 8;
	case D3DFMT_A1R5G5B5:
		return 1;
	case D3DFMT_A4R4G4B4:
		return 4;
	case D3DFMT_A2B10G10R10:
	case D3DFMT_A2R10G10B10:
		return 2;
	default:
		return 0;
	}
};


//---------------------------------------------------------------------------

/**
 *  Returns number of depth bits for D3DFORMAT.
 */
static int gGetDepthBits( D3DFORMAT fmt ) {
	switch( fmt ) {
	case D3DFMT_D16:
		return 16;
	case D3DFMT_D15S1:
		return 15;
	case D3DFMT_D24X8:
	case D3DFMT_D24S8:
	case D3DFMT_D24X4S4:
		return 24;
	case D3DFMT_D32:
		return 32;
	default:
		return 0;
	}
};


//---------------------------------------------------------------------------

/**
 *  Returns number of stencil bits for D3DFORMAT.
 */
static int gGetStencilBits( D3DFORMAT fmt ) {
	switch( fmt ) {
	case D3DFMT_D16:
	case D3DFMT_D24X8:
	case D3DFMT_D32:
		return 0;
	case D3DFMT_D15S1:
		return 1;
	case D3DFMT_D24S8:
		return 8;
	case D3DFMT_D24X4S4:
		return 4;
	default:
		return 0;
	}
};


//---------------------------------------------------------------------------
//  SD3DAdapterInfo
//---------------------------------------------------------------------------

SD3DAdapterInfo::~SD3DAdapterInfo()
{
	stl_utils::wipe( deviceInfos );
}

//---------------------------------------------------------------------------
// SD3DDeviceInfo
//---------------------------------------------------------------------------

SD3DDeviceInfo::~SD3DDeviceInfo()
{
	stl_utils::wipe( deviceCombos );
}



//---------------------------------------------------------------------------
// CD3DEnumeration
//---------------------------------------------------------------------------


CD3DEnumeration::CD3DEnumeration()
:	mMinFullscreenWidth(640),
	mMinFullscreenHeight(480),
	mMinColorChannelBits(5),
	mMinAlphaChannelBits(0),
	mMinDepthBits(15),
	mMinStencilBits(0),
	mUsesDepthBuffer(false),
	mUsesMixedVP(false),
	mRequiresWindowed(false),
	mRequiresFullscreen(false)
{
}


CD3DEnumeration::~CD3DEnumeration()
{
	stl_utils::wipe( mAdapterInfos );
}


//-----------------------------------------------------------------------------

// Used to sort display modes.
/*
bool operator< ( const D3DDISPLAYMODE& dm1, const D3DDISPLAYMODE& dm2 )
{
	if (dm1.Width < dm2.Width)
		return true;
	if (dm1.Height < dm2.Height)
		return true;
	if (dm1.Format < dm2.Format)
		return true;
	if (dm1.RefreshRate < dm2.RefreshRate)
		return true;
	return false;
};
*/


HRESULT CD3DEnumeration::enumerate()
{
	HRESULT hr;
	
	if( !mDirect3D )
		return E_FAIL;
	
	stl_utils::wipe( mAdapterInfos );
	
	mAllowedFormats.clear();
	mAllowedFormats.push_back( D3DFMT_X8R8G8B8 );
	mAllowedFormats.push_back( D3DFMT_X1R5G5B5 );
	mAllowedFormats.push_back( D3DFMT_R5G6B5 );
	mAllowedFormats.push_back( D3DFMT_A2R10G10B10 );

	//
	// get all adapters

	int adapterCount = mDirect3D->GetAdapterCount();
	for( int adOrd = 0; adOrd < adapterCount; ++adOrd ) {
		SD3DAdapterInfo *adapterInfo = new SD3DAdapterInfo();
		if( adapterInfo == NULL ) return E_OUTOFMEMORY;

		adapterInfo->adapterOrdinal = adOrd;
		mDirect3D->GetAdapterIdentifier( adOrd, 0, &adapterInfo->adapterID );
		
		//
		// get list of all display modes on this adapter.  
		// also build a temporary list of all display adapter formats.

		TDwordVector adapterFormatList; // D3DFORMAT
		
		for( int ifmt = 0; ifmt < mAllowedFormats.size(); ++ifmt ) {
			D3DFORMAT format = (D3DFORMAT)mAllowedFormats[ifmt];
			int modeCount = mDirect3D->GetAdapterModeCount( adOrd, format );
			for( int mode = 0; mode < modeCount; ++mode ) {
				D3DDISPLAYMODE dm;
				mDirect3D->EnumAdapterModes( adOrd, format, mode, &dm );
				if( dm.Width < mMinFullscreenWidth || 
					dm.Height < mMinFullscreenHeight ||
					gGetColorChannelBits(dm.Format) < mMinColorChannelBits )
				{
					continue;
				}
				adapterInfo->displayModes.push_back( dm );
				if( std::find(adapterFormatList.begin(),adapterFormatList.end(),dm.Format) == adapterFormatList.end() )
					adapterFormatList.push_back( dm.Format );
			}
		}

		// sort displaymode list
		// TBD: no sort, causes some problems on some weird computers
		//std::sort( adapterInfo->displayModes.begin(), adapterInfo->displayModes.end() );
		
		// get info for each device on this adapter
		if( FAILED( hr = enumerateDevices( *adapterInfo, adapterFormatList ) ) ) {
			delete adapterInfo;
			return hr;
		}

		// if at least one device on this adapter is available and compatible
		// with the app, add adapterInfo to the list
		if( adapterInfo->deviceInfos.empty() )
			delete adapterInfo;
		else
			mAdapterInfos.push_back( adapterInfo );
	}

	return S_OK;
}




HRESULT CD3DEnumeration::enumerateDevices( SD3DAdapterInfo& adapterInfo, const TDwordVector& adapterFormats )
{
	const D3DDEVTYPE devTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_SW, D3DDEVTYPE_REF };
	const int devTypeCount = sizeof(devTypes) / sizeof(devTypes[0]);
	
	HRESULT hr;
	
	for( int idt = 0; idt < devTypeCount; ++idt ) {
		SD3DDeviceInfo* deviceInfo = new SD3DDeviceInfo();
		if( deviceInfo == NULL ) return E_OUTOFMEMORY;

		deviceInfo->adapterOrdinal = adapterInfo.adapterOrdinal;
		deviceInfo->deviceType = devTypes[idt];
		if( FAILED( mDirect3D->GetDeviceCaps( adapterInfo.adapterOrdinal, deviceInfo->deviceType, &deviceInfo->caps ) ) ) {
			delete deviceInfo;
			continue;
		}
		
		// get info for each device combo on this device
		if( FAILED( hr = enumerateDeviceCombos( *deviceInfo, adapterFormats ) ) ) {
			delete deviceInfo;
			return hr;
		}
		
		// if at least one combo for is found, add the deviceInfo to the list
		if( deviceInfo->deviceCombos.empty() ) {
			delete deviceInfo;
			continue;
		}
		adapterInfo.deviceInfos.push_back( deviceInfo );
	}
	return S_OK;
}




HRESULT CD3DEnumeration::enumerateDeviceCombos( SD3DDeviceInfo& deviceInfo, const TDwordVector& adapterFormats )
{
	const D3DFORMAT bbufferFormats[] = {
		D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A2R10G10B10,
		D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5
	};
	const int bbufferFormatCount = sizeof(bbufferFormats) / sizeof(bbufferFormats[0]);
	
	bool isWindowedArray[] = { false, true };
	
	//
	// see which adapter formats are supported by this device
	for( int iaf = 0; iaf < adapterFormats.size(); ++iaf ) {
		D3DFORMAT format = (D3DFORMAT)adapterFormats[iaf];
		for( int ibbf = 0; ibbf < bbufferFormatCount; ibbf++ ) {
			D3DFORMAT bbufferFormat = bbufferFormats[ibbf];
			if( gGetAlphaChannelBits(bbufferFormat) < mMinAlphaChannelBits )
				continue;
			for( int iiw = 0; iiw < 2; ++iiw ) {
				bool isWindowed = isWindowedArray[iiw];
				if( !isWindowed && mRequiresWindowed )
					continue;
				if( isWindowed && mRequiresFullscreen )
					continue;
				if( FAILED( mDirect3D->CheckDeviceType(
					deviceInfo.adapterOrdinal, deviceInfo.deviceType, 
					format, bbufferFormat, isWindowed ) ) )
				{
					continue;
				}

				// Here, we have an adapter/device/adapterformat/backbufferformat/iswindowed
				// combo that is supported by the system. We still need to
				// confirm that it's compatible with the app, and find one or
				// more suitable depth/stencil buffer format, multisample type,
				// vertex processing type, and present interval.
				SD3DDeviceCombo* devCombo = new SD3DDeviceCombo();
				if( devCombo == NULL ) return E_OUTOFMEMORY;

				devCombo->adapterOrdinal = deviceInfo.adapterOrdinal;
				devCombo->deviceType = deviceInfo.deviceType;
				devCombo->adapterFormat = format;
				devCombo->backBufferFormat = bbufferFormat;
				devCombo->isWindowed = isWindowed;
				if( mUsesDepthBuffer ) {
					buildDepthStencilFormats( *devCombo );
					if( devCombo->depthStencilFormats.empty() ) {
						delete devCombo;
						continue;
					}
				}
				buildMultiSampleTypes( *devCombo );
				if( devCombo->multiSampleTypes.empty() ) {
					delete devCombo;
					continue;
				}
				buildConflicts( *devCombo );
				buildVertexProcessings( deviceInfo, *devCombo );
				if( devCombo->vertexProcessings.empty() ) {
					delete devCombo;
					continue;
				}
				buildPresentIntervals( deviceInfo, *devCombo );
				
				deviceInfo.deviceCombos.push_back( devCombo );
			}
		}
	}
	
	return S_OK;
}



void CD3DEnumeration::buildDepthStencilFormats( SD3DDeviceCombo& devCombo )
{
	const D3DFORMAT dsFormats[] = {
		D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1, D3DFMT_D32,
	};
	const int dsFormatCount = sizeof(dsFormats) / sizeof(dsFormats[0]);
	
	for( int idsf = 0; idsf < dsFormatCount; ++idsf ) {
		D3DFORMAT format = dsFormats[idsf];
		if( gGetDepthBits(format) < mMinDepthBits )
			continue;
		if( gGetStencilBits(format) < mMinStencilBits )
			continue;
		if( SUCCEEDED( mDirect3D->CheckDeviceFormat(
			devCombo.adapterOrdinal, devCombo.deviceType, devCombo.adapterFormat, 
			D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format ) ) )
		{
			if( SUCCEEDED( mDirect3D->CheckDepthStencilMatch(
				devCombo.adapterOrdinal, devCombo.deviceType, devCombo.adapterFormat, 
				devCombo.backBufferFormat, format ) ) )
			{
				devCombo.depthStencilFormats.push_back( format );
			}
		}
	}
}


void CD3DEnumeration::buildMultiSampleTypes( SD3DDeviceCombo& devCombo )
{
	const D3DMULTISAMPLE_TYPE msTypes[] = { 
		D3DMULTISAMPLE_NONE,
		D3DMULTISAMPLE_NONMASKABLE,
		D3DMULTISAMPLE_2_SAMPLES,
		D3DMULTISAMPLE_3_SAMPLES,
		D3DMULTISAMPLE_4_SAMPLES,
		D3DMULTISAMPLE_5_SAMPLES,
		D3DMULTISAMPLE_6_SAMPLES,
		D3DMULTISAMPLE_7_SAMPLES,
		D3DMULTISAMPLE_8_SAMPLES,
		D3DMULTISAMPLE_9_SAMPLES,
		D3DMULTISAMPLE_10_SAMPLES,
		D3DMULTISAMPLE_11_SAMPLES,
		D3DMULTISAMPLE_12_SAMPLES,
		D3DMULTISAMPLE_13_SAMPLES,
		D3DMULTISAMPLE_14_SAMPLES,
		D3DMULTISAMPLE_15_SAMPLES,
		D3DMULTISAMPLE_16_SAMPLES,
	};
	const int msTypeCount = sizeof(msTypes) / sizeof(msTypes[0]);
	
	for( int imst = 0; imst < msTypeCount; ++imst ) {
		D3DMULTISAMPLE_TYPE	msType = msTypes[imst];
		DWORD msQuality;
		if( SUCCEEDED( mDirect3D->CheckDeviceMultiSampleType(
			devCombo.adapterOrdinal, devCombo.deviceType, 
			devCombo.backBufferFormat, devCombo.isWindowed,
			msType, &msQuality ) ) )
		{
			devCombo.multiSampleTypes.push_back( msType );
			devCombo.multiSampleQualities.push_back( msQuality );
		}
	}
}


void CD3DEnumeration::buildConflicts( SD3DDeviceCombo& devCombo )
{
	
	for( int ids = 0; ids < devCombo.depthStencilFormats.size(); ++ids ) {
		D3DFORMAT format = (D3DFORMAT)devCombo.depthStencilFormats[ids];
		for( int ims = 0; ims < devCombo.multiSampleTypes.size(); ++ims ) {
			D3DMULTISAMPLE_TYPE msType = (D3DMULTISAMPLE_TYPE)devCombo.multiSampleTypes[ims];
			if( FAILED( mDirect3D->CheckDeviceMultiSampleType(
				devCombo.adapterOrdinal, devCombo.deviceType,
				format, devCombo.isWindowed, msType, NULL ) ) )
			{
				SD3DDeviceCombo::SDSMSConflict conflict;
				conflict.format = format;
				conflict.type = msType;
				devCombo.conflicts.push_back( conflict );
			}
		}
	}
};



void CD3DEnumeration::buildVertexProcessings( const SD3DDeviceInfo& deviceInfo, SD3DDeviceCombo& devCombo )
{
	if( deviceInfo.caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) {
		if( deviceInfo.caps.DevCaps & D3DDEVCAPS_PUREDEVICE ) {
			if( !mConfirmDeviceCallback ||
				mConfirmDeviceCallback( deviceInfo.caps, PURE_HARDWARE_VP, devCombo.backBufferFormat ) )
			{
				devCombo.vertexProcessings.push_back( PURE_HARDWARE_VP );
			}
		}
		if( !mConfirmDeviceCallback ||
			mConfirmDeviceCallback( deviceInfo.caps, HARDWARE_VP, devCombo.backBufferFormat ) )
		{
			devCombo.vertexProcessings.push_back( HARDWARE_VP );
		}
		if( mUsesMixedVP && (!mConfirmDeviceCallback ||
			mConfirmDeviceCallback( deviceInfo.caps, MIXED_VP, devCombo.backBufferFormat ) ) )
		{
			devCombo.vertexProcessings.push_back( MIXED_VP );
		}
	}

	if( !mConfirmDeviceCallback ||
		mConfirmDeviceCallback( deviceInfo.caps, SOFTWARE_VP, devCombo.backBufferFormat ) )
	{
		devCombo.vertexProcessings.push_back( SOFTWARE_VP );
	}
}



void CD3DEnumeration::buildPresentIntervals( const SD3DDeviceInfo& deviceInfo, SD3DDeviceCombo& devCombo )
{
	const int pis[] = { 
		D3DPRESENT_INTERVAL_IMMEDIATE,
		D3DPRESENT_INTERVAL_DEFAULT,
		D3DPRESENT_INTERVAL_ONE,
		D3DPRESENT_INTERVAL_TWO,
		D3DPRESENT_INTERVAL_THREE,
		D3DPRESENT_INTERVAL_FOUR,
	};
	const int piCount = sizeof(pis) / sizeof(pis[0]);
	
	for( int ipi = 0; ipi < piCount; ++ipi ) {
		int pi = pis[ipi];
		if( devCombo.isWindowed ) {
			if( pi == D3DPRESENT_INTERVAL_TWO ||
				pi == D3DPRESENT_INTERVAL_THREE ||
				pi == D3DPRESENT_INTERVAL_FOUR )
			{
				// These intervals are not supported in windowed mode.
				continue;
			}
		}
		// D3DPRESENT_INTERVAL_DEFAULT is zero, so you
		// can't do a caps check for it -- it is always available.
		if( pi == D3DPRESENT_INTERVAL_DEFAULT || (deviceInfo.caps.PresentationIntervals & pi) )
			devCombo.presentIntervals.push_back( pi );
	}
}

⌨️ 快捷键说明

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