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

📄 vertexshaderdx8.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			if ( !( byteCode.m_nSizeInBytes == 4 && 
					( ( unsigned int * )byteCode.m_pRawData )[0] == 0x00000000 ) )
			{
				shader = ::CreatePixelShader( byteCode, info.m_pPrecompiledDXShader->m_nCentroidMask );
			}

			// Check again
			if ( shader == INVALID_HARDWARE_PIXEL_SHADER )
			{
				// Set shader to ugly green for invalid shader...
				shader = s_pIllegalMaterialPS;
				Assert( 0 );
			}
		}
	}

	return (PixelShader_t)i;
}


//-----------------------------------------------------------------------------
// Destroys a pixel shader
//-----------------------------------------------------------------------------
void CShaderDictionary::DestroyPixelShader( PixelShader_t shader )
{
	// Can't delete this one...
	if ( (shader == INVALID_PIXEL_SHADER) || ((int)shader >= m_PixelShaders.Count()) )
		return;

	if (--m_PixelShaders[shader].m_nRefCount <= 0)
	{
		for (int i = m_PixelShaders[shader].m_nShaderCount; --i >= 0; )
		{
			HardwarePixelShader_t pixelShader = m_PixelShaders[shader].m_HardwareShaders[i];
			if (pixelShader == INVALID_HARDWARE_PIXEL_SHADER)
				continue;

			// GR - invalid material hack
			// don't delete shared shader used for hack
			if ( pixelShader != s_pIllegalMaterialPS )
			{
				RECORD_COMMAND( DX8_DESTROY_PIXEL_SHADER, 1 );
				RECORD_INT( ( int )pixelShader );
				
				pixelShader->Release();
			}
		}

		if ( m_PixelShaders[shader].m_HardwareShaders )
		{
			delete[] m_PixelShaders[shader].m_HardwareShaders;
		}

		m_PixelShaders.RemoveAt( shader );
	}
}


//-----------------------------------------------------------------------------
// Destroys all pixel shaders
//-----------------------------------------------------------------------------
void CShaderDictionary::DestroyAllPixelShaders( )
{
	for (int i = m_PixelShaders.First(); i != m_PixelShaders.InvalidIndex(); i = m_PixelShaders.Next(i) )
	{
		for (int j = m_PixelShaders[i].m_nShaderCount; --j >= 0; )
		{
			HardwarePixelShader_t pixelShader = m_PixelShaders[i].m_HardwareShaders[j];
			if ( (pixelShader == INVALID_HARDWARE_PIXEL_SHADER) || ( pixelShader == s_pIllegalMaterialPS ))
				continue;

			RECORD_COMMAND( DX8_DESTROY_PIXEL_SHADER, 1 );
			RECORD_INT( ( int )pixelShader );
			pixelShader->Release();
		}

		if ( m_PixelShaders[i].m_HardwareShaders )
		{
			delete[] m_PixelShaders[i].m_HardwareShaders;
		}
	}
	m_PixelShaders.RemoveAll();
}


//-----------------------------------------------------------------------------
// Gets the hardware pixel shader
//-----------------------------------------------------------------------------
HardwarePixelShader_t CShaderDictionary::GetHardwarePixelShader( PixelShader_t shader, int pshIndex )
{
	return m_PixelShaders[shader].m_HardwareShaders[pshIndex];	
}


//-----------------------------------------------------------------------------
// Vertex + pixel shader manager
//-----------------------------------------------------------------------------
class CShaderManager : public IShaderManager
{
public:
	CShaderManager();
	~CShaderManager();

	// Methods of IShaderManager
	virtual void Init( bool bPreloadShaders );
	virtual void Shutdown();
	virtual VertexShader_t CreateVertexShader( const char *pVertexShaderFile, int nStaticVshIndex = 0 );
	virtual PixelShader_t CreatePixelShader( const char *pPixelShaderFile, int nStaticPshIndex = 0 );
	virtual void SetVertexShaderIndex( int vshIndex = -1 );
	virtual void SetPixelShaderIndex( int pshIndex = 0 );
	virtual void SetVertexShader( VertexShader_t shader, int nStaticVshIndex = 0 );
	virtual void SetPixelShader( PixelShader_t shader, int nStaticPshIndex = 0 );
	virtual void* GetCurrentVertexShader();
	virtual void* GetCurrentPixelShader();
	virtual void ResetShaderState();
	virtual ShaderDLL_t AddShaderDLL( );
	virtual void RemoveShaderDLL( ShaderDLL_t hShaderDLL );
	virtual void AddShaderDictionary( ShaderDLL_t hShaderDLL, IPrecompiledShaderDictionary *pDict );
	virtual void SetShaderDLL( ShaderDLL_t hShaderDLL );

private:
	// The low-level dx call to set the vertex shader state
	void SetVertexShaderState( HardwareVertexShader_t shader );

