aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/glow_overlay.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/client/glow_overlay.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/client/glow_overlay.cpp')
-rw-r--r--mp/src/game/client/glow_overlay.cpp1158
1 files changed, 579 insertions, 579 deletions
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<CGlowOverlay*, unsigned short> 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<CGlowOverlay*, unsigned short> 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
+