📄 shadershadowdx8.cpp
字号:
}
}
// Deal with texture stage 1 -> n
int lastUsedTextureStage = 0;
for ( int i = 1; 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;
// Not doing anything? Disable the stage
if (!IsUsingTextureCoordinates( (TextureStage_t)i ))
{
if (m_TextureStage[i].m_OverbrightVal < 2.0f)
{
m_ShadowState.m_TextureStage[i].m_ColorOp = D3DTOP_DISABLE;
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_DISABLE;
}
else
{
// Here, we're modulating. Add in the constant color if we need to...
m_ShadowState.m_TextureStage[i].m_ColorArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[i].m_AlphaArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[i].m_ColorOp = OverbrightBlendValue((TextureStage_t)i);
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_MODULATE;
isUsingConstantColor = false;
lastUsedTextureStage = i;
}
}
else
{
// Here, we're modulating. Keep track of the last modulation stage,
// cause the constant color modulation comes in the stage after that
lastUsedTextureStage = i;
m_ShadowState.m_TextureStage[i].m_ColorOp = OverbrightBlendValue((TextureStage_t)i);
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_MODULATE;
}
}
// massive amounts of suck: gotta overbright here if we really
// wanted to overbright stage0 but couldn't because of the add.
// This isn't totally correct, but there's no way around putting it here
// because we can't texture out of stage2 on low or medium end hardware
m_ShadowState.m_ModulateConstantColor = false;
if (isUsingConstantColor)
{
++lastUsedTextureStage;
if (isUsingConstantColor &&
(lastUsedTextureStage >= m_pHardwareConfig->GetNumTextureStages()))
{
// This is the case where we'd want to modulate in a particular texture
// stage, but we can't because there aren't enough. In this case, we're gonna
// need to do the modulation in the per-vertex color.
m_ShadowState.m_ModulateConstantColor = true;
}
else
{
Assert (lastUsedTextureStage < 2);
// Here, we've got enough texture stages to do the modulation
m_ShadowState.m_TextureStage[lastUsedTextureStage].m_ColorArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[lastUsedTextureStage].m_ColorArg2 = D3DTA_CURRENT;
m_ShadowState.m_TextureStage[lastUsedTextureStage].m_AlphaArg1 = D3DTA_TFACTOR;
m_ShadowState.m_TextureStage[lastUsedTextureStage].m_AlphaArg2 = D3DTA_CURRENT;
m_ShadowState.m_TextureStage[lastUsedTextureStage].m_ColorOp = D3DTOP_MODULATE;
m_ShadowState.m_TextureStage[lastUsedTextureStage].m_AlphaOp = D3DTOP_MODULATE;
}
}
// Overwrite the alpha stuff if we asked to independently control it
if (m_AlphaPipe)
ConfigureAlphaPipe( flags );
}
//-----------------------------------------------------------------------------
// Makes sure we report if we're getting garbage.
//-----------------------------------------------------------------------------
void CShaderShadowDX8::DrawFlags( unsigned int flags )
{
m_DrawFlags = flags;
m_ShadowState.m_UsingFixedFunction = true;
}
//-----------------------------------------------------------------------------
// Compute texture coordinates
//-----------------------------------------------------------------------------
void CShaderShadowDX8::ConfigureTextureCoordinates( unsigned int flags )
{
// default...
for (int i = 0; i < m_pHardwareConfig->GetNumTextureUnits(); ++i)
{
TextureCoordinate( (TextureStage_t)i, i );
}
if (flags & SHADER_DRAW_TEXCOORD0)
{
Assert( (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD0) == 0 );
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD0) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE0, 0 );
}
else if (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD0)
{
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD0) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE0, 1 );
}
else if (flags & (SHADER_DRAW_TEXGEN_TEXCOORD0 | SHADER_DRAW_SECONDARY_TEXCOORD0) )
{
TextureCoordinate( SHADER_TEXTURE_STAGE0, 2 );
}
if (flags & SHADER_DRAW_TEXCOORD1)
{
Assert( (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD1) == 0 );
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD1) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE1, 0 );
}
else if (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD1)
{
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD1) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE1, 1 );
}
else if (flags & (SHADER_DRAW_TEXGEN_TEXCOORD1 | SHADER_DRAW_SECONDARY_TEXCOORD1) )
{
TextureCoordinate( SHADER_TEXTURE_STAGE1, 2 );
}
if (flags & SHADER_DRAW_TEXCOORD2)
{
Assert( (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD2) == 0 );
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD2) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE2, 0 );
}
else if (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD2)
{
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD2) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE2, 1 );
}
else if (flags & (SHADER_DRAW_TEXGEN_TEXCOORD2 | SHADER_DRAW_SECONDARY_TEXCOORD2) )
{
TextureCoordinate( SHADER_TEXTURE_STAGE2, 2 );
}
if (flags & SHADER_DRAW_TEXCOORD3)
{
Assert( (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD3) == 0 );
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD3) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE3, 0 );
}
else if (flags & SHADER_DRAW_LIGHTMAP_TEXCOORD3)
{
Assert( (flags & SHADER_DRAW_TEXGEN_TEXCOORD3) == 0 );
TextureCoordinate( SHADER_TEXTURE_STAGE3, 1 );
}
else if (flags & (SHADER_DRAW_TEXGEN_TEXCOORD3 | SHADER_DRAW_SECONDARY_TEXCOORD3) )
{
TextureCoordinate( SHADER_TEXTURE_STAGE3, 2 );
}
}
//-----------------------------------------------------------------------------
// Converts draw flags into vertex format
//-----------------------------------------------------------------------------
VertexFormat_t CShaderShadowDX8::FlagsToVertexFormat( int flags ) const
{
// Flags -1 occurs when there's an error condition;
// we'll just give em the max space and let them fill it in.
int formatFlags = 0;
int numTexCoords = 0;
int texCoordSize[4] = { 0, 0, 0, 0 };
int userDataSize = 0;
int numBones = 0;
// Flags -1 occurs when there's an error condition;
// we'll just give em the max space and let them fill it in.
if (flags == -1)
{
formatFlags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_COLOR |
VERTEX_TANGENT_S | VERTEX_TANGENT_T;
numTexCoords = 3;
texCoordSize[0] = texCoordSize[1] = texCoordSize[2] = 2;
}
else
{
if (flags & SHADER_DRAW_POSITION)
formatFlags |= VERTEX_POSITION;
if (flags & SHADER_DRAW_NORMAL)
formatFlags |= VERTEX_NORMAL;
if (flags & SHADER_DRAW_COLOR)
formatFlags |= VERTEX_COLOR;
if( flags & SHADER_DRAW_SPECULAR )
formatFlags |= VERTEX_SPECULAR;
if (flags & SHADER_TEXCOORD_MASK)
{
// normal texture coords into texture 0
numTexCoords = 1;
texCoordSize[0] = 2;
}
if (flags & SHADER_LIGHTMAP_TEXCOORD_MASK)
{
// lightmaps go into texcoord 1
numTexCoords = 2;
texCoordSize[1] = 2;
}
if (flags & (SHADER_TEXGEN_TEXCOORD_MASK | SHADER_SECONDARY_TEXCOORD_MASK))
{
// any texgen, or secondary texture coordinate is put into texcoord 2
numTexCoords = 3;
texCoordSize[2] = 2;
}
}
// Hardware skinning... always store space for up to 3 bones
// and always assume index blend enabled if available
if (m_ShadowState.m_VertexBlendEnable)
{
if (HardwareConfig()->MaxBlendMatrixIndices() > 0)
formatFlags |= VERTEX_BONE_INDEX;
if (HardwareConfig()->MaxBlendMatrices() > 2)
numBones = 2; // the third bone weight is implied
else
numBones = HardwareConfig()->MaxBlendMatrices() - 1;
}
return MeshMgr()->ComputeVertexFormat( formatFlags, numTexCoords,
texCoordSize, numBones, userDataSize );
}
//-----------------------------------------------------------------------------
// Computes shadow state based on bunches of other parameters
//-----------------------------------------------------------------------------
void CShaderShadowDX8::ComputeAggregateShadowState( )
{
bool isPreprocessing = m_PreprocessVertexData;
unsigned int flags = 0;
// Initialize the texture stage usage; this may get changed later
for (int i = 0; i < m_pHardwareConfig->GetNumTextureUnits(); ++i)
{
m_ShadowState.m_TextureStage[i].m_TextureEnable =
IsUsingTextureCoordinates( (TextureStage_t)i );
// Deal with the alpha pipe
if ( m_ShadowState.m_UsingFixedFunction && m_AlphaPipe)
{
if (m_TextureStage[i].m_TextureAlphaEnable)
{
m_ShadowState.m_TextureStage[i].m_TextureEnable = true;
}
}
}
// Always use the same alpha src + dest if it's disabled
// NOTE: This is essential for stateblocks to work
if (m_ShadowState.m_AlphaBlendEnable)
{
m_ShadowState.m_SrcBlend = m_SrcBlend;
m_ShadowState.m_DestBlend = m_DestBlend;
}
else
{
m_ShadowState.m_SrcBlend = D3DBLEND_ONE;
m_ShadowState.m_DestBlend = D3DBLEND_ZERO;
}
// GR
if (m_ShadowState.m_SeparateAlphaBlendEnable)
{
m_ShadowState.m_SrcBlendAlpha = m_SrcBlendAlpha;
m_ShadowState.m_DestBlendAlpha = m_DestBlendAlpha;
}
else
{
m_ShadowState.m_SrcBlendAlpha = D3DBLEND_ONE;
m_ShadowState.m_DestBlendAlpha = D3DBLEND_ZERO;
}
// Use the same func if it's disabled
if (m_ShadowState.m_AlphaTestEnable)
{
m_ShadowState.m_AlphaFunc = m_AlphaFunc;
m_ShadowState.m_AlphaRef = m_AlphaRef;
}
else
{
// A default value
m_ShadowState.m_AlphaFunc = D3DCMP_GREATEREQUAL;
m_ShadowState.m_AlphaRef = 0;
}
if ( m_ShadowState.m_UsingFixedFunction )
{
flags = m_DrawFlags;
// We need to take this bad boy into account
if (HasConstantColor())
flags |= SHADER_HAS_CONSTANT_COLOR;
// We need to take lighting into account..
if ((m_ShadowState.m_Lighting) || m_AmbientCubeEnabled)
flags |= SHADER_DRAW_NORMAL;
if (m_ShadowState.m_Lighting)
flags |= SHADER_DRAW_COLOR;
// Look for inconsistency in the shadow state (can't have texgen &
// SHADER_DRAW_TEXCOORD or SHADER_DRAW_SECONDARY_TEXCOORD0 on the same stage)
if (flags & (SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_SECONDARY_TEXCOORD0))
{
if (m_AmbientCubeEnabled)
{
Warning("Invalid shader configuration! Can't use stage0 when ambient light cube is enabled!\n");
}
Assert( (m_ShadowState.m_TextureStage[0].m_TexCoordIndex & 0xFFFF0000) == 0 );
}
if (flags & (SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_SECONDARY_TEXCOORD1))
{
Assert( (m_ShadowState.m_TextureStage[1].m_TexCoordIndex & 0xFFFF0000) == 0 );
}
if (flags & (SHADER_DRAW_TEXCOORD2 | SHADER_DRAW_SECONDARY_TEXCOORD2))
{
Assert( (m_ShadowState.m_TextureStage[2].m_TexCoordIndex & 0xFFFF0000) == 0 );
}
if (flags & (SHADER_DRAW_TEXCOORD3 | SHADER_DRAW_SECONDARY_TEXCOORD3))
{
Assert( (m_ShadowState.m_TextureStage[3].m_TexCoordIndex & 0xFFFF0000) == 0 );
}
int texFlags[] =
{
SHADER_DRAW_TEXGEN_TEXCOORD0,
SHADER_DRAW_TEXGEN_TEXCOORD1,
SHADER_DRAW_TEXGEN_TEXCOORD2,
SHADER_DRAW_TEXGEN_TEXCOORD3,
};
// Spheremap coordinates always go into tex coord 0
int i;
for ( i = 0; i < m_pHardwareConfig->GetNumTextureUnits(); ++i)
{
if (IsGeneratingSpheremapCoords((TextureStage_t)i))
{
flags |= texFlags[i];
isPreprocessing = true;
}
}
// If we have to modulate the constant color (computed in ConfigureFVF)
// then we're going to be modifying vertex data
if (m_ShadowState.m_ModulateConstantColor)
isPreprocessing = true;
// Vertex usage has already been set for pixel + vertex shaders
m_ShadowState.m_VertexUsage = FlagsToVertexFormat( flags );
// Configure the texture stages
ConfigureFVFVertexShader(flags);
#if 0
//#ifdef _DEBUG
// NOTE: This must be true for stateblocks to work
for ( i = 0; i < m_pHardwareConfig->GetNumTextureStages(); ++i )
{
if ( m_ShadowState.m_TextureStage[i].m_ColorOp == D3DTOP_DISABLE )
{
Assert( m_ShadowState.m_TextureStage[i].m_ColorArg1 == D3DTA_TEXTURE );
Assert( m_ShadowState.m_TextureStage[i].m_ColorArg2 == ((i == 0) ? D3DTA_DIFFUSE : D3DTA_CURRENT) );
}
if ( m_ShadowState.m_TextureStage[i].m_AlphaOp == D3DTOP_DISABLE )
{
Assert( m_ShadowState.m_TextureStage[i].m_AlphaArg1 == D3DTA_TEXTURE );
Assert( m_ShadowState.m_TextureStage[i].m_AlphaArg2 == ((i == 0) ? D3DTA_DIFFUSE : D3DTA_CURRENT) );
}
}
#endif
}
else
{
// Pixel shaders, disable everything so as to prevent unnecessary state changes....
for ( int i = 0; i < m_pHardwareConfig->GetNumTextureStages(); ++i )
{
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_AlphaArg1 = D3DTA_TEXTURE;
m_ShadowState.m_TextureStage[i].m_AlphaArg2 = (i == 0) ? D3DTA_DIFFUSE : D3DTA_CURRENT;
m_ShadowState.m_TextureStage[i].m_ColorOp = D3DTOP_DISABLE;
m_ShadowState.m_TextureStage[i].m_AlphaOp = D3DTOP_DISABLE;
m_ShadowState.m_TextureStage[i].m_TexCoordIndex = i;
m_ShadowState.m_TextureStage[i].m_GenerateSphericalCoords = false;
}
m_ShadowState.m_Lighting = false;
m_ShadowState.m_SpecularEnable = false;
m_ShadowState.m_VertexBlendEnable = false;
m_ShadowState.m_AmbientCubeOnStage0 = false;
m_ShadowState.m_ModulateConstantColor = false;
}
// Compute texture coordinates
ConfigureTextureCoordinates(flags);
// This is naughty of me, but it's simplest best place for this for now
if (isPreprocessing)
{
m_ShadowState.m_VertexUsage |= VERTEX_PREPROCESS_DATA;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -