Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

289 lines
8.6 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
// Implementation of the sprite shader
//=============================================================================//
#include "shaderlib/cshader.h"
#include <string.h>
#include "const.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// WARNING! Change these in engine/SpriteGn.h if you change them here!
#define SPR_VP_PARALLEL_UPRIGHT 0
#define SPR_FACING_UPRIGHT 1
#define SPR_VP_PARALLEL 2
#define SPR_ORIENTED 3
#define SPR_VP_PARALLEL_ORIENTED 4
DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX6 )
BEGIN_SHADER( Sprite_DX6,
"Help for Sprite_DX6" )
BEGIN_SHADER_PARAMS
SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" )
SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" )
SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" )
SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" )
END_SHADER_PARAMS
SHADER_INIT_PARAMS()
{
// FIXME: This can share code with sprite.cpp
// FIXME: Not sure if this is the best solution, but it's a very]
// easy one. When graphics aren't enabled, we oftentimes need to get
// at the parameters of a shader. Therefore, we must set the default
// values in a separate phase from when we load resources.
if (!params[ALPHA]->IsDefined())
params[ ALPHA ]->SetFloatValue( 1.0f );
SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR );
SET_FLAGS( MATERIAL_VAR_VERTEXALPHA );
// translate from a string orientation to an enumeration
if (params[SPRITEORIENTATION]->IsDefined())
{
const char *orientationString = params[SPRITEORIENTATION]->GetStringValue();
if( stricmp( orientationString, "parallel_upright" ) == 0 )
{
params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT );
}
else if( stricmp( orientationString, "facing_upright" ) == 0 )
{
params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT );
}
else if( stricmp( orientationString, "vp_parallel" ) == 0 )
{
params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL );
}
else if( stricmp( orientationString, "oriented" ) == 0 )
{
params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED );
}
else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 )
{
params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED );
}
else
{
Warning( "error with $spriteOrientation\n" );
params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT );
}
}
else
{
// default case
params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT );
}
}
SHADER_INIT
{
LoadTexture( BASETEXTURE );
}
SHADER_DRAW
{
SHADOW_STATE
{
pShaderShadow->EnableCulling( false );
}
switch( params[SPRITERENDERMODE]->GetIntValue() )
{
case kRenderNormal:
SHADOW_STATE
{
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 );
FogToFogColor();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
break;
case kRenderTransColor:
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
FogToFogColor();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
break;
case kRenderTransTexture:
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
FogToFogColor();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
break;
case kRenderGlow:
case kRenderWorldGlow:
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableDepthTest( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
FogToBlack();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
break;
case kRenderTransAlpha:
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
FogToFogColor();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
break;
case kRenderTransAlphaAdd:
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
FogToFogColor();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
SHADOW_STATE
{
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
FogToBlack();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
break;
case kRenderTransAdd:
SHADOW_STATE
{
if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() )
{
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 );
}
else
{
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
}
pShaderShadow->EnableConstantColor( true );
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
FogToBlack();
}
DYNAMIC_STATE
{
SetColorState( COLOR, ALPHA );
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
}
Draw();
break;
case kRenderTransAddFrameBlend:
{
float flFrame = params[FRAME]->GetFloatValue();
float flFade = params[ALPHA]->GetFloatValue();
SHADOW_STATE
{
if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() )
{
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 );
}
else
{
pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR );
}
pShaderShadow->EnableConstantColor( true );
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
FogToBlack();
}
DYNAMIC_STATE
{
float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame );
pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha );
ITexture *pTexture = params[BASETEXTURE]->GetTextureValue();
BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame );
}
Draw();
SHADOW_STATE
{
FogToBlack();
}
DYNAMIC_STATE
{
float frameBlendAlpha = ( flFrame - ( int )flFrame );
pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha );
ITexture *pTexture = params[BASETEXTURE]->GetTextureValue();
int numAnimationFrames = pTexture->GetNumAnimationFrames();
BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames );
}
Draw();
}
break;
default:
ShaderWarning( "shader Sprite: Unknown sprite render mode\n" );
break;
}
}
END_SHADER