Files
source-sdk-2013/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp
Joe Ludwig 7309a5f13f Added many shader source files
This should include the latest version of every shader that was in the
2007 SDK. It also includes a smattering of debug shaders, both VR
distortion shaders, and other assorted shaders that will hopefully be
useful.

None of these new files are included in the game shader DLL project. If
you need to modify one of these shaders for use in your mod you will
need to rename it so that you don't collide with the version of that
shader that lives in stdshader_dx9.dll.
2013-12-23 15:00:03 -08:00

803 lines
25 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Lightmap only shader
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#include "BaseVSShader.h"
#include "lightmappedgeneric_vs11.inc"
#include "unlitgeneric_vs11.inc"
#include "worldvertextransition_seamless.inc"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT );
DEFINE_FALLBACK_SHADER( LightmappedGeneric, LightmappedGeneric_DX8 )
BEGIN_VS_SHADER( LightmappedGeneric_DX8,
"Help for LightmappedGeneric_DX8" )
BEGIN_SHADER_PARAMS
SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" )
SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" )
SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" )
SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" )
SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "amount of detail texture to apply" )
SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" )
SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" )
SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" )
SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" )
SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" )
SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" )
SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" )
SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" )
SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" )
SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" )
SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" )
SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" )
SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_INTEGER, "90", "Do specular pass only on dxlevel or higher (ie.80, 81, 90)" )
SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_BOOL, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" )
SHADER_PARAM( FORCEBUMP, SHADER_PARAM_TYPE_BOOL, "0", "0 == Do bumpmapping if the card says it can handle it. 1 == Always do bumpmapping." )
SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" )
SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" )
SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" )
END_SHADER_PARAMS
virtual bool ShouldUseBumpmapping( IMaterialVar **params )
{
return g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined();
}
// Set up anything that is necessary to make decisions in SHADER_FALLBACK.
SHADER_INIT_PARAMS()
{
// FLASHLIGHTFIXME
params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" );
// Write over $basetexture with $albedo if we are going to be using diffuse normal mapping.
if( ShouldUseBumpmapping( params ) && params[ALBEDO]->IsDefined() &&
params[BASETEXTURE]->IsDefined() &&
!( params[NODIFFUSEBUMPLIGHTING]->IsDefined() && params[NODIFFUSEBUMPLIGHTING]->GetIntValue() ) )
{
params[BASETEXTURE]->SetStringValue( params[ALBEDO]->GetStringValue() );
}
if( IsUsingGraphics() && params[ENVMAP]->IsDefined() && !CanUseEditorMaterials() )
{
if( stricmp( params[ENVMAP]->GetStringValue(), "env_cubemap" ) == 0 )
{
Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName );
params[ENVMAP]->SetUndefined();
}
}
if( !params[ENVMAPMASKSCALE]->IsDefined() )
{
params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f );
}
if( !params[ENVMAPTINT]->IsDefined() )
{
params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f );
}
if( !params[SELFILLUMTINT]->IsDefined() )
{
params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f );
}
if( !params[DETAILSCALE]->IsDefined() )
{
params[DETAILSCALE]->SetFloatValue( 4.0f );
}
if( !params[DETAILBLENDFACTOR]->IsDefined() )
{
params[DETAILBLENDFACTOR]->SetFloatValue( 1.0f );
}
if( !params[FRESNELREFLECTION]->IsDefined() )
{
params[FRESNELREFLECTION]->SetFloatValue( 1.0f );
}
if( !params[ENVMAPMASKFRAME]->IsDefined() )
{
params[ENVMAPMASKFRAME]->SetIntValue( 0 );
}
if( !params[ENVMAPFRAME]->IsDefined() )
{
params[ENVMAPFRAME]->SetIntValue( 0 );
}
if( !params[BUMPFRAME]->IsDefined() )
{
params[BUMPFRAME]->SetIntValue( 0 );
}
if( !params[ENVMAPCONTRAST]->IsDefined() )
{
params[ENVMAPCONTRAST]->SetFloatValue( 0.0f );
}
if( !params[ENVMAPSATURATION]->IsDefined() )
{
params[ENVMAPSATURATION]->SetFloatValue( 1.0f );
}
if( !params[ALPHATESTREFERENCE]->IsDefined() )
{
params[ALPHATESTREFERENCE]->SetFloatValue( 0.0f );
}
// No texture means no self-illum or env mask in base alpha
if ( !params[BASETEXTURE]->IsDefined() )
{
CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
}
// If in decal mode, no debug override...
if (IS_FLAG_SET(MATERIAL_VAR_DECAL))
{
SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
}
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP );
if( ShouldUseBumpmapping( params ) && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0) )
{
SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP );
}
// Get rid of the envmap if it's optional for this dx level.
if( params[ENVMAPOPTIONAL]->IsDefined() && (params[ENVMAPOPTIONAL]->GetIntValue() > g_pHardwareConfig->GetDXSupportLevel()) )
{
params[ENVMAP]->SetUndefined();
}
// If mat_specular 0, then get rid of envmap
if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() )
{
params[ENVMAP]->SetUndefined();
}
if( params[SEAMLESS_SCALE]->IsDefined() && params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f )
{
if( params[BUMPMAP]->IsDefined() )
{
Warning( "Can't use $bumpmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $bumpmap: %s\n", pMaterialName );
params[BUMPMAP]->SetUndefined();
}
if( params[ENVMAP]->IsDefined() )
{
Warning( "Can't use $envmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $envmap: %s\n", pMaterialName );
params[ENVMAP]->SetUndefined();
}
}
if ( !params[SEAMLESS_SCALE]->IsDefined() )
{
// zero means don't do seamless mapping.
params[SEAMLESS_SCALE]->SetFloatValue( 0.0f );
}
// Get rid of envmap if we aren't using bumpmapping
// *and* we have normalmapalphaenvmapmask *and* we don't have envmapmask elsewhere
if ( params[ENVMAP]->IsDefined() && params[BUMPMAP]->IsDefined() && IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) && !ShouldUseBumpmapping( params ) )
{
if ( !IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) && !params[ENVMAPMASK]->IsDefined() )
{
params[ENVMAP]->SetUndefined();
}
}
}
SHADER_FALLBACK
{
if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80)
return "LightmappedGeneric_DX6";
if ( IsPC() && g_pHardwareConfig->PreferReducedFillrate() )
return "LightmappedGeneric_NoBump_DX8";
return 0;
}
SHADER_INIT
{
LoadTexture( FLASHLIGHTTEXTURE );
if( ShouldUseBumpmapping( params ) )
{
LoadBumpMap( BUMPMAP );
}
if (params[BASETEXTURE]->IsDefined())
{
LoadTexture( BASETEXTURE );
if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent())
{
CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
}
}
if (params[DETAIL]->IsDefined())
{
LoadTexture( DETAIL );
}
// Don't alpha test if the alpha channel is used for other purposes
if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) )
CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST );
if (params[ENVMAP]->IsDefined())
{
if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) )
LoadCubeMap( ENVMAP );
else
LoadTexture( ENVMAP );
if( !g_pHardwareConfig->SupportsCubeMaps() )
{
SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE );
}
if (params[ENVMAPMASK]->IsDefined())
LoadTexture( ENVMAPMASK );
}
if( ShouldUseBumpmapping( params ) )
{
SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES );
}
}
#ifndef USE_HLSL_PIXEL_SHADERS
inline const char *GetPixelShaderName( IMaterialVar** params, bool bBumpedEnvMap )
{
static char const* s_pPixelShaders[] =
{
// Unmasked
"LightmappedGeneric_EnvMapV2",
"LightmappedGeneric_SelfIlluminatedEnvMapV2",
"LightmappedGeneric_BaseAlphaMaskedEnvMapV2",
"LightmappedGeneric_SelfIlluminatedEnvMapV2",
// Env map mask
"LightmappedGeneric_MaskedEnvMapV2",
"LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2",
"LightmappedGeneric_MaskedEnvMapV2",
"LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2",
};
if (!params[BASETEXTURE]->IsTexture())
{
if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap )
{
if (!params[ENVMAPMASK]->IsDefined() )
{
return "LightmappedGeneric_EnvmapNoTexture";
}
else
{
return "LightmappedGeneric_MaskedEnvmapNoTexture";
}
}
else
{
return "LightmappedGeneric_NoTexture";
}
}
else
{
if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap )
{
int pshIndex = 0;
if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM))
pshIndex |= 0x1;
if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK))
pshIndex |= 0x2;
if (params[ENVMAPMASK]->IsTexture())
pshIndex |= 0x4;
return s_pPixelShaders[pshIndex];
}
else
{
if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM))
return "LightmappedGeneric_SelfIlluminated";
else
return "LightmappedGeneric";
}
}
}
#endif
void DrawUnbumpedUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap )
{
bool hasEnvmap = params[ENVMAP]->IsTexture() && !bBumpedEnvMap;
bool hasBaseTexture = params[BASETEXTURE]->IsTexture();
bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
bool hasEnvmapCameraSpace = IS_FLAG_SET( MATERIAL_VAR_ENVMAPCAMERASPACE );
bool hasEnvmapSphere = IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE );
if ( hasEnvmap || hasBaseTexture || hasVertexColor || !bBumpedEnvMap )
{
SHADOW_STATE
{
// Alpha test
pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f )
{
pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() );
}
// Base texture on stage 0
if (params[BASETEXTURE]->IsTexture())
{
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
}
// Lightmap on stage 1
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
int fmt = VERTEX_POSITION;
if ( hasEnvmap )
{
fmt |= VERTEX_NORMAL;
// envmap on stage 2
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
// envmapmask on stage 3
if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
}
}
if (params[BASETEXTURE]->IsTexture() || bBumpedEnvMap)
{
SetDefaultBlendingShadowState( BASETEXTURE, true );
}
else
{
SetDefaultBlendingShadowState( ENVMAPMASK, false );
}
if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR))
{
fmt |= VERTEX_COLOR;
}
pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 );
lightmappedgeneric_vs11_Static_Index vshIndex;
vshIndex.SetDETAIL( false );
vshIndex.SetENVMAP( hasEnvmap );
vshIndex.SetENVMAPCAMERASPACE( hasEnvmap && hasEnvmapCameraSpace );
vshIndex.SetENVMAPSPHERE( hasEnvmap && hasEnvmapSphere );
vshIndex.SetVERTEXCOLOR( hasVertexColor );
pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() );
const char *pshName = GetPixelShaderName( params, bBumpedEnvMap );
pShaderShadow->SetPixelShader( pshName );
DefaultFog();
}
DYNAMIC_STATE
{
if (hasBaseTexture)
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM );
}
pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP );
if ( hasEnvmap )
{
BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME );
if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) )
{
if (params[ENVMAPMASK]->IsTexture() )
BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME );
else
BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME );
SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE );
}
if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ||
IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE))
{
LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL );
}
SetEnvMapTintPixelShaderDynamicState( 2, ENVMAPTINT, -1 );
}
if ( !hasEnvmap || hasBaseTexture || hasVertexColor )
{
SetModulationVertexShaderDynamicState();
}
EnablePixelShaderOverbright( 0, true, true );
SetPixelShaderConstant( 1, SELFILLUMTINT );
lightmappedgeneric_vs11_Dynamic_Index vshIndex;
vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
}
Draw();
}
if ( bBumpedEnvMap )
{
DrawWorldBumpedSpecularLighting(
BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME,
ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION,
BUMPTRANSFORM, FRESNELREFLECTION,
hasEnvmap || hasBaseTexture || hasVertexColor );
}
}
void DrawDetailNoEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doSelfIllum )
{
SHADOW_STATE
{
// Alpha test
pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
// Base texture on stage 0
if (params[BASETEXTURE]->IsTexture())
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
// Lightmap on stage 1
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
// Detail on stage 2
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
int fmt = VERTEX_POSITION;
SetDefaultBlendingShadowState( BASETEXTURE, true );
if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR))
fmt |= VERTEX_COLOR;
pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 );
lightmappedgeneric_vs11_Static_Index vshIndex;
vshIndex.SetDETAIL( true );
vshIndex.SetENVMAP( false );
vshIndex.SetENVMAPCAMERASPACE( false );
vshIndex.SetENVMAPSPHERE( false );
vshIndex.SetVERTEXCOLOR( IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) );
pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() );
if (!params[BASETEXTURE]->IsTexture())
{
pShaderShadow->SetPixelShader("LightmappedGeneric_DetailNoTexture");
}
else
{
if (!IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || (!doSelfIllum))
{
pShaderShadow->SetPixelShader("LightmappedGeneric_Detail");
}
else
{
pShaderShadow->SetPixelShader("LightmappedGeneric_DetailSelfIlluminated");
}
}
DefaultFog();
}
DYNAMIC_STATE
{
if (params[BASETEXTURE]->IsTexture())
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM );
}
pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP );
BindTexture( SHADER_SAMPLER2, DETAIL, FRAME );
SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE );
SetModulationVertexShaderDynamicState();
EnablePixelShaderOverbright( 0, true, true );
if (doSelfIllum)
{
SetPixelShaderConstant( 1, SELFILLUMTINT );
}
float c2[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
c2[0] = c2[1] = c2[2] = c2[3] = params[DETAILBLENDFACTOR]->GetFloatValue();
pShaderAPI->SetPixelShaderConstant( 2, c2, 1 );
lightmappedgeneric_vs11_Dynamic_Index vshIndex;
vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
}
Draw();
}
inline const char *GetAdditiveEnvmapPixelShaderName( bool usingMask,
bool usingBaseTexture, bool usingBaseAlphaEnvmapMask )
{
static char const* s_pPixelShaders[] =
{
"LightmappedGeneric_AddEnvmapNoTexture",
"LightmappedGeneric_AddEnvmapMaskNoTexture",
};
if ( !usingMask && usingBaseTexture && usingBaseAlphaEnvmapMask )
return "LightmappedGeneric_AddBaseAlphaMaskedEnvMap";
int pshIndex = 0;
if (usingMask)
pshIndex |= 0x1;
return s_pPixelShaders[pshIndex];
}
void DrawAdditiveEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow )
{
bool usingBaseTexture = params[BASETEXTURE]->IsTexture();
bool usingMask = params[ENVMAPMASK]->IsTexture();
bool usingBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK);
SHADOW_STATE
{
// Alpha test
pShaderShadow->EnableAlphaTest( false );
pShaderShadow->EnableTexture( SHADER_SAMPLER0, false );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, false );
// envmap on stage 2
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
// envmapmask on stage 3
if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
}
if (params[BASETEXTURE]->IsTexture())
{
SetAdditiveBlendingShadowState( BASETEXTURE, true );
}
else
{
SetAdditiveBlendingShadowState( ENVMAPMASK, false );
}
int fmt = VERTEX_POSITION | VERTEX_NORMAL;
pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 );
// Compute the vertex shader index.
lightmappedgeneric_vs11_Static_Index vshIndex;
vshIndex.SetDETAIL( false );
vshIndex.SetENVMAP( true );
vshIndex.SetENVMAPCAMERASPACE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) );
vshIndex.SetENVMAPSPHERE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) );
vshIndex.SetVERTEXCOLOR( false );
s_pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() );
const char *pshName = GetAdditiveEnvmapPixelShaderName( usingMask,
usingBaseTexture, usingBaseAlphaEnvmapMask );
pShaderShadow->SetPixelShader( pshName );
FogToBlack();
}
DYNAMIC_STATE
{
BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME );
if (usingMask || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK))
{
if (usingMask)
BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME );
else
BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME );
SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE );
}
SetPixelShaderConstant( 2, ENVMAPTINT );
if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE))
{
LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL );
}
SetModulationVertexShaderDynamicState();
// Compute the vertex shader index.
lightmappedgeneric_vs11_Dynamic_Index vshIndex;
vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
}
Draw();
}
void DrawDetailMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap )
{
// Mode 1 :
// Pass 1 : B * L * D + Self Illum
// Pass 2 : Add E * M
// Draw the detail w/ no envmap
DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, true );
if ( !bBumpedEnvMap )
{
DrawAdditiveEnvmap( params, pShaderAPI, pShaderShadow );
}
else
{
DrawWorldBumpedSpecularLighting(
BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME,
ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION,
BUMPTRANSFORM, FRESNELREFLECTION,
true );
}
}
void DrawDetailUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap )
{
// We don't have enough textures; gotta do this in two passes if there's envmapping
if (!params[ENVMAP]->IsTexture())
{
DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) );
}
else
{
if (!params[BASETEXTURE]->IsTexture())
{
// If there's an envmap but no base texture, ignore detail
DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap );
}
else
{
DrawDetailMode1( params, pShaderAPI, pShaderShadow, bBumpedEnvMap );
}
}
}
void DrawUnbumpedSeamlessUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow )
{
// This is the seamless_scale version, which doesn't use $detail or $bumpmap
SHADOW_STATE
{
// three copies of the base texture for seamless blending
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
// lightmap
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
int fmt = VERTEX_POSITION;
pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 );
worldvertextransition_seamless_Static_Index vshIndex;
pShaderShadow->SetVertexShader( "WorldVertexTransition_Seamless", vshIndex.GetIndex() );
int pshIndex = 0;
pShaderShadow->SetPixelShader( "WorldVertexTransition_Seamless", pshIndex );
FogToFogColor();
}
DYNAMIC_STATE
{
bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
// Texture 0..2
if( bLightingOnly )
{
pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY );
pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY );
pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY );
}
else
{
BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME );
BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME );
}
// Texture 3 = lightmap
pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP );
EnablePixelShaderOverbright( 0, true, true );
float fSeamlessScale = params[SEAMLESS_SCALE]->GetFloatValue();
float map_scale[4]= { fSeamlessScale, fSeamlessScale, fSeamlessScale, fSeamlessScale };
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale );
worldvertextransition_seamless_Dynamic_Index vshIndex;
vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
}
Draw();
}
SHADER_DRAW
{
bool hasFlashlight = UsingFlashlight( params );
bool bBump = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() &&
(params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0);
bool bSSBump = bBump && ( params[SSBUMP]->GetIntValue() != 0 );
if( hasFlashlight )
{
DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM,
FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 );
}
else if( bBump )
{
DrawWorldBumpedUsingVertexShader(
BASETEXTURE, BASETEXTURETRANSFORM,
BUMPMAP, BUMPFRAME, BUMPTRANSFORM, ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP,
ENVMAPFRAME, ENVMAPTINT, COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, FRESNELREFLECTION,
false, -1, -1, -1, bSSBump );
}
else
{
bool bBumpedEnvMap = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() && params[ENVMAP]->IsTexture();
if (!params[DETAIL]->IsTexture())
{
if( params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f )
{
DrawUnbumpedSeamlessUsingVertexShader( params, pShaderAPI, pShaderShadow );
}
else
{
DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap );
}
}
else
{
DrawDetailUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap );
}
}
}
END_SHADER
//-----------------------------------------------------------------------------
// Version that doesn't do bumpmapping
//-----------------------------------------------------------------------------
BEGIN_INHERITED_SHADER( LightmappedGeneric_NoBump_DX8, LightmappedGeneric_DX8,
"Help for LightmappedGeneric_NoBump_DX8" )
SHADER_FALLBACK
{
if (g_pHardwareConfig->GetDXSupportLevel() < 80)
return "LightmappedGeneric_DX6";
return 0;
}
virtual bool ShouldUseBumpmapping( IMaterialVar **params )
{
if ( !g_pConfig->UseBumpmapping() )
return false;
if ( !params[BUMPMAP]->IsDefined() )
return false;
return ( params[FORCEBUMP]->GetIntValue() != 0 );
}
END_INHERITED_SHADER