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

📄 shaderapidx8.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
static CMaterialSystemStatsDX8 g_Stats;
CMaterialSystemStatsDX8 *g_pStats = &g_Stats;

EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CMaterialSystemStatsDX8, IMaterialSystemStats, 
							MATERIAL_SYSTEM_STATS_INTERFACE_VERSION, g_Stats )


//-----------------------------------------------------------------------------
// Accessors for major interfaces
//-----------------------------------------------------------------------------
IShaderUtil* g_pShaderUtil = 0;
IBaseFileSystem* g_pFileSystem = 0;

IDirect3DDevice* D3DDevice()
{
	return g_ShaderAPIDX8.D3DDevice();
}

IDirect3D* D3D()  
{
	return g_ShaderAPIDX8.D3D();
}

 
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CShaderAPIDX8::CShaderAPIDX8() : 
	m_pD3D(0), m_pD3DDevice(0), m_Textures( 32 ), m_DisplayLost(false),
	m_CurrStack(-1), m_ModifyTextureIdx(-1), m_pRenderMesh(0), m_OtherAppInitializing(false),
	m_IsResizing(false), m_CurrentFrame(0), m_CachedAmbientLightCube(STATE_CHANGED),
	m_InSelectionMode(false), m_SelectionMinZ(FLT_MAX), m_SelectionMaxZ(FLT_MIN),
	m_pSelectionBuffer(0), m_pSelectionBufferEnd(0), m_ModifyTextureLockedLevel(-1),
	m_pDebugFont( NULL ), m_pBackBufferSurface(0), m_pZBufferSurface(0)
{
	memset( m_pMatrixStack, 0, sizeof(ID3DXMatrixStack*) * NUM_MATRIX_MODES );
	memset( &m_DynamicState, 0, sizeof(m_DynamicState) );
	memset( &m_Mode, 0, sizeof(m_Mode) );
	memset( &m_Caps, 0, sizeof(m_Caps) );
	m_FirstLightmapId = m_LastLightmapId = -1;
	m_Mode.m_Format = (ImageFormat)-1;
	m_DynamicState.m_HeightClipMode = MATERIAL_HEIGHTCLIPMODE_DISABLE;
	m_nWindowHeight = m_nWindowWidth = 0;

	m_SceneFogColor[0] = 0;
	m_SceneFogColor[1] = 0;
	m_SceneFogColor[2] = 0;
	m_SceneFogMode = MATERIAL_FOG_NONE;

	// FIXME: This is kind of a hack to deal with DX8 worldcraft startup.
	// We can at least have this much texture 
	m_Caps.m_MaxTextureWidth = m_Caps.m_MaxTextureHeight = 256;

	// We haven't yet detected whether we support CreateQuery or not yet.
	m_DeviceSupportsCreateQuery = -1;
}

CShaderAPIDX8::~CShaderAPIDX8()
{
	if (m_DynamicState.m_pPixelShaderConstant)
		delete[] m_DynamicState.m_pPixelShaderConstant;
	if (m_DynamicState.m_pVertexShaderConstant)
		delete[] m_DynamicState.m_pVertexShaderConstant;
}


//-----------------------------------------------------------------------------
// Initialization
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::Init( IShaderUtil* pShaderUtil, IBaseFileSystem* pFileSystem, int nAdapter, int nAdapterFlags )
{
	MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
	m_pFrameSyncQueryObject = NULL;
	
	// So others can access it
	g_pShaderUtil = pShaderUtil;
	g_pFileSystem = pFileSystem;

	// Read dx support levels
	ReadDXSupportLevels();

	// Create the main interface
	m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if (!m_pD3D)
        return false;

	// Set up hardware information for this adapter...
	m_DeviceType = (nAdapterFlags & MATERIAL_INIT_REFERENCE_RASTERIZER) ? 
		D3DDEVTYPE_REF : D3DDEVTYPE_HAL;
	m_DisplayAdapter = nAdapter;
	if ( m_DisplayAdapter >= (UINT)GetDisplayAdapterCount() )
	{
		m_DisplayAdapter = 0;
	}

	return DetermineHardwareCaps( );
}


