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

📄 shadershadowdx8.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 shader API
//=============================================================================

#include "ShaderShadowDX8.h"
#include "locald3dtypes.h"
#include "UtlVector.h"
#include "IShaderUtil.h"
#include "ShaderAPIDX8_Global.h"
#include "ShaderAPIDX8.h"
#include "materialsystem/IMaterialSystemHardwareConfig.h"
#include "materialsystem/IMaterialSystem.h"
#include "IMeshDX8.h"
#include "materialsystem/MaterialSystem_Config.h"
#include "vertexshaderdx8.h"

// NOTE: This must be the last file included!
#include "tier0/memdbgon.h"


//-----------------------------------------------------------------------------
// The DX8 implementation of the shader setup interface
//-----------------------------------------------------------------------------
class CShaderShadowDX8 : public IShaderShadowDX8
{
public:
	// constructor, destructor
	CShaderShadowDX8( );
	virtual ~CShaderShadowDX8();

	// Initialize render state
	void Init( );

	// Sets the default state
	void SetDefaultState();

	// Methods related to depth buffering
	void DepthFunc( ShaderDepthFunc_t depthFunc );
	void EnableDepthWrites( bool bEnable );
	void EnableDepthTest( bool bEnable );
	void EnablePolyOffset( bool bEnable );

	// Suppresses/activates color writing 
	void EnableColorWrites( bool bEnable );
	void EnableAlphaWrites( bool bEnable );

	// Methods related to alpha blending
	void EnableBlending( bool bEnable );

	void BlendFunc( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor );

	// Alpha testing
	void EnableAlphaTest( bool bEnable );
	void AlphaFunc( ShaderAlphaFunc_t alphaFunc, float alphaRef /* [0-1] */ );

	// Wireframe/filled polygons
	void PolyMode( ShaderPolyModeFace_t face, ShaderPolyMode_t polyMode );

	// Back face culling
	void EnableCulling( bool bEnable );
	
	// constant color
	void EnableConstantColor( bool bEnable );

	// Indicates we're going to light the model
	void EnableLighting( bool bEnable );

	// Indicates specular lighting is going to be used
	void EnableSpecular( bool bEnable );

	// Convert from linear to gamma color space on writes to frame buffer.
	void EnableSRGBWrite( bool bEnable );

	// Indicates we're preprocessing vertex data
	void EnableVertexDataPreprocess( bool bEnable );

	// Computes the vertex format
	void VertexShaderVertexFormat( unsigned int flags, 
			int numTexCoords, int* pTexCoordDimensions, int numBoneWeights,
			int userDataSize );

	// Pixel and vertex shader methods
	virtual void SetVertexShader( char const* pFileName, int nStaticVshIndex );
	virtual	void SetPixelShader( char const* pFileName, int nStaticPshIndex );

	// Indicates we're going to be using the ambient cube
	void EnableAmbientLightCubeOnStage0( bool bEnable );

	// Activate/deactivate skinning
	void EnableVertexBlend( bool bEnable );

	// per texture unit stuff
	void OverbrightValue( TextureStage_t stage, float value );
	void EnableTexture( TextureStage_t stage, bool bEnable );
	void EnableTexGen( TextureStage_t stage, bool bEnable );
	void TexGen( TextureStage_t stage, ShaderTexGenParam_t param );
	void TextureCoordinate( TextureStage_t stage, int useCoord );

	// alternate method of specifying per-texture unit stuff, more flexible and more complicated
	// Can be used to specify different operation per channel (alpha/color)...
	void EnableCustomPixelPipe( bool bEnable );
	void CustomTextureStages( int stageCount );
	void CustomTextureOperation( TextureStage_t stage, ShaderTexChannel_t channel,
		ShaderTexOp_t op, ShaderTexArg_t arg1, ShaderTexArg_t arg2 );

	// per texture unit stuff
	void VertexShaderOverbrightValue( float value );

	// A simpler method of dealing with alpha modulation
	void EnableAlphaPipe( bool bEnable );
	void EnableConstantAlpha( bool bEnable );
	void EnableVertexAlpha( bool bEnable );
	void EnableTextureAlpha( TextureStage_t stage, bool bEnable );

	// helper functions
	void EnableSphereMapping( TextureStage_t stage, bool bEnable );

	// Last call to be make before snapshotting
	void ComputeAggregateShadowState( );

	// Gets at the shadow state
	const ShadowState_t & GetShadowState();
	const ShadowShaderState_t & GetShadowShaderState();

	// GR - Separate alpha blending
	void EnableBlendingSeparateAlpha( bool bEnable );
	void BlendFuncSeparateAlpha( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor );


private:
	struct TextureStageState_t
	{
		int m_TexCoordIndex;
		int m_TexCoordinate;
		float m_OverbrightVal;
		bool m_TextureEnable;
		bool m_TexGenEnable;
		bool m_GenerateSphericalCoords;
		bool m_TextureAlphaEnable;
		ShaderTexArg_t	m_Arg[2][2];
		ShaderTexOp_t	m_Op[2];
	};

	// Computes the blend factor
	D3DBLEND BlendFuncValue( ShaderBlendFactor_t factor ) const;

	// Configures the FVF vertex shader
	void ConfigureFVFVertexShader( unsigned int flags );
	void ConfigureCustomFVFVertexShader( unsigned int flags );

	// Configures our texture indices
	void ConfigureTextureCoordinates( unsigned int flags );

	// Returns a blend value based on overbrighting
	D3DTEXTUREOP OverbrightBlendValue( TextureStage_t stage );

	// Sets the desired color and alpha op state
	void DrawFlags( unsigned int flags );

	// Computes a vertex format for the draw flags
	VertexFormat_t FlagsToVertexFormat( int flags ) const;

	// Indicates we've got a constant color specified
	bool HasConstantColor() const;

	// Configures the alpha pipe
	void ConfigureAlphaPipe( unsigned int flags );

	// returns true if we're using texture coordinates at a given stage
	bool IsUsingTextureCoordinates( TextureStage_t stage ) const;

	// Returns true if the snapshot thinks we're generating spheremap coordinates
	bool IsGeneratingSpheremapCoords(TextureStage_t stage) const;

	// Recomputes the tex coord index
	void RecomputeTexCoordIndex( TextureStage_t stage );

	// State needed to create the snapshots
	IMaterialSystemHardwareConfig* m_pHardwareConfig;
	
	// Separate alpha control?
	bool		m_AlphaPipe;

	// Constant color state
	bool		m_HasConstantColor;
	bool		m_HasConstantAlpha;

	// Vertex color state
	bool		m_HasVertexAlpha;

	// Preprocessing...?
	bool		m_PreprocessVertexData;

	// Ambient light cube
	bool		m_AmbientCubeEnabled;

	// funky custom method of specifying shader state
	bool		m_CustomTextureStageState;

	// Number of stages used by the custom pipeline
	int			m_CustomTextureStages;

	// Number of bones...
	int			m_NumBlendVertices;

	// Draw flags
	int			m_DrawFlags;

	// Alpha blending...
	D3DBLEND	m_SrcBlend;
	D3DBLEND	m_DestBlend;

	// GR - Separate alpha blending...
	D3DBLEND	m_SrcBlendAlpha;
	D3DBLEND	m_DestBlendAlpha;

	// Alpha testing
	D3DCMPFUNC	m_AlphaFunc;
	int			m_AlphaRef;

	// The current shadow state
	ShadowState_t m_ShadowState;
	ShadowShaderState_t m_ShadowShaderState;

	// State info stores with each texture stage
	TextureStageState_t m_TextureStage[NUM_TEXTURE_STAGES];
};


//-----------------------------------------------------------------------------
// Class factory
//-----------------------------------------------------------------------------
static CShaderShadowDX8 g_ShaderShadow;

EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderShadowDX8, IShaderShadow, 
								SHADERSHADOW_INTERFACE_VERSION, g_ShaderShadow )


//-----------------------------------------------------------------------------
// Global instance
//-----------------------------------------------------------------------------
IShaderShadowDX8* ShaderShadow()
{
	return &g_ShaderShadow;
}


//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CShaderShadowDX8::CShaderShadowDX8( ) :
	m_DrawFlags(0), m_pHardwareConfig(0), m_HasConstantColor(false)
{	
	memset( &m_ShadowState, 0, sizeof(m_ShadowState) );
	memset( &m_TextureStage, 0, sizeof(m_TextureStage) );
}

CShaderShadowDX8::~CShaderShadowDX8()
{
}


//-----------------------------------------------------------------------------
// Initialize render state
//-----------------------------------------------------------------------------
void CShaderShadowDX8::Init( )
{
	m_pHardwareConfig = HardwareConfig();
	
	// No preprocessing
	m_PreprocessVertexData = false;

	// No funky custom methods..
	m_CustomTextureStageState = false;

	// No constant color modulation
	m_HasConstantColor = false;
	m_HasConstantAlpha = false;
	m_HasVertexAlpha = false;

	m_ShadowState.m_ModulateConstantColor = false;

	// By default we're using fixed function
	m_ShadowState.m_UsingFixedFunction = true;

	// Lighting off by default
	m_ShadowState.m_Lighting = false;

	// Default overbright val
	m_ShadowState.m_VertexShaderOverbright = 1.0;

	// Pixel + vertex shaders
	m_ShadowShaderState.m_VertexShader = INVALID_VERTEX_SHADER;
	m_ShadowShaderState.m_PixelShader = INVALID_PIXEL_SHADER;
	m_ShadowShaderState.m_nStaticPshIndex = 0;
	m_ShadowShaderState.m_nStaticVshIndex = 0;

	// Drawing nothing..
	m_DrawFlags = 0;

	// No alpha control
	m_AlphaPipe = false;

	// Vertex blending
	m_NumBlendVertices = 0;
	m_ShadowState.m_VertexBlendEnable = false;

	// NOTE: If you change these defaults, change the code in ComputeAggregateShadowState + CreateTransitionTableEntry
	int i;
	for (i = 0; i < m_pHardwareConfig->GetNumTextureStages(); ++i)
	{
		m_ShadowState.m_TextureStage[i].m_ColorOp	= D3DTOP_DISABLE;
		m_ShadowState.m_TextureStage[i].m_ColorArg1 = D3DTA_TEXTURE;
		m_ShadowState.m_TextureStage[i].m_ColorArg2 = (i == 0) ? D3DTA_DIFFUSE : D3DTA_CURRENT;
		m_ShadowState.m_TextureStage[i].m_AlphaOp	= D3DTOP_DISABLE;
		m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_TEXTURE;
		m_ShadowState.m_TextureStage[i].m_AlphaArg2 = (i == 0) ? D3DTA_DIFFUSE : D3DTA_CURRENT;
		m_ShadowState.m_TextureStage[i].m_TexCoordIndex = i;
		m_ShadowState.m_TextureStage[i].m_TextureEnable = false;
		m_ShadowState.m_TextureStage[i].m_GenerateSphericalCoords = false;
	}

	for (i = 0; i < m_pHardwareConfig->GetNumTextureUnits(); ++i)
	{
		// This is state that isn't part of the snapshot per-se, because we
		// don't need it when it's actually time to render. This just helps us
		// to construct the shadow state.
		m_TextureStage[i].m_TexCoordIndex = i;
		m_TextureStage[i].m_TexGenEnable = false;
		m_TextureStage[i].m_GenerateSphericalCoords = false;

		// A *real* measure if the texture stage is being used.
		// we sometimes have to set the shadow state to not mirror this.
		m_TextureStage[i].m_TextureEnable = false;
		m_TextureStage[i].m_TextureAlphaEnable = false;
		m_TextureStage[i].m_OverbrightVal = 1.0f;
	}
}


//-----------------------------------------------------------------------------
// Sets the default state
//-----------------------------------------------------------------------------
void CShaderShadowDX8::SetDefaultState()
{
	ShaderUtil()->SetDefaultShadowState();
}


//-----------------------------------------------------------------------------
// Gets at the shadow state
//-----------------------------------------------------------------------------
const ShadowState_t &CShaderShadowDX8::GetShadowState()
{
	return m_ShadowState;
}

const ShadowShaderState_t &CShaderShadowDX8::GetShadowShaderState()
{
	return m_ShadowShaderState;
}


//-----------------------------------------------------------------------------
// Depth functions...
//-----------------------------------------------------------------------------
void CShaderShadowDX8::DepthFunc( ShaderDepthFunc_t depthFunc )
{
	D3DCMPFUNC zFunc;

	switch( depthFunc )
	{
	case SHADER_DEPTHFUNC_NEVER:
		zFunc = D3DCMP_NEVER;
		break;
	case SHADER_DEPTHFUNC_NEARER:
		zFunc = ShaderUtil()->GetConfig().bReverseDepth ? D3DCMP_GREATER : D3DCMP_LESS;
		break;
	case SHADER_DEPTHFUNC_EQUAL:
		zFunc = D3DCMP_EQUAL;
		break;
	case SHADER_DEPTHFUNC_NEAREROREQUAL:
		zFunc = ShaderUtil()->GetConfig().bReverseDepth ? D3DCMP_GREATEREQUAL : D3DCMP_LESSEQUAL;
		break;
	case SHADER_DEPTHFUNC_FARTHER:
		zFunc = ShaderUtil()->GetConfig().bReverseDepth ? D3DCMP_LESS : D3DCMP_GREATER;
		break;
	case SHADER_DEPTHFUNC_NOTEQUAL:
		zFunc = D3DCMP_NOTEQUAL;
		break;
	case SHADER_DEPTHFUNC_FARTHEROREQUAL:
		zFunc = ShaderUtil()->GetConfig().bReverseDepth ? D3DCMP_LESSEQUAL : D3DCMP_GREATEREQUAL;
		break;
	case SHADER_DEPTHFUNC_ALWAYS:
		zFunc = D3DCMP_ALWAYS;
		break;
	default:
		zFunc = D3DCMP_ALWAYS;
		Warning( "DepthFunc: invalid param\n" );
		break;
	}

	m_ShadowState.m_ZFunc = zFunc;
}

void CShaderShadowDX8::EnableDepthWrites( bool bEnable )
{
	m_ShadowState.m_ZWriteEnable = bEnable;
}

void CShaderShadowDX8::EnableDepthTest( bool bEnable )
{
	m_ShadowState.m_ZEnable = bEnable ? D3DZB_TRUE : D3DZB_FALSE;
}

void CShaderShadowDX8::EnablePolyOffset( bool bEnable )

⌨️ 快捷键说明

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