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

📄 transitiontable.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The dx8 implementation of the transition table
//=============================================================================

#include <windows.h>	    

#include "transitiontable.h"
#include "recording.h"
#include "shaderapidx8.h"
#include "materialsystem/materialsystem_config.h"
#include "IShaderUtil.h"
#include "CMaterialSystemStats.h"
#include "materialsystem/IMaterialSystemHardwareConfig.h"
#include "vertexshaderdx8.h"


// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"


//-----------------------------------------------------------------------------
// Singleton
//-----------------------------------------------------------------------------
CTransitionTable *g_pTransitionTable = NULL;

#ifdef DEBUG_BOARD_STATE

inline ShadowState_t& BoardState()
{
	return g_pTransitionTable->BoardState();
}

#endif


//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CTransitionTable::CTransitionTable() : m_DefaultStateSnapshot(-1),
	m_CurrentShadowId(-1), m_CurrentSnapshotId(-1), m_TransitionOps( 0, 1024 ), m_ShadowStateList( 0, 32 ),
	m_TransitionTable( 0, 32 ), m_SnapshotList( 0, 32 )
{
	Assert( !g_pTransitionTable );
	g_pTransitionTable = this;
	m_bUsingStateBlocks = false;

#ifdef DEBUG_BOARD_STATE
	memset( &m_BoardState, 0, sizeof( m_BoardState ) );
	memset( &m_BoardShaderState, 0, sizeof( m_BoardShaderState ) );
#endif
}

CTransitionTable::~CTransitionTable()
{
	Assert( g_pTransitionTable == this );
	g_pTransitionTable = NULL;
}


//-----------------------------------------------------------------------------
// Initialization, shutdown
//-----------------------------------------------------------------------------
bool CTransitionTable::Init( bool bUseStateBlocks )
{
	m_bUsingStateBlocks = false; // bUseStateBlocks;
	return true;
}

void CTransitionTable::Shutdown( )
{
	Reset();
}


//-----------------------------------------------------------------------------
// Creates a shadow, adding an entry into the shadow list and transition table
//-----------------------------------------------------------------------------
StateSnapshot_t CTransitionTable::CreateStateSnapshot( )
{
	return m_SnapshotList.AddToTail();
}


//-----------------------------------------------------------------------------
// Creates a shadow, adding an entry into the shadow list and transition table
//-----------------------------------------------------------------------------
CTransitionTable::ShadowStateId_t CTransitionTable::CreateShadowState( )
{
	int newShaderState = m_ShadowStateList.AddToTail();

	// all existing states must transition to the new state
	int i;
	for ( i = 0; i < newShaderState; ++i )
	{
		// Add a new transition to all existing states
		int newElem = m_TransitionTable[i].AddToTail();
		m_TransitionTable[i][newElem].m_FirstOperation = INVALID_TRANSITION_OP;
		m_TransitionTable[i][newElem].m_NumOperations = 0;
		m_TransitionTable[i][newElem].m_nOpCountInStateBlock = 0;

		m_TransitionTable[i][newElem].m_pStateBlock = NULL;
	}

	// Add a new vector for this transition
	int newTransitionElem = m_TransitionTable.AddToTail();
	m_TransitionTable[newTransitionElem].EnsureCapacity( 32 );
	Assert( newShaderState == newTransitionElem );

	for ( i = 0; i <= newShaderState; ++i )
	{
		// Add a new transition from all existing states
		int newElem = m_TransitionTable[newShaderState].AddToTail();
		m_TransitionTable[newShaderState][newElem].m_FirstOperation = INVALID_TRANSITION_OP;
		m_TransitionTable[newShaderState][newElem].m_NumOperations = 0;
		m_TransitionTable[newShaderState][newElem].m_nOpCountInStateBlock = 0;
		m_TransitionTable[newShaderState][newElem].m_pStateBlock = NULL;
	}

	return newShaderState;
}


//-----------------------------------------------------------------------------
// Finds a snapshot, if it exists. Or creates a new one if it doesn't.
//-----------------------------------------------------------------------------
CTransitionTable::ShadowStateId_t CTransitionTable::FindShadowState( const ShadowState_t& currentState ) const
{
	for (int i = m_ShadowStateList.Count(); --i >= 0; )
	{
		if (!memcmp(&m_ShadowStateList[i], &currentState, sizeof(ShadowState_t) ))
			return i;
	}

	// Need to create a new one
	return (ShadowStateId_t)-1;
}


//-----------------------------------------------------------------------------
// Finds a snapshot, if it exists. Or creates a new one if it doesn't.
//-----------------------------------------------------------------------------
StateSnapshot_t CTransitionTable::FindStateSnapshot( ShadowStateId_t id, const ShadowShaderState_t& currentState ) const
{
	for (int i = m_SnapshotList.Count(); --i >= 0; )
	{
		if ( (id == m_SnapshotList[i].m_ShadowStateId) && 
			!memcmp(&m_SnapshotList[i].m_ShaderState, &currentState, sizeof(ShadowShaderState_t)) )
		{
			return i;
		}
	}

	// Need to create a new one
	return (StateSnapshot_t)-1;
}


//-----------------------------------------------------------------------------
// Used to clear out state blocks from the transition table
//-----------------------------------------------------------------------------
void CTransitionTable::ClearStateBlocks()
{
	// Release state blocks
	for ( int i = m_TransitionTable.Count(); --i >= 0;  )
	{
		for ( int j = m_TransitionTable[i].Count(); --j >= 0; )
		{
			if ( m_TransitionTable[i][j].m_pStateBlock )
			{
				m_TransitionTable[i][j].m_pStateBlock->Release();
				m_TransitionTable[i][j].m_pStateBlock = NULL;
			}
		}
	}
}


//-----------------------------------------------------------------------------
// Used to clear the transition table when we know it's become invalid.
//-----------------------------------------------------------------------------
void CTransitionTable::Reset()
{
	ClearStateBlocks();
	m_ShadowStateList.RemoveAll();
	m_SnapshotList.RemoveAll();
	m_TransitionTable.RemoveAll();
	m_TransitionOps.RemoveAll();
	m_CurrentShadowId = -1;
	m_CurrentSnapshotId = -1;
	m_DefaultStateSnapshot = -1;
}


//-----------------------------------------------------------------------------
// Sets the texture stage state
//-----------------------------------------------------------------------------
#pragma warning( disable : 4189 )

static inline void SetTextureStageState( int stage, D3DTEXTURESTAGESTATETYPE state, DWORD val )
{
	Assert( !ShaderAPI()->IsDeactivated() );

	RECORD_TEXTURE_STAGE_STATE( stage, state, val ); 

	HRESULT	hr = D3DDevice()->SetTextureStageState( stage, state, val );
	Assert( !FAILED(hr) );
}

static inline void SetRenderState( D3DRENDERSTATETYPE state, DWORD val )
{
	Assert( !ShaderAPI()->IsDeactivated() );

	RECORD_RENDER_STATE( state, val );
	
	HRESULT	hr = D3DDevice()->SetRenderState( state, val );
	Assert( !FAILED(hr) );
}

#pragma warning( default : 4189 )


//-----------------------------------------------------------------------------
// Methods that actually apply the state
//-----------------------------------------------------------------------------
#ifdef DEBUG_BOARD_STATE

static bool g_SpewTransitions = false;

