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

📄 shadershadowdx8.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 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 + -