//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Responsible for drawing the scene
//
// $NoKeywords: $
//=============================================================================//
# include "cbase.h"
# include "view.h"
# include "iviewrender.h"
# include "view_shared.h"
# include "ivieweffects.h"
# include "iinput.h"
# include "model_types.h"
# include "clientsideeffects.h"
# include "particlemgr.h"
# include "viewrender.h"
# include "iclientmode.h"
# include "voice_status.h"
# include "radio_status.h"
# include "glow_overlay.h"
# include "materialsystem/imesh.h"
# include "materialsystem/itexture.h"
# include "materialsystem/imaterial.h"
# include "materialsystem/imaterialvar.h"
# include "materialsystem/imaterialsystemhardwareconfig.h"
# include "detailobjectsystem.h"
# include "tier0/vprof.h"
# include "engine/IEngineTrace.h"
# include "engine/ivmodelinfo.h"
# include "view_scene.h"
# include "particles_ez.h"
# include "engine/IStaticPropMgr.h"
# include "engine/ivdebugoverlay.h"
# include "cs_view_scene.h"
# include "c_cs_player.h"
# include "cs_gamerules.h"
# include "shake.h"
# include "clienteffectprecachesystem.h"
# include <vgui/ISurface.h>
CLIENTEFFECT_REGISTER_BEGIN ( PrecacheCSViewScene )
CLIENTEFFECT_MATERIAL ( " effects/flashbang " )
CLIENTEFFECT_MATERIAL ( " effects/flashbang_white " )
CLIENTEFFECT_MATERIAL ( " effects/nightvision " )
CLIENTEFFECT_REGISTER_END ( )
static CCSViewRender g_ViewRender ;
CCSViewRender : : CCSViewRender ( )
{
view = ( IViewRender * ) & g_ViewRender ;
m_pFlashTexture = NULL ;
}
struct ConVarFlags
{
const char * name ;
int flags ;
} ;
ConVarFlags s_flaggedConVars [ ] =
{
{ " r_screenfademinsize " , FCVAR_CHEAT } ,
{ " r_screenfademaxsize " , FCVAR_CHEAT } ,
{ " developer " , FCVAR_CHEAT } ,
} ;
void CCSViewRender : : Init ( void )
{
for ( int i = 0 ; i < ARRAYSIZE ( s_flaggedConVars ) ; + + i )
{
ConVar * flaggedConVar = cvar - > FindVar ( s_flaggedConVars [ i ] . name ) ;
if ( flaggedConVar )
{
flaggedConVar - > AddFlags ( s_flaggedConVars [ i ] . flags ) ;
}
}
CViewRender : : Init ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the min/max fade distances
//-----------------------------------------------------------------------------
void CCSViewRender : : GetScreenFadeDistances ( float * min , float * max )
{
if ( min )
{
* min = 0.0f ;
}
if ( max )
{
* max = 0.0f ;
}
}
void CCSViewRender : : PerformNightVisionEffect ( const CViewSetup & view )
{
C_CSPlayer * pPlayer = C_CSPlayer : : GetLocalCSPlayer ( ) ;
if ( ! pPlayer )
return ;
if ( pPlayer - > GetObserverMode ( ) = = OBS_MODE_IN_EYE )
{
CBaseEntity * target = pPlayer - > GetObserverTarget ( ) ;
if ( target & & target - > IsPlayer ( ) )
{
pPlayer = ( C_CSPlayer * ) target ;
}
}
if ( pPlayer & & pPlayer - > m_flNightVisionAlpha > 0 )
{
IMaterial * pMaterial = materials - > FindMaterial ( " effects/nightvision " , TEXTURE_GROUP_CLIENT_EFFECTS , true ) ;
if ( pMaterial )
{
int iMaxValue = 255 ;
byte overlaycolor [ 4 ] = { 0 , 255 , 0 , 255 } ;
if ( g_pMaterialSystemHardwareConfig - > GetDXSupportLevel ( ) > = 80 )
{
UpdateScreenEffectTexture ( 0 , view . x , view . y , view . width , view . height ) ;
}
else
{
// In DX7, use the values CS:goldsrc uses.
iMaxValue = 225 ;
overlaycolor [ 0 ] = overlaycolor [ 2 ] = 50 / 2 ;
overlaycolor [ 1 ] = 225 / 2 ;
}
if ( pPlayer - > m_bNightVisionOn )
{
pPlayer - > m_flNightVisionAlpha + = 15 ;
pPlayer - > m_flNightVisionAlpha = MIN ( pPlayer - > m_flNightVisionAlpha , iMaxValue ) ;
}
else
{
pPlayer - > m_flNightVisionAlpha - = 40 ;
pPlayer - > m_flNightVisionAlpha = MAX ( pPlayer - > m_flNightVisionAlpha , 0 ) ;
}
overlaycolor [ 3 ] = pPlayer - > m_flNightVisionAlpha ;
render - > ViewDrawFade ( overlaycolor , pMaterial ) ;
// Only one pass in DX7.
/* if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 80 )
{
CMatRenderContextPtr pRenderContext ( materials ) ;
pRenderContext - > DrawScreenSpaceQuad ( pMaterial ) ;
render - > ViewDrawFade ( overlaycolor , pMaterial ) ;
pRenderContext - > DrawScreenSpaceQuad ( pMaterial ) ;
} */
}
}
}
//Adrian - Super Nifty Flashbang Effect(tm)
// this does the burn in for the flashbang effect.
void CCSViewRender : : PerformFlashbangEffect ( const CViewSetup & view )
{
C_CSPlayer * pPlayer = C_CSPlayer : : GetLocalCSPlayer ( ) ;
if ( pPlayer = = NULL )
return ;
if ( pPlayer - > m_flFlashBangTime < gpGlobals - > curtime )
return ;
IMaterial * pMaterial = materials - > FindMaterial ( " effects/flashbang " , TEXTURE_GROUP_CLIENT_EFFECTS , true ) ;
if ( ! pMaterial )
return ;
byte overlaycolor [ 4 ] = { 255 , 255 , 255 , 255 } ;
CMatRenderContextPtr pRenderContext ( materials ) ;
if ( pPlayer - > m_flFlashAlpha < pPlayer - > m_flFlashMaxAlpha )
{
pPlayer - > m_flFlashAlpha + = 45 ;
pPlayer - > m_flFlashAlpha = MIN ( pPlayer - > m_flFlashAlpha , pPlayer - > m_flFlashMaxAlpha ) ;
overlaycolor [ 0 ] = overlaycolor [ 1 ] = overlaycolor [ 2 ] = pPlayer - > m_flFlashAlpha ;
m_pFlashTexture = GetFullFrameFrameBufferTexture ( 1 ) ;
bool foundVar ;
IMaterialVar * m_BaseTextureVar = pMaterial - > FindVar ( " $basetexture " , & foundVar , false ) ;
Rect_t srcRect ;
srcRect . x = view . x ;
srcRect . y = view . y ;
srcRect . width = view . width ;
srcRect . height = view . height ;
m_BaseTextureVar - > SetTextureValue ( m_pFlashTexture ) ;
pRenderContext - > CopyRenderTargetToTextureEx ( m_pFlashTexture , 0 , & srcRect , NULL ) ;
pRenderContext - > SetFrameBufferCopyTexture ( m_pFlashTexture ) ;
render - > ViewDrawFade ( overlaycolor , pMaterial ) ;
// just do one pass for dxlevel < 80.
/*
if ( g_pMaterialSystemHardwareConfig - > GetDXSupportLevel ( ) > = 80 )
{
pRenderContext - > DrawScreenSpaceRectangle ( pMaterial , view . x , view . y , view . width , view . height ,
0 , 0 , m_pFlashTexture - > GetActualWidth ( ) - 1 , m_pFlashTexture - > GetActualHeight ( ) - 1 ,
m_pFlashTexture - > GetActualWidth ( ) , m_pFlashTexture - > GetActualHeight ( ) ) ;
render - > ViewDrawFade ( overlaycolor , pMaterial ) ;
pRenderContext - > DrawScreenSpaceRectangle ( pMaterial , view . x , view . y , view . width , view . height ,
0 , 0 , m_pFlashTexture - > GetActualWidth ( ) - 1 , m_pFlashTexture - > GetActualHeight ( ) - 1 ,
m_pFlashTexture - > GetActualWidth ( ) , m_pFlashTexture - > GetActualHeight ( ) ) ;
}
*/
}
else if ( m_pFlashTexture )
{
float flAlpha = pPlayer - > m_flFlashMaxAlpha * ( pPlayer - > m_flFlashBangTime - gpGlobals - > curtime ) / pPlayer - > m_flFlashDuration ;
flAlpha = clamp ( flAlpha , 0 , pPlayer - > m_flFlashMaxAlpha ) ;
overlaycolor [ 0 ] = overlaycolor [ 1 ] = overlaycolor [ 2 ] = flAlpha ;
render - > ViewDrawFade ( overlaycolor , pMaterial ) ;
// just do one pass for dxlevel < 80.
/* if (g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 80)
{
pRenderContext - > DrawScreenSpaceRectangle ( pMaterial , view . x , view . y , view . width , view . height ,
0 , 0 , m_pFlashTexture - > GetActualWidth ( ) - 1 , m_pFlashTexture - > GetActualHeight ( ) - 1 ,
m_pFlashTexture - > GetActualWidth ( ) , m_pFlashTexture - > GetActualHeight ( ) ) ;
render - > ViewDrawFade ( overlaycolor , pMaterial ) ;
pRenderContext - > DrawScreenSpaceRectangle ( pMaterial , view . x , view . y , view . width , view . height ,
0 , 0 , m_pFlashTexture - > GetActualWidth ( ) - 1 , m_pFlashTexture - > GetActualHeight ( ) - 1 ,
m_pFlashTexture - > GetActualWidth ( ) , m_pFlashTexture - > GetActualHeight ( ) ) ;
} */
}
// this does the pure white overlay part of the flashbang effect.
pMaterial = materials - > FindMaterial ( " effects/flashbang_white " , TEXTURE_GROUP_CLIENT_EFFECTS , true ) ;
if ( ! pMaterial )
return ;
float flAlpha = 255 ;
if ( pPlayer - > m_flFlashAlpha < pPlayer - > m_flFlashMaxAlpha )
{
flAlpha = pPlayer - > m_flFlashAlpha ;
}
else
{
float flFlashTimeLeft = pPlayer - > m_flFlashBangTime - gpGlobals - > curtime ;
float flAlphaPercentage = 1.0 ;
const float certainBlindnessTimeThresh = 3.0 ; // yes this is a magic number, necessary to match CS/CZ flashbang effectiveness cause the rendering system is completely different.
if ( flFlashTimeLeft > certainBlindnessTimeThresh )
{
// if we still have enough time of blindness left, make sure the player can't see anything yet.
flAlphaPercentage = 1.0 ;
}
else
{
// blindness effects shorter than 'certainBlindnessTimeThresh' will start off at less than 255 alpha.
flAlphaPercentage = flFlashTimeLeft / certainBlindnessTimeThresh ;
if ( g_pMaterialSystemHardwareConfig - > GetDXSupportLevel ( ) > = 80 )
{
// reduce alpha level quicker with dx 8 support and higher to compensate
// for having the burn-in effect.
flAlphaPercentage * = flAlphaPercentage ;
}
}
flAlpha = flAlphaPercentage * = pPlayer - > m_flFlashMaxAlpha ; // scale a [0..1) value to a [0..MaxAlpha] value for the alpha.
// make sure the alpha is in the range of [0..MaxAlpha]
flAlpha = MAX ( flAlpha , 0 ) ;
flAlpha = MIN ( flAlpha , pPlayer - > m_flFlashMaxAlpha ) ;
}
overlaycolor [ 0 ] = overlaycolor [ 1 ] = overlaycolor [ 2 ] = flAlpha ;
render - > ViewDrawFade ( overlaycolor , pMaterial ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Renders extra 2D effects in derived classes while the 2D view is on the stack
//-----------------------------------------------------------------------------
void CCSViewRender : : Render2DEffectsPreHUD ( const CViewSetup & view )
{
PerformNightVisionEffect ( view ) ; // this needs to come before the HUD is drawn, or it will wash the HUD out
}
//-----------------------------------------------------------------------------
// Purpose: Renders extra 2D effects in derived classes while the 2D view is on the stack
//-----------------------------------------------------------------------------
void CCSViewRender : : Render2DEffectsPostHUD ( const CViewSetup & view )
{
PerformFlashbangEffect ( view ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Renders voice feedback and other sprites attached to players
// Input : none
//-----------------------------------------------------------------------------
void CCSViewRender : : RenderPlayerSprites ( )
{
GetClientVoiceMgr ( ) - > SetHeadLabelOffset ( 40 ) ;
CViewRender : : RenderPlayerSprites ( ) ;
RadioManager ( ) - > DrawHeadLabels ( ) ;
}