#define APPLY_RENDER_STATE_FUNC( _d3dState, _state )					\
	void Apply ## _state( const ShadowState_t& shaderState, int arg ) 	\
	{																	\
		SetRenderState( _d3dState, shaderState.m_ ## _state );	\
		BoardState().m_ ## _state = shaderState.m_ ## _state;			\
		if (g_SpewTransitions)											\
		{																\
			char buf[128];												\
			sprintf( buf, "Apply %s : %d\n", #_d3dState, shaderState.m_ ## _state ); \
			OutputDebugString(buf);										\
		}																\
	}

#define APPLY_TEXTURE_STAGE_STATE_FUNC( _d3dState, _state )				\
	void Apply ## _state( const ShadowState_t& shaderState, int stage )	\
	{																	\
		SetTextureStageState( stage, _d3dState, shaderState.m_TextureStage[stage].m_ ## _state );	\
		BoardState().m_TextureStage[stage].m_ ## _state = shaderState.m_TextureStage[stage].m_ ## _state;	\
		if (g_SpewTransitions)											\
		{																\
			char buf[128];												\
			sprintf( buf, "Apply Tex %s (%d): %d\n", #_d3dState, stage, shaderState.m_TextureStage[stage].m_ ## _state ); \
			OutputDebugString(buf);										\
		}																\
	}																	\

#else

#define APPLY_RENDER_STATE_FUNC( _d3dState, _state )					\
	void Apply ## _state( const ShadowState_t& shaderState, int arg )	\
	{																	\
		SetRenderState( _d3dState, shaderState.m_ ## _state );	\
	}

#define APPLY_TEXTURE_STAGE_STATE_FUNC( _d3dState, _state )				\
	void Apply ## _state( const ShadowState_t& shaderState, int stage )	\
	{																	\
		SetTextureStageState( stage, _d3dState, shaderState.m_TextureStage[stage].m_ ## _state );	\
	}

#endif


APPLY_RENDER_STATE_FUNC( D3DRS_ZFUNC,				ZFunc )
APPLY_RENDER_STATE_FUNC( D3DRS_ZENABLE,				ZEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_ZWRITEENABLE,		ZWriteEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_COLORWRITEENABLE,	ColorWriteEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_ALPHATESTENABLE,		AlphaTestEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_ALPHAFUNC,			AlphaFunc )
APPLY_RENDER_STATE_FUNC( D3DRS_ALPHAREF,			AlphaRef )
APPLY_RENDER_STATE_FUNC( D3DRS_FILLMODE,			FillMode )
APPLY_RENDER_STATE_FUNC( D3DRS_LIGHTING,			Lighting )
APPLY_RENDER_STATE_FUNC( D3DRS_SPECULARENABLE,		SpecularEnable )
APPLY_RENDER_STATE_FUNC( D3DRS_SRGBWRITEENABLE,		SRGBWriteEnable )
APPLY_TEXTURE_STAGE_STATE_FUNC( D3DTSS_TEXCOORDINDEX, TexCoordIndex )

void ApplyAlphaBlend( const ShadowState_t& state, int stage )
{
	g_pTransitionTable->ApplyAlphaBlend( state.m_AlphaBlendEnable, state.m_SrcBlend, state.m_DestBlend );
}

void CTransitionTable::ApplyAlphaBlend( bool bEnable, D3DBLEND srcBlend, D3DBLEND destBlend )
{
	if (!bEnable)
	{
		if (m_CurrentState.m_AlphaBlendEnable)
		{
			SetRenderState( D3DRS_ALPHABLENDENABLE, bEnable );
			m_CurrentState.m_AlphaBlendEnable = bEnable;
		}
	}
	else
	{
		if (!m_CurrentState.m_AlphaBlendEnable)
		{
			SetRenderState( D3DRS_ALPHABLENDENABLE, bEnable );
			m_CurrentState.m_AlphaBlendEnable = bEnable;
		}

		// Set the blend state here...
		if (m_CurrentState.m_SrcBlend != srcBlend)
		{
			SetRenderState( D3DRS_SRCBLEND, srcBlend );
			m_CurrentState.m_SrcBlend = srcBlend;
		}

		if (m_CurrentState.m_DestBlend != destBlend)
		{
			SetRenderState( D3DRS_DESTBLEND, destBlend );
			m_CurrentState.m_DestBlend = destBlend;
		}
	}

⌨️ 快捷键说明

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