From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/client/glow_overlay.cpp | 1158 +++++++++++++++++------------------ 1 file changed, 579 insertions(+), 579 deletions(-) (limited to 'mp/src/game/client/glow_overlay.cpp') diff --git a/mp/src/game/client/glow_overlay.cpp b/mp/src/game/client/glow_overlay.cpp index 5df81de1..72915e3c 100644 --- a/mp/src/game/client/glow_overlay.cpp +++ b/mp/src/game/client/glow_overlay.cpp @@ -1,579 +1,579 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// -#include "cbase.h" -#include "view.h" -#include "iviewrender.h" -#include "c_sun.h" -#include "particles_simple.h" -#include "clienteffectprecachesystem.h" -#include "c_pixel_visibility.h" -#include "glow_overlay.h" -#include "utllinkedlist.h" -#include "view_shared.h" -#include "tier0/vprof.h" -#include "materialsystem/imaterialvar.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectGlow ) -CLIENTEFFECT_MATERIAL( "sun/overlay" ) -CLIENTEFFECT_MATERIAL( "sprites/light_glow02_add_noz" ) -CLIENTEFFECT_REGISTER_END() - -class CGlowOverlaySystem : public CAutoGameSystem -{ -public: - CGlowOverlaySystem() : CAutoGameSystem( "CGlowOverlaySystem" ) - { - } - // Level init, shutdown - virtual void LevelInitPreEntity() {} - - virtual void LevelShutdownPostEntity() - { - m_GlowOverlays.PurgeAndDeleteElements(); - } - - unsigned short AddToOverlayList( CGlowOverlay *pGlow ) - { - return m_GlowOverlays.AddToTail( pGlow ); - } - void RemoveFromOverlayList( unsigned short handle ) - { - if( handle != m_GlowOverlays.InvalidIndex() ) - { - m_GlowOverlays.Remove( handle ); - } - } - CUtlLinkedList m_GlowOverlays; -}; -CGlowOverlaySystem g_GlowOverlaySystem; - -ConVar cl_ShowSunVectors( "cl_ShowSunVectors", "0", 0 ); - -ConVar cl_sun_decay_rate( "cl_sun_decay_rate", "0.05", FCVAR_CHEAT ); - -// Dot product space the overlays are drawn in. -// Here it's setup to allow you to see it if you're looking within 40 degrees of the source. -float g_flOverlayRange = cos( DEG2RAD( 40 ) ); - -// ----------------------------------------------------------------------------- // -// ----------------------------------------------------------------------------- // - -void Do2DRotation( Vector vIn, Vector &vOut, float flDegrees, int i1, int i2, int i3 ) -{ - float c, s; - SinCos( DEG2RAD( flDegrees ), &s, &c ); - - vOut[i1] = vIn[i1]*c - vIn[i2]*s; - vOut[i2] = vIn[i1]*s + vIn[i2]*c; - vOut[i3] = vIn[i3]; -} - - -// ----------------------------------------------------------------------------- // -// ----------------------------------------------------------------------------- // - -CGlowOverlay::CGlowOverlay() -{ - m_ListIndex = 0xFFFF; - m_nSprites = 0; - m_flGlowObstructionScale = 0.0f; - m_bDirectional = false; - m_bInSky = false; - m_skyObstructionScale = 1.0f; - m_bActivated = false; - - m_flProxyRadius = 2.0f; - - m_queryHandle = 0; - - m_flHDRColorScale = 1.0f; - - //Init our sprites - for ( int i = 0; i < MAX_SUN_LAYERS; i++ ) - { - m_Sprites[i].m_vColor.Init(); - m_Sprites[i].m_flHorzSize = 1.0f; - m_Sprites[i].m_flVertSize = 1.0f; - m_Sprites[i].m_pMaterial = NULL; - } - -#ifdef PORTAL - for( int i = 0; i != MAX_PORTAL_RECURSIVE_VIEWS; ++i ) - { - m_skyObstructionScaleBackups[i] = 1.0f; - } -#endif -} - - -CGlowOverlay::~CGlowOverlay() -{ - g_GlowOverlaySystem.RemoveFromOverlayList( m_ListIndex ); -} - - -bool CGlowOverlay::Update() -{ - return true; -} - -ConVar building_cubemaps( "building_cubemaps", "0" ); - -float CGlowOverlay::CalcGlowAspect() -{ - if ( m_nSprites ) - { - if ( m_Sprites[0].m_flHorzSize != 0 && m_Sprites[0].m_flVertSize != 0 ) - return m_Sprites[0].m_flHorzSize / m_Sprites[0].m_flVertSize; - } - return 1.0f; -} - -void CGlowOverlay::UpdateSkyGlowObstruction( float zFar, bool bCacheFullSceneState ) -{ - Assert( m_bInSky ); - - // If we already cached the sky obstruction and are still using that, early-out - if ( bCacheFullSceneState && m_bCacheSkyObstruction ) - return; - - // Turning on sky obstruction caching mode - if ( bCacheFullSceneState && !m_bCacheSkyObstruction ) - { - m_bCacheSkyObstruction = true; - } - - // Turning off sky obstruction caching mode - if ( !bCacheFullSceneState && m_bCacheSkyObstruction ) - { - m_bCacheSkyObstruction = false; - } - - if ( PixelVisibility_IsAvailable() ) - { - // Trace a ray at the object. - Vector pos = CurrentViewOrigin() + m_vDirection * zFar * 0.999f; - - // UNDONE: Can probably do only the pixelvis query in this case if you can figure out where - // to put it - or save the position of this trace - pixelvis_queryparams_t params; - params.Init( pos, m_flProxyRadius ); - params.bSizeInScreenspace = true; - m_skyObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ); - return; - } - // Trace a ray at the object. - trace_t trace; - UTIL_TraceLine( CurrentViewOrigin(), CurrentViewOrigin() + (m_vDirection*MAX_TRACE_LENGTH), - CONTENTS_SOLID, NULL, COLLISION_GROUP_NONE, &trace ); - - // back the trace with a pixel query to occlude with models - if ( trace.surface.flags & SURF_SKY ) - { - m_skyObstructionScale = 1.0f; - } - else - { - m_skyObstructionScale = 0.0f; - } -} - - -void CGlowOverlay::UpdateGlowObstruction( const Vector &vToGlow, bool bCacheFullSceneState ) -{ - // If we already cached the glow obstruction and are still using that, early-out - if ( bCacheFullSceneState && m_bCacheGlowObstruction ) - return; - - if ( bCacheFullSceneState && !m_bCacheGlowObstruction ) // If turning on sky obstruction caching mode - { - m_bCacheGlowObstruction = true; - } - - if ( !bCacheFullSceneState && m_bCacheGlowObstruction ) - { - m_bCacheGlowObstruction = false; - } - - if ( PixelVisibility_IsAvailable() ) - { - if ( m_bInSky ) - { - const CViewSetup *pViewSetup = view->GetViewSetup(); - Vector pos = CurrentViewOrigin() + m_vDirection * (pViewSetup->zFar * 0.999f); - pixelvis_queryparams_t params; - params.Init( pos, m_flProxyRadius, CalcGlowAspect() ); - params.bSizeInScreenspace = true; - // use a pixel query to occlude with models - m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ) * m_skyObstructionScale; - } - else - { - // If it's not in the sky, then we need a valid position or else we don't - // know what's in front of it. - Assert( !m_bDirectional ); - - pixelvis_queryparams_t params; - params.Init( m_vPos, m_flProxyRadius, CalcGlowAspect() ); - - m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ); - } - return; - } - - bool bFade = false; - if ( m_bInSky ) - { - // Trace a ray at the object. - trace_t trace; - UTIL_TraceLine( CurrentViewOrigin(), CurrentViewOrigin() + (vToGlow*MAX_TRACE_LENGTH), - CONTENTS_SOLID, NULL, COLLISION_GROUP_NONE, &trace ); - - bFade = (trace.fraction < 1 && !(trace.surface.flags & SURF_SKY)); - } - else - { - // If it's not in the sky, then we need a valid position or else we don't - // know what's in front of it. - Assert( !m_bDirectional ); - - pixelvis_queryparams_t params; - params.Init( m_vPos, m_flProxyRadius ); - - bFade = PixelVisibility_FractionVisible( params, &m_queryHandle ) < 1.0f ? true : false; - - } - - if ( bFade ) - { - if ( building_cubemaps.GetBool() ) - { - m_flGlowObstructionScale = 0.0f; - } - else - { - m_flGlowObstructionScale -= gpGlobals->frametime / cl_sun_decay_rate.GetFloat(); - m_flGlowObstructionScale = MAX( m_flGlowObstructionScale, 0.0f ); - } - } - else - { - if ( building_cubemaps.GetBool() ) - { - m_flGlowObstructionScale = 1.0f; - } - else - { - m_flGlowObstructionScale += gpGlobals->frametime / cl_sun_decay_rate.GetFloat(); - m_flGlowObstructionScale = MIN( m_flGlowObstructionScale, 1.0f ); - } - } -} - -void CGlowOverlay::CalcSpriteColorAndSize( - float flDot, - CGlowSprite *pSprite, - float *flHorzSize, - float *flVertSize, - Vector *vColor ) -{ - // The overlay is largest and completely translucent at g_flOverlayRange. - // When the dot product is 1, then it's smaller and more opaque. - const float flSizeAtOverlayRangeMul = 150; - const float flSizeAtOneMul = 70; - - const float flOpacityAtOverlayRange = 0; - const float flOpacityAtOne = 1; - - // Figure out how big and how opaque it will be. - *flHorzSize = RemapValClamped( - flDot, - g_flOverlayRange, - 1, - flSizeAtOverlayRangeMul * pSprite->m_flHorzSize, - flSizeAtOneMul * pSprite->m_flHorzSize ); - - *flVertSize = RemapValClamped( - flDot, - g_flOverlayRange, - 1, - flSizeAtOverlayRangeMul * pSprite->m_flVertSize, - flSizeAtOneMul * pSprite->m_flVertSize ); - - float flOpacity = RemapValClamped( - flDot, - g_flOverlayRange, - 1, - flOpacityAtOverlayRange, - flOpacityAtOne ); - - flOpacity = flOpacity * m_flGlowObstructionScale; - *vColor = pSprite->m_vColor * flOpacity; -} - - -void CGlowOverlay::CalcBasis( - const Vector &vToGlow, - float flHorzSize, - float flVertSize, - Vector &vBasePt, - Vector &vUp, - Vector &vRight ) -{ - const float flOverlayDist = 100; - vBasePt = CurrentViewOrigin() + vToGlow * flOverlayDist; - - vUp.Init( 0, 0, 1 ); - - vRight = vToGlow.Cross( vUp ); - VectorNormalize( vRight ); - - vUp = vRight.Cross( vToGlow ); - VectorNormalize( vUp ); - - vRight *= flHorzSize; - vUp *= flVertSize; -} - - -void CGlowOverlay::Draw( bool bCacheFullSceneState ) -{ - extern ConVar r_drawsprites; - if( !r_drawsprites.GetBool() ) - return; - - // Get the vector to the sun. - Vector vToGlow; - - if( m_bDirectional ) - vToGlow = m_vDirection; - else - vToGlow = m_vPos - CurrentViewOrigin(); - - VectorNormalize( vToGlow ); - - float flDot = vToGlow.Dot( CurrentViewForward() ); - - UpdateGlowObstruction( vToGlow, bCacheFullSceneState ); - if( m_flGlowObstructionScale == 0 ) - return; - - bool bWireframe = ShouldDrawInWireFrameMode() || (r_drawsprites.GetInt() == 2); - - CMatRenderContextPtr pRenderContext( materials ); - - for( int iSprite=0; iSprite < m_nSprites; iSprite++ ) - { - CGlowSprite *pSprite = &m_Sprites[iSprite]; - - // Figure out the color and size to draw it. - float flHorzSize, flVertSize; - Vector vColor; - CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor ); - - // If we're alpha'd out, then don't bother - if ( vColor.LengthSqr() < 0.00001f ) - continue; - - // Setup the basis to draw the sprite. - Vector vBasePt, vUp, vRight; - CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight ); - - //Get our diagonal radius - float radius = (vRight+vUp).Length(); - if ( R_CullSphere( view->GetFrustum(), 5, &vBasePt, radius ) ) - continue; - - // Get our material (deferred default load) - if ( m_Sprites[iSprite].m_pMaterial == NULL ) - { - m_Sprites[iSprite].m_pMaterial = materials->FindMaterial( "sprites/light_glow02_add_noz", TEXTURE_GROUP_CLIENT_EFFECTS ); - } - - Assert( m_Sprites[iSprite].m_pMaterial ); - static unsigned int nHDRColorScaleCache = 0; - IMaterialVar *pHDRColorScaleVar = m_Sprites[iSprite].m_pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache ); - if( pHDRColorScaleVar ) - { - pHDRColorScaleVar->SetFloatValue( m_flHDRColorScale ); - } - - // Draw the sprite. - IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, m_Sprites[iSprite].m_pMaterial ); - - CMeshBuilder builder; - builder.Begin( pMesh, MATERIAL_QUADS, 1 ); - - Vector vPt; - - vPt = vBasePt - vRight + vUp; - builder.Position3fv( vPt.Base() ); - builder.Color4f( VectorExpand(vColor), 1 ); - builder.TexCoord2f( 0, 0, 1 ); - builder.AdvanceVertex(); - - vPt = vBasePt + vRight + vUp; - builder.Position3fv( vPt.Base() ); - builder.Color4f( VectorExpand(vColor), 1 ); - builder.TexCoord2f( 0, 1, 1 ); - builder.AdvanceVertex(); - - vPt = vBasePt + vRight - vUp; - builder.Position3fv( vPt.Base() ); - builder.Color4f( VectorExpand(vColor), 1 ); - builder.TexCoord2f( 0, 1, 0 ); - builder.AdvanceVertex(); - - vPt = vBasePt - vRight - vUp; - builder.Position3fv( vPt.Base() ); - builder.Color4f( VectorExpand(vColor), 1 ); - builder.TexCoord2f( 0, 0, 0 ); - builder.AdvanceVertex(); - - builder.End( false, true ); - - if( bWireframe ) - { - IMaterial *pWireframeMaterial = materials->FindMaterial( "debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER ); - pRenderContext->Bind( pWireframeMaterial ); - - // Draw the sprite. - IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pWireframeMaterial ); - - CMeshBuilder builder; - builder.Begin( pMesh, MATERIAL_QUADS, 1 ); - - Vector vPt; - - vPt = vBasePt - vRight + vUp; - builder.Position3fv( vPt.Base() ); - builder.Color3f( 1.0f, 0.0f, 0.0f ); - builder.AdvanceVertex(); - - vPt = vBasePt + vRight + vUp; - builder.Position3fv( vPt.Base() ); - builder.Color3f( 1.0f, 0.0f, 0.0f ); - builder.AdvanceVertex(); - - vPt = vBasePt + vRight - vUp; - builder.Position3fv( vPt.Base() ); - builder.Color3f( 1.0f, 0.0f, 0.0f ); - builder.AdvanceVertex(); - - vPt = vBasePt - vRight - vUp; - builder.Position3fv( vPt.Base() ); - builder.Color3f( 1.0f, 0.0f, 0.0f ); - builder.AdvanceVertex(); - - builder.End( false, true ); - } - } -} - - -void CGlowOverlay::Activate() -{ - m_bActivated = true; - if( m_ListIndex == 0xFFFF ) - { - m_ListIndex = g_GlowOverlaySystem.AddToOverlayList( this ); - } -} - - -void CGlowOverlay::Deactivate() -{ - m_bActivated = false; -} - - -void CGlowOverlay::DrawOverlays( bool bCacheFullSceneState ) -{ - VPROF("CGlowOverlay::DrawOverlays()"); - - CMatRenderContextPtr pRenderContext( materials ); - - bool bClippingEnabled = pRenderContext->EnableClipping( true ); - - unsigned short iNext; - for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) - { - iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); - CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; - - if( !pOverlay->m_bActivated ) - continue; - - if( pOverlay->Update() ) - { - pRenderContext->EnableClipping( ((pOverlay->m_bInSky) ? (false):(bClippingEnabled)) ); //disable clipping in skybox, restore clipping to pre-existing state when not in skybox (it may be off as well) - pOverlay->Draw( bCacheFullSceneState ); - } - else - { - delete pOverlay; - } - } - - pRenderContext->EnableClipping( bClippingEnabled ); //restore clipping to original state -} - -void CGlowOverlay::UpdateSkyOverlays( float zFar, bool bCacheFullSceneState ) -{ - unsigned short iNext; - for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) - { - iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); - CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; - - if( !pOverlay->m_bActivated || !pOverlay->m_bDirectional || !pOverlay->m_bInSky ) - continue; - - pOverlay->UpdateSkyGlowObstruction( zFar, bCacheFullSceneState ); - } -} - - - - -#ifdef PORTAL - -void CGlowOverlay::BackupSkyOverlayData( int iBackupToSlot ) -{ - unsigned short iNext; - for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) - { - iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); - CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; - - if( !pOverlay->m_bActivated || !pOverlay->m_bDirectional || !pOverlay->m_bInSky ) - continue; - - pOverlay->m_skyObstructionScaleBackups[iBackupToSlot] = pOverlay->m_skyObstructionScale; - } -} - -void CGlowOverlay::RestoreSkyOverlayData( int iRestoreFromSlot ) -{ - unsigned short iNext; - for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) - { - iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); - CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; - - if( !pOverlay->m_bActivated || !pOverlay->m_bDirectional || !pOverlay->m_bInSky ) - continue; - - pOverlay->m_skyObstructionScale = pOverlay->m_skyObstructionScaleBackups[iRestoreFromSlot]; - } -} - -#endif //#ifdef PORTAL - +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "view.h" +#include "iviewrender.h" +#include "c_sun.h" +#include "particles_simple.h" +#include "clienteffectprecachesystem.h" +#include "c_pixel_visibility.h" +#include "glow_overlay.h" +#include "utllinkedlist.h" +#include "view_shared.h" +#include "tier0/vprof.h" +#include "materialsystem/imaterialvar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectGlow ) +CLIENTEFFECT_MATERIAL( "sun/overlay" ) +CLIENTEFFECT_MATERIAL( "sprites/light_glow02_add_noz" ) +CLIENTEFFECT_REGISTER_END() + +class CGlowOverlaySystem : public CAutoGameSystem +{ +public: + CGlowOverlaySystem() : CAutoGameSystem( "CGlowOverlaySystem" ) + { + } + // Level init, shutdown + virtual void LevelInitPreEntity() {} + + virtual void LevelShutdownPostEntity() + { + m_GlowOverlays.PurgeAndDeleteElements(); + } + + unsigned short AddToOverlayList( CGlowOverlay *pGlow ) + { + return m_GlowOverlays.AddToTail( pGlow ); + } + void RemoveFromOverlayList( unsigned short handle ) + { + if( handle != m_GlowOverlays.InvalidIndex() ) + { + m_GlowOverlays.Remove( handle ); + } + } + CUtlLinkedList m_GlowOverlays; +}; +CGlowOverlaySystem g_GlowOverlaySystem; + +ConVar cl_ShowSunVectors( "cl_ShowSunVectors", "0", 0 ); + +ConVar cl_sun_decay_rate( "cl_sun_decay_rate", "0.05", FCVAR_CHEAT ); + +// Dot product space the overlays are drawn in. +// Here it's setup to allow you to see it if you're looking within 40 degrees of the source. +float g_flOverlayRange = cos( DEG2RAD( 40 ) ); + +// ----------------------------------------------------------------------------- // +// ----------------------------------------------------------------------------- // + +void Do2DRotation( Vector vIn, Vector &vOut, float flDegrees, int i1, int i2, int i3 ) +{ + float c, s; + SinCos( DEG2RAD( flDegrees ), &s, &c ); + + vOut[i1] = vIn[i1]*c - vIn[i2]*s; + vOut[i2] = vIn[i1]*s + vIn[i2]*c; + vOut[i3] = vIn[i3]; +} + + +// ----------------------------------------------------------------------------- // +// ----------------------------------------------------------------------------- // + +CGlowOverlay::CGlowOverlay() +{ + m_ListIndex = 0xFFFF; + m_nSprites = 0; + m_flGlowObstructionScale = 0.0f; + m_bDirectional = false; + m_bInSky = false; + m_skyObstructionScale = 1.0f; + m_bActivated = false; + + m_flProxyRadius = 2.0f; + + m_queryHandle = 0; + + m_flHDRColorScale = 1.0f; + + //Init our sprites + for ( int i = 0; i < MAX_SUN_LAYERS; i++ ) + { + m_Sprites[i].m_vColor.Init(); + m_Sprites[i].m_flHorzSize = 1.0f; + m_Sprites[i].m_flVertSize = 1.0f; + m_Sprites[i].m_pMaterial = NULL; + } + +#ifdef PORTAL + for( int i = 0; i != MAX_PORTAL_RECURSIVE_VIEWS; ++i ) + { + m_skyObstructionScaleBackups[i] = 1.0f; + } +#endif +} + + +CGlowOverlay::~CGlowOverlay() +{ + g_GlowOverlaySystem.RemoveFromOverlayList( m_ListIndex ); +} + + +bool CGlowOverlay::Update() +{ + return true; +} + +ConVar building_cubemaps( "building_cubemaps", "0" ); + +float CGlowOverlay::CalcGlowAspect() +{ + if ( m_nSprites ) + { + if ( m_Sprites[0].m_flHorzSize != 0 && m_Sprites[0].m_flVertSize != 0 ) + return m_Sprites[0].m_flHorzSize / m_Sprites[0].m_flVertSize; + } + return 1.0f; +} + +void CGlowOverlay::UpdateSkyGlowObstruction( float zFar, bool bCacheFullSceneState ) +{ + Assert( m_bInSky ); + + // If we already cached the sky obstruction and are still using that, early-out + if ( bCacheFullSceneState && m_bCacheSkyObstruction ) + return; + + // Turning on sky obstruction caching mode + if ( bCacheFullSceneState && !m_bCacheSkyObstruction ) + { + m_bCacheSkyObstruction = true; + } + + // Turning off sky obstruction caching mode + if ( !bCacheFullSceneState && m_bCacheSkyObstruction ) + { + m_bCacheSkyObstruction = false; + } + + if ( PixelVisibility_IsAvailable() ) + { + // Trace a ray at the object. + Vector pos = CurrentViewOrigin() + m_vDirection * zFar * 0.999f; + + // UNDONE: Can probably do only the pixelvis query in this case if you can figure out where + // to put it - or save the position of this trace + pixelvis_queryparams_t params; + params.Init( pos, m_flProxyRadius ); + params.bSizeInScreenspace = true; + m_skyObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ); + return; + } + // Trace a ray at the object. + trace_t trace; + UTIL_TraceLine( CurrentViewOrigin(), CurrentViewOrigin() + (m_vDirection*MAX_TRACE_LENGTH), + CONTENTS_SOLID, NULL, COLLISION_GROUP_NONE, &trace ); + + // back the trace with a pixel query to occlude with models + if ( trace.surface.flags & SURF_SKY ) + { + m_skyObstructionScale = 1.0f; + } + else + { + m_skyObstructionScale = 0.0f; + } +} + + +void CGlowOverlay::UpdateGlowObstruction( const Vector &vToGlow, bool bCacheFullSceneState ) +{ + // If we already cached the glow obstruction and are still using that, early-out + if ( bCacheFullSceneState && m_bCacheGlowObstruction ) + return; + + if ( bCacheFullSceneState && !m_bCacheGlowObstruction ) // If turning on sky obstruction caching mode + { + m_bCacheGlowObstruction = true; + } + + if ( !bCacheFullSceneState && m_bCacheGlowObstruction ) + { + m_bCacheGlowObstruction = false; + } + + if ( PixelVisibility_IsAvailable() ) + { + if ( m_bInSky ) + { + const CViewSetup *pViewSetup = view->GetViewSetup(); + Vector pos = CurrentViewOrigin() + m_vDirection * (pViewSetup->zFar * 0.999f); + pixelvis_queryparams_t params; + params.Init( pos, m_flProxyRadius, CalcGlowAspect() ); + params.bSizeInScreenspace = true; + // use a pixel query to occlude with models + m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ) * m_skyObstructionScale; + } + else + { + // If it's not in the sky, then we need a valid position or else we don't + // know what's in front of it. + Assert( !m_bDirectional ); + + pixelvis_queryparams_t params; + params.Init( m_vPos, m_flProxyRadius, CalcGlowAspect() ); + + m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ); + } + return; + } + + bool bFade = false; + if ( m_bInSky ) + { + // Trace a ray at the object. + trace_t trace; + UTIL_TraceLine( CurrentViewOrigin(), CurrentViewOrigin() + (vToGlow*MAX_TRACE_LENGTH), + CONTENTS_SOLID, NULL, COLLISION_GROUP_NONE, &trace ); + + bFade = (trace.fraction < 1 && !(trace.surface.flags & SURF_SKY)); + } + else + { + // If it's not in the sky, then we need a valid position or else we don't + // know what's in front of it. + Assert( !m_bDirectional ); + + pixelvis_queryparams_t params; + params.Init( m_vPos, m_flProxyRadius ); + + bFade = PixelVisibility_FractionVisible( params, &m_queryHandle ) < 1.0f ? true : false; + + } + + if ( bFade ) + { + if ( building_cubemaps.GetBool() ) + { + m_flGlowObstructionScale = 0.0f; + } + else + { + m_flGlowObstructionScale -= gpGlobals->frametime / cl_sun_decay_rate.GetFloat(); + m_flGlowObstructionScale = MAX( m_flGlowObstructionScale, 0.0f ); + } + } + else + { + if ( building_cubemaps.GetBool() ) + { + m_flGlowObstructionScale = 1.0f; + } + else + { + m_flGlowObstructionScale += gpGlobals->frametime / cl_sun_decay_rate.GetFloat(); + m_flGlowObstructionScale = MIN( m_flGlowObstructionScale, 1.0f ); + } + } +} + +void CGlowOverlay::CalcSpriteColorAndSize( + float flDot, + CGlowSprite *pSprite, + float *flHorzSize, + float *flVertSize, + Vector *vColor ) +{ + // The overlay is largest and completely translucent at g_flOverlayRange. + // When the dot product is 1, then it's smaller and more opaque. + const float flSizeAtOverlayRangeMul = 150; + const float flSizeAtOneMul = 70; + + const float flOpacityAtOverlayRange = 0; + const float flOpacityAtOne = 1; + + // Figure out how big and how opaque it will be. + *flHorzSize = RemapValClamped( + flDot, + g_flOverlayRange, + 1, + flSizeAtOverlayRangeMul * pSprite->m_flHorzSize, + flSizeAtOneMul * pSprite->m_flHorzSize ); + + *flVertSize = RemapValClamped( + flDot, + g_flOverlayRange, + 1, + flSizeAtOverlayRangeMul * pSprite->m_flVertSize, + flSizeAtOneMul * pSprite->m_flVertSize ); + + float flOpacity = RemapValClamped( + flDot, + g_flOverlayRange, + 1, + flOpacityAtOverlayRange, + flOpacityAtOne ); + + flOpacity = flOpacity * m_flGlowObstructionScale; + *vColor = pSprite->m_vColor * flOpacity; +} + + +void CGlowOverlay::CalcBasis( + const Vector &vToGlow, + float flHorzSize, + float flVertSize, + Vector &vBasePt, + Vector &vUp, + Vector &vRight ) +{ + const float flOverlayDist = 100; + vBasePt = CurrentViewOrigin() + vToGlow * flOverlayDist; + + vUp.Init( 0, 0, 1 ); + + vRight = vToGlow.Cross( vUp ); + VectorNormalize( vRight ); + + vUp = vRight.Cross( vToGlow ); + VectorNormalize( vUp ); + + vRight *= flHorzSize; + vUp *= flVertSize; +} + + +void CGlowOverlay::Draw( bool bCacheFullSceneState ) +{ + extern ConVar r_drawsprites; + if( !r_drawsprites.GetBool() ) + return; + + // Get the vector to the sun. + Vector vToGlow; + + if( m_bDirectional ) + vToGlow = m_vDirection; + else + vToGlow = m_vPos - CurrentViewOrigin(); + + VectorNormalize( vToGlow ); + + float flDot = vToGlow.Dot( CurrentViewForward() ); + + UpdateGlowObstruction( vToGlow, bCacheFullSceneState ); + if( m_flGlowObstructionScale == 0 ) + return; + + bool bWireframe = ShouldDrawInWireFrameMode() || (r_drawsprites.GetInt() == 2); + + CMatRenderContextPtr pRenderContext( materials ); + + for( int iSprite=0; iSprite < m_nSprites; iSprite++ ) + { + CGlowSprite *pSprite = &m_Sprites[iSprite]; + + // Figure out the color and size to draw it. + float flHorzSize, flVertSize; + Vector vColor; + CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor ); + + // If we're alpha'd out, then don't bother + if ( vColor.LengthSqr() < 0.00001f ) + continue; + + // Setup the basis to draw the sprite. + Vector vBasePt, vUp, vRight; + CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight ); + + //Get our diagonal radius + float radius = (vRight+vUp).Length(); + if ( R_CullSphere( view->GetFrustum(), 5, &vBasePt, radius ) ) + continue; + + // Get our material (deferred default load) + if ( m_Sprites[iSprite].m_pMaterial == NULL ) + { + m_Sprites[iSprite].m_pMaterial = materials->FindMaterial( "sprites/light_glow02_add_noz", TEXTURE_GROUP_CLIENT_EFFECTS ); + } + + Assert( m_Sprites[iSprite].m_pMaterial ); + static unsigned int nHDRColorScaleCache = 0; + IMaterialVar *pHDRColorScaleVar = m_Sprites[iSprite].m_pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache ); + if( pHDRColorScaleVar ) + { + pHDRColorScaleVar->SetFloatValue( m_flHDRColorScale ); + } + + // Draw the sprite. + IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, m_Sprites[iSprite].m_pMaterial ); + + CMeshBuilder builder; + builder.Begin( pMesh, MATERIAL_QUADS, 1 ); + + Vector vPt; + + vPt = vBasePt - vRight + vUp; + builder.Position3fv( vPt.Base() ); + builder.Color4f( VectorExpand(vColor), 1 ); + builder.TexCoord2f( 0, 0, 1 ); + builder.AdvanceVertex(); + + vPt = vBasePt + vRight + vUp; + builder.Position3fv( vPt.Base() ); + builder.Color4f( VectorExpand(vColor), 1 ); + builder.TexCoord2f( 0, 1, 1 ); + builder.AdvanceVertex(); + + vPt = vBasePt + vRight - vUp; + builder.Position3fv( vPt.Base() ); + builder.Color4f( VectorExpand(vColor), 1 ); + builder.TexCoord2f( 0, 1, 0 ); + builder.AdvanceVertex(); + + vPt = vBasePt - vRight - vUp; + builder.Position3fv( vPt.Base() ); + builder.Color4f( VectorExpand(vColor), 1 ); + builder.TexCoord2f( 0, 0, 0 ); + builder.AdvanceVertex(); + + builder.End( false, true ); + + if( bWireframe ) + { + IMaterial *pWireframeMaterial = materials->FindMaterial( "debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER ); + pRenderContext->Bind( pWireframeMaterial ); + + // Draw the sprite. + IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pWireframeMaterial ); + + CMeshBuilder builder; + builder.Begin( pMesh, MATERIAL_QUADS, 1 ); + + Vector vPt; + + vPt = vBasePt - vRight + vUp; + builder.Position3fv( vPt.Base() ); + builder.Color3f( 1.0f, 0.0f, 0.0f ); + builder.AdvanceVertex(); + + vPt = vBasePt + vRight + vUp; + builder.Position3fv( vPt.Base() ); + builder.Color3f( 1.0f, 0.0f, 0.0f ); + builder.AdvanceVertex(); + + vPt = vBasePt + vRight - vUp; + builder.Position3fv( vPt.Base() ); + builder.Color3f( 1.0f, 0.0f, 0.0f ); + builder.AdvanceVertex(); + + vPt = vBasePt - vRight - vUp; + builder.Position3fv( vPt.Base() ); + builder.Color3f( 1.0f, 0.0f, 0.0f ); + builder.AdvanceVertex(); + + builder.End( false, true ); + } + } +} + + +void CGlowOverlay::Activate() +{ + m_bActivated = true; + if( m_ListIndex == 0xFFFF ) + { + m_ListIndex = g_GlowOverlaySystem.AddToOverlayList( this ); + } +} + + +void CGlowOverlay::Deactivate() +{ + m_bActivated = false; +} + + +void CGlowOverlay::DrawOverlays( bool bCacheFullSceneState ) +{ + VPROF("CGlowOverlay::DrawOverlays()"); + + CMatRenderContextPtr pRenderContext( materials ); + + bool bClippingEnabled = pRenderContext->EnableClipping( true ); + + unsigned short iNext; + for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) + { + iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); + CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; + + if( !pOverlay->m_bActivated ) + continue; + + if( pOverlay->Update() ) + { + pRenderContext->EnableClipping( ((pOverlay->m_bInSky) ? (false):(bClippingEnabled)) ); //disable clipping in skybox, restore clipping to pre-existing state when not in skybox (it may be off as well) + pOverlay->Draw( bCacheFullSceneState ); + } + else + { + delete pOverlay; + } + } + + pRenderContext->EnableClipping( bClippingEnabled ); //restore clipping to original state +} + +void CGlowOverlay::UpdateSkyOverlays( float zFar, bool bCacheFullSceneState ) +{ + unsigned short iNext; + for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) + { + iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); + CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; + + if( !pOverlay->m_bActivated || !pOverlay->m_bDirectional || !pOverlay->m_bInSky ) + continue; + + pOverlay->UpdateSkyGlowObstruction( zFar, bCacheFullSceneState ); + } +} + + + + +#ifdef PORTAL + +void CGlowOverlay::BackupSkyOverlayData( int iBackupToSlot ) +{ + unsigned short iNext; + for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) + { + iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); + CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; + + if( !pOverlay->m_bActivated || !pOverlay->m_bDirectional || !pOverlay->m_bInSky ) + continue; + + pOverlay->m_skyObstructionScaleBackups[iBackupToSlot] = pOverlay->m_skyObstructionScale; + } +} + +void CGlowOverlay::RestoreSkyOverlayData( int iRestoreFromSlot ) +{ + unsigned short iNext; + for( unsigned short i=g_GlowOverlaySystem.m_GlowOverlays.Head(); i != g_GlowOverlaySystem.m_GlowOverlays.InvalidIndex(); i = iNext ) + { + iNext = g_GlowOverlaySystem.m_GlowOverlays.Next( i ); + CGlowOverlay *pOverlay = g_GlowOverlaySystem.m_GlowOverlays[i]; + + if( !pOverlay->m_bActivated || !pOverlay->m_bDirectional || !pOverlay->m_bInSky ) + continue; + + pOverlay->m_skyObstructionScale = pOverlay->m_skyObstructionScaleBackups[iRestoreFromSlot]; + } +} + +#endif //#ifdef PORTAL + -- cgit v1.2.3