📄 shadershadowdx8.cpp
字号:
//=========== (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 + -