	// The low-level dx call to set the pixel shader state
	void SetPixelShaderState( HardwarePixelShader_t shader );

private:
	// Shaders defined in external DLLs
	CUtlLinkedList< CShaderDictionary > m_ShaderDLLs;
	ShaderDLL_t m_hCurrentShaderDLL;

	// The current vertex + pixel shader
	HardwareVertexShader_t	m_HardwareVertexShader;
	HardwarePixelShader_t	m_HardwarePixelShader;

	// The current vertex + pixel shader index
	int m_nVertexShaderIndex;
	int m_nPixelShaderIndex;

	// Should we preload shaders?
	bool m_bPreloadShaders;
};


//-----------------------------------------------------------------------------
// Singleton accessor
//-----------------------------------------------------------------------------
static CShaderManager s_ShaderManager;
IShaderManager *g_pShaderManager = &s_ShaderManager;


//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CShaderManager::CShaderManager()
{
	m_hCurrentShaderDLL = m_ShaderDLLs.InvalidIndex();
}


CShaderManager::~CShaderManager()
{
}


//-----------------------------------------------------------------------------
// Initialization, shutdown
//-----------------------------------------------------------------------------
void CShaderManager::Init( bool bPreloadShaders )
{
	m_bPreloadShaders = bPreloadShaders;
	CShaderDictionary::CreateErrorPS();
}

void CShaderManager::Shutdown()
{
	for ( unsigned short i = m_ShaderDLLs.Head(); i != m_ShaderDLLs.InvalidIndex(); i = m_ShaderDLLs.Next(i) )
	{
		RemoveShaderDLL( i );
	}
	CShaderDictionary::DestroyErrorPS();
}


//-----------------------------------------------------------------------------
// Adds/removes shader DLLs
//-----------------------------------------------------------------------------
ShaderDLL_t CShaderManager::AddShaderDLL( )
{
	return m_ShaderDLLs.AddToTail();
}

void CShaderManager::RemoveShaderDLL( ShaderDLL_t hShaderDLL )
{
	// Destroy all vertex shaders
	m_ShaderDLLs[hShaderDLL].DestroyAllVertexShaders( );

	// Destroy all pixel shaders
	m_ShaderDLLs[hShaderDLL].DestroyAllPixelShaders( );

	m_ShaderDLLs.Remove( hShaderDLL );
}


//-----------------------------------------------------------------------------
// Adds precompiled shader dictionaries
//-----------------------------------------------------------------------------
void CShaderManager::AddShaderDictionary( ShaderDLL_t hShaderDLL, IPrecompiledShaderDictionary *pDict )
{
	Assert( m_ShaderDLLs.IsValidIndex( hShaderDLL ) );
	m_ShaderDLLs[hShaderDLL].AddShaderDictionary( pDict, m_bPreloadShaders );
}


//-----------------------------------------------------------------------------
// Sets the shader DLL index
//-----------------------------------------------------------------------------
void CShaderManager::SetShaderDLL( ShaderDLL_t hShaderDLL )
{
	m_hCurrentShaderDLL = (hShaderDLL >= 0) ? hShaderDLL : m_ShaderDLLs.InvalidIndex();
}


//-----------------------------------------------------------------------------
// Creates and destroys vertex shaders
//-----------------------------------------------------------------------------
VertexShader_t CShaderManager::CreateVertexShader( char const* pFileName, int nStaticVshIndex )
{
	if ( !pFileName || (m_hCurrentShaderDLL == m_ShaderDLLs.InvalidIndex()) )
		return INVALID_VERTEX_SHADER;

	VertexShader_t shader = m_ShaderDLLs[m_hCurrentShaderDLL].CreateVertexShader( pFileName, nStaticVshIndex );
	if ( shader != INVALID_VERTEX_SHADER )
	{
		shader |= (m_hCurrentShaderDLL << 16);
	}
	return shader;
}


//-----------------------------------------------------------------------------
// Creates and destroys pixel shaders
//-----------------------------------------------------------------------------
PixelShader_t CShaderManager::CreatePixelShader( char const* pFileName, int nStaticPshIndex )
{
	// FIXME: NOTE: We could also implement this by returning a unique PixelShader_t
	// for each pFileName/nStaticPshIndex combination. I didn't do this because
	// even though it's cleaner from the API standpoint because it would mean a
	// much larger m_PixelShader dictionary + resulting slower search times.

	if ( !pFileName || (m_hCurrentShaderDLL == m_ShaderDLLs.InvalidIndex()) )
		return INVALID_PIXEL_SHADER;

	PixelShader_t shader = m_ShaderDLLs[m_hCurrentShaderDLL].CreatePixelShader( pFileName, nStaticPshIndex );
	if ( shader != INVALID_PIXEL_SHADER )
	{
		shader |= (m_hCurrentShaderDLL << 16);
	}
	return shader;
}