//-----------------------------------------------------------------------------
// Shutdown
//-----------------------------------------------------------------------------
void CShaderAPIDX8::Shutdown( )
{
	if (m_pD3D)
	{
		ShutdownDevice();
		m_pD3D->Release();
		m_pD3D = 0;
	}
}


//-----------------------------------------------------------------------------
// Gets the number of adapters...
//-----------------------------------------------------------------------------
int CShaderAPIDX8::GetDisplayAdapterCount() const
{
	Assert( m_pD3D );
	return m_pD3D->GetAdapterCount( );
}


//-----------------------------------------------------------------------------
// Returns info about each adapter
//-----------------------------------------------------------------------------
void CShaderAPIDX8::GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const
{
	Assert( m_pD3D && (adapter < GetDisplayAdapterCount()) );
	
	HRESULT hr;
	D3DADAPTER_IDENTIFIER ident;
	hr = m_pD3D->GetAdapterIdentifier( adapter, D3DENUM_WHQL_LEVEL, &ident );
	Assert( !FAILED(hr) );

	Q_strncpy( info.m_pDriverName, ident.Driver, MATERIAL_ADAPTER_NAME_LENGTH );
	Q_strncpy( info.m_pDriverDescription, ident.Description, MATERIAL_ADAPTER_NAME_LENGTH );
}


//-----------------------------------------------------------------------------
// Returns the number of modes
//-----------------------------------------------------------------------------
int	 CShaderAPIDX8::GetModeCount( int adapter ) const
{
	Assert( m_pD3D && (adapter < GetDisplayAdapterCount()) );
	// fixme - what format should I use here?
	return m_pD3D->GetAdapterModeCount( adapter, D3DFMT_X8R8G8B8 );
}


//-----------------------------------------------------------------------------
// Returns mode information..
//-----------------------------------------------------------------------------
void CShaderAPIDX8::GetModeInfo( int adapter, int mode, MaterialVideoMode_t& info ) const
{
	Assert( m_pD3D && (adapter < GetDisplayAdapterCount()) );
	Assert( mode < GetModeCount( adapter ) );

	HRESULT hr;
	D3DDISPLAYMODE d3dInfo;
	// fixme - what format should I use here?
	hr = m_pD3D->EnumAdapterModes( adapter, D3DFMT_X8R8G8B8, mode, &d3dInfo );
	Assert( !FAILED(hr) );

	info.m_Width = d3dInfo.Width;
	info.m_Height = d3dInfo.Height;
	info.m_Format = D3DFormatToImageFormat( d3dInfo.Format );
	info.m_RefreshRate = d3dInfo.RefreshRate;
}


//-----------------------------------------------------------------------------
// Returns the mode info for the current display device
//-----------------------------------------------------------------------------
void CShaderAPIDX8::GetDisplayMode( MaterialVideoMode_t& info ) const
{
	Assert( m_pD3D );

	HRESULT hr;
	D3DDISPLAYMODE mode;
	hr = m_pD3D->GetAdapterDisplayMode( m_DisplayAdapter, &mode );
	Assert( !FAILED(hr) );

	info.m_Width = mode.Width;
	info.m_Height = mode.Height;
	info.m_Format = D3DFormatToImageFormat( mode.Format );
	info.m_RefreshRate = mode.RefreshRate;
}

bool CShaderAPIDX8::Prefer16BitTextures( void ) const
{
	return ::Prefer16BitTextures();
}


