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.
589 lines
21 KiB
589 lines
21 KiB
//========= Copyright © 1996-2005, 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 "precache_register.h"
|
|
#include "engine/IEngineSound.h"
|
|
#include <vgui/ISurface.h>
|
|
#include "hltvreplaysystem.h"
|
|
|
|
// NOTE: This has to be the last file included!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
PRECACHE_REGISTER_BEGIN( GLOBAL, PrecacheCSViewScene )
|
|
PRECACHE( MATERIAL, "effects/overlaysmoke" )
|
|
PRECACHE( MATERIAL, "effects/flashbang" )
|
|
PRECACHE( MATERIAL, "effects/flashbang_white" )
|
|
PRECACHE( MATERIAL, "effects/nightvision" )
|
|
PRECACHE_REGISTER_END()
|
|
|
|
static CCSViewRender g_ViewRender;
|
|
IViewRender *GetViewRenderInstance()
|
|
{
|
|
return &g_ViewRender;
|
|
}
|
|
|
|
|
|
CCSViewRender::CCSViewRender()
|
|
{
|
|
m_pFlashTexture = NULL;
|
|
}
|
|
|
|
void CCSViewRender::Init( void )
|
|
{
|
|
CViewRender::Init();
|
|
}
|
|
|
|
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 };
|
|
|
|
UpdateScreenEffectTexture( 0, view.x, view.y, view.width, view.height );
|
|
|
|
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 );
|
|
|
|
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 *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
|
|
if ( pLocalPlayer == NULL )
|
|
return;
|
|
|
|
C_CSPlayer *pFlashBangPlayer = pLocalPlayer;
|
|
//bool bReduceEffect = false;
|
|
|
|
float flAlphaScale = 1.0f;
|
|
if ( pLocalPlayer->GetObserverMode() != OBS_MODE_NONE )
|
|
{
|
|
// If spectating, use values from target
|
|
CBaseEntity *pTarget = pLocalPlayer->GetObserverTarget();
|
|
if ( pTarget )
|
|
{
|
|
C_CSPlayer *pPlayerTmp = ToCSPlayer(pTarget);
|
|
if ( pPlayerTmp )
|
|
{
|
|
pFlashBangPlayer = pPlayerTmp;
|
|
}
|
|
}
|
|
|
|
// reduce the effect
|
|
if ( pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE && CanSeeSpectatorOnlyTools() )
|
|
{
|
|
// Reduce alpha.
|
|
// Note: the logic to reduce the duration of the effect is done when the effect is started (RecvProxy_FlashTime).
|
|
flAlphaScale = 0.6f;
|
|
}
|
|
else if ( pLocalPlayer->GetObserverMode() == OBS_MODE_FIXED || pLocalPlayer->GetObserverMode() == OBS_MODE_ROAMING )
|
|
{
|
|
// Reduce alpha.
|
|
// Note: the logic to reduce the duration of the effect is done when the effect is started (RecvProxy_FlashTime).
|
|
flAlphaScale = 0.2f;
|
|
}
|
|
else if ( pLocalPlayer->GetObserverMode() != OBS_MODE_IN_EYE )
|
|
{
|
|
// Reduce alpha.
|
|
// Note: the logic to reduce the duration of the effect is done when the effect is started (RecvProxy_FlashTime).
|
|
flAlphaScale = 0.6f;
|
|
}
|
|
}
|
|
|
|
if ( !pFlashBangPlayer->IsFlashBangActive() || CSGameRules()->IsIntermission() )
|
|
{
|
|
if ( !pLocalPlayer->m_bFlashDspHasBeenCleared )
|
|
{
|
|
CLocalPlayerFilter filter;
|
|
enginesound->SetPlayerDSP( filter, 0, true );
|
|
pLocalPlayer->m_bFlashDspHasBeenCleared = true;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// bandaid to insure that flashbang dsp effect doesn't continue on indefinitely
|
|
if( pFlashBangPlayer->GetFlashTimeElapsed() > 1.6f && !pLocalPlayer->m_bFlashDspHasBeenCleared )
|
|
{
|
|
CLocalPlayerFilter filter;
|
|
enginesound->SetPlayerDSP( filter, 0, true );
|
|
pLocalPlayer->m_bFlashDspHasBeenCleared = true;
|
|
}
|
|
|
|
byte overlaycolor[4] = { 255, 255, 255, 255 };
|
|
|
|
// draw the screenshot overlay portion of the flashbang effect
|
|
IMaterial *pMaterial = materials->FindMaterial( "effects/flashbang", TEXTURE_GROUP_CLIENT_EFFECTS, true );
|
|
if ( pMaterial )
|
|
{
|
|
// This is for handling split screen where we could potentially enter this function more than once a frame.
|
|
// Since this bit of code grabs both the left and right viewports of the buffer, it only needs to be done once per frame per flash.
|
|
static float lastTimeGrabbed = 0.0f;
|
|
if ( gpGlobals->curtime == lastTimeGrabbed )
|
|
{
|
|
pLocalPlayer->m_bFlashScreenshotHasBeenGrabbed = true;
|
|
pFlashBangPlayer->m_bFlashScreenshotHasBeenGrabbed = true;
|
|
}
|
|
|
|
if ( !pFlashBangPlayer->m_bFlashScreenshotHasBeenGrabbed )
|
|
{
|
|
CMatRenderContextPtr pRenderContext( materials );
|
|
int nScreenWidth, nScreenHeight;
|
|
pRenderContext->GetRenderTargetDimensions( nScreenWidth, nScreenHeight );
|
|
|
|
// update m_pFlashTexture
|
|
lastTimeGrabbed = gpGlobals->curtime;
|
|
bool foundVar;
|
|
|
|
IMaterialVar* m_BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false );
|
|
m_pFlashTexture = GetFullFrameFrameBufferTexture( 1 );
|
|
|
|
// When grabbing the texture for the super imposed frame, we grab the whole buffer, not just the viewport.
|
|
// We were having issues with trying to grab only the right side of the buffer for the second player in split screen.
|
|
Rect_t srcRect;
|
|
srcRect.x = 0;
|
|
srcRect.y = 0;
|
|
srcRect.width = nScreenWidth;
|
|
srcRect.height = nScreenHeight;
|
|
m_BaseTextureVar->SetTextureValue( m_pFlashTexture );
|
|
pRenderContext->CopyRenderTargetToTextureEx( m_pFlashTexture, 0, &srcRect, NULL );
|
|
pRenderContext->SetFrameBufferCopyTexture( m_pFlashTexture );
|
|
|
|
pFlashBangPlayer->m_bFlashScreenshotHasBeenGrabbed = true;
|
|
pLocalPlayer->m_bFlashScreenshotHasBeenGrabbed = true;
|
|
}
|
|
|
|
if ( !CanSeeSpectatorOnlyTools() )
|
|
{
|
|
overlaycolor[0] = overlaycolor[1] = overlaycolor[2] = pFlashBangPlayer->m_flFlashScreenshotAlpha * flAlphaScale;
|
|
if ( m_pFlashTexture != NULL )
|
|
{
|
|
static int NUM_AFTER_IMAGE_PASSES = 4;
|
|
for ( int pass = 0; pass < NUM_AFTER_IMAGE_PASSES; ++pass )
|
|
{
|
|
render->ViewDrawFade( overlaycolor, pMaterial, false );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// draw pure white overlay part of the flashbang effect.
|
|
pMaterial = materials->FindMaterial( "effects/flashbang_white", TEXTURE_GROUP_CLIENT_EFFECTS, true );
|
|
if ( pMaterial )
|
|
{
|
|
overlaycolor[0] = overlaycolor[1] = overlaycolor[2] = pFlashBangPlayer->m_flFlashOverlayAlpha * flAlphaScale;
|
|
render->ViewDrawFade( overlaycolor, pMaterial );
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef _DEBUG
|
|
//These are the outer ranges of the smoke overlay volume, at which there is 0% overlay.
|
|
ConVar cl_smoke_origin_height_cv( "cl_smoke_origin_height", "68", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_HIDDEN, "The center of the visible smoke torus is this many units above the origin of the grenade that's on the ground." );
|
|
ConVar cl_smoke_torus_ring_radius_cv( "cl_smoke_torus_ring_radius", "61", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_HIDDEN, "The radius of the overall ring of the entire visible smoke volume, measured from the exact local center of the visible cloud." );
|
|
ConVar cl_smoke_torus_ring_subradius_cv( "cl_smoke_torus_ring_subradius", "88", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_HIDDEN, "The radius of the extruded circle that follows the main ring and forms the torus shape." );
|
|
ConVar cl_smoke_edge_feather_cv( "cl_smoke_edge_feather", "21", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_HIDDEN, "This many units towards the inner threshold and you will hit 100% overlay opacity." );
|
|
ConVar cl_smoke_lower_speed_cv( "cl_smoke_lower_speed", "4.5", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_HIDDEN, "How fast the smoke screen overlay clears." );
|
|
ConVar cl_show_smoke_overlay_thresholds( "cl_show_smoke_overlay_thresholds", "0", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_HIDDEN, "Show visualization of smoke overlay inner and outer thresholds." );
|
|
|
|
#define cl_smoke_origin_height cl_smoke_origin_height_cv.GetFloat()
|
|
#define cl_smoke_torus_ring_radius cl_smoke_torus_ring_radius_cv.GetFloat()
|
|
#define cl_smoke_torus_ring_subradius cl_smoke_torus_ring_subradius_cv.GetFloat()
|
|
#define cl_smoke_edge_feather cl_smoke_edge_feather_cv.GetFloat()
|
|
#define cl_smoke_lower_speed cl_smoke_lower_speed_cv.GetFloat()
|
|
#else
|
|
#define cl_smoke_origin_height 68.0f
|
|
#define cl_smoke_torus_ring_radius 61.0f
|
|
#define cl_smoke_torus_ring_subradius 88.0f
|
|
#define cl_smoke_edge_feather 21.0f
|
|
#define cl_smoke_lower_speed 4.5f
|
|
#endif
|
|
|
|
//If your eyes are less than this distance from the center of the visible smoke torus, we should check exact distance and may need to apply the screen overlay.
|
|
#define cl_smoke_must_be_at_least_this_close_to_have_any_effect (cl_smoke_torus_ring_radius + cl_smoke_torus_ring_subradius)
|
|
|
|
void DrawCappedTorus( Vector vecOrigin, float flRadiusA, float flRadiusB, Color colWireColor, float flDuration )
|
|
{
|
|
// Draw a debug wireframe 'capped' torus. It's a torus with the middle filled in, like a cheese-boule shape that's meant to match a smoke volume
|
|
|
|
Vector vecPointA, vecPointB, vecPointC;
|
|
vecPointA.Init();
|
|
vecPointB.Init();
|
|
vecPointC.Init();
|
|
|
|
int i = 0;
|
|
int j = 0;
|
|
bool bTri = true;
|
|
|
|
for ( int n=0; n<1643; n++ )
|
|
{
|
|
bTri ? i++ : j++;
|
|
bTri = !bTri;
|
|
|
|
float phi = i * 6.28318f / 41.0f;
|
|
float theta = j * 6.28318f / 20.0f;
|
|
|
|
Vector vecTorusNode;
|
|
vecTorusNode.Init( cos(phi) * ( flRadiusA + cos(theta) * flRadiusB ),
|
|
sin(phi) * ( flRadiusA + cos(theta) * flRadiusB ),
|
|
sin(theta) * flRadiusB );
|
|
|
|
vecTorusNode += vecOrigin;
|
|
|
|
vecPointC = vecPointB;
|
|
vecPointB = vecPointA;
|
|
vecPointA = vecTorusNode;
|
|
|
|
if ( cos(theta) < 0 )
|
|
{
|
|
vecPointA.x = vecOrigin.x;
|
|
vecPointA.y = vecOrigin.y;
|
|
vecPointA.z = ( vecPointA.z > vecOrigin.z ) ? ( vecOrigin.z + flRadiusB ) : ( vecOrigin.z - flRadiusB );
|
|
|
|
if ( vecPointA.x == vecPointB.x && vecPointA.y == vecPointB.y )
|
|
continue;
|
|
}
|
|
|
|
if ( n > 1 )
|
|
debugoverlay->AddLineOverlay( vecPointB, vecPointA, colWireColor.r(), colWireColor.g(), colWireColor.b(), false, flDuration );
|
|
|
|
//triangulate
|
|
//if ( n > 2 )
|
|
//{
|
|
// if ( !bTri )
|
|
// {
|
|
// debugoverlay->AddTriangleOverlay( vecPointA, vecPointB, vecPointC, 255, 255, 255, 10, false, flDuration );
|
|
// }
|
|
// else
|
|
// {
|
|
// debugoverlay->AddTriangleOverlay( vecPointC, vecPointB, vecPointA, 255, 255, 255, 10, false, flDuration );
|
|
// }
|
|
//}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Renders pre-viewmodel smoke screen
|
|
//-----------------------------------------------------------------------------
|
|
#include "c_cs_player.h" // for clientSmokeGrenadeRecord_t
|
|
extern CUtlVector<EHANDLE> g_SmokeGrenadeHandles;
|
|
void CCSViewRender::RenderSmokeOverlay( bool bPreViewModel )
|
|
{
|
|
if ( bPreViewModel )
|
|
{
|
|
// update the overlay
|
|
|
|
//Assume we have no smoke overlay
|
|
float flOptimalSmokeOverlayAlpha = 0;
|
|
|
|
if ( g_SmokeGrenadeHandles.Count() > 0 )
|
|
{
|
|
Vector vecPlayerEyePos = MainViewOrigin(GET_ACTIVE_SPLITSCREEN_SLOT());
|
|
|
|
Vector vecClosestVecToSmoke;
|
|
|
|
int iClosestSmokeIndex = -1;
|
|
float flTempSmokeDistance = cl_smoke_must_be_at_least_this_close_to_have_any_effect;
|
|
|
|
#ifdef _DEBUG
|
|
if ( cl_show_smoke_overlay_thresholds.GetBool() )
|
|
flTempSmokeDistance = 2000.0f;
|
|
#endif
|
|
|
|
// we need to find the closest smoke to prevent a latter grenade in the list lifting the opacity of a potentially closer one
|
|
for( int it=0; it < g_SmokeGrenadeHandles.Count(); it++ )
|
|
{
|
|
CBaseCSGrenadeProjectile *pGrenade = static_cast< CBaseCSGrenadeProjectile* >( g_SmokeGrenadeHandles[it].Get() );
|
|
if ( !pGrenade )
|
|
continue;
|
|
|
|
Vector toGrenade = ( pGrenade->GetAbsOrigin() + Vector( 0, 0, cl_smoke_origin_height) ) - vecPlayerEyePos;
|
|
if ( toGrenade.Length() < flTempSmokeDistance )
|
|
{
|
|
//save the new closest smoke
|
|
flTempSmokeDistance = toGrenade.Length();
|
|
iClosestSmokeIndex = it;
|
|
|
|
//remember its vector
|
|
vecClosestVecToSmoke = toGrenade;
|
|
}
|
|
}
|
|
|
|
//only continue if we actually found a close-enough smoke
|
|
if ( iClosestSmokeIndex != -1 )
|
|
{
|
|
Vector vecSmokePos = Vector( 0, 0, 0 );
|
|
CBaseCSGrenadeProjectile *pGrenade = static_cast< CBaseCSGrenadeProjectile* >( g_SmokeGrenadeHandles[iClosestSmokeIndex].Get() );
|
|
if ( pGrenade )
|
|
vecSmokePos = pGrenade->GetAbsOrigin();
|
|
|
|
//draw debug visualization
|
|
#ifdef _DEBUG
|
|
if ( cl_show_smoke_overlay_thresholds.GetBool() )
|
|
{
|
|
Vector vecSmokeVisualOrigin = vecSmokePos + Vector( 0, 0, cl_smoke_origin_height );
|
|
|
|
//draw inner threshold
|
|
DrawCappedTorus( vecSmokeVisualOrigin, cl_smoke_torus_ring_radius, cl_smoke_torus_ring_subradius - cl_smoke_edge_feather, Color( 200, 0, 0 ), gpGlobals->frametime );
|
|
|
|
//draw outer threshold
|
|
DrawCappedTorus( vecSmokeVisualOrigin, cl_smoke_torus_ring_radius, cl_smoke_torus_ring_subradius, Color( 100, 0, 0 ), gpGlobals->frametime );
|
|
}
|
|
#endif
|
|
|
|
//linear interpolation between two capped torusoids
|
|
|
|
//are we within the Z axis bounds?
|
|
if ( abs( vecClosestVecToSmoke.z ) < cl_smoke_torus_ring_subradius )
|
|
{
|
|
|
|
float flvecClosestVecToSmokeLength2D = vecClosestVecToSmoke.Length2D();
|
|
|
|
//are we within the cylindrical cap-space on the XY axis?
|
|
if ( flvecClosestVecToSmokeLength2D < cl_smoke_torus_ring_radius )
|
|
{
|
|
//if so we can just use z delta
|
|
flOptimalSmokeOverlayAlpha = ( cl_smoke_torus_ring_subradius - abs( vecClosestVecToSmoke.z ) ) / cl_smoke_edge_feather;
|
|
|
|
#ifdef _DEBUG
|
|
if ( cl_show_smoke_overlay_thresholds.GetBool() )
|
|
{
|
|
//draw the closest point on the inner torusoid threshold
|
|
Vector vecSmokeVisualOrigin = vecSmokePos + Vector( 0, 0, cl_smoke_origin_height );
|
|
Vector vecClosestPoint = Vector( -vecClosestVecToSmoke.x, -vecClosestVecToSmoke.y, vecClosestVecToSmoke.z < 0 ? cl_smoke_torus_ring_subradius - cl_smoke_edge_feather : -cl_smoke_torus_ring_subradius + cl_smoke_edge_feather );
|
|
|
|
debugoverlay->AddBoxOverlay( vecClosestPoint + vecSmokeVisualOrigin, Vector( -1, -1, -1 ), Vector( 1, 1, 1 ), QAngle( 0, 0, 0 ), 0, 200, 0, 255, gpGlobals->frametime );
|
|
|
|
//line to eyes
|
|
//debugoverlay->AddLineOverlay( vecPlayerEyePos, vecClosestPoint + vecSmokeVisualOrigin, 0,200,0, false, gpGlobals->frametime );
|
|
}
|
|
#endif
|
|
|
|
}
|
|
else if ( flvecClosestVecToSmokeLength2D < cl_smoke_torus_ring_radius + cl_smoke_torus_ring_subradius )
|
|
{
|
|
//are we within the outer possible horizontal range of the torusoid? if so we need the distance to the nearest point on the primary radius
|
|
Vector vecRingPosOnSmokePlane = Vector( vecClosestVecToSmoke.x, vecClosestVecToSmoke.y, 0 ).Normalized() * cl_smoke_torus_ring_radius;
|
|
|
|
#ifdef _DEBUG
|
|
if ( cl_show_smoke_overlay_thresholds.GetBool() )
|
|
{
|
|
//draw the closest point on the inner torusoid threshold
|
|
Vector vecRingPosToInnerSurface = ( vecClosestVecToSmoke - vecRingPosOnSmokePlane ).Normalized() * ( cl_smoke_torus_ring_subradius - cl_smoke_edge_feather );
|
|
|
|
Vector vecSmokeVisualOrigin = vecSmokePos + Vector( 0, 0, cl_smoke_origin_height );
|
|
debugoverlay->AddBoxOverlay( vecSmokeVisualOrigin - vecRingPosOnSmokePlane - vecRingPosToInnerSurface, Vector( -1, -1, -1 ), Vector( 1, 1, 1 ), QAngle( 0, 0, 0 ), 0, 200, 0, 255, gpGlobals->frametime );
|
|
|
|
//line to eyes
|
|
//debugoverlay->AddLineOverlay( vecPlayerEyePos, vecSmokeVisualOrigin - vecRingPosOnSmokePlane - vecRingPosToInnerSurface, 0,200,0, false, gpGlobals->frametime );
|
|
}
|
|
#endif
|
|
//and check the distance value
|
|
float flDistanceToClosestRingPoint = ( vecClosestVecToSmoke - vecRingPosOnSmokePlane ).Length();
|
|
if ( flDistanceToClosestRingPoint < cl_smoke_torus_ring_subradius )
|
|
{
|
|
flOptimalSmokeOverlayAlpha = ( cl_smoke_torus_ring_subradius - flDistanceToClosestRingPoint ) / cl_smoke_edge_feather;
|
|
}
|
|
}
|
|
|
|
//clamp to 0-1 range
|
|
flOptimalSmokeOverlayAlpha = clamp( flOptimalSmokeOverlayAlpha, 0.0f, 1.0f );
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
if ( cl_show_smoke_overlay_thresholds.GetBool() )
|
|
{
|
|
debugoverlay->AddTextOverlay(vecPlayerEyePos, gpGlobals->frametime, "Overlay: %f", flOptimalSmokeOverlayAlpha );
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
//alpha can instantly increase, but decreases to the ideal at a constant rate.
|
|
if ( flOptimalSmokeOverlayAlpha < m_flSmokeOverlayAmount )
|
|
{
|
|
flOptimalSmokeOverlayAlpha = Approach( flOptimalSmokeOverlayAlpha, m_flSmokeOverlayAmount, gpGlobals->frametime * cl_smoke_lower_speed );
|
|
}
|
|
m_flSmokeOverlayAmount = flOptimalSmokeOverlayAlpha;
|
|
|
|
}
|
|
|
|
if ( m_flSmokeOverlayAmount <= 0 )
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
IMaterial *pMaterial = materials->FindMaterial( "effects/overlaysmoke", TEXTURE_GROUP_CLIENT_EFFECTS, true );
|
|
if ( pMaterial )
|
|
{
|
|
byte overlaycolor[4] = { 90, 90, 90, (byte)( m_flSmokeOverlayAmount * ( bPreViewModel ? 255 : 128 ) ) };
|
|
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 );
|
|
|
|
float flFade = g_HltvReplaySystem.GetReplayVideoFadeAmount();
|
|
|
|
// replay camera post-process
|
|
if ( g_HltvReplaySystem.WantsReplayEffect() )
|
|
{
|
|
// demo playback uses full-screen quad to fade in/out. Hltv replay uses the pixel shader here.
|
|
CMatRenderContextPtr pRenderContext( materials );
|
|
int x, y, w, h;
|
|
pRenderContext->GetViewport( x, y, w, h );
|
|
|
|
if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 95 ) // bail if ps30 is unsupported
|
|
return;
|
|
|
|
UpdateScreenEffectTexture( 0, view.x, view.y, view.width, view.height, false );
|
|
|
|
// overlay
|
|
IMaterial *pMatReplay = materials->FindMaterial( "dev/replay", TEXTURE_GROUP_OTHER, true );
|
|
if ( pMatReplay )
|
|
{
|
|
IMaterialVar* pVar = pMatReplay->FindVar( "$c0_x", NULL );
|
|
pVar->SetFloatValue( 1.0f / w );
|
|
|
|
pVar = pMatReplay->FindVar( "$c0_y", NULL );
|
|
pVar->SetFloatValue( 1.0f / h );
|
|
|
|
pVar = pMatReplay->FindVar( "$c0_z", NULL );
|
|
pVar->SetFloatValue( gpGlobals->realtime );
|
|
|
|
pVar = pMatReplay->FindVar( "$c0_w", NULL );
|
|
pVar->SetFloatValue( flFade );
|
|
//if( flFade > 0 && g_HltvReplaySystem.GetHltvReplayDelay() ) Msg( "%.2f dev/replay fade %.2f\n", Plat_FloatTime(), flFade ); // replayfade
|
|
|
|
pRenderContext->DrawScreenSpaceRectangle( pMatReplay, x, y, w, h, 0, 0, w-1, h-1, w, h );
|
|
}
|
|
}
|
|
else if ( flFade > 0 )
|
|
{
|
|
//Msg( "%.2f simple fade %.2f\n", Plat_FloatTime(), flFade ); // replayfade
|
|
float flFadeAdj = flFade;// sinf( flFade * ( M_PI * .5f ) );
|
|
CMatRenderContextPtr pRenderContext( materials );
|
|
int x, y, w, h;
|
|
pRenderContext->GetViewport( x, y, w, h );
|
|
|
|
//bars
|
|
if ( IMaterial *pMatFade = materials->FindMaterial( "dev/replay_bars", TEXTURE_GROUP_OTHER, true ) )
|
|
{
|
|
if ( IMaterialVar* pVar = pMatFade->FindVar( "$alpha", NULL ) )
|
|
{
|
|
pVar->SetFloatValue( flFadeAdj );
|
|
pRenderContext->DrawScreenSpaceRectangle( pMatFade, 0, 0, w, h, 0, 0, 0, 0, 1, 1 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Renders voice feedback and other sprites attached to players
|
|
// Input : none
|
|
//-----------------------------------------------------------------------------
|
|
void CCSViewRender::RenderPlayerSprites()
|
|
{
|
|
CViewRender::RenderPlayerSprites();
|
|
RadioManager()->DrawHeadLabels();
|
|
}
|
|
|