//-----------------------------------------------------------------------------
//
// Methods related to setting vertex + pixel shader state
//
//-----------------------------------------------------------------------------
void CShaderManager::SetVertexShaderIndex( int vshIndex )
{
	m_nVertexShaderIndex = vshIndex;
}

void CShaderManager::SetPixelShaderIndex( int pshIndex )
{
	m_nPixelShaderIndex = pshIndex;
}

void* CShaderManager::GetCurrentVertexShader()
{
	return m_HardwareVertexShader;
}

void* CShaderManager::GetCurrentPixelShader()
{
	return m_HardwarePixelShader;
}


//-----------------------------------------------------------------------------
// The low-level dx call to set the vertex shader state
//-----------------------------------------------------------------------------
void CShaderManager::SetVertexShaderState( HardwareVertexShader_t shader )
{
	MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_SET_VERTEX_SHADER);
	
	if ( m_HardwareVertexShader != shader )
	{
		RECORD_COMMAND( DX8_SET_VERTEX_SHADER, 1 );
		RECORD_INT( ( int )shader ); // hack hack hack

#ifdef _DEBUG
		HRESULT hr = 
#endif
				D3DDevice()->SetVertexShader( shader );
		Assert( hr == D3D_OK );

		m_HardwareVertexShader = shader;
		MaterialSystemStats()->IncrementCountedStat( MATERIAL_SYSTEM_STATS_DYNAMIC_STATE, 1 );
	}
}


//-----------------------------------------------------------------------------
// Sets a particular vertex shader as the current shader
//-----------------------------------------------------------------------------
void CShaderManager::SetVertexShader( VertexShader_t shader, int nStaticVshIndex )
{
	// Determine which vertex shader to use...
	if( shader == INVALID_VERTEX_SHADER )
	{
		SetVertexShaderState( 0 );
		return;
	}

	int hShaderDLL = shader >> 16;
	shader &= 0xFFFF;

	int vshIndex = (m_nVertexShaderIndex >= 0) ? m_nVertexShaderIndex + nStaticVshIndex : -1;
	HardwareVertexShader_t dxshader = m_ShaderDLLs[hShaderDLL].GetHardwareVertexShader( shader, vshIndex );
	SetVertexShaderState( dxshader );
}


//-----------------------------------------------------------------------------
// The low-level dx call to set the pixel shader state
//-----------------------------------------------------------------------------
void CShaderManager::SetPixelShaderState( HardwarePixelShader_t shader )
{
	MEASURE_TIMED_STAT(MATERIAL_SYSTEM_STATS_SET_PIXEL_SHADER);

	if ( m_HardwarePixelShader != shader )
	{
		RECORD_COMMAND( DX8_SET_PIXEL_SHADER, 1 );
		RECORD_INT( ( int )shader );
		
#ifdef _DEBUG
		HRESULT hr = 
#endif
				D3DDevice()->SetPixelShader( shader );
		Assert( !FAILED(hr) );

		m_HardwarePixelShader = shader;
		MaterialSystemStats()->IncrementCountedStat( MATERIAL_SYSTEM_STATS_DYNAMIC_STATE, 1 );
	}
}


//-----------------------------------------------------------------------------
// Sets a particular pixel shader as the current shader
//-----------------------------------------------------------------------------
void CShaderManager::SetPixelShader( PixelShader_t shader, int nStaticPshIndex )
{
	if( shader == INVALID_PIXEL_SHADER )
	{
		SetPixelShaderState( 0 );
		return;
	}

	int hShaderDLL = shader >> 16;
	shader &= 0xFFFF;

	int pshIndex = m_nPixelShaderIndex + nStaticPshIndex;
	Assert( pshIndex >= 0 );
	HardwarePixelShader_t hardwarePixelShader =	m_ShaderDLLs[hShaderDLL].GetHardwarePixelShader( shader, pshIndex );
	Assert( hardwarePixelShader != INVALID_HARDWARE_PIXEL_SHADER );
	SetPixelShaderState( hardwarePixelShader );
}


//-----------------------------------------------------------------------------
// Resets the shader state
//-----------------------------------------------------------------------------
void CShaderManager::ResetShaderState()
{
	// This will force the calls to SetVertexShader + SetPixelShader to actually set the state
	m_HardwareVertexShader = (HardwareVertexShader_t)-1;
	m_HardwarePixelShader = (HardwarePixelShader_t)-1;

	SetVertexShader( INVALID_VERTEX_SHADER );
	SetPixelShader( INVALID_PIXEL_SHADER );
}

⌨️ 快捷键说明

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