diff --git a/sp/src/game/client/c_env_screenoverlay.cpp b/sp/src/game/client/c_env_screenoverlay.cpp index a31258829d..e6d7e55321 100644 --- a/sp/src/game/client/c_env_screenoverlay.cpp +++ b/sp/src/game/client/c_env_screenoverlay.cpp @@ -219,6 +219,11 @@ enum SCREENEFFECT_EP2_ADVISOR_STUN, SCREENEFFECT_EP1_INTRO, SCREENEFFECT_EP2_GROGGY, + +#ifdef MAPBASE + SCREENEFFECT_MAPBASE_CHROMATIC_BLUR = 100, // Overlays 3 different frames of red, green, and blue tints respectively with different offsets + SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION, // Similar to above, except it stretches frames in addition to offsetting them +#endif }; // ============================================================================ @@ -303,6 +308,21 @@ void C_EnvScreenEffect::ReceiveMessage( int classID, bf_read &msg ) g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys ); g_pScreenSpaceEffects->EnableScreenSpaceEffect( "ep2_groggy" ); } +#ifdef MAPBASE + else if ( m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_BLUR || m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION ) + { + if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 ) + return; + + // Set our keys + pKeys->SetFloat( "duration", m_flDuration ); + pKeys->SetInt( "fadeout", 0 ); + pKeys->SetInt( "stretch", m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION ); + + g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "mapbase_chromatic_aberration", pKeys ); + g_pScreenSpaceEffects->EnableScreenSpaceEffect( "mapbase_chromatic_aberration" ); + } +#endif pKeys->deleteThis(); } @@ -349,6 +369,25 @@ void C_EnvScreenEffect::ReceiveMessage( int classID, bf_read &msg ) g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys ); } +#ifdef MAPBASE + else if ( m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_BLUR || m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION ) + { + if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 ) + return; + + // Create a keyvalue block to set these params + KeyValues *pKeys = new KeyValues( "keys" ); + if ( pKeys == NULL ) + return; + + // Set our keys + pKeys->SetFloat( "duration", m_flDuration ); + pKeys->SetInt( "fadeout", 1 ); + pKeys->SetInt( "stretch", m_nType == SCREENEFFECT_MAPBASE_CHROMATIC_ABERRATION ); + + g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "mapbase_chromatic_aberration", pKeys ); + } +#endif break; } diff --git a/sp/src/game/client/episodic/episodic_screenspaceeffects.cpp b/sp/src/game/client/episodic/episodic_screenspaceeffects.cpp index a2b59bbcfb..fd8cafb282 100644 --- a/sp/src/game/client/episodic/episodic_screenspaceeffects.cpp +++ b/sp/src/game/client/episodic/episodic_screenspaceeffects.cpp @@ -462,3 +462,225 @@ void CEP2StunEffect::Render( int x, int y, int w, int h ) pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->PopMatrix(); } + +// ================================================================================================================ +// +// Chromatic Aberration +// +// ================================================================================================================ + +#ifdef MAPBASE +ConVar r_chromatic_aberration_offset( "r_chromatic_aberration_offset", "8.0" ); +ConVar r_chromatic_aberration_intensity( "r_chromatic_aberration_intensity", "0.2" ); +ConVar r_chromatic_aberration_noise( "r_chromatic_aberration_noise", "4.0" ); + +ConVar r_chromatic_aberration_frame1_clr( "r_chromatic_aberration_frame1_clr", "1.0 0.0 0.0 1.0" ); +ConVar r_chromatic_aberration_frame1_offset_x( "r_chromatic_aberration_frame1_offset_x", "1.0" ); +ConVar r_chromatic_aberration_frame1_offset_y( "r_chromatic_aberration_frame1_offset_y", "4.0" ); + +ConVar r_chromatic_aberration_frame2_clr( "r_chromatic_aberration_frame2_clr", "0.0 1.0 0.0 1.0" ); +ConVar r_chromatic_aberration_frame2_offset_x( "r_chromatic_aberration_frame2_offset_x", "-5.0" ); +ConVar r_chromatic_aberration_frame2_offset_y( "r_chromatic_aberration_frame2_offset_y", "-1.0" ); + +ConVar r_chromatic_aberration_frame3_clr( "r_chromatic_aberration_frame3_clr", "0.0 0.0 1.0 1.0" ); +ConVar r_chromatic_aberration_frame3_offset_x( "r_chromatic_aberration_frame3_offset_x", "3.0" ); +ConVar r_chromatic_aberration_frame3_offset_y( "r_chromatic_aberration_frame3_offset_y", "-3.0" ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CChromaticAberrationEffect::Init( void ) +{ + m_flDuration = 0.0f; + m_flFinishTime = 0.0f; + m_bUpdateView = true; + + KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); + pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE ); + m_EffectMaterial.Init( "__stuneffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues ); + m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS ); +} + +void CChromaticAberrationEffect::Shutdown( void ) +{ + m_EffectMaterial.Shutdown(); + m_StunTexture.Shutdown(); +} + +//------------------------------------------------------------------------------ +// Purpose: Pick up changes in our parameters +//------------------------------------------------------------------------------ +void CChromaticAberrationEffect::SetParameters( KeyValues *params ) +{ + if( params->FindKey( "duration" ) ) + { + m_flDuration = params->GetFloat( "duration" ); + m_flFinishTime = gpGlobals->curtime + m_flDuration; + m_bUpdateView = true; + } + + if( params->FindKey( "fadeout" ) ) + { + m_bFadeOut = ( params->GetInt( "fadeout" ) == 1 ); + } + + if( params->FindKey( "stretch" ) ) + { + m_bStretch = ( params->GetInt( "stretch" ) == 1 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Render the effect +//----------------------------------------------------------------------------- +void CChromaticAberrationEffect::RenderColorFrame( CMatRenderContextPtr &pRenderContext, float flEffectPerc, int nColorMode, int x, int y, int w, int h ) +{ + // Change color + float flColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + + float viewOffsX = flEffectPerc; + if (m_bStretch) + viewOffsX *= r_chromatic_aberration_offset.GetFloat() * 2; + else + viewOffsX *= r_chromatic_aberration_offset.GetFloat(); + + float viewOffsY = viewOffsX; + + { + char szColor[16] = { 0 }; + float flNoise = sin( gpGlobals->curtime * r_chromatic_aberration_noise.GetFloat() ) * flEffectPerc; + + switch (nColorMode) + { + // Red + case 0: + Q_strncpy( szColor, r_chromatic_aberration_frame1_clr.GetString(), sizeof( szColor ) ); + + viewOffsX *= r_chromatic_aberration_frame1_offset_x.GetFloat(); + viewOffsY *= r_chromatic_aberration_frame1_offset_y.GetFloat(); + + viewOffsX += flNoise; + viewOffsY += flNoise; + break; + + // Green + case 1: + Q_strncpy( szColor, r_chromatic_aberration_frame2_clr.GetString(), sizeof( szColor ) ); + + viewOffsX *= r_chromatic_aberration_frame2_offset_x.GetFloat(); + viewOffsY *= r_chromatic_aberration_frame2_offset_y.GetFloat(); + + viewOffsX += flNoise; + viewOffsY += flNoise; + break; + + // Blue + case 2: + Q_strncpy( szColor, r_chromatic_aberration_frame3_clr.GetString(), sizeof( szColor ) ); + + viewOffsX *= r_chromatic_aberration_frame3_offset_x.GetFloat(); + viewOffsY *= r_chromatic_aberration_frame3_offset_y.GetFloat(); + + viewOffsX += flNoise; + viewOffsY += flNoise; + break; + } + + char *c = strtok( szColor, " " ); + for (int i = 0; i < 4 && c != NULL; i++, c = strtok( NULL, " " )) + { + flColor[i] = atof( c ); + } + } + + if (flColor[3] == 0.0f || g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80) + return; + + m_EffectMaterial->ColorModulate( flColor[0], flColor[1], flColor[2] ); + + // Set alpha blend value + float flOverlayAlpha = clamp( r_chromatic_aberration_intensity.GetFloat() * flEffectPerc * flColor[3], 0.0f, 1.0f); + m_EffectMaterial->AlphaModulate( flOverlayAlpha ); + + // Draw full screen alpha-blended quad + if (m_bStretch) + { + float vX = x - (viewOffsX * 0.5f); + float vY = y - (viewOffsY * 0.5f); + + pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, vX, vY, w + viewOffsX, h + viewOffsY, + 0, 0, (m_StunTexture->GetActualWidth()-1), (m_StunTexture->GetActualHeight()-1), + m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() ); + } + else + { + float vX = x + viewOffsX; + float vY = y + viewOffsY; + + pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, 0, 0, w, h, + vX, vY, (m_StunTexture->GetActualWidth()-1)+vX, (m_StunTexture->GetActualHeight()-1)+vY, + m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Render the effect +//----------------------------------------------------------------------------- +void CChromaticAberrationEffect::Render( int x, int y, int w, int h ) +{ + // Make sure we're ready to play this effect + if ( !IsEnabled() ) + return; + + if ( m_bFadeOut && m_flFinishTime < gpGlobals->curtime ) + { + g_pScreenSpaceEffects->DisableScreenSpaceEffect( "mapbase_chromatic_aberration" ); + return; + } + + CMatRenderContextPtr pRenderContext( materials ); + + // Set ourselves to the proper rendermode + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + + // Draw the texture if we're using it + if ( m_bUpdateView ) + { + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + m_bUpdateView = false; + } + + float flEffectPerc = SmoothCurve( clamp( ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration, 0.0f, 1.0f ) ); + if (!m_bFadeOut) + flEffectPerc = 1.0f - flEffectPerc; + + RenderColorFrame( pRenderContext, flEffectPerc, 0, x, y, w, h ); + RenderColorFrame( pRenderContext, flEffectPerc, 1, x, y, w, h ); + RenderColorFrame( pRenderContext, flEffectPerc, 2, x, y, w, h ); + + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + + // Restore our state + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PopMatrix(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PopMatrix(); +} +#endif diff --git a/sp/src/game/client/episodic/episodic_screenspaceeffects.h b/sp/src/game/client/episodic/episodic_screenspaceeffects.h index ff5bc71610..661aa403d9 100644 --- a/sp/src/game/client/episodic/episodic_screenspaceeffects.h +++ b/sp/src/game/client/episodic/episodic_screenspaceeffects.h @@ -116,4 +116,38 @@ class CEP2StunEffect : public IScreenSpaceEffect ADD_SCREENSPACE_EFFECT( CEP2StunEffect, ep2_groggy ); +#ifdef MAPBASE +class CChromaticAberrationEffect : public IScreenSpaceEffect +{ +public: + CChromaticAberrationEffect( void ) : + m_flDuration( 0.0f ), + m_flFinishTime( 0.0f ), + m_bUpdateView( true ), + m_bEnabled( false ), + m_bFadeOut( false ) {} + + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void SetParameters( KeyValues *params ); + virtual void Enable( bool bEnable ) { m_bEnabled = bEnable; }; + virtual bool IsEnabled( ) { return m_bEnabled; } + + virtual void RenderColorFrame( CMatRenderContextPtr &pRenderContext, float flEffectPerc, int nColorMode, int x, int y, int w, int h ); + virtual void Render( int x, int y, int w, int h ); + +private: + CTextureReference m_StunTexture; + CMaterialReference m_EffectMaterial; + float m_flDuration; + float m_flFinishTime; + bool m_bUpdateView; + bool m_bStretch; + bool m_bFadeOut; + bool m_bEnabled; +}; + +ADD_SCREENSPACE_EFFECT( CChromaticAberrationEffect, mapbase_chromatic_aberration ); +#endif + #endif // EPISODIC_SCREENSPACEEFFECTS_H