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

📄 shadershadowdx8.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		}
	}

	// 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 + -