📄 shadershadowdx8.cpp
字号:
// per texture unit stuff
//-----------------------------------------------------------------------------
void CShaderShadowDX8::VertexShaderOverbrightValue( float value )
{
if (m_pHardwareConfig->SupportsVertexAndPixelShaders())
{
m_ShadowState.m_VertexShaderOverbright = value;
}
}
//-----------------------------------------------------------------------------
// 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 CShaderShadowDX8::EnableCustomPixelPipe( bool bEnable )
{
m_CustomTextureStageState = bEnable;
}
void CShaderShadowDX8::CustomTextureStages( int stageCount )
{
m_CustomTextureStages = stageCount;
Assert( stageCount <= m_pHardwareConfig->GetNumTextureStages() );
if ( stageCount > m_pHardwareConfig->GetNumTextureStages() )
stageCount = m_pHardwareConfig->GetNumTextureStages();
}
void CShaderShadowDX8::CustomTextureOperation( TextureStage_t stage,
ShaderTexChannel_t channel, ShaderTexOp_t op, ShaderTexArg_t arg1, ShaderTexArg_t arg2 )
{
m_TextureStage[stage].m_Op[channel]= op;
m_TextureStage[stage].m_Arg[channel][0] = arg1;
m_TextureStage[stage].m_Arg[channel][1] = arg2;
}
//-----------------------------------------------------------------------------
// Compute the vertex format from vertex descriptor flags
//-----------------------------------------------------------------------------
void CShaderShadowDX8::VertexShaderVertexFormat( unsigned int flags,
int numTexCoords, int* pTexCoordDimensions, int numBoneWeights,
int userDataSize )
{
// This indicates we're using a vertex shader
flags |= VERTEX_FORMAT_VERTEX_SHADER;
m_ShadowState.m_VertexUsage = MeshMgr()->ComputeVertexFormat( flags, numTexCoords,
pTexCoordDimensions, numBoneWeights, userDataSize);
m_ShadowState.m_UsingFixedFunction = false;
}
//-----------------------------------------------------------------------------
// Pixel and vertex shader methods
//-----------------------------------------------------------------------------
void CShaderShadowDX8::SetVertexShader( char const* pFileName, int nStaticVshIndex )
{
Assert( nStaticVshIndex == 0 );
m_ShadowShaderState.m_VertexShader = ShaderManager()->CreateVertexShader( pFileName, nStaticVshIndex );
m_ShadowShaderState.m_nStaticVshIndex = nStaticVshIndex;
}
void CShaderShadowDX8::SetPixelShader( char const* pFileName, int nStaticPshIndex )
{
m_ShadowShaderState.m_PixelShader = ShaderManager()->CreatePixelShader( pFileName, nStaticPshIndex );
m_ShadowShaderState.m_nStaticPshIndex = nStaticPshIndex;
}
//-----------------------------------------------------------------------------
// Data preprocessing
//-----------------------------------------------------------------------------
void CShaderShadowDX8::EnableVertexDataPreprocess( bool bEnable )
{
m_PreprocessVertexData = bEnable;
}
//-----------------------------------------------------------------------------
// NOTE: See Version 5 of this file for NVidia 8-stage shader stuff
//-----------------------------------------------------------------------------
inline bool CShaderShadowDX8::IsUsingTextureCoordinates( TextureStage_t stage ) const
{
if (m_ShadowState.m_UsingFixedFunction && (stage == SHADER_TEXTURE_STAGE0) &&
m_AmbientCubeEnabled)
{
return true;
}
return m_TextureStage[stage].m_TextureEnable;
}
inline D3DTEXTUREOP CShaderShadowDX8::OverbrightBlendValue( TextureStage_t stage )
{
D3DTEXTUREOP colorop;
if (m_TextureStage[stage].m_OverbrightVal < 2.0F)
colorop = D3DTOP_MODULATE;
else if (m_TextureStage[stage].m_OverbrightVal < 4.0F)
colorop = D3DTOP_MODULATE2X;
else
colorop = D3DTOP_MODULATE4X;
return colorop;
}
static inline int ComputeArg( ShaderTexArg_t arg )
{
switch(arg)
{
case SHADER_TEXARG_TEXTURE:
return D3DTA_TEXTURE;
case SHADER_TEXARG_ZERO:
return D3DTA_SPECULAR | D3DTA_COMPLEMENT;
case SHADER_TEXARG_ONE:
return D3DTA_SPECULAR;
case SHADER_TEXARG_TEXTUREALPHA:
return D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE;
case SHADER_TEXARG_INVTEXTUREALPHA:
return D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE | D3DTA_COMPLEMENT;
case SHADER_TEXARG_NONE:
case SHADER_TEXARG_VERTEXCOLOR:
return D3DTA_DIFFUSE;
case SHADER_TEXARG_SPECULARCOLOR:
return D3DTA_SPECULAR;
case SHADER_TEXARG_CONSTANTCOLOR:
return D3DTA_TFACTOR;
case SHADER_TEXARG_PREVIOUSSTAGE:
return D3DTA_CURRENT;
}
Assert(0);
return D3DTA_TEXTURE;
}
static inline D3DTEXTUREOP ComputeOp( ShaderTexOp_t op )
{
switch(op)
{
case SHADER_TEXOP_MODULATE:
return D3DTOP_MODULATE;
case SHADER_TEXOP_MODULATE2X:
return D3DTOP_MODULATE2X;
case SHADER_TEXOP_SELECTARG1:
return D3DTOP_SELECTARG1;
case SHADER_TEXOP_SELECTARG2:
return D3DTOP_SELECTARG2;
case SHADER_TEXOP_ADD:
return D3DTOP_ADD;
case SHADER_TEXOP_SUBTRACT:
return D3DTOP_SUBTRACT;
case SHADER_TEXOP_ADDSIGNED2X:
return D3DTOP_ADDSIGNED2X;
case SHADER_TEXOP_BLEND_CONSTANTALPHA:
return D3DTOP_BLENDFACTORALPHA;
case SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA:
return D3DTOP_BLENDCURRENTALPHA;
case SHADER_TEXOP_BLEND_TEXTUREALPHA:
return D3DTOP_BLENDTEXTUREALPHA;
case SHADER_TEXOP_DISABLE:
return D3DTOP_DISABLE;
}
Assert(0);
return D3DTOP_MODULATE;
}
void CShaderShadowDX8::ConfigureCustomFVFVertexShader( unsigned int flags )
{
int i;
for ( i = 0; i < m_CustomTextureStages; ++i)
{
m_ShadowState.m_TextureStage[i].m_ColorArg1 = ComputeArg( m_TextureStage[i].m_Arg[0][0] );
m_ShadowState.m_TextureStage[i].m_ColorArg2 = ComputeArg( m_TextureStage[i].m_Arg[0][1] );
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = ComputeArg( m_TextureStage[i].m_Arg[1][0] );
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = ComputeArg( m_TextureStage[i].m_Arg[1][1] );
m_ShadowState.m_TextureStage[i].m_ColorOp = ComputeOp( m_TextureStage[i].m_Op[0] );
m_ShadowState.m_TextureStage[i].m_AlphaOp = ComputeOp( m_TextureStage[i].m_Op[1] );
}
// Deal with texture stage 1 -> n
for ( i = m_CustomTextureStages; i < m_pHardwareConfig->GetNumTextureStages(); ++i )
{
m_ShadowState.m_TextureStage[i].m_ColorArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[i].m_ColorArg2 = D3DTA_CURRENT;
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = D3DTA_CURRENT;
m_ShadowState.m_TextureStage[i].m_ColorOp = D3DTOP_DISABLE;
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_DISABLE;
}
}
//-----------------------------------------------------------------------------
// Sets up the alpha texture stage state
//-----------------------------------------------------------------------------
void CShaderShadowDX8::ConfigureAlphaPipe( unsigned int flags )
{
// Are we using color?
bool isUsingVertexAlpha = m_HasVertexAlpha && ((flags & SHADER_DRAW_COLOR) != 0);
bool isUsingConstantAlpha = m_HasConstantAlpha;
int lastTextureStage = m_pHardwareConfig->GetNumTextureUnits();
while (lastTextureStage >= 0)
{
if ( m_TextureStage[lastTextureStage].m_TextureAlphaEnable )
break;
--lastTextureStage;
}
for (int i = 0; i < m_pHardwareConfig->GetNumTextureStages(); ++i)
{
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_MODULATE;
if ( m_TextureStage[i].m_TextureAlphaEnable )
{
if (i == 0)
{
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[i].m_AlphaArg2 =
isUsingConstantAlpha ? D3DTA_TFACTOR : D3DTA_DIFFUSE;
if (!isUsingConstantAlpha && !isUsingVertexAlpha)
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_SELECTARG1;
if (isUsingConstantAlpha)
isUsingConstantAlpha = false;
else if (isUsingVertexAlpha)
isUsingVertexAlpha = false;
}
else
{
// Deal with texture stage 0
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = D3DTA_CURRENT;
}
}
else
{
// Blat out unused stages
if ((i > lastTextureStage) && !isUsingVertexAlpha && !isUsingConstantAlpha)
{
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = D3DTA_CURRENT;
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_DISABLE;
continue;
}
// No texture coordinates; try to fold in vertex or constant alpha
if (i == 0)
{
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = D3DTA_DIFFUSE;
if (isUsingVertexAlpha)
{
m_ShadowState.m_TextureStage[i].m_AlphaOp =
isUsingConstantAlpha ? D3DTOP_MODULATE : D3DTOP_SELECTARG2;
}
else
{
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_SELECTARG1;
}
isUsingVertexAlpha = false;
isUsingConstantAlpha = false;
}
else
{
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_CURRENT;
if (isUsingConstantAlpha)
{
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = D3DTA_TFACTOR;
isUsingConstantAlpha = false;
}
else if (isUsingVertexAlpha)
{
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = D3DTA_DIFFUSE;
isUsingVertexAlpha = false;
}
else
{
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = D3DTA_DIFFUSE;
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_SELECTARG1;
}
}
}
}
}
//-----------------------------------------------------------------------------
// Sets up the texture stage state
//-----------------------------------------------------------------------------
void CShaderShadowDX8::ConfigureFVFVertexShader( unsigned int flags )
{
// For non-modulation, we can't really use the path below...
if (m_CustomTextureStageState)
{
ConfigureCustomFVFVertexShader( flags );
return;
}
// Deal with texture stage 0
m_ShadowState.m_TextureStage[0].m_ColorArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[0].m_ColorArg2 = D3DTA_DIFFUSE;
m_ShadowState.m_TextureStage[0].m_AlphaArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[0].m_AlphaArg2 = D3DTA_DIFFUSE;
// Are we using color?
bool isUsingVertexColor = (flags & SHADER_DRAW_COLOR) != 0;
bool isUsingConstantColor = (flags & SHADER_HAS_CONSTANT_COLOR) != 0;
// Are we using texture coordinates?
if (IsUsingTextureCoordinates( SHADER_TEXTURE_STAGE0 ))
{
if (isUsingVertexColor)
{
if (!m_AmbientCubeEnabled)
{
m_ShadowState.m_TextureStage[0].m_ColorOp = OverbrightBlendValue(SHADER_TEXTURE_STAGE0);
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_MODULATE;
}
else
{
if (flags & (SHADER_DRAW_TEXCOORD0 |
SHADER_DRAW_LIGHTMAP_TEXCOORD0 | SHADER_DRAW_TEXGEN_TEXCOORD0))
{
Warning("Invalid shader configuration! Can't use stage0 when ambient light cube is enabled!\n");
Assert(0);
}
// can't have overbright on stage 0
Assert(m_TextureStage[0].m_OverbrightVal < 2.0f);
m_ShadowState.m_TextureStage[0].m_ColorOp = D3DTOP_ADDSIGNED2X;
// WARNING: If this is change to arg2 to enable specular lighting (or
// otherwise), alpha testing, etc. gets borked.
// should make the next texture unit not use the alpha from this texture
// unit. . revisit if we need to do specular per vertex lighting.
// m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_SELECTARG2;
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_SELECTARG1;
}
}
else
{
// Just blend in the constant color here, and don't blend it in below
m_ShadowState.m_TextureStage[0].m_ColorArg2 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[0].m_AlphaArg2 = D3DTA_TFACTOR;
isUsingConstantColor = false;
m_ShadowState.m_TextureStage[0].m_ColorOp = OverbrightBlendValue(SHADER_TEXTURE_STAGE0);
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_MODULATE;
}
}
else
{
Assert(!m_AmbientCubeEnabled);
// Are we using color?
if (isUsingVertexColor)
{
// Color, but no texture
if ( m_TextureStage[0].m_OverbrightVal < 2.0f )
{
// Use diffuse * constant color, if we have a constant color
if (isUsingConstantColor)
{
m_ShadowState.m_TextureStage[0].m_ColorArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[0].m_AlphaArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[0].m_ColorOp = OverbrightBlendValue((TextureStage_t)0);
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_MODULATE;
// This'll make sure we don't apply the constant color again below
isUsingConstantColor = false;
}
else
{
m_ShadowState.m_TextureStage[0].m_ColorOp = D3DTOP_SELECTARG2;
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_SELECTARG2;
}
}
else if (m_TextureStage[0].m_OverbrightVal < 4.0f)
{
// Produce diffuse + diffuse
m_ShadowState.m_TextureStage[0].m_ColorArg1 = D3DTA_DIFFUSE;
m_ShadowState.m_TextureStage[0].m_ColorOp = D3DTOP_ADD;
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_SELECTARG2;
}
else
{
// no 4x overbright yet!
Assert(0);
}
}
else
{
// No texture, no color
if (isUsingConstantColor)
{
m_ShadowState.m_TextureStage[0].m_ColorArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[0].m_AlphaArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[0].m_ColorOp = D3DTOP_SELECTARG1;
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_SELECTARG1;
// This'll make sure we don't apply the constant color again below
isUsingConstantColor = false;
}
else
{
// Deal with texture stage 0
m_ShadowState.m_TextureStage[0].m_ColorArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[0].m_AlphaArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[0].m_ColorOp = D3DTOP_SELECTARG1;
m_ShadowState.m_TextureStage[0].m_AlphaOp = D3DTOP_SELECTARG1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -