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.
325 lines
9.8 KiB
325 lines
9.8 KiB
//========= 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(); |
|
} |
|
|
|
|