//-----------------------------------------------------------------------------
// Validates the mode...
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::ValidateMode( void* hwnd,
							const MaterialVideoMode_t & mode, int flags ) const
{
	// validate...
	if (m_DisplayAdapter >= (int)m_pD3D->GetAdapterCount())
		return false;

	if (flags & MATERIAL_VIDEO_MODE_WINDOWED)
	{
		// make sure the window fits within the current video mode
		MaterialVideoMode_t displayMode;
		GetDisplayMode( displayMode );

		if ((mode.m_Width >= displayMode.m_Width) ||
			(mode.m_Height >= displayMode.m_Height))
			return false;
	}
	else
	{
		// If the width and height == 0, then we just use whatever the current
		// video mode is
		if ((mode.m_Width == 0) && (mode.m_Height == 0))
			return true;

		// make sure we support that display mode
		MaterialVideoMode_t testMode;
		int count = GetModeCount( m_DisplayAdapter );
		for (int i = 0; i < count; ++i)
		{
			GetModeInfo( m_DisplayAdapter, i, testMode );

			// Found a match, we're ok
			if ((testMode.m_Width == mode.m_Width) &&
				(testMode.m_Height == mode.m_Height) &&
				(testMode.m_Format == mode.m_Format) &&
				((mode.m_RefreshRate == 0) || (testMode.m_RefreshRate == mode.m_RefreshRate)) )
			{
				return true;
			}
		}

		// not found baby
		return false;
	}

	return true;
}


//-----------------------------------------------------------------------------
// Do we have to change the device, or can we do something simpler...
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::DoesModeRequireDeviceChange( void* hwnd, 
							const MaterialVideoMode_t &mode, int flags ) const
{
	if (m_HWnd != (HWND)hwnd)
		return true;

	if ((flags & MATERIAL_VIDEO_MODE_RESIZING) != (m_ModeFlags & MATERIAL_VIDEO_MODE_RESIZING))
		return true;

	return false;
}


//-----------------------------------------------------------------------------
// Can we render windowed?
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::CanRenderWindowed( ) const
{
	// DX9 only supports dx7 drivers and above.  All existing dx7 can render in windowed mode.
	return true;
}


//-----------------------------------------------------------------------------
// Computes the supersample flags
//-----------------------------------------------------------------------------
static D3DMULTISAMPLE_TYPE ComputeMultisampleType( int nSampleCount )
{
	switch (nSampleCount)
	{
	case 2: return D3DMULTISAMPLE_2_SAMPLES;
	case 3: return D3DMULTISAMPLE_3_SAMPLES;
	case 4: return D3DMULTISAMPLE_4_SAMPLES;
	case 5: return D3DMULTISAMPLE_5_SAMPLES;
	case 6: return D3DMULTISAMPLE_6_SAMPLES;
	case 7: return D3DMULTISAMPLE_7_SAMPLES;
	case 8: return D3DMULTISAMPLE_8_SAMPLES;
	case 9: return D3DMULTISAMPLE_9_SAMPLES;
	case 10: return D3DMULTISAMPLE_10_SAMPLES;
	case 11: return D3DMULTISAMPLE_11_SAMPLES;
	case 12: return D3DMULTISAMPLE_12_SAMPLES;
	case 13: return D3DMULTISAMPLE_13_SAMPLES;
	case 14: return D3DMULTISAMPLE_14_SAMPLES;
	case 15: return D3DMULTISAMPLE_15_SAMPLES;
	case 16: return D3DMULTISAMPLE_16_SAMPLES;

	default:
	case 0:
	case 1:
		return D3DMULTISAMPLE_NONE;
	}
}


