Counter Strike : Global Offensive Source Code
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.
 
 
 
 
 
 

1204 lines
40 KiB

//===== Copyright (c) 1996-2007, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
// This is what all vs/ps (dx8+) shaders inherit from.
//===========================================================================//
#if !defined(_STATIC_LINKED) || defined(STDSHADER_DX9_DLL_EXPORT)
#include "cpp_shader_constant_register_map.h"
#include "BaseVSShader.h"
#include "mathlib/vmatrix.h"
#include "mathlib/bumpvects.h"
#include "convar.h"
#include "tier0/icommandline.h"
#ifdef HDR
#include "vertexlit_and_unlit_generic_hdr_ps20.inc"
#include "vertexlit_and_unlit_generic_hdr_ps20b.inc"
#endif
#if !defined( _X360 ) && !defined( _PS3 )
#include "lightmappedgeneric_flashlight_vs30.inc"
#include "flashlight_ps30.inc"
#endif
#include "lightmappedgeneric_flashlight_vs20.inc"
#include "flashlight_ps20.inc"
#include "flashlight_ps20b.inc"
#include "vertexlitgeneric_flashlight_vs20.inc"
#include "shaderapifast.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// NOTE: This is externed in BaseVSShader.h so it needs to be here
#if defined( _PS3 ) || defined( OSX )
extern ConVar r_flashlightbrightness;
#else
ConVar r_flashlightbrightness( "r_flashlightbrightness", "0.25", FCVAR_CHEAT );
#endif
// These functions are to be called from the shaders.
//-----------------------------------------------------------------------------
// Pixel and vertex shader constants....
//-----------------------------------------------------------------------------
void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 )
{
Assert( !IsSnapshotting() );
if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1))
return;
IMaterialVar* pPixelVar = s_ppParams[constantVar];
Assert( pPixelVar );
IMaterialVar* pPixelVar2 = s_ppParams[constantVar2];
Assert( pPixelVar2 );
float val[4];
if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
{
pPixelVar->GetVecValue( val, 3 );
}
else
{
val[0] = val[1] = val[2] = pPixelVar->GetFloatValue();
}
val[3] = pPixelVar2->GetFloatValue();
s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
}
void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 )
{
Assert( !IsSnapshotting() );
if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1))
return;
IMaterialVar* pPixelVar = s_ppParams[constantVar];
Assert( pPixelVar );
IMaterialVar* pPixelVar2 = s_ppParams[constantVar2];
Assert( pPixelVar2 );
float val[4];
if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
{
pPixelVar->GetVecValue( val, 3 );
}
else
{
val[0] = val[1] = val[2] = pPixelVar->GetFloatValue();
}
val[3] = pPixelVar2->GetFloatValue();
val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] );
val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] );
val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] );
s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
}
void CBaseVSShader::SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue )
{
Assert( !IsSnapshotting() );
if ((!s_ppParams) || (constantVar == -1))
return;
IMaterialVar* pPixelVar = s_ppParams[constantVar];
Assert( pPixelVar );
float val[4];
if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pPixelVar->GetVecValue( val, 4 );
else
val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue();
val[3]=fWValue;
s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
}
void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar )
{
Assert( !IsSnapshotting() );
if ((!s_ppParams) || (constantVar == -1))
return;
IMaterialVar* pPixelVar = s_ppParams[constantVar];
Assert( pPixelVar );
float val[4];
if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pPixelVar->GetVecValue( val, 4 );
else
val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue();
s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
}
void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar )
{
Assert( !IsSnapshotting() );
if ((!s_ppParams) || (constantVar == -1))
return;
IMaterialVar* pPixelVar = s_ppParams[constantVar];
Assert( pPixelVar );
float val[4];
if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pPixelVar->GetVecValue( val, 4 );
else
val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue();
val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] );
val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] );
val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] );
s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
}
void CBaseVSShader::SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce )
{
int i;
for( i = 0; i < numConst; i++ )
{
float vec[4];
vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] );
vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] );
vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] );
vec[3] = pVec[i*4+3];
s_pShaderAPI->SetVertexShaderConstant( var + i, vec, 1, bForce );
}
}
void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce )
{
int i;
for( i = 0; i < numConst; i++ )
{
float vec[4];
vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] );
vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] );
vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] );
vec[3] = pVec[i*4+3];
s_pShaderAPI->SetPixelShaderConstant( var + i, vec, 1, bForce );
}
}
// GR - special version with fix for const/lerp issue
void CBaseVSShader::SetPixelShaderConstantFudge( int pixelReg, int constantVar )
{
Assert( !IsSnapshotting() );
if ((!s_ppParams) || (constantVar == -1))
return;
IMaterialVar* pPixelVar = s_ppParams[constantVar];
Assert( pPixelVar );
float val[4];
if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
{
pPixelVar->GetVecValue( val, 4 );
val[0] = val[0] * 0.992f + 0.0078f;
val[1] = val[1] * 0.992f + 0.0078f;
val[2] = val[2] * 0.992f + 0.0078f;
val[3] = val[3] * 0.992f + 0.0078f;
}
else
val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue() * 0.992f + 0.0078f;
s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
}
void CBaseVSShader::SetVertexShaderConstant( int vertexReg, int constantVar )
{
Assert( !IsSnapshotting() );
if ((!s_ppParams) || (constantVar == -1))
return;
IMaterialVar* pVertexVar = s_ppParams[constantVar];
Assert( pVertexVar );
float val[4];
if (pVertexVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pVertexVar->GetVecValue( val, 4 );
else
val[0] = val[1] = val[2] = val[3] = pVertexVar->GetFloatValue();
s_pShaderAPI->SetVertexShaderConstant( vertexReg, val );
}
//-----------------------------------------------------------------------------
// Sets vertex shader texture transforms
//-----------------------------------------------------------------------------
void CBaseVSShader::SetVertexShaderTextureTranslation( int vertexReg, int translationVar )
{
float offset[2] = {0, 0};
IMaterialVar* pTranslationVar = s_ppParams[translationVar];
if (pTranslationVar)
{
if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pTranslationVar->GetVecValue( offset, 2 );
else
offset[0] = offset[1] = pTranslationVar->GetFloatValue();
}
Vector4D translation[2];
translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] );
translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] );
s_pShaderAPI->SetVertexShaderConstant( vertexReg, translation[0].Base(), 2 );
}
void CBaseVSShader::SetVertexShaderTextureScale( int vertexReg, int scaleVar )
{
float scale[2] = {1, 1};
IMaterialVar* pScaleVar = s_ppParams[scaleVar];
if (pScaleVar)
{
if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pScaleVar->GetVecValue( scale, 2 );
else if (pScaleVar->IsDefined())
scale[0] = scale[1] = pScaleVar->GetFloatValue();
}
Vector4D scaleMatrix[2];
scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f );
scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f );
s_pShaderAPI->SetVertexShaderConstant( vertexReg, scaleMatrix[0].Base(), 2 );
}
void CBaseVSShader::SetVertexShaderTextureTransform( int vertexReg, int transformVar )
{
Vector4D transformation[2];
IMaterialVar* pTransformationVar = s_ppParams[transformVar];
if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
{
const VMatrix &mat = pTransformationVar->GetMatrixValue();
transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
}
else
{
transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
}
s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 );
}
void CBaseVSShader::SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar )
{
Vector4D transformation[2];
IMaterialVar* pTransformationVar = s_ppParams[transformVar];
if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
{
const VMatrix &mat = pTransformationVar->GetMatrixValue();
transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
}
else
{
transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
}
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();
}
// Apply the scaling
transformation[0][0] *= scale[0];
transformation[0][1] *= scale[1];
transformation[1][0] *= scale[0];
transformation[1][1] *= scale[1];
transformation[0][3] *= scale[0];
transformation[1][3] *= scale[1];
s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 );
}
//-----------------------------------------------------------------------------
// Sets pixel shader texture transforms
//-----------------------------------------------------------------------------
void CBaseVSShader::SetPixelShaderTextureTranslation( int pixelReg, int translationVar )
{
float offset[2] = {0, 0};
IMaterialVar* pTranslationVar = s_ppParams[translationVar];
if (pTranslationVar)
{
if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pTranslationVar->GetVecValue( offset, 2 );
else
offset[0] = offset[1] = pTranslationVar->GetFloatValue();
}
Vector4D translation[2];
translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] );
translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] );
s_pShaderAPI->SetPixelShaderConstant( pixelReg, translation[0].Base(), 2 );
}
void CBaseVSShader::SetPixelShaderTextureScale( int pixelReg, int scaleVar )
{
float scale[2] = {1, 1};
IMaterialVar* pScaleVar = s_ppParams[scaleVar];
if (pScaleVar)
{
if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pScaleVar->GetVecValue( scale, 2 );
else if (pScaleVar->IsDefined())
scale[0] = scale[1] = pScaleVar->GetFloatValue();
}
Vector4D scaleMatrix[2];
scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f );
scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f );
s_pShaderAPI->SetPixelShaderConstant( pixelReg, scaleMatrix[0].Base(), 2 );
}
void CBaseVSShader::SetPixelShaderTextureTransform( int pixelReg, int transformVar )
{
Vector4D transformation[2];
IMaterialVar* pTransformationVar = s_ppParams[transformVar];
if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
{
const VMatrix &mat = pTransformationVar->GetMatrixValue();
transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
}
else
{
transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
}
s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 );
}
void CBaseVSShader::SetPixelShaderTextureScaledTransform( int pixelReg, int transformVar, int scaleVar )
{
Vector4D transformation[2];
IMaterialVar* pTransformationVar = s_ppParams[transformVar];
if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
{
const VMatrix &mat = pTransformationVar->GetMatrixValue();
transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
}
else
{
transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
}
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();
}
// Apply the scaling
transformation[0][0] *= scale[0];
transformation[0][1] *= scale[1];
transformation[1][0] *= scale[0];
transformation[1][1] *= scale[1];
transformation[0][3] *= scale[0];
transformation[1][3] *= scale[1];
s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 );
}
//-----------------------------------------------------------------------------
// Moves a matrix into vertex shader constants
//-----------------------------------------------------------------------------
void CBaseVSShader::SetVertexShaderMatrix3x4( int vertexReg, int matrixVar )
{
IMaterialVar* pTranslationVar = s_ppParams[matrixVar];
if (pTranslationVar)
{
s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 3 );
}
else
{
VMatrix matrix;
MatrixSetIdentity( matrix );
s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 3 );
}
}
void CBaseVSShader::SetVertexShaderMatrix4x4( int vertexReg, int matrixVar )
{
IMaterialVar* pTranslationVar = s_ppParams[matrixVar];
if (pTranslationVar)
{
#ifdef _PS3
VMatrix transpose = pTranslationVar->GetMatrixValue().Transpose();
s_pShaderAPI->SetVertexShaderConstant( vertexReg, &transpose[0][0], 4 );
#else // _PS3
s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 4 );
#endif // !_PS3
}
else
{
VMatrix matrix;
MatrixSetIdentity( matrix );
s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 4 );
}
}
//-----------------------------------------------------------------------------
// Loads the view matrix into vertex shader constants
//-----------------------------------------------------------------------------
void CBaseVSShader::LoadViewMatrixIntoVertexShaderConstant( int vertexReg )
{
VMatrix mat, transpose;
s_pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] );
#ifdef _PS3
transpose = mat;
#else // _PS3
MatrixTranspose( mat, transpose );
#endif // !_PS3
s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 3 );
}
//-----------------------------------------------------------------------------
// Loads the projection matrix into pixel shader constants
//-----------------------------------------------------------------------------
void CBaseVSShader::LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg )
{
VMatrix mat, transpose;
s_pShaderAPI->GetActualProjectionMatrix( mat.m[0] );
#ifdef _PS3
transpose = mat;
#else // _PS3
MatrixTranspose( mat, transpose );
#endif // !_PS3
s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 4 );
}
//-----------------------------------------------------------------------------
// Loads the model * view matrix into pixel shader constants
//-----------------------------------------------------------------------------
void CBaseVSShader::LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg )
{
VMatrix view, model, modelView, transpose;
s_pShaderAPI->GetMatrix( MATERIAL_MODEL, model.m[0] );
MatrixTranspose( model, model );
s_pShaderAPI->GetMatrix( MATERIAL_VIEW, view.m[0] );
MatrixTranspose( view, view );
MatrixMultiply( view, model, modelView );
s_pShaderAPI->SetVertexShaderConstant( vertexReg, modelView.m[0], 3 );
}
//-----------------------------------------------------------------------------
// Loads bump lightmap coordinates into the pixel shader
//-----------------------------------------------------------------------------
void CBaseVSShader::LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg )
{
Vector4D basis[3];
for (int i = 0; i < 3; ++i)
{
memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) );
basis[i][3] = 0.0f;
}
s_pShaderAPI->SetPixelShaderConstant( pixelReg, (float*)basis, 3 );
}
//-----------------------------------------------------------------------------
// Loads bump lightmap coordinates into the pixel shader
//-----------------------------------------------------------------------------
void CBaseVSShader::LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg )
{
Vector4D basis[3];
// transpose
int i;
for (i = 0; i < 3; ++i)
{
basis[i][0] = g_localBumpBasis[0][i];
basis[i][1] = g_localBumpBasis[1][i];
basis[i][2] = g_localBumpBasis[2][i];
basis[i][3] = 0.0f;
}
s_pShaderAPI->SetVertexShaderConstant( vertexReg, (float*)basis, 3 );
for (i = 0; i < 3; ++i)
{
memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) );
basis[i][3] = 0.0f;
}
s_pShaderAPI->SetVertexShaderConstant( vertexReg + 3, (float*)basis, 3 );
}
//-----------------------------------------------------------------------------
// Helper methods for pixel shader overbrighting
//-----------------------------------------------------------------------------
void CBaseVSShader::EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo )
{
// can't have other overbright values with pixel shaders as it stands.
float v[4];
if( bEnable )
{
v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? OVERBRIGHT / 2.0f : OVERBRIGHT;
}
else
{
v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? 1.0f / 2.0f : 1.0f;
}
s_pShaderAPI->SetPixelShaderConstant( reg, v, 1 );
}
//-----------------------------------------------------------------------------
// Converts a color + alpha into a vector4
//-----------------------------------------------------------------------------
void CBaseVSShader::ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color )
{
color.Init( 1.0, 1.0, 1.0, 1.0 );
if ( colorVar != -1 )
{
IMaterialVar* pColorVar = s_ppParams[colorVar];
if ( pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR )
{
pColorVar->GetVecValue( color.Base(), 3 );
}
else
{
color[0] = color[1] = color[2] = pColorVar->GetFloatValue();
}
}
if ( alphaVar != -1 )
{
float flAlpha = s_ppParams[alphaVar]->GetFloatValue();
color[3] = clamp( flAlpha, 0.0f, 1.0f );
}
}
#ifdef _DEBUG
ConVar mat_envmaptintoverride( "mat_envmaptintoverride", "-1" );
ConVar mat_envmaptintscale( "mat_envmaptintscale", "-1" );
#endif
//-----------------------------------------------------------------------------
// Helpers for dealing with envmap tint
//-----------------------------------------------------------------------------
// set alphaVar to -1 to ignore it.
void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear )
{
float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
if( g_pConfig->bShowSpecular && g_pConfig->nFullbright != 2 )
{
IMaterialVar* pAlphaVar = NULL;
if( alphaVar >= 0 )
{
pAlphaVar = s_ppParams[alphaVar];
}
if( pAlphaVar )
{
color[3] = pAlphaVar->GetFloatValue();
}
IMaterialVar* pTintVar = s_ppParams[tintVar];
#ifdef _DEBUG
pTintVar->GetVecValue( color, 3 );
float envmapTintOverride = mat_envmaptintoverride.GetFloat();
float envmapTintScaleOverride = mat_envmaptintscale.GetFloat();
if( envmapTintOverride != -1.0f )
{
color[0] = color[1] = color[2] = envmapTintOverride;
}
if( envmapTintScaleOverride != -1.0f )
{
color[0] *= envmapTintScaleOverride;
color[1] *= envmapTintScaleOverride;
color[2] *= envmapTintScaleOverride;
}
if( bConvertFromGammaToLinear )
{
color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] );
color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] );
color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] );
}
#else
if( bConvertFromGammaToLinear )
{
pTintVar->GetLinearVecValue( color, 3 );
}
else
{
pTintVar->GetVecValue( color, 3 );
}
#endif
}
else
{
color[0] = color[1] = color[2] = color[3] = 0.0f;
}
s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 );
}
//-----------------------------------------------------------------------------
// Sets up hw morphing state for the vertex shader
//-----------------------------------------------------------------------------
void CBaseVSShader::SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler )
{
#if !defined( _X360 ) && !defined( _PS3 )
if ( !s_pShaderAPI->IsHWMorphingEnabled() )
return;
int nMorphWidth, nMorphHeight;
s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR );
int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT );
float pMorphAccumSize[4] = { nMorphWidth, nMorphHeight, nDim, 0.0f };
s_pShaderAPI->SetVertexShaderConstant( nDimConst, pMorphAccumSize );
int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET );
int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET );
int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH );
int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT );
float pMorphAccumSubrect[4] = { nXOffset, nYOffset, nWidth, nHeight };
s_pShaderAPI->SetVertexShaderConstant( nSubrectConst, pMorphAccumSubrect );
s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR );
#endif
}
//-----------------------------------------------------------------------------
// GR - translucency query
//-----------------------------------------------------------------------------
BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture,
int detailTextureVar )
{
// 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 (for blending or alpha test)
isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) &&
!(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) );
if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) )
{
isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture );
}
if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE )
{
return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive
}
else
{
return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending
}
}
void CBaseVSShader::SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms )
{
Assert( !IsSnapshotting() );
VMatrix worldToTexture;
const FlashlightState_t &flashlightState = s_pShaderAPI->GetFlashlightState( worldToTexture );
// Set the flashlight origin
float pos[4];
pos[0] = flashlightState.m_vecLightOrigin[0];
pos[1] = flashlightState.m_vecLightOrigin[1];
pos[2] = flashlightState.m_vecLightOrigin[2];
pos[3] = 1.0f / ( ( 0.6f * flashlightState.m_FarZ ) - flashlightState.m_FarZ ); // DX8 needs this
s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, pos, 1 );
s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, worldToTexture.Base(), 4 );
// Set the flashlight attenuation factors
float atten[4];
atten[0] = flashlightState.m_fConstantAtten;
atten[1] = flashlightState.m_fLinearAtten;
atten[2] = flashlightState.m_fQuadraticAtten;
atten[3] = flashlightState.m_FarZAtten;
s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, atten, 1 );
if ( bDetail )
{
SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, BASETEXTURETRANSFORM, detailScaleVar );
}
if( bSetTextureTransforms )
{
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BASETEXTURETRANSFORM );
if( !bDetail && bBump && bumpTransformVar != -1 )
{
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, bumpTransformVar ); // aliased on top of detail transform
}
}
}
void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars )
{
bool bSFM = ( ToolsEnabled() && IsPlatformWindowsPC() && g_pHardwareConfig->SupportsPixelShaders_3_0() ) ? true : false;
// FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric
if( !vars.m_bLightmappedGeneric )
{
vars.m_bBump = false;
}
bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmapVar2 != -1 && params[vars.m_nBumpmapVar2]->IsTexture();
bool bSeamless = vars.m_fSeamlessScale != 0.0;
bool bDetail = vars.m_bLightmappedGeneric && (vars.m_nDetailVar != -1) && params[vars.m_nDetailVar]->IsDefined() && (vars.m_nDetailScale != -1) && g_pConfig->UseDetailTexturing();
int nDetailBlendMode = DETAIL_BLEND_MODE_RGB_EQUALS_BASE_x_DETAILx2;
if ( bDetail )
{
nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params );
ITexture *pDetailTexture = params[vars.m_nDetailVar]->GetTextureValue();
if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP )
{
if ( vars.m_bBump )
nDetailBlendMode = DETAIL_BLEND_MODE_SSBUMP_BUMP; // ssbump
else
nDetailBlendMode = DETAIL_BLEND_MODE_SSBUMP_NOBUMP; // ssbump_nobump
}
}
if( pShaderShadow )
{
SetInitialShadowState();
pShaderShadow->EnableDepthWrites( false );
pShaderShadow->EnableAlphaWrites( false );
// Alpha blend
SetAdditiveBlendingShadowState( BASETEXTURE, true );
// Alpha test
pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) );
if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f )
{
pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() );
}
// Spot sampler
pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
// Base sampler
pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true );
// Normalizing cubemap sampler
pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
// Normalizing cubemap sampler2 or normal map sampler
pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
// RandomRotation sampler
pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
// Flashlight depth sampler
pShaderShadow->EnableTexture( SHADER_SAMPLER7, true );
//pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 );
if( vars.m_bWorldVertexTransition )
{
// $basetexture2
pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true );
}
if( bBump2 )
{
// Normalmap2 sampler
pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
}
if( bDetail )
{
pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler
pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, IsSRGBDetailTexture( nDetailBlendMode ) );
}
pShaderShadow->EnableSRGBWrite( true );
if( vars.m_bLightmappedGeneric )
{
#if !defined( _X360 ) && !defined( _PS3 )
if ( g_pHardwareConfig->SupportsPixelShaders_3_0() )
{
DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 );
SET_STATIC_VERTEX_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition );
SET_STATIC_VERTEX_SHADER_COMBO( NORMALMAP, vars.m_bBump );
SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamless );
SET_STATIC_VERTEX_SHADER_COMBO( DETAIL, bDetail );
SET_STATIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 );
}
else
#endif
{
DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition );
SET_STATIC_VERTEX_SHADER_COMBO( NORMALMAP, vars.m_bBump );
SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamless );
SET_STATIC_VERTEX_SHADER_COMBO( DETAIL, bDetail );
SET_STATIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 );
}
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
if( vars.m_bBump )
{
flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T;
}
int numTexCoords = 1;
if( vars.m_bWorldVertexTransition )
{
flags |= VERTEX_COLOR;
numTexCoords = 2; // need lightmap texcoords to get alpha.
}
pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 );
}
else
{
// Need a 3.0 vs here?
DECLARE_STATIC_VERTEX_SHADER( vertexlitgeneric_flashlight_vs20 );
SET_STATIC_VERTEX_SHADER_COMBO( TEETH, vars.m_bTeeth );
SET_STATIC_VERTEX_SHADER( vertexlitgeneric_flashlight_vs20 );
unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
int numTexCoords = 1;
pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, vars.m_bBump ? 4 : 0 );
}
int nBumpMapVariant = 0;
if ( vars.m_bBump )
{
nBumpMapVariant = ( vars.m_bSSBump ) ? 2 : 1;
}
#if !defined( _X360 ) && !defined( _PS3 )
if ( g_pHardwareConfig->SupportsPixelShaders_3_0() )
{
ShadowFilterMode_t nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode( false /* bForceLowQuality */, true /* bPS30 */ );
DECLARE_STATIC_PIXEL_SHADER( flashlight_ps30 );
SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, nBumpMapVariant );
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP2, bBump2 );
SET_STATIC_PIXEL_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition );
SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamless );
SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bDetail );
SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
SET_STATIC_PIXEL_SHADER( flashlight_ps30 );
}
else
#endif
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
ShadowFilterMode_t nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode( false /* bForceLowQuality */, false /* bPS30 */ );
DECLARE_STATIC_PIXEL_SHADER( flashlight_ps20b );
SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, nBumpMapVariant );
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP2, bBump2 );
SET_STATIC_PIXEL_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition );
SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamless );
SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bDetail );
SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
SET_STATIC_PIXEL_SHADER( flashlight_ps20b );
}
else
{
DECLARE_STATIC_PIXEL_SHADER( flashlight_ps20 );
SET_STATIC_PIXEL_SHADER_COMBO( SFM, bSFM );
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP, nBumpMapVariant );
SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAP2, bBump2 );
SET_STATIC_PIXEL_SHADER_COMBO( WORLDVERTEXTRANSITION, vars.m_bWorldVertexTransition );
SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamless );
SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bDetail );
SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode );
SET_STATIC_PIXEL_SHADER( flashlight_ps20 );
}
FogToBlack();
PI_BeginCommandBuffer();
PI_SetModulationPixelShaderDynamicState( PSREG_DIFFUSE_MODULATION );
PI_EndCommandBuffer();
}
else
{
VMatrix worldToTexture;
ITexture *pFlashlightDepthTexture;
FlashlightState_t flashlightState = ShaderApiFast( pShaderAPI )->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture );
SetFlashLightColorFromState( flashlightState, pShaderAPI, false );
BindTexture( SHADER_SAMPLER0, TEXTURE_BINDFLAGS_SRGBREAD, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame );
ShaderApiFast( pShaderAPI )->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, TEXTURE_SHADOW_NOISE_2D );
if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows )
{
BindTexture( SHADER_SAMPLER7, TEXTURE_BINDFLAGS_SHADOWDEPTH, pFlashlightDepthTexture, 0 );
// Tweaks associated with a given flashlight
float tweaks[4];
tweaks[0] = ShadowFilterFromState( flashlightState );
tweaks[1] = ShadowAttenFromState( flashlightState );
HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] );
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 );
// Dimensions of screen, used for screen-space noise map sampling
float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
int nWidth, nHeight;
ShaderApiFast( pShaderAPI )->GetBackBufferDimensions( nWidth, nHeight );
int nTexWidth, nTexHeight;
ShaderApiFast( pShaderAPI )->GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SHADOW_NOISE_2D );
vScreenScale[0] = (float) nWidth / nTexWidth;
vScreenScale[1] = (float) nHeight / nTexHeight;
vScreenScale[2] = 1.0f / flashlightState.m_flShadowMapResolution;
vScreenScale[3] = 2.0f / flashlightState.m_flShadowMapResolution;
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 );
}
else
{
ShaderApiFast( pShaderAPI )->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_BINDFLAGS_NONE, TEXTURE_WHITE );
}
if( params[BASETEXTURE]->IsTexture() && g_pConfig->nFullbright != 2 )
{
BindTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_SRGBREAD, BASETEXTURE, FRAME );
}
else
{
ShaderApiFast( pShaderAPI )->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_GREY );
}
if( vars.m_bWorldVertexTransition )
{
Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 );
BindTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_SRGBREAD, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar );
}
ShaderApiFast( pShaderAPI )->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALIZATION_CUBEMAP );
if( vars.m_bBump )
{
BindTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, vars.m_nBumpmapVar, vars.m_nBumpmapFrame );
}
else
{
ShaderApiFast( pShaderAPI )->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALIZATION_CUBEMAP );
}
if( bDetail )
{
BindTexture( SHADER_SAMPLER8, IsSRGBDetailTexture( nDetailBlendMode ) ? TEXTURE_BINDFLAGS_SRGBREAD : TEXTURE_BINDFLAGS_NONE, vars.m_nDetailVar );
}
if( vars.m_bWorldVertexTransition )
{
if( bBump2 )
{
BindTexture( SHADER_SAMPLER6, TEXTURE_BINDFLAGS_NONE, vars.m_nBumpmapVar2, vars.m_nBumpmapFrame2 );
}
}
if( vars.m_bLightmappedGeneric )
{
#if !defined( _X360 ) && !defined( _PS3 )
if ( g_pHardwareConfig->SupportsPixelShaders_3_0() )
{
DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 );
SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs30 );
}
else
#endif
{
DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 );
SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 );
}
if ( bSeamless )
{
float const0[4]={ vars.m_fSeamlessScale,0,0,0};
ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 );
}
if ( bDetail )
{
float vDetailConstants[4] = {1,1,1,1};
if ( vars.m_nDetailTint != -1 )
{
params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 );
}
if ( vars.m_nDetailTextureBlendFactor != -1 )
{
vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue();
}
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( 0, vDetailConstants, 1 );
}
}
else
{
DECLARE_DYNAMIC_VERTEX_SHADER( vertexlitgeneric_flashlight_vs20 );
SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, ShaderApiFast( pShaderAPI )->GetCurrentNumBones() > 0 );
SET_DYNAMIC_VERTEX_SHADER( vertexlitgeneric_flashlight_vs20 );
if( vars.m_bTeeth )
{
Assert( vars.m_nTeethForwardVar >= 0 );
Assert( vars.m_nTeethIllumFactorVar >= 0 );
Vector4D lighting;
params[vars.m_nTeethForwardVar]->GetVecValue( lighting.Base(), 3 );
lighting[3] = params[vars.m_nTeethIllumFactorVar]->GetFloatValue();
ShaderApiFast( pShaderAPI )->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() );
}
}
ShaderApiFast( pShaderAPI )->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
float vEyePos_SpecExponent[4];
ShaderApiFast( pShaderAPI )->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
vEyePos_SpecExponent[3] = 0.0f;
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
#if !defined( _X360 ) && !defined( _PS3 )
if ( g_pHardwareConfig->SupportsPixelShaders_3_0() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps30 );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) );
SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, flashlightState.m_bUberlight && bSFM );
SET_DYNAMIC_PIXEL_SHADER( flashlight_ps30 );
SetupUberlightFromState( pShaderAPI, flashlightState );
}
else
#endif
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20b );
SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) );
SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20b );
}
else
{
DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20 );
SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20 );
}
float atten[4]; // Set the flashlight attenuation factors
atten[0] = flashlightState.m_fConstantAtten;
atten[1] = flashlightState.m_fLinearAtten;
atten[2] = flashlightState.m_fQuadraticAtten;
atten[3] = flashlightState.m_FarZAtten;
s_pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 );
float pos[4]; // Set the flashlight origin
pos[0] = flashlightState.m_vecLightOrigin[0];
pos[1] = flashlightState.m_vecLightOrigin[1];
pos[2] = flashlightState.m_vecLightOrigin[2];
pos[3] = flashlightState.m_FarZ;
ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // rim boost not really used here
SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true );
}
Draw();
}
// Take 0..1 seed and map to (u, v) coordinate to be used in shadow filter jittering...
void CBaseVSShader::HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV )
{
int nTexWidth, nTexHeight;
s_pShaderAPI->GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SHADOW_NOISE_2D );
int nSeed = fmod (fJitterSeed, 1.0f) * nTexWidth * nTexHeight;
int nRow = nSeed / nTexHeight;
int nCol = nSeed % nTexWidth;
// Div and mod to get an individual texel in the fTexRes x fTexRes grid
*fU = nRow / (float) nTexHeight; // Row
*fV = nCol / (float) nTexWidth; // Column
}
#endif // !_STATIC_LINKED || STDSHADER_DX8_DLL_EXPORT
void CBaseVSShader::DrawEqualDepthToDestAlpha( void )
{
#ifdef STDSHADER_DX9_DLL_EXPORT
if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
{
bool bMakeActualDrawCall = false;
if( s_pShaderShadow )
{
s_pShaderShadow->EnableColorWrites( false );
s_pShaderShadow->EnableAlphaWrites( true );
s_pShaderShadow->EnableDepthWrites( false );
s_pShaderShadow->EnableAlphaTest( false );
s_pShaderShadow->EnableBlending( false );
s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
s_pShaderShadow->SetVertexShader( "depthtodestalpha_vs20", 0 );
s_pShaderShadow->SetPixelShader( "depthtodestalpha_ps20b", 0 );
}
if( s_pShaderAPI )
{
s_pShaderAPI->SetVertexShaderIndex( 0 );
s_pShaderAPI->SetPixelShaderIndex( 0 );
bMakeActualDrawCall = s_pShaderAPI->ShouldWriteDepthToDestAlpha();
}
Draw( bMakeActualDrawCall );
}
#else
Assert( 0 ); //probably just needs a shader update to the latest
#endif
}
#if !defined( _PS3 ) && !defined( OSX )
//-----------------------------------------------------------------------------
bool ToolsEnabled()
{
static bool bToolsMode = ( CommandLine()->CheckParm( "-tools" ) != NULL );
return bToolsMode;
}
#endif