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.
1791 lines
53 KiB
1791 lines
53 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=====================================================================================// |
|
|
|
#include "shaderlib/BaseShader.h" |
|
#include "shaderlib/ShaderDLL.h" |
|
#include "tier0/dbg.h" |
|
#include "shaderDLL_Global.h" |
|
#include "IShaderSystem.h" |
|
#include "materialsystem/imaterial.h" |
|
#include "materialsystem/itexture.h" |
|
#include "materialsystem/ishaderapi.h" |
|
#include "materialsystem/materialsystem_config.h" |
|
#include "shaderlib/cshader.h" |
|
#include "mathlib/vmatrix.h" |
|
#include "tier1/strtools.h" |
|
#include "convar.h" |
|
#include "tier0/vprof.h" |
|
|
|
// NOTE: This must be the last include file in a .cpp file! |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Globals |
|
//----------------------------------------------------------------------------- |
|
const char *CBaseShader::s_pTextureGroupName = NULL; |
|
IMaterialVar **CBaseShader::s_ppParams; |
|
IShaderShadow *CBaseShader::s_pShaderShadow; |
|
IShaderDynamicAPI *CBaseShader::s_pShaderAPI; |
|
IShaderInit *CBaseShader::s_pShaderInit; |
|
int CBaseShader::s_nModulationFlags; |
|
CMeshBuilder *CBaseShader::s_pMeshBuilder; |
|
static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); |
|
|
|
bool g_shaderConfigDumpEnable = false; //true; //DO NOT CHECK IN ENABLED FIXME |
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor |
|
//----------------------------------------------------------------------------- |
|
CBaseShader::CBaseShader() |
|
{ |
|
GetShaderDLL()->InsertShader( this ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Shader parameter info |
|
//----------------------------------------------------------------------------- |
|
// Look in BaseShader.h for the enumeration for these. |
|
// Update there if you update here. |
|
static ShaderParamInfo_t s_StandardParams[NUM_SHADER_MATERIAL_VARS] = |
|
{ |
|
{ "$flags", "flags", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, |
|
{ "$flags_defined", "flags_defined", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, |
|
{ "$flags2", "flags2", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, |
|
{ "$flags_defined2", "flags2_defined", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, |
|
{ "$color", "color", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 }, |
|
{ "$alpha", "alpha", SHADER_PARAM_TYPE_FLOAT, "1.0", 0 }, |
|
{ "$basetexture", "Base Texture with lighting built in", SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", 0 }, |
|
{ "$frame", "Animation Frame", SHADER_PARAM_TYPE_INTEGER, "0", 0 }, |
|
{ "$basetexturetransform", "Base Texture Texcoord Transform",SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", 0 }, |
|
{ "$flashlighttexture", "flashlight spotlight shape texture", SHADER_PARAM_TYPE_TEXTURE, "effects/flashlight001", SHADER_PARAM_NOT_EDITABLE }, |
|
{ "$flashlighttextureframe", "Animation Frame for $flashlight", SHADER_PARAM_TYPE_INTEGER, "0", SHADER_PARAM_NOT_EDITABLE }, |
|
{ "$color2", "color2", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 }, |
|
{ "$srgbtint", "tint value to be applied when running on new-style srgb parts", SHADER_PARAM_TYPE_COLOR, "[1 1 1]", 0 }, |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Gets the standard shader parameter names |
|
// FIXME: Turn this into one function? |
|
//----------------------------------------------------------------------------- |
|
int CBaseShader::GetNumParams( ) const |
|
{ |
|
return NUM_SHADER_MATERIAL_VARS; |
|
} |
|
|
|
char const* CBaseShader::GetParamName( int nParamIndex ) const |
|
{ |
|
Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); |
|
return s_StandardParams[nParamIndex].m_pName; |
|
} |
|
|
|
const char *CBaseShader::GetParamHelp( int nParamIndex ) const |
|
{ |
|
Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); |
|
return s_StandardParams[nParamIndex].m_pHelp; |
|
} |
|
|
|
ShaderParamType_t CBaseShader::GetParamType( int nParamIndex ) const |
|
{ |
|
Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); |
|
return s_StandardParams[nParamIndex].m_Type; |
|
} |
|
|
|
const char *CBaseShader::GetParamDefault( int nParamIndex ) const |
|
{ |
|
Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); |
|
return s_StandardParams[nParamIndex].m_pDefaultValue; |
|
} |
|
|
|
int CBaseShader::GetParamFlags( int nParamIndex ) const |
|
{ |
|
Assert( nParamIndex < NUM_SHADER_MATERIAL_VARS ); |
|
return s_StandardParams[nParamIndex].m_nFlags; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Necessary to snag ahold of some important data for the helper methods |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::InitShaderParams( IMaterialVar** ppParams, const char *pMaterialName ) |
|
{ |
|
// Re-entrancy check |
|
Assert( !s_ppParams ); |
|
|
|
s_ppParams = ppParams; |
|
|
|
OnInitShaderParams( ppParams, pMaterialName ); |
|
|
|
s_ppParams = NULL; |
|
} |
|
|
|
void CBaseShader::InitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName, const char *pTextureGroupName ) |
|
{ |
|
// Re-entrancy check |
|
Assert( !s_ppParams ); |
|
|
|
s_ppParams = ppParams; |
|
s_pShaderInit = pShaderInit; |
|
s_pTextureGroupName = pTextureGroupName; |
|
|
|
OnInitShaderInstance( ppParams, pShaderInit, pMaterialName ); |
|
|
|
s_pTextureGroupName = NULL; |
|
s_ppParams = NULL; |
|
s_pShaderInit = NULL; |
|
} |
|
|
|
void CBaseShader::DrawElements( IMaterialVar **ppParams, int nModulationFlags, |
|
IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) |
|
{ |
|
VPROF("CBaseShader::DrawElements"); |
|
// Re-entrancy check |
|
Assert( !s_ppParams ); |
|
|
|
s_ppParams = ppParams; |
|
s_pShaderAPI = pShaderAPI; |
|
s_pShaderShadow = pShaderShadow; |
|
s_nModulationFlags = nModulationFlags; |
|
s_pMeshBuilder = pShaderAPI ? pShaderAPI->GetVertexModifyBuilder() : NULL; |
|
|
|
if ( IsSnapshotting() ) |
|
{ |
|
// Set up the shadow state |
|
SetInitialShadowState( ); |
|
} |
|
|
|
OnDrawElements( ppParams, pShaderShadow, pShaderAPI, vertexCompression, pContextDataPtr ); |
|
|
|
s_nModulationFlags = 0; |
|
s_ppParams = NULL; |
|
s_pShaderAPI = NULL; |
|
s_pShaderShadow = NULL; |
|
s_pMeshBuilder = NULL; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the default shadow state |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::SetInitialShadowState( ) |
|
{ |
|
// Set the default state |
|
s_pShaderShadow->SetDefaultState(); |
|
|
|
// Init the standard states... |
|
int flags = s_ppParams[FLAGS]->GetIntValue(); |
|
if (flags & MATERIAL_VAR_IGNOREZ) |
|
{ |
|
s_pShaderShadow->EnableDepthTest( false ); |
|
s_pShaderShadow->EnableDepthWrites( false ); |
|
} |
|
|
|
if (flags & MATERIAL_VAR_DECAL) |
|
{ |
|
s_pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_DECAL ); |
|
s_pShaderShadow->EnableDepthWrites( false ); |
|
} |
|
|
|
if (flags & MATERIAL_VAR_NOCULL) |
|
{ |
|
s_pShaderShadow->EnableCulling( false ); |
|
} |
|
|
|
if (flags & MATERIAL_VAR_ZNEARER) |
|
{ |
|
s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_NEARER ); |
|
} |
|
|
|
if (flags & MATERIAL_VAR_WIREFRAME) |
|
{ |
|
s_pShaderShadow->PolyMode( SHADER_POLYMODEFACE_FRONT_AND_BACK, SHADER_POLYMODE_LINE ); |
|
} |
|
|
|
// Set alpha to coverage |
|
if (flags & MATERIAL_VAR_ALLOWALPHATOCOVERAGE) |
|
{ |
|
// Force the bit on and then check against alpha blend and test states in CShaderShadowDX8::ComputeAggregateShadowState() |
|
s_pShaderShadow->EnableAlphaToCoverage( true ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Draws a snapshot |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::Draw( bool bMakeActualDrawCall ) |
|
{ |
|
if ( IsSnapshotting() ) |
|
{ |
|
// Turn off transparency if we're asked to.... |
|
if (g_pConfig->bNoTransparency && |
|
((s_ppParams[FLAGS]->GetIntValue() & MATERIAL_VAR_NO_DEBUG_OVERRIDE) == 0)) |
|
{ |
|
s_pShaderShadow->EnableDepthWrites( true ); |
|
s_pShaderShadow->EnableBlending( false ); |
|
} |
|
|
|
GetShaderSystem()->TakeSnapshot(); |
|
} |
|
else |
|
{ |
|
GetShaderSystem()->DrawSnapshot( bMakeActualDrawCall ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Finds a particular parameter (works because the lowest parameters match the shader) |
|
//----------------------------------------------------------------------------- |
|
int CBaseShader::FindParamIndex( const char *pName ) const |
|
{ |
|
int numParams = GetNumParams(); |
|
for( int i = 0; i < numParams; i++ ) |
|
{ |
|
if( Q_strnicmp( GetParamName( i ), pName, 64 ) == 0 ) |
|
{ |
|
return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Are we using graphics? |
|
//----------------------------------------------------------------------------- |
|
bool CBaseShader::IsUsingGraphics() |
|
{ |
|
return GetShaderSystem()->IsUsingGraphics(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Are we using graphics? |
|
//----------------------------------------------------------------------------- |
|
bool CBaseShader::CanUseEditorMaterials() |
|
{ |
|
return GetShaderSystem()->CanUseEditorMaterials(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Gets the builder... |
|
//----------------------------------------------------------------------------- |
|
CMeshBuilder* CBaseShader::MeshBuilder() |
|
{ |
|
return s_pMeshBuilder; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Loads a texture |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::LoadTexture( int nTextureVar, int nAdditionalCreationFlags /* = 0 */ ) |
|
{ |
|
if ((!s_ppParams) || (nTextureVar == -1)) |
|
return; |
|
|
|
IMaterialVar* pNameVar = s_ppParams[nTextureVar]; |
|
if( pNameVar && pNameVar->IsDefined() ) |
|
{ |
|
s_pShaderInit->LoadTexture( pNameVar, s_pTextureGroupName, nAdditionalCreationFlags ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Loads a bumpmap |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::LoadBumpMap( int nTextureVar ) |
|
{ |
|
if ((!s_ppParams) || (nTextureVar == -1)) |
|
return; |
|
|
|
IMaterialVar* pNameVar = s_ppParams[nTextureVar]; |
|
if( pNameVar && pNameVar->IsDefined() ) |
|
{ |
|
s_pShaderInit->LoadBumpMap( pNameVar, s_pTextureGroupName ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Loads a cubemap |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::LoadCubeMap( int nTextureVar, int nAdditionalCreationFlags /* = 0 */ ) |
|
{ |
|
if ((!s_ppParams) || (nTextureVar == -1)) |
|
return; |
|
|
|
IMaterialVar* pNameVar = s_ppParams[nTextureVar]; |
|
if( pNameVar && pNameVar->IsDefined() ) |
|
{ |
|
s_pShaderInit->LoadCubeMap( s_ppParams, pNameVar, nAdditionalCreationFlags ); |
|
} |
|
} |
|
|
|
|
|
ShaderAPITextureHandle_t CBaseShader::GetShaderAPITextureBindHandle( int nTextureVar, int nFrameVar, int nTextureChannel ) |
|
{ |
|
// Assert( !IsSnapshotting() ); |
|
Assert( nTextureVar != -1 ); |
|
Assert ( s_ppParams ); |
|
|
|
IMaterialVar* pTextureVar = s_ppParams[nTextureVar]; |
|
IMaterialVar* pFrameVar = (nFrameVar != -1) ? s_ppParams[nFrameVar] : NULL; |
|
int nFrame = pFrameVar ? pFrameVar->GetIntValue() : 0; |
|
return GetShaderSystem()->GetShaderAPITextureBindHandle( pTextureVar->GetTextureValue(), nFrame, nTextureChannel ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Four different flavors of BindTexture(), handling the two-sampler |
|
// case as well as ITexture* versus textureVar forms |
|
//----------------------------------------------------------------------------- |
|
|
|
void CBaseShader::BindTexture( Sampler_t sampler1, int nTextureVar, int nFrameVar /* = -1 */ ) |
|
{ |
|
BindTexture( sampler1, (Sampler_t) -1, nTextureVar, nFrameVar ); |
|
} |
|
|
|
|
|
void CBaseShader::BindTexture( Sampler_t sampler1, Sampler_t sampler2, int nTextureVar, int nFrameVar /* = -1 */ ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
Assert( nTextureVar != -1 ); |
|
Assert ( s_ppParams ); |
|
|
|
IMaterialVar* pTextureVar = s_ppParams[nTextureVar]; |
|
IMaterialVar* pFrameVar = (nFrameVar != -1) ? s_ppParams[nFrameVar] : NULL; |
|
if (pTextureVar) |
|
{ |
|
int nFrame = pFrameVar ? pFrameVar->GetIntValue() : 0; |
|
|
|
if ( sampler2 == Sampler_t(-1) ) |
|
{ |
|
GetShaderSystem()->BindTexture( sampler1, pTextureVar->GetTextureValue(), nFrame ); |
|
} |
|
else |
|
{ |
|
GetShaderSystem()->BindTexture( sampler1, sampler2, pTextureVar->GetTextureValue(), nFrame ); |
|
} |
|
} |
|
} |
|
|
|
|
|
void CBaseShader::BindTexture( Sampler_t sampler1, ITexture *pTexture, int nFrame /* = 0 */ ) |
|
{ |
|
BindTexture( sampler1, (Sampler_t) -1, pTexture, nFrame ); |
|
} |
|
|
|
void CBaseShader::BindTexture( Sampler_t sampler1, Sampler_t sampler2, ITexture *pTexture, int nFrame /* = 0 */ ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
|
|
if ( sampler2 == Sampler_t(-1 ) ) |
|
{ |
|
GetShaderSystem()->BindTexture( sampler1, pTexture, nFrame ); |
|
} |
|
else |
|
{ |
|
GetShaderSystem()->BindTexture( sampler1, sampler2, pTexture, nFrame ); |
|
} |
|
} |
|
|
|
void CBaseShader::GetTextureDimensions( float* pOutWidth, float* pOutHeight, int nTextureVar ) |
|
{ |
|
Assert( pOutWidth && pOutHeight ); // Outputs must be provided. |
|
Assert( nTextureVar != -1 ); |
|
|
|
IMaterialVar* pTextureVar = s_ppParams[nTextureVar]; |
|
|
|
if (pTextureVar && pTextureVar->GetTextureValue()) |
|
{ |
|
*pOutWidth = (float) (pTextureVar->GetTextureValue()->GetActualWidth()); |
|
*pOutHeight = (float) (pTextureVar->GetTextureValue()->GetActualHeight()); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Does the texture store translucency in its alpha channel? |
|
//----------------------------------------------------------------------------- |
|
bool CBaseShader::TextureIsTranslucent( int textureVar, bool isBaseTexture ) |
|
{ |
|
if (textureVar < 0) |
|
return false; |
|
|
|
IMaterialVar** params = s_ppParams; |
|
if (params[textureVar]->GetType() == MATERIAL_VAR_TYPE_TEXTURE) |
|
{ |
|
if (!isBaseTexture) |
|
{ |
|
return params[textureVar]->GetTextureValue()->IsTranslucent(); |
|
} |
|
else |
|
{ |
|
// Override translucency settings if this flag is set. |
|
if (IS_FLAG_SET(MATERIAL_VAR_OPAQUETEXTURE)) |
|
return false; |
|
|
|
if ( (CurrentMaterialVarFlags() & (MATERIAL_VAR_SELFILLUM | MATERIAL_VAR_BASEALPHAENVMAPMASK)) == 0) |
|
{ |
|
if ((CurrentMaterialVarFlags() & MATERIAL_VAR_TRANSLUCENT) || |
|
(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST)) |
|
{ |
|
return params[textureVar]->GetTextureValue()->IsTranslucent(); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Helper methods for color modulation |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Are we alpha or color modulating? |
|
//----------------------------------------------------------------------------- |
|
bool CBaseShader::IsAlphaModulating() |
|
{ |
|
return (s_nModulationFlags & SHADER_USING_ALPHA_MODULATION) != 0; |
|
} |
|
|
|
bool CBaseShader::IsColorModulating() |
|
{ |
|
return (s_nModulationFlags & SHADER_USING_COLOR_MODULATION) != 0; |
|
} |
|
|
|
|
|
void CBaseShader::GetColorParameter( IMaterialVar **params, float *pColorOut ) const |
|
{ |
|
float flColor2[3]; |
|
params[COLOR]->GetVecValue( pColorOut, 3 ); |
|
params[COLOR2]->GetVecValue( flColor2, 3 ); |
|
|
|
pColorOut[0] *= flColor2[0]; |
|
pColorOut[1] *= flColor2[1]; |
|
pColorOut[2] *= flColor2[2]; |
|
|
|
if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) |
|
{ |
|
float flSRGBTint[3]; |
|
params[SRGBTINT]->GetVecValue( flSRGBTint, 3 ); |
|
|
|
pColorOut[0] *= flSRGBTint[0]; |
|
pColorOut[1] *= flSRGBTint[1]; |
|
pColorOut[2] *= flSRGBTint[2]; |
|
} |
|
|
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// FIXME: Figure out a better way to do this? |
|
//----------------------------------------------------------------------------- |
|
int CBaseShader::ComputeModulationFlags( IMaterialVar** params, IShaderDynamicAPI* pShaderAPI ) |
|
{ |
|
s_pShaderAPI = pShaderAPI; |
|
|
|
int mod = 0; |
|
if ( GetAlpha(params) < 1.0f ) |
|
{ |
|
mod |= SHADER_USING_ALPHA_MODULATION; |
|
} |
|
|
|
float color[3]; |
|
GetColorParameter( params, color ); |
|
|
|
if ((color[0] != 1.0) || (color[1] != 1.0) || (color[2] != 1.0)) |
|
{ |
|
mod |= SHADER_USING_COLOR_MODULATION; |
|
} |
|
|
|
if( UsingFlashlight(params) ) |
|
{ |
|
mod |= SHADER_USING_FLASHLIGHT; |
|
} |
|
|
|
if ( UsingEditor(params) ) |
|
{ |
|
mod |= SHADER_USING_EDITOR; |
|
} |
|
|
|
if( IS_FLAG2_SET( MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING ) ) |
|
{ |
|
AssertOnce( IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ) ); |
|
if( IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ) ) |
|
{ |
|
mod |= SHADER_USING_FIXED_FUNCTION_BAKED_LIGHTING; |
|
} |
|
} |
|
|
|
s_pShaderAPI = NULL; |
|
|
|
return mod; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
bool CBaseShader::NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const |
|
{ |
|
return CShader_IsFlag2Set( params, MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
bool CBaseShader::NeedsFullFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const |
|
{ |
|
return CShader_IsFlag2Set( params, MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
bool CBaseShader::IsTranslucent( IMaterialVar **params ) const |
|
{ |
|
return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the translucency... |
|
//----------------------------------------------------------------------------- |
|
float CBaseShader::GetAlpha( IMaterialVar** ppParams ) |
|
{ |
|
if ( !ppParams ) |
|
{ |
|
ppParams = s_ppParams; |
|
} |
|
|
|
if (!ppParams) |
|
return 1.0f; |
|
|
|
if ( ppParams[FLAGS]->GetIntValue() & MATERIAL_VAR_NOALPHAMOD ) |
|
return 1.0f; |
|
|
|
float flAlpha = ppParams[ALPHA]->GetFloatValue(); |
|
return clamp( flAlpha, 0.0f, 1.0f ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the color + transparency |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::SetColorState( int colorVar, bool setAlpha ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
if ( !s_ppParams ) |
|
return; |
|
|
|
// Use tint instead of color if it was specified... |
|
IMaterialVar* pColorVar = (colorVar != -1) ? s_ppParams[colorVar] : 0; |
|
|
|
float color[4] = { 1.0, 1.0, 1.0, 1.0 }; |
|
if (pColorVar) |
|
{ |
|
if (pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) |
|
{ |
|
pColorVar->GetVecValue( color, 3 ); |
|
} |
|
else |
|
{ |
|
color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); |
|
} |
|
|
|
if ( !g_pHardwareConfig->SupportsPixelShaders_1_4() ) // Clamp 0..1 for ps_1_1 and below |
|
{ |
|
color[0] = clamp( color[0], 0.0f, 1.0f ); |
|
color[1] = clamp( color[1], 0.0f, 1.0f ); |
|
color[2] = clamp( color[2], 0.0f, 1.0f ); |
|
} |
|
else if ( !g_pHardwareConfig->SupportsPixelShaders_2_0() ) // Clamp 0..8 for ps_1_4 |
|
{ |
|
color[0] = clamp( color[0], 0.0f, 8.0f ); |
|
color[1] = clamp( color[1], 0.0f, 8.0f ); |
|
color[2] = clamp( color[2], 0.0f, 8.0f ); |
|
} |
|
} |
|
ApplyColor2Factor( color ); |
|
color[3] = setAlpha ? GetAlpha() : 1.0f; |
|
s_pShaderAPI->Color4fv( color ); |
|
} |
|
|
|
|
|
void CBaseShader::SetModulationShadowState( int tintVar ) |
|
{ |
|
// Have have no control over the tint var... |
|
bool doModulation = (tintVar != -1); |
|
|
|
// We activate color modulating when we're alpha or color modulating |
|
doModulation = doModulation || IsAlphaModulating() || IsColorModulating(); |
|
|
|
s_pShaderShadow->EnableConstantColor( doModulation ); |
|
} |
|
|
|
void CBaseShader::SetModulationDynamicState( int tintVar ) |
|
{ |
|
if (tintVar != -1) |
|
{ |
|
SetColorState( tintVar, true ); |
|
} |
|
else |
|
{ |
|
SetColorState( COLOR, true ); |
|
} |
|
} |
|
|
|
void CBaseShader::ApplyColor2Factor( float *pColorOut ) const // (*pColorOut) *= COLOR2 |
|
{ |
|
IMaterialVar* pColor2Var = s_ppParams[COLOR2]; |
|
if (pColor2Var->GetType() == MATERIAL_VAR_TYPE_VECTOR) |
|
{ |
|
float flColor2[3]; |
|
pColor2Var->GetVecValue( flColor2, 3 ); |
|
|
|
pColorOut[0] *= flColor2[0]; |
|
pColorOut[1] *= flColor2[1]; |
|
pColorOut[2] *= flColor2[2]; |
|
} |
|
if ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) |
|
{ |
|
IMaterialVar* pSRGBVar = s_ppParams[SRGBTINT]; |
|
if (pSRGBVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) |
|
{ |
|
float flSRGB[3]; |
|
pSRGBVar->GetVecValue( flSRGB, 3 ); |
|
|
|
pColorOut[0] *= flSRGB[0]; |
|
pColorOut[1] *= flSRGB[1]; |
|
pColorOut[2] *= flSRGB[2]; |
|
} |
|
} |
|
} |
|
|
|
void CBaseShader::ComputeModulationColor( float* color ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
if (!s_ppParams) |
|
return; |
|
|
|
IMaterialVar* pColorVar = s_ppParams[COLOR]; |
|
if (pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) |
|
{ |
|
pColorVar->GetVecValue( color, 3 ); |
|
} |
|
else |
|
{ |
|
color[0] = color[1] = color[2] = pColorVar->GetFloatValue(); |
|
} |
|
|
|
ApplyColor2Factor( color ); |
|
|
|
if( !g_pConfig->bShowDiffuse ) |
|
{ |
|
color[0] = color[1] = color[2] = 0.0f; |
|
} |
|
if( mat_fullbright.GetInt() == 2 ) |
|
{ |
|
color[0] = color[1] = color[2] = 1.0f; |
|
} |
|
color[3] = GetAlpha(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Helper methods for alpha blending.... |
|
// |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::EnableAlphaBlending( ShaderBlendFactor_t src, ShaderBlendFactor_t dst ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
s_pShaderShadow->EnableBlending( true ); |
|
s_pShaderShadow->BlendFunc( src, dst ); |
|
s_pShaderShadow->EnableDepthWrites(false); |
|
} |
|
|
|
void CBaseShader::DisableAlphaBlending() |
|
{ |
|
Assert( IsSnapshotting() ); |
|
s_pShaderShadow->EnableBlending( false ); |
|
} |
|
|
|
void CBaseShader::SetNormalBlendingShadowState( int textureVar, bool isBaseTexture ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
|
|
// Either we've got a constant modulation |
|
bool isTranslucent = IsAlphaModulating(); |
|
|
|
// Or we've got a vertex alpha |
|
isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); |
|
|
|
// Or we've got a texture alpha |
|
isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && |
|
!(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); |
|
|
|
if (isTranslucent) |
|
{ |
|
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); |
|
} |
|
else |
|
{ |
|
DisableAlphaBlending(); |
|
} |
|
} |
|
|
|
//ConVar mat_debug_flashlight_only( "mat_debug_flashlight_only", "0" ); |
|
void CBaseShader::SetAdditiveBlendingShadowState( int textureVar, bool isBaseTexture ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
|
|
// Either we've got a constant modulation |
|
bool isTranslucent = IsAlphaModulating(); |
|
|
|
// Or we've got a vertex alpha |
|
isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); |
|
|
|
// Or we've got a texture alpha |
|
isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && |
|
!(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); |
|
|
|
/* |
|
if ( mat_debug_flashlight_only.GetBool() ) |
|
{ |
|
if (isTranslucent) |
|
{ |
|
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA); |
|
//s_pShaderShadow->EnableAlphaTest( true ); |
|
//s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.99f ); |
|
} |
|
else |
|
{ |
|
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ZERO); |
|
} |
|
} |
|
else |
|
*/ |
|
{ |
|
if (isTranslucent) |
|
{ |
|
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); |
|
} |
|
else |
|
{ |
|
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); |
|
} |
|
} |
|
} |
|
|
|
void CBaseShader::SetDefaultBlendingShadowState( int textureVar, bool isBaseTexture ) |
|
{ |
|
if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) |
|
{ |
|
SetAdditiveBlendingShadowState( textureVar, isBaseTexture ); |
|
} |
|
else |
|
{ |
|
SetNormalBlendingShadowState( textureVar, isBaseTexture ); |
|
} |
|
} |
|
|
|
void CBaseShader::SetBlendingShadowState( BlendType_t nMode ) |
|
{ |
|
switch ( nMode ) |
|
{ |
|
case BT_NONE: |
|
DisableAlphaBlending(); |
|
break; |
|
|
|
case BT_BLEND: |
|
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); |
|
break; |
|
|
|
case BT_ADD: |
|
EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); |
|
break; |
|
|
|
case BT_BLENDADD: |
|
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); |
|
break; |
|
} |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets lightmap blending mode for single texturing |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::SingleTextureLightmapBlendMode( ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
|
|
s_pShaderShadow->EnableBlending( true ); |
|
s_pShaderShadow->BlendFunc( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Loads the identity transform into a matrix |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::LoadIdentity( MaterialMatrixMode_t matrixMode ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
|
|
s_pShaderAPI->MatrixMode( matrixMode ); |
|
s_pShaderAPI->LoadIdentity( ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Loads the camera to world transform into a matrix |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::LoadCameraToWorldTransform( MaterialMatrixMode_t matrixMode ) |
|
{ |
|
s_pShaderAPI->MatrixMode( matrixMode ); |
|
s_pShaderAPI->LoadCameraToWorld(); |
|
} |
|
|
|
void CBaseShader::LoadCameraSpaceSphereMapTransform( MaterialMatrixMode_t matrixMode ) |
|
{ |
|
static float mat[4][4] = |
|
{ |
|
{ 0.5f, 0.0f, 0.0f, 0.0f }, |
|
{ 0.0f, -0.5f, 0.0f, 0.0f }, |
|
{ 0.0f, 0.0f, 0.0f, 0.0f }, |
|
{ 0.5f, -0.5f, 0.0f, 1.0f }, |
|
}; |
|
|
|
s_pShaderAPI->MatrixMode( matrixMode ); |
|
s_pShaderAPI->LoadMatrix( (float*)mat ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Sets a texture translation transform |
|
// |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::SetFixedFunctionTextureTranslation( MaterialMatrixMode_t textureTransform, int translationVar ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
|
|
// handle scrolling of base texture |
|
Vector2D vDelta( 0, 0 ); |
|
|
|
if (translationVar != -1) |
|
{ |
|
s_ppParams[translationVar]->GetVecValue( vDelta.Base(), 2 ); |
|
} |
|
|
|
if( vDelta[0] != 0.0f || vDelta[1] != 0.0f ) |
|
{ |
|
s_pShaderAPI->MatrixMode( textureTransform ); |
|
|
|
// only do the upper 3x3 since this is a 2D matrix |
|
float mat[16]; |
|
mat[0] = 1.0f; mat[1] = 0.0f; mat[2] = 0.0f; |
|
mat[4] = 0.0f; mat[5] = 1.0f; mat[6] = 0.0f; |
|
mat[8] = vDelta[0]; mat[9] = vDelta[1]; mat[10] = 1.0f; |
|
|
|
// Better set the stuff we don't set with some sort of value! |
|
mat[3] = mat[7] = mat[11] = 0; |
|
mat[12] = mat[13] = mat[14] = 0; |
|
mat[15] = 1; |
|
|
|
s_pShaderAPI->LoadMatrix( mat ); |
|
} |
|
else |
|
{ |
|
LoadIdentity( textureTransform ); |
|
} |
|
} |
|
|
|
void CBaseShader::SetFixedFunctionTextureScale( MaterialMatrixMode_t textureTransform, int scaleVar ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
|
|
// handle scrolling of base texture |
|
Vector2D vScale; |
|
s_ppParams[scaleVar]->GetVecValue( vScale.Base(), 2 ); |
|
if( vScale[0] != 0.0f || vScale[1] != 0.0f ) |
|
{ |
|
s_pShaderAPI->MatrixMode( textureTransform ); |
|
|
|
// only do the upper 3x3 since this is a 2D matrix |
|
float mat[16]; |
|
mat[0] = vScale[0]; mat[1] = 0.0f; mat[2] = 0.0f; |
|
mat[4] = 0.0f; mat[5] = vScale[1]; mat[6] = 0.0f; |
|
mat[8] = 0.0f; mat[9] = 0.0f; mat[10] = 1.0f; |
|
|
|
// Better set the stuff we don't set with some sort of value! |
|
mat[3] = mat[7] = mat[11] = 0; |
|
mat[12] = mat[13] = mat[14] = 0; |
|
mat[15] = 1; |
|
|
|
s_pShaderAPI->LoadMatrix( mat ); |
|
} |
|
else |
|
{ |
|
LoadIdentity( textureTransform ); |
|
} |
|
} |
|
|
|
void CBaseShader::SetFixedFunctionTextureTransform( MaterialMatrixMode_t textureTransform, int transformVar ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
|
|
IMaterialVar* pTransformationVar = s_ppParams[transformVar]; |
|
if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) |
|
{ |
|
s_pShaderAPI->MatrixMode( textureTransform ); |
|
|
|
const VMatrix &transformation = pTransformationVar->GetMatrixValue(); |
|
|
|
// only do the upper 3x3 since this is a 2D matrix |
|
float mat[16]; |
|
mat[0] = transformation[0][0]; mat[1] = transformation[1][0]; mat[2] = transformation[3][0]; |
|
mat[4] = transformation[0][1]; mat[5] = transformation[1][1]; mat[6] = transformation[3][1]; |
|
mat[8] = transformation[0][3]; mat[9] = transformation[1][3]; mat[10] = transformation[3][3]; |
|
|
|
// Better set the stuff we don't set with some sort of value! |
|
mat[3] = mat[7] = mat[11] = 0; |
|
mat[12] = mat[13] = mat[14] = 0; |
|
mat[15] = 1; |
|
|
|
s_pShaderAPI->LoadMatrix( mat ); |
|
} |
|
else |
|
{ |
|
LoadIdentity( textureTransform ); |
|
} |
|
} |
|
|
|
void CBaseShader::SetFixedFunctionTextureScaledTransform( MaterialMatrixMode_t textureTransform, |
|
int transformVar, int scaleVar ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
|
|
float mat[16]; |
|
IMaterialVar* pTransformationVar = s_ppParams[transformVar]; |
|
if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) |
|
{ |
|
Vector2D scale( 1, 1 ); |
|
IMaterialVar* pScaleVar = s_ppParams[scaleVar]; |
|
if (pScaleVar) |
|
{ |
|
if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) |
|
pScaleVar->GetVecValue( scale.Base(), 2 ); |
|
else if (pScaleVar->IsDefined()) |
|
scale[0] = scale[1] = pScaleVar->GetFloatValue(); |
|
} |
|
|
|
s_pShaderAPI->MatrixMode( textureTransform ); |
|
|
|
const VMatrix &transformation = pTransformationVar->GetMatrixValue(); |
|
|
|
// only do the upper 3x3 since this is a 2D matrix |
|
mat[0] = transformation[0][0] * scale[0]; mat[1] = transformation[1][0] * scale[0]; mat[2] = transformation[3][0] * scale[0]; |
|
mat[4] = transformation[0][1] * scale[1]; mat[5] = transformation[1][1] * scale[1]; mat[6] = transformation[3][1] * scale[1]; |
|
mat[8] = transformation[0][3]; mat[9] = transformation[1][3]; mat[10] = transformation[3][3]; |
|
|
|
// Better set the stuff we don't set with some sort of value! |
|
mat[3] = mat[7] = mat[11] = 0; |
|
mat[12] = mat[13] = mat[14] = 0; |
|
mat[15] = 1; |
|
|
|
s_pShaderAPI->LoadMatrix( mat ); |
|
} |
|
else |
|
{ |
|
SetFixedFunctionTextureScale( textureTransform, scaleVar ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Helper methods for fog |
|
// |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::FogToOOOverbright( void ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_OO_OVERBRIGHT ); |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); |
|
} |
|
} |
|
|
|
void CBaseShader::FogToWhite( void ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_WHITE ); |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); |
|
} |
|
} |
|
void CBaseShader::FogToBlack( void ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_BLACK ); |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); |
|
} |
|
} |
|
|
|
void CBaseShader::FogToGrey( void ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_GREY ); |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); |
|
} |
|
} |
|
|
|
void CBaseShader::FogToFogColor( void ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
if (( CurrentMaterialVarFlags() & MATERIAL_VAR_NOFOG ) == 0) |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_FOGCOLOR ); |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); |
|
} |
|
} |
|
|
|
void CBaseShader::DisableFog( void ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
s_pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); |
|
} |
|
|
|
void CBaseShader::DefaultFog( void ) |
|
{ |
|
if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) |
|
{ |
|
FogToBlack(); |
|
} |
|
else |
|
{ |
|
FogToFogColor(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Fixed function multiply by detail texture pass |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::FixedFunctionMultiplyByDetailPass( int baseTextureVar, int frameVar, |
|
int textureTransformVar, int detailVar, int detailScaleVar ) |
|
{ |
|
IMaterialVar** params = s_ppParams; |
|
|
|
if (!params[detailVar]->IsDefined()) |
|
return; |
|
|
|
if (IsSnapshotting()) |
|
{ |
|
SetInitialShadowState(); |
|
|
|
s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); |
|
|
|
bool translucentTexture = TextureIsTranslucent( baseTextureVar, true ) || |
|
IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); |
|
s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); |
|
s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); |
|
|
|
// Mod 2x blend here |
|
EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); |
|
|
|
s_pShaderShadow->EnableCustomPixelPipe( true ); |
|
s_pShaderShadow->CustomTextureStages( 2 ); |
|
|
|
// We need to blend towards grey based on alpha... |
|
// We can never get the perfect alpha (vertex alpha * cc alpha * texture alpha) |
|
// so we'll just choose to use cc alpha * texture alpha |
|
|
|
int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1; |
|
|
|
// Compute alpha, stage 0 is used, stage 1 isn't. |
|
if ( translucentTexture ) |
|
{ |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
flags |= SHADER_DRAW_TEXCOORD0; |
|
} |
|
else |
|
{ |
|
bool hasVertexAlpha = (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA) != 0; |
|
if (hasVertexAlpha) |
|
{ |
|
flags |= SHADER_DRAW_COLOR; |
|
} |
|
|
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_ALPHA, hasVertexAlpha ? SHADER_TEXOP_MODULATE : SHADER_TEXOP_SELECTARG1, |
|
SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_VERTEXCOLOR ); |
|
} |
|
|
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, |
|
SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); |
|
|
|
// This here will perform color = vertex light * alpha + 0.5f * (1 - alpha) |
|
// Stage 0 really doesn't do anything |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
|
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
|
|
s_pShaderShadow->DrawFlags( flags ); |
|
FogToGrey(); |
|
Draw( ); |
|
|
|
s_pShaderShadow->EnableCustomPixelPipe( false ); |
|
DisableAlphaBlending(); |
|
} |
|
else |
|
{ |
|
if (TextureIsTranslucent( baseTextureVar, true ) ) |
|
{ |
|
SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, textureTransformVar ); |
|
BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); |
|
} |
|
else |
|
{ |
|
// Unnecessary... but we get strange colors if we don't put something on stage 0 |
|
BindTexture( SHADER_SAMPLER0, detailVar, frameVar ); |
|
} |
|
|
|
BindTexture( SHADER_SAMPLER1, detailVar, frameVar ); |
|
SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, textureTransformVar, detailScaleVar ); |
|
float alpha = GetAlpha(); |
|
s_pShaderAPI->Color4ub( 128, 128, 128, 255 * alpha ); |
|
|
|
Draw( ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Multiply by lightmap pass |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::FixedFunctionMultiplyByLightmapPass( int baseTextureVar, |
|
int frameVar, int baseTextureTransformVar, float alphaOverride ) |
|
{ |
|
if (IsSnapshotting()) |
|
{ |
|
SetInitialShadowState(); |
|
|
|
s_pShaderShadow->EnableAlphaTest( false ); |
|
|
|
s_pShaderShadow->EnableBlending( true ); |
|
SingleTextureLightmapBlendMode(); |
|
|
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); |
|
s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); |
|
s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); |
|
|
|
s_pShaderShadow->EnableCustomPixelPipe( true ); |
|
s_pShaderShadow->CustomTextureStages( 2 ); |
|
|
|
// Stage zero color is not used, this op doesn't matter |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, |
|
SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); |
|
|
|
// This here will perform color = lightmap * (cc alpha) + 1 * (1- cc alpha) |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
|
|
int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD1; |
|
|
|
// Multiply the constant alpha by the texture alpha for total alpha |
|
if (TextureIsTranslucent(baseTextureVar, true)) |
|
{ |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
|
|
flags |= SHADER_DRAW_TEXCOORD0; |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG2, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
} |
|
|
|
// Alpha isn't used, it doesn't matter what we set it to. |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, |
|
SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); |
|
|
|
s_pShaderShadow->DrawFlags( flags ); |
|
|
|
FogToOOOverbright(); |
|
Draw(); |
|
|
|
s_pShaderShadow->EnableCustomPixelPipe( false ); |
|
} |
|
else |
|
{ |
|
s_pShaderAPI->SetDefaultState(); |
|
|
|
// Put the alpha in the color channel to modulate the color down.... |
|
float alpha = (alphaOverride < 0) ? GetAlpha() : alphaOverride; |
|
|
|
// NOTE: 128 is a more exact OO_OVERBRIGHT; it prevents some artifacts |
|
// s_pShaderAPI->Color4f( OO_OVERBRIGHT, OO_OVERBRIGHT, OO_OVERBRIGHT, alpha ); |
|
s_pShaderAPI->Color4ub( 128, 128, 128, (int)(alpha * 255)); |
|
|
|
if (TextureIsTranslucent(baseTextureVar, true)) |
|
{ |
|
SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, baseTextureTransformVar ); |
|
BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); |
|
} |
|
|
|
LoadIdentity( MATERIAL_TEXTURE1 ); |
|
s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); |
|
|
|
Draw(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Fixed function Self illumination pass |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::FixedFunctionSelfIlluminationPass( Sampler_t sampler, |
|
int baseTextureVar, int frameVar, int baseTextureTransformVar, int selfIllumTintVar ) |
|
{ |
|
// IMaterialVar** params = s_ppParams; |
|
|
|
if ( IsSnapshotting() ) |
|
{ |
|
SetInitialShadowState(); |
|
|
|
// A little setup for self illum here... |
|
SetModulationShadowState( selfIllumTintVar ); |
|
|
|
s_pShaderShadow->EnableTexture( sampler, true ); |
|
|
|
// No overbrighting |
|
s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); |
|
s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); |
|
|
|
// Don't bother with z writes here... |
|
s_pShaderShadow->EnableDepthWrites( false ); |
|
|
|
// We're always blending |
|
EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); |
|
|
|
int flags = SHADER_DRAW_POSITION; |
|
if ( sampler == SHADER_SAMPLER0 ) |
|
flags |= SHADER_DRAW_TEXCOORD0; |
|
else |
|
flags |= SHADER_DRAW_TEXCOORD1; |
|
|
|
s_pShaderShadow->DrawFlags( flags ); |
|
FogToFogColor(); |
|
} |
|
else |
|
{ |
|
s_pShaderAPI->SetDefaultState(); |
|
|
|
SetFixedFunctionTextureTransform( |
|
(sampler == SHADER_SAMPLER0) ? MATERIAL_TEXTURE0 : MATERIAL_TEXTURE1, |
|
baseTextureTransformVar ); |
|
BindTexture( sampler, baseTextureVar, frameVar ); |
|
|
|
// NOTE: Texture + texture offset are set from BaseTimesLightmap |
|
SetModulationDynamicState( selfIllumTintVar ); |
|
} |
|
Draw(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Fixed function Base * detail pass |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::FixedFunctionBaseTimesDetailPass( int baseTextureVar, |
|
int frameVar, int baseTextureTransformVar, int detailVar, int detailScaleVar ) |
|
{ |
|
IMaterialVar** params = s_ppParams; |
|
|
|
// We can't do this one one pass if CC and VC are both active... |
|
bool hasDetail = (detailVar != -1) && params[detailVar]->IsDefined(); |
|
bool detailInSecondPass = hasDetail && IsColorModulating() && |
|
(IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) || IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA)); |
|
|
|
if (IsSnapshotting()) |
|
{ |
|
s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); |
|
s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); |
|
|
|
// alpha test |
|
s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); |
|
|
|
// Alpha blending |
|
SetDefaultBlendingShadowState( baseTextureVar, true ); |
|
|
|
// independently configure alpha and color |
|
s_pShaderShadow->EnableAlphaPipe( true ); |
|
|
|
// Here's the color states (NOTE: SHADER_DRAW_COLOR == use Vertex Color) |
|
s_pShaderShadow->EnableConstantColor( IsColorModulating() ); |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); |
|
|
|
int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0; |
|
|
|
// Detail texture.. |
|
if (hasDetail && (!detailInSecondPass)) |
|
{ |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); |
|
|
|
// Force mod2x |
|
s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 2.0f ); |
|
|
|
flags |= SHADER_DRAW_TEXCOORD1; |
|
} |
|
|
|
// Here's the alpha states |
|
s_pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); |
|
s_pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); |
|
s_pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, TextureIsTranslucent(baseTextureVar, true) ); |
|
|
|
if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) |
|
flags |= SHADER_DRAW_COLOR; |
|
s_pShaderShadow->DrawFlags( flags ); |
|
|
|
DefaultFog(); |
|
|
|
Draw(); |
|
|
|
s_pShaderShadow->EnableAlphaPipe( false ); |
|
} |
|
else |
|
{ |
|
SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, baseTextureTransformVar ); |
|
BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar ); |
|
|
|
// Detail texture.. |
|
if (hasDetail && (!detailInSecondPass)) |
|
{ |
|
BindTexture( SHADER_SAMPLER1, detailVar, frameVar ); |
|
SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, baseTextureTransformVar, detailScaleVar ); |
|
} |
|
|
|
SetModulationDynamicState(); |
|
|
|
Draw(); |
|
} |
|
|
|
if (detailInSecondPass) |
|
{ |
|
FixedFunctionMultiplyByDetailPass( baseTextureVar, frameVar, baseTextureTransformVar, detailVar, detailScaleVar ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Helpers for environment mapping... |
|
//----------------------------------------------------------------------------- |
|
int CBaseShader::SetShadowEnvMappingState( int envMapMaskVar, int tintVar ) |
|
{ |
|
Assert( IsSnapshotting() ); |
|
IMaterialVar** params = s_ppParams; |
|
|
|
int varFlags = params[FLAGS]->GetIntValue(); |
|
|
|
s_pShaderShadow->EnableAlphaTest( false ); |
|
|
|
// envmap on stage 0 |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); |
|
s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); |
|
if ( (varFlags & MATERIAL_VAR_ENVMAPSPHERE) == 0 ) |
|
s_pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_CAMERASPACEREFLECTIONVECTOR ); |
|
else |
|
s_pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_SPHERE_MAP ); |
|
|
|
int flags = SHADER_DRAW_POSITION | SHADER_DRAW_NORMAL; |
|
|
|
// mask on stage 1 |
|
if (params[envMapMaskVar]->IsDefined() || (varFlags & MATERIAL_VAR_BASEALPHAENVMAPMASK)) |
|
{ |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); |
|
flags |= SHADER_DRAW_TEXCOORD1; |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); |
|
} |
|
|
|
if (varFlags & MATERIAL_VAR_BASEALPHAENVMAPMASK) |
|
{ |
|
s_pShaderShadow->EnableCustomPixelPipe( true ); |
|
s_pShaderShadow->CustomTextureStages( 2 ); |
|
|
|
// Color = base texture * envmaptint * (1 - mask alpha) |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_INVTEXTUREALPHA ); |
|
|
|
// Use alpha modulation * vertex alpha * env map alpha |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, SHADER_TEXARG_VERTEXCOLOR, SHADER_TEXARG_TEXTURE ); |
|
s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); |
|
} |
|
else |
|
{ |
|
s_pShaderShadow->EnableAlphaPipe( true ); |
|
|
|
// Color = base texture * envmaptint * mask |
|
s_pShaderShadow->EnableConstantColor( tintVar >= 0 ); |
|
|
|
// Alpha = vertex alpha * constant alpha * env map alpha * mask alpha (only if it's not a base alpha mask) |
|
s_pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); |
|
s_pShaderShadow->EnableVertexAlpha( (varFlags & MATERIAL_VAR_VERTEXALPHA) != 0 ); |
|
s_pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, true ); |
|
s_pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, params[envMapMaskVar]->IsTexture() ); |
|
} |
|
|
|
return flags; |
|
} |
|
|
|
void CBaseShader::SetDynamicEnvMappingState( int envMapVar, int envMapMaskVar, |
|
int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, int frameVar, |
|
int maskOffsetVar, int maskScaleVar, int tintVar ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
|
|
IMaterialVar** params = s_ppParams; |
|
int varFlags = params[FLAGS]->GetIntValue(); |
|
|
|
if( (varFlags & MATERIAL_VAR_ENVMAPSPHERE) == 0 ) |
|
{ |
|
if ( (varFlags & MATERIAL_VAR_ENVMAPCAMERASPACE) == 0 ) |
|
{ |
|
LoadCameraToWorldTransform( MATERIAL_TEXTURE0 ); |
|
} |
|
else |
|
{ |
|
LoadIdentity( MATERIAL_TEXTURE0 ); |
|
} |
|
} |
|
else |
|
{ |
|
LoadCameraSpaceSphereMapTransform( MATERIAL_TEXTURE0 ); |
|
} |
|
|
|
BindTexture( SHADER_SAMPLER0, envMapVar, envMapFrameVar ); |
|
|
|
if (params[envMapMaskVar]->IsTexture()) |
|
{ |
|
SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, |
|
maskOffsetVar, maskScaleVar ); |
|
BindTexture( SHADER_SAMPLER1, envMapMaskVar, envMapMaskFrameVar ); |
|
} |
|
else if (varFlags & MATERIAL_VAR_BASEALPHAENVMAPMASK) |
|
{ |
|
SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, |
|
maskOffsetVar, maskScaleVar ); |
|
BindTexture( SHADER_SAMPLER1, baseTextureVar, frameVar ); |
|
} |
|
|
|
SetModulationDynamicState( tintVar ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Masked environment map |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::FixedFunctionMaskedEnvmapPass( int envMapVar, int envMapMaskVar, |
|
int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, |
|
int frameVar, int maskOffsetVar, int maskScaleVar, int envMapTintVar ) |
|
{ |
|
// IMaterialVar** params = ShaderState().m_ppParams; |
|
|
|
if (IsSnapshotting()) |
|
{ |
|
// Alpha blending |
|
SetDefaultBlendingShadowState( envMapMaskVar, false ); |
|
|
|
// Disable overbright |
|
s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); |
|
s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); |
|
|
|
int flags = SetShadowEnvMappingState( envMapMaskVar, envMapTintVar ); |
|
s_pShaderShadow->DrawFlags( flags ); |
|
|
|
DefaultFog(); |
|
Draw(); |
|
|
|
s_pShaderShadow->EnableCustomPixelPipe( false ); |
|
s_pShaderShadow->EnableAlphaPipe( false ); |
|
} |
|
else |
|
{ |
|
SetDynamicEnvMappingState( envMapVar, envMapMaskVar, baseTextureVar, |
|
envMapFrameVar, envMapMaskFrameVar, frameVar, |
|
maskOffsetVar, maskScaleVar, envMapTintVar ); |
|
|
|
Draw(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Add masked environment map |
|
//----------------------------------------------------------------------------- |
|
void CBaseShader::FixedFunctionAdditiveMaskedEnvmapPass( int envMapVar, int envMapMaskVar, |
|
int baseTextureVar, int envMapFrameVar, int envMapMaskFrameVar, |
|
int frameVar, int maskOffsetVar, int maskScaleVar, int envMapTintVar ) |
|
{ |
|
// IMaterialVar** params = ShaderState().m_ppParams; |
|
|
|
if (IsSnapshotting()) |
|
{ |
|
SetInitialShadowState(); |
|
|
|
// Alpha blending |
|
SetAdditiveBlendingShadowState( envMapMaskVar, false ); |
|
|
|
// Disable overbright |
|
s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); |
|
s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); |
|
|
|
// Don't bother with z writes here... |
|
s_pShaderShadow->EnableDepthWrites( false ); |
|
|
|
int flags = SetShadowEnvMappingState( envMapMaskVar, envMapTintVar ); |
|
s_pShaderShadow->DrawFlags( flags ); |
|
|
|
FogToBlack(); |
|
Draw(); |
|
|
|
s_pShaderShadow->EnableCustomPixelPipe( false ); |
|
s_pShaderShadow->EnableAlphaPipe( false ); |
|
} |
|
else |
|
{ |
|
SetDynamicEnvMappingState( envMapVar, envMapMaskVar, baseTextureVar, |
|
envMapFrameVar, envMapMaskFrameVar, frameVar, |
|
maskOffsetVar, maskScaleVar, envMapTintVar ); |
|
|
|
Draw(); |
|
} |
|
} |
|
|
|
|
|
void CBaseShader::CleanupDynamicStateFixedFunction( ) |
|
{ |
|
Assert( !IsSnapshotting() ); |
|
LoadIdentity( MATERIAL_TEXTURE0 ); |
|
} |
|
|
|
bool CBaseShader::UsingFlashlight( IMaterialVar **params ) const |
|
{ |
|
if( IsSnapshotting() ) |
|
{ |
|
return CShader_IsFlag2Set( params, MATERIAL_VAR2_USE_FLASHLIGHT ); |
|
} |
|
else |
|
{ |
|
return s_pShaderAPI->InFlashlightMode(); |
|
} |
|
} |
|
|
|
bool CBaseShader::UsingEditor( IMaterialVar **params ) const |
|
{ |
|
if( IsSnapshotting() ) |
|
{ |
|
return CShader_IsFlag2Set( params, MATERIAL_VAR2_USE_EDITOR ); |
|
} |
|
else |
|
{ |
|
return s_pShaderAPI->InEditorMode(); |
|
} |
|
} |
|
|
|
void CBaseShader::DrawFlashlight_dx70( |
|
IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, |
|
int flashlightTextureVar, int flashlightTextureFrameVar, |
|
bool suppress_lighting ) |
|
{ |
|
SHADOW_STATE |
|
{ |
|
SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); |
|
pShaderShadow->EnableDepthWrites( false ); |
|
pShaderShadow->EnableAlphaWrites( false ); |
|
|
|
// Alpha test |
|
// pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); |
|
bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; |
|
if( bIsAlphaTested ) |
|
{ |
|
// disable alpha test and use the zfunc zequals since alpha isn't guaranteed to |
|
// be the same on both the regular pass and the flashlight pass. |
|
s_pShaderShadow->EnableAlphaTest( false ); |
|
s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); |
|
} |
|
|
|
// Alpha blend |
|
SetAdditiveBlendingShadowState( BASETEXTURE, true ); |
|
|
|
int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_COLOR | SHADER_DRAW_NORMAL; |
|
pShaderShadow->DrawFlags( flags ); |
|
FogToBlack(); |
|
|
|
if ( !suppress_lighting ) |
|
pShaderShadow->EnableLighting( true ); |
|
|
|
pShaderShadow->EnableCustomPixelPipe( true ); |
|
pShaderShadow->CustomTextureStages( 2 ); |
|
|
|
// color stage 0 |
|
// projected texture * vertex color (lighting) |
|
pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_COLOR, |
|
SHADER_TEXOP_MODULATE, |
|
SHADER_TEXARG_TEXTURE, |
|
SHADER_TEXARG_VERTEXCOLOR ); |
|
|
|
// color stage 1 |
|
// * base texture |
|
pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_COLOR, |
|
SHADER_TEXOP_MODULATE, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); |
|
|
|
// alpha stage 0 |
|
// get alpha from constant alpha |
|
pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, |
|
SHADER_TEXCHANNEL_ALPHA, |
|
SHADER_TEXOP_SELECTARG1, |
|
SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); |
|
|
|
// alpha stage 1 |
|
// get alpha from $basetexture |
|
pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, |
|
SHADER_TEXCHANNEL_ALPHA, |
|
SHADER_TEXOP_MODULATE, |
|
SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); |
|
|
|
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); |
|
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); |
|
|
|
// Shove the view position into texcoord 0 before the texture matrix. |
|
pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); |
|
pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); |
|
} |
|
DYNAMIC_STATE |
|
{ |
|
SetFlashlightFixedFunctionTextureTransform( MATERIAL_TEXTURE0 ); |
|
|
|
// NOTE: This has to come after the loadmatrix since the loadmatrix screws with the |
|
// transform flags!!!!!! |
|
// Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. |
|
// NOTE Tried to divide XY by Z, but doesn't work. |
|
pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 3, true ); |
|
|
|
BindTexture( SHADER_SAMPLER0, flashlightTextureVar, flashlightTextureFrameVar ); |
|
if( params[BASETEXTURE]->IsTexture() ) |
|
{ |
|
BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); |
|
} |
|
else |
|
{ |
|
pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); |
|
} |
|
|
|
SetModulationDynamicState(); |
|
} |
|
Draw(); |
|
} |
|
|
|
void CBaseShader::SetFlashlightFixedFunctionTextureTransform( MaterialMatrixMode_t matrix ) |
|
{ |
|
VMatrix worldToTexture; |
|
s_pShaderAPI->GetFlashlightState( worldToTexture ); |
|
|
|
VMatrix worldToView, viewToWorld, viewToTexture; |
|
s_pShaderAPI->GetMatrix( MATERIAL_VIEW, &worldToView[0][0] ); |
|
// The matrix that we get back from the shader api is transposed. . . yuck. |
|
MatrixTranspose( worldToView, worldToView ); |
|
MatrixInverseGeneral( worldToView, viewToWorld ); |
|
MatrixMultiply( worldToTexture, viewToWorld, viewToTexture ); |
|
|
|
s_pShaderAPI->MatrixMode( matrix ); |
|
// tranpose before going into the shaderapi. . . suck |
|
MatrixTranspose( viewToTexture, viewToTexture ); |
|
s_pShaderAPI->LoadMatrix( &viewToTexture[0][0] ); |
|
} |
|
|
|
bool CBaseShader::IsHDREnabled( void ) |
|
{ |
|
// HDRFIXME! Need to fix this for vgui materials |
|
HDRType_t hdr_mode=g_pHardwareConfig->GetHDRType(); |
|
switch(hdr_mode) |
|
{ |
|
case HDR_TYPE_NONE: |
|
return false; |
|
|
|
case HDR_TYPE_INTEGER: |
|
return true; |
|
|
|
case HDR_TYPE_FLOAT: |
|
{ |
|
ITexture *pRT = s_pShaderAPI->GetRenderTargetEx( 0 ); |
|
if( pRT && pRT->GetImageFormat() == IMAGE_FORMAT_RGBA16161616F ) |
|
{ |
|
return true; |
|
} |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
|