//-----------------------------------------------------------------------------
// Sets the present parameters
//-----------------------------------------------------------------------------
void CShaderAPIDX8::SetPresentParameters( const MaterialVideoMode_t &mode, int flags, int nSampleCount )
{
	D3DDISPLAYMODE d3ddm;
	HRESULT hr = m_pD3D->GetAdapterDisplayMode( m_DisplayAdapter, &d3ddm );
	if (FAILED(hr))
		return;

	bool windowed = (flags & MATERIAL_VIDEO_MODE_WINDOWED) != 0;
	bool resizing = (flags & MATERIAL_VIDEO_MODE_RESIZING) != 0;

	ZeroMemory( &m_PresentParameters, sizeof(m_PresentParameters) );
	m_PresentParameters.Windowed   = windowed;
	m_PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
//	m_PresentParameters.SwapEffect = D3DSWAPEFFECT_FLIP;
//	m_PresentParameters.SwapEffect = D3DSWAPEFFECT_COPY;
    m_PresentParameters.EnableAutoDepthStencil = TRUE;
    m_PresentParameters.AutoDepthStencilFormat = FindNearestSupportedDepthFormat( D3DFMT_D24S8 );
	m_PresentParameters.hDeviceWindow = m_HWnd;

	// If we can't use CreateQuery() to check for the end of a frame, then we have to lock the backbuffer
	m_PresentParameters.Flags = 0;

#ifdef D3D_BUG_TRACKED_DOWN
	if( m_DeviceSupportsCreateQuery == 0 )
#else
	// NJS: Until we track down the D3D bug, basically force a lockable backbuffer unless createQuery is already detected.
	if( m_DeviceSupportsCreateQuery != 1 )
#endif
	{
		m_PresentParameters.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
	}

	if (!windowed)
	{
		bool useDefault = (mode.m_Width == 0) || (mode.m_Height == 0);
		m_PresentParameters.BackBufferWidth = useDefault ? d3ddm.Width : mode.m_Width;
		m_PresentParameters.BackBufferHeight = useDefault ? d3ddm.Height : mode.m_Height;
		if( g_pHardwareConfig->GetDXSupportLevel() >= 90 && g_pHardwareConfig->SupportsHDR() )
		{
			// hack to get dest alpha
			m_PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8;
		}
		else
		{
			m_PresentParameters.BackBufferFormat = useDefault ? d3ddm.Format : ImageFormatToD3DFormat( mode.m_Format );
		}
		m_PresentParameters.BackBufferCount = 1;

		if (flags & MATERIAL_VIDEO_MODE_NO_WAIT_FOR_VSYNC)
			m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
		else
			m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
		m_PresentParameters.FullScreen_RefreshRateInHz = useDefault || !mode.m_RefreshRate ? 
			D3DPRESENT_RATE_DEFAULT : mode.m_RefreshRate; 
	}
	else
	{
		// NJS: We are seeing a lot of time spent in present in some cases when this isn't set.
		m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

		/*
		if (flags & MATERIAL_VIDEO_MODE_NO_WAIT_FOR_VSYNC)
			m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
		else
			m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
		*/

		if (resizing)
		{
			// When in resizing windowed mode, 
			// we want to allocate enough memory to deal with any resizing...
			m_PresentParameters.BackBufferWidth = d3ddm.Width;
			m_PresentParameters.BackBufferHeight = d3ddm.Height;
		}
		else
		{
			m_PresentParameters.BackBufferWidth = mode.m_Width;
			m_PresentParameters.BackBufferHeight = mode.m_Height;
		}
		if( g_pHardwareConfig->GetDXSupportLevel() >= 90 && g_pHardwareConfig->SupportsHDR() )
		{
			// hack to get dest alpha
			m_PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8;
		}
		else
		{
			m_PresentParameters.BackBufferFormat = d3ddm.Format;
		}
		m_PresentParameters.BackBufferCount = 1;
	}

	if (flags & MATERIAL_VIDEO_MODE_ANTIALIAS)
	{
		DWORD nQualityLevel;
		D3DMULTISAMPLE_TYPE multiSampleType = ComputeMultisampleType( nSampleCount );
		hr = m_pD3D->CheckDeviceMultiSampleType( m_DisplayAdapter, m_DeviceType, 
			m_PresentParameters.BackBufferFormat, m_PresentParameters.Windowed, 
			multiSampleType, &nQualityLevel 
			);

		if (!FAILED(hr))
		{
			m_PresentParameters.MultiSampleType = multiSampleType;
			m_PresentParameters.MultiSampleQuality = nQualityLevel - 1;
		}
	}
}


ImageFormat CShaderAPIDX8::GetBackBufferFormat() const
{
	return D3DFormatToImageFormat( m_PresentParameters.BackBufferFormat );
}

⌨️ 快捷键说明

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