This commit is contained in:
Kamay Xutax 2024-09-08 20:34:51 +02:00
parent 543b8a5d89
commit 481f881cb8
9 changed files with 344 additions and 209 deletions

View file

@ -31,6 +31,8 @@ C_BaseCombatCharacter::C_BaseCombatCharacter()
}
#ifdef GLOWS_ENABLE
m_bGlowOccluded = true;
m_bGlowNonOccluded = false;
m_pGlowEffect = NULL;
m_bGlowEnabled = false;
m_bOldGlowEnabled = false;
@ -130,7 +132,7 @@ void C_BaseCombatCharacter::UpdateGlowEffect( void )
float r, g, b;
GetGlowEffectColor( &r, &g, &b );
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, m_bGlowOccluded, m_bGlowNonOccluded );
}
}

View file

@ -120,7 +120,10 @@ private:
CHandle<C_BaseCombatWeapon> m_hMyWeapons[MAX_WEAPONS];
CHandle< C_BaseCombatWeapon > m_hActiveWeapon;
protected:
#ifdef GLOWS_ENABLE
bool m_bGlowOccluded;
bool m_bGlowNonOccluded;
bool m_bGlowEnabled;
bool m_bOldGlowEnabled;
CGlowObject *m_pGlowEffect;

View file

@ -41,7 +41,6 @@ $Project "Client (CStrike)"
$File "hud_baseachievement_tracker.h"
$File "$SRCDIR\game\client\hud_vote.h"
$File "$SRCDIR\game\client\hud_vote.cpp"
$File "$SRCDIR\game\client\glow_outline_effect.cpp"
$File "$SRCDIR\game\shared\predicted_viewmodel.cpp"
$File "$SRCDIR\game\shared\predicted_viewmodel.h"

View file

@ -2878,6 +2878,27 @@ bool C_CSPlayer::SetupBones( matrix3x4_t* pBoneToWorldOut, int nMaxBones, int bo
return BaseClass::SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime );
}
#ifdef GLOWS_ENABLE
void C_CSPlayer::GetGlowEffectColor( float* r, float* g, float* b )
{
if ( GetTeamNumber() == TEAM_CT )
{
*r = 0;
*g = 0;
*b = 1.0f;
}
else if ( GetTeamNumber() == TEAM_TERRORIST )
{
*r = 1.0f;
*g = 0;
*b = 0;
}
m_bGlowOccluded = false;
m_bGlowNonOccluded = true;
}
#endif
//=============================================================================
// HPE_END
//=============================================================================

View file

@ -313,6 +313,10 @@ private:
Vector m_lastLadderNormal;
Vector m_lastLadderPos;
#ifdef GLOWS_ENABLE
void GetGlowEffectColor( float *r, float *g, float *b ) override;
#endif
void UpdateRadar();
void UpdateSoundEvents();

View file

@ -4,6 +4,8 @@
//
//===============================================================================
// A huge thanks to ZMR, check their awesome project https://zombiemaster.de
#include "cbase.h"
#include "glow_outline_effect.h"
#include "model_types.h"
@ -15,10 +17,39 @@
#define FULL_FRAME_TEXTURE "_rt_FullFrameFB"
#ifdef ZMR // ZMRCHANGE: Enable glow.
#define GLOWS_ENABLE
#endif
#ifdef GLOWS_ENABLE
// If you've added IMatRenderContext::OverrideDepthFunc (see ::DrawGlowOccluded below),
// then you can enable this and have single-pass glows for "glow when occluded" outlines.
// ***PLEASE*** increment MATERIAL_SYSTEM_INTERFACE_VERSION when you add this!
#define ADDED_OVERRIDE_DEPTH_FUNC 0
// If you've fixed IMatRenderContext::CopyTextureToRenderTargetEx
// (see CGlowObjectManager::RenderGlowModels below), then you can enable this and have
// code that's a bit cleaner. Also, then you won't have to ship debug/debugfbtexture1.
// ZMRCHANGE: I'm changing this because it was causing the world to suddenly become lighter due to the shader replacements.
// On Linux, it seems to cause a black screen.
#ifdef _WIN32
#define FIXED_COPY_TEXTURE_TO_RENDER_TARGET 1
#else
#define FIXED_COPY_TEXTURE_TO_RENDER_TARGET 0
#endif
ConVar glow_outline_effect_enable( "glow_outline_effect_enable", "1", FCVAR_ARCHIVE, "Enable entity outline glow effects." );
ConVar glow_outline_effect_width( "glow_outline_width", "10.0f", FCVAR_CHEAT, "Width of glow outline effect in screen space." );
// This doesn't actually do anything.
ConVar glow_outline_effect_width( "glow_outline_width", "10.0f", FCVAR_CHEAT | FCVAR_UNREGISTERED, "Width of glow outline effect in screen space." );
// Not really necessary, but it's two different styles. I prefer style 0, but style 1 "closes off" partially occluded glows.
static ConVar glow_outline_effect_stencil_mode("glow_outline_effect_stencil_mode", "0", 0,
"\n\t0: Draws partially occluded glows in a more 3d-esque way, making them look more like they're actually surrounding the model."
"\n\t1: Draws partially occluded glows in a more 2d-esque way, which can make them more visible."
"\n\tSee https://i.imgur.com/OJQkXei.gif",
true, 0, true, 1);
extern bool g_bDumpRenderTargets; // in viewpostprocess.cpp
@ -44,16 +75,20 @@ struct ShaderStencilState_t
m_nTestMask = m_nWriteMask = 0xFFFFFFFF;
}
void SetStencilState( CMatRenderContextPtr &pRenderContext )
void SetStencilState( CMatRenderContextPtr& pRenderContext )
{
pRenderContext->SetStencilEnable( m_bEnable );
pRenderContext->SetStencilFailOperation( m_FailOp );
pRenderContext->SetStencilZFailOperation( m_ZFailOp );
pRenderContext->SetStencilPassOperation( m_PassOp );
pRenderContext->SetStencilCompareFunction( m_CompareFunc );
pRenderContext->SetStencilReferenceValue( m_nReferenceValue );
pRenderContext->SetStencilTestMask( m_nTestMask );
pRenderContext->SetStencilWriteMask( m_nWriteMask );
if ( m_bEnable )
{
pRenderContext->SetStencilFailOperation( m_FailOp );
pRenderContext->SetStencilZFailOperation( m_ZFailOp );
pRenderContext->SetStencilPassOperation( m_PassOp );
pRenderContext->SetStencilCompareFunction( m_CompareFunc );
pRenderContext->SetStencilReferenceValue( m_nReferenceValue );
pRenderContext->SetStencilTestMask( m_nTestMask );
pRenderContext->SetStencilWriteMask( m_nWriteMask );
}
}
};
@ -74,240 +109,294 @@ void CGlowObjectManager::RenderGlowEffects( const CViewSetup *pSetup, int nSplit
}
}
static void SetRenderTargetAndViewPort( ITexture *rt, int w, int h )
void CGlowObjectManager::DrawGlowAlways(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext)
{
CMatRenderContextPtr pRenderContext( materials );
pRenderContext->SetRenderTarget(rt);
pRenderContext->Viewport(0,0,w,h);
}
void CGlowObjectManager::RenderGlowModels( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext )
{
//==========================================================================================//
// This renders solid pixels with the correct coloring for each object that needs the glow. //
// After this function returns, this image will then be blurred and added into the frame //
// buffer with the objects stenciled out. //
//==========================================================================================//
pRenderContext->PushRenderTargetAndViewport();
// Save modulation color and blend
Vector vOrigColor;
render->GetColorModulation( vOrigColor.Base() );
float flOrigBlend = render->GetBlend();
// Get pointer to FullFrameFB
ITexture *pRtFullFrame = NULL;
pRtFullFrame = materials->FindTexture( FULL_FRAME_TEXTURE, TEXTURE_GROUP_RENDER_TARGET );
SetRenderTargetAndViewPort( pRtFullFrame, pSetup->width, pSetup->height );
pRenderContext->ClearColor3ub( 0, 0, 0 );
pRenderContext->ClearBuffers( true, false, false );
// Set override material for glow color
IMaterial *pMatGlowColor = NULL;
pMatGlowColor = materials->FindMaterial( "dev/glow_color", TEXTURE_GROUP_OTHER, true );
g_pStudioRender->ForcedMaterialOverride( pMatGlowColor );
ShaderStencilState_t stencilState;
stencilState.m_bEnable = false;
stencilState.m_nReferenceValue = 0;
stencilState.m_nTestMask = 0xFF;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 1;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
stencilState.m_PassOp = STENCILOPERATION_KEEP;
stencilState.m_PassOp = STENCILOPERATION_REPLACE;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;
stencilState.SetStencilState(pRenderContext);
stencilState.SetStencilState( pRenderContext );
//==================//
// Draw the objects //
//==================//
for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
pRenderContext->OverrideDepthEnable(false, false);
render->SetBlend(1);
for (int i = 0; i < m_GlowObjectDefinitions.Count(); i++)
{
if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
auto& current = m_GlowObjectDefinitions[i];
if (current.IsUnused() || !current.ShouldDraw(nSplitScreenSlot) || !current.m_bRenderWhenOccluded || !current.m_bRenderWhenUnoccluded)
continue;
render->SetBlend( m_GlowObjectDefinitions[i].m_flGlowAlpha );
Vector vGlowColor = m_GlowObjectDefinitions[i].m_vGlowColor * m_GlowObjectDefinitions[i].m_flGlowAlpha;
render->SetColorModulation( &vGlowColor[0] ); // This only sets rgb, not alpha
Vector vGlowColor = current.m_vGlowColor * current.m_flGlowAlpha;
render->SetColorModulation(vGlowColor.Base()); // This only sets rgb, not alpha
m_GlowObjectDefinitions[i].DrawModel();
}
current.DrawModel();
}
}
if ( g_bDumpRenderTargets )
void CGlowObjectManager::DrawGlowOccluded(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext)
{
#if ADDED_OVERRIDE_DEPTH_FUNC // Enable this when the TF2 team has added IMatRenderContext::OverrideDepthFunc or similar.
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 1;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
stencilState.m_PassOp = glow_outline_effect_stencil_mode.GetBool() ? STENCILOPERATION_KEEP : STENCILOPERATION_REPLACE;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;
stencilState.SetStencilState(pRenderContext);
pRenderContext->OverrideDepthEnable(true, false);
// Not implemented, we need this feature to be able to do this in 1 pass. Otherwise,
// we'd have to do 2 passes, 1st to mark on the stencil where the depth test failed,
// 2nd to actually utilize that information and draw color there.
pRenderContext->OverrideDepthFunc(true, SHADER_DEPTHFUNC_NEARER);
for (int i = 0; i < glowObjectDefinitions.Count(); i++)
{
DumpTGAofRenderTarget( pSetup->width, pSetup->height, "GlowModels" );
auto& current = glowObjectDefinitions[i];
if (current.IsUnused() || !current.ShouldDraw(nSplitScreenSlot) || !current.m_bRenderWhenOccluded || current.m_bRenderWhenUnoccluded)
continue;
render->SetBlend(current.m_flGlowAlpha);
Vector vGlowColor = current.m_vGlowColor * current.m_flGlowAlpha;
render->SetColorModulation(&vGlowColor[0]); // This only sets rgb, not alpha
current.DrawModel();
}
g_pStudioRender->ForcedMaterialOverride( NULL );
render->SetColorModulation( vOrigColor.Base() );
render->SetBlend( flOrigBlend );
ShaderStencilState_t stencilStateDisable;
stencilStateDisable.m_bEnable = false;
stencilStateDisable.SetStencilState( pRenderContext );
pRenderContext->OverrideDepthFunc(false, SHADER_DEPTHFUNC_NEAREROREQUAL)
#else // 2-pass as a proof of concept so I can take a nice screenshot.
pRenderContext->OverrideDepthEnable(true, false);
pRenderContext->PopRenderTargetAndViewport();
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 2;
stencilState.m_nWriteMask = 2;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
stencilState.m_PassOp = STENCILOPERATION_REPLACE;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_KEEP;
stencilState.SetStencilState(pRenderContext);
// Draw depthtest-passing pixels to the stencil buffer
{
render->SetBlend(0);
pRenderContext->OverrideAlphaWriteEnable(true, false);
pRenderContext->OverrideColorWriteEnable(true, false);
for (int i = 0; i < m_GlowObjectDefinitions.Count(); i++)
{
auto& current = m_GlowObjectDefinitions[i];
if (current.IsUnused() || !current.ShouldDraw(nSplitScreenSlot) || !current.m_bRenderWhenOccluded || current.m_bRenderWhenUnoccluded)
continue;
current.DrawModel();
}
}
pRenderContext->OverrideAlphaWriteEnable(false, true);
pRenderContext->OverrideColorWriteEnable(false, true);
pRenderContext->OverrideDepthEnable(false, false);
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 3;
stencilState.m_nTestMask = 2;
stencilState.m_nWriteMask = 1;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_NOTEQUAL;
stencilState.m_PassOp = STENCILOPERATION_REPLACE;
stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;
stencilState.m_FailOp = glow_outline_effect_stencil_mode.GetBool() ? STENCILOPERATION_KEEP : STENCILOPERATION_REPLACE;
stencilState.SetStencilState(pRenderContext);
// Draw color+alpha, stenciling out pixels from the first pass
render->SetBlend(1);
for (int i = 0; i < m_GlowObjectDefinitions.Count(); i++)
{
auto& current = m_GlowObjectDefinitions[i];
if (current.IsUnused() || !current.ShouldDraw(nSplitScreenSlot) || !current.m_bRenderWhenOccluded || current.m_bRenderWhenUnoccluded)
continue;
const Vector vGlowColor = current.m_vGlowColor * current.m_flGlowAlpha;
render->SetColorModulation(vGlowColor.Base()); // This only sets rgb, not alpha
current.DrawModel();
}
#endif
}
void CGlowObjectManager::DrawGlowVisible(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext)
{
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 1;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
stencilState.m_PassOp = STENCILOPERATION_REPLACE;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = glow_outline_effect_stencil_mode.GetBool() ? STENCILOPERATION_KEEP : STENCILOPERATION_REPLACE;
stencilState.SetStencilState(pRenderContext);
pRenderContext->OverrideDepthEnable(true, false);
render->SetBlend(1);
for (int i = 0; i < m_GlowObjectDefinitions.Count(); i++)
{
auto& current = m_GlowObjectDefinitions[i];
if (current.IsUnused() || !current.ShouldDraw(nSplitScreenSlot) || current.m_bRenderWhenOccluded || !current.m_bRenderWhenUnoccluded)
continue;
Vector vGlowColor = current.m_vGlowColor * current.m_flGlowAlpha;
render->SetColorModulation(vGlowColor.Base()); // This only sets rgb, not alpha
current.DrawModel();
}
}
void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext, float flBloomScale, int x, int y, int w, int h )
{
//=======================================================//
// Render objects into stencil buffer //
//=======================================================//
// Set override shader to the same simple shader we use to render the glow models
IMaterial *pMatGlowColor = materials->FindMaterial( "dev/glow_color", TEXTURE_GROUP_OTHER, true );
g_pStudioRender->ForcedMaterialOverride( pMatGlowColor );
const PIXEvent pixEvent(pRenderContext, "ApplyEntityGlowEffects");
ShaderStencilState_t stencilStateDisable;
stencilStateDisable.m_bEnable = false;
float flSavedBlend = render->GetBlend();
// Set alpha to 0 so we don't touch any color pixels
render->SetBlend( 0.0f );
pRenderContext->OverrideDepthEnable( true, false );
int iNumGlowObjects = 0;
for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
// Optimization: only do all the framebuffer shuffling if there's at least one glow to be drawn
{
if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
continue;
bool atLeastOneGlow = false;
if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded || m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
for (int i = 0; i < m_GlowObjectDefinitions.Count(); i++)
{
if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
{
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 1;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
stencilState.m_PassOp = STENCILOPERATION_REPLACE;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;
if (m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw(nSplitScreenSlot))
continue;
stencilState.SetStencilState( pRenderContext );
m_GlowObjectDefinitions[i].DrawModel();
}
else if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded )
{
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 1;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
stencilState.m_PassOp = STENCILOPERATION_KEEP;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;
stencilState.SetStencilState( pRenderContext );
m_GlowObjectDefinitions[i].DrawModel();
}
else if ( m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
{
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 2;
stencilState.m_nTestMask = 0x1;
stencilState.m_nWriteMask = 0x3;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_EQUAL;
stencilState.m_PassOp = STENCILOPERATION_INCRSAT;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;
stencilState.SetStencilState( pRenderContext );
m_GlowObjectDefinitions[i].DrawModel();
}
atLeastOneGlow = true;
break;
}
iNumGlowObjects++;
if (!atLeastOneGlow)
return;
}
// Need to do a 2nd pass to warm stencil for objects which are rendered only when occluded
for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
{
if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
continue;
ITexture* const pRtFullFrameFB0 = materials->FindTexture("_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET);
ITexture* const pRtFullFrameFB1 = materials->FindTexture("_rt_FullFrameFB1", TEXTURE_GROUP_RENDER_TARGET);
if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && !m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
pRenderContext->PushRenderTargetAndViewport();
// Set backbuffer + hardware depth as MRT 0. We CANNOT CHANGE RENDER TARGETS after this point!!!
// In CShaderAPIDx8::CreateDepthTexture all depth+stencil buffers are created with the "discard"
// flag set to TRUE. Not sure about OpenGL, but according to
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb174356(v=vs.85).aspx, if you change
// the depth+stencil buffer away from a buffer that has discard=TRUE, the contents become garbage.
pRenderContext->SetRenderTargetEx(0, nullptr);
// Save current backbuffer to _rt_FullFrameFB1
pRenderContext->CopyRenderTargetToTexture(pRtFullFrameFB1);
// Clear backbuffer color and stencil, keep depth for testing
pRenderContext->ClearColor4ub(0, 0, 0, 0);
pRenderContext->ClearBuffers(true, false, true);
// Draw glow models
{
// Save modulation color and blend
Vector vOrigColor;
render->GetColorModulation(vOrigColor.Base());
const float flOrigBlend = render->GetBlend();
// Set override material for glow color
g_pStudioRender->ForcedMaterialOverride(materials->FindMaterial("dev/glow_color", TEXTURE_GROUP_OTHER, true));
pRenderContext->OverrideColorWriteEnable(true, true);
pRenderContext->OverrideAlphaWriteEnable(true, true);
// Draw "glow when visible" objects
DrawGlowVisible(nSplitScreenSlot, pRenderContext);
// Draw "glow when occluded" objects
DrawGlowOccluded(nSplitScreenSlot, pRenderContext);
// Draw "glow always" objects
DrawGlowAlways(nSplitScreenSlot, pRenderContext);
// Unset override material
g_pStudioRender->ForcedMaterialOverride(NULL);
// Restore modulation color and blend
render->SetColorModulation(vOrigColor.Base());
render->SetBlend(flOrigBlend);
pRenderContext->OverrideDepthEnable(false, false);
}
// Copy MSAA'd glow models to _rt_FullFrameFB0
pRenderContext->CopyRenderTargetToTexture(pRtFullFrameFB0);
// Move original contents of the backbuffer from _rt_FullFrameFB1 to the backbuffer
{
#if FIXED_COPY_TEXTURE_TO_RENDER_TARGET // Coordinates don't seem to be mapped 1:1 properly, screen becomes slightly blurry
pRenderContext->CopyTextureToRenderTargetEx(0, pRtFullFrameFB1, nullptr);
#else
pRenderContext->SetStencilEnable(false);
IMaterial* const pFullFrameFB1 = materials->FindMaterial("debug/debugfbtexture1", TEXTURE_GROUP_RENDER_TARGET);
pFullFrameFB1->AddRef();
pRenderContext->Bind(pFullFrameFB1);
const int nSrcWidth = pSetup->width;
const int nSrcHeight = pSetup->height;
int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
pRenderContext->GetViewport(nViewportX, nViewportY, nViewportWidth, nViewportHeight);
pRenderContext->OverrideDepthEnable(true, false);
{
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nReferenceValue = 2;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
stencilState.m_PassOp = STENCILOPERATION_REPLACE;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_KEEP;
stencilState.SetStencilState( pRenderContext );
m_GlowObjectDefinitions[i].DrawModel();
pRenderContext->DrawScreenSpaceRectangle(pFullFrameFB1,
0, 0, nViewportWidth, nViewportHeight,
0, 0, nSrcWidth - 1, nSrcHeight - 1,
pRtFullFrameFB1->GetActualWidth(), pRtFullFrameFB1->GetActualHeight());
}
pRenderContext->OverrideDepthEnable(false, false);
pFullFrameFB1->Release();
#endif
}
pRenderContext->OverrideDepthEnable( false, false );
render->SetBlend( flSavedBlend );
stencilStateDisable.SetStencilState( pRenderContext );
g_pStudioRender->ForcedMaterialOverride( NULL );
// If there aren't any objects to glow, don't do all this other stuff
// this fixes a bug where if there are glow objects in the list, but none of them are glowing,
// the whole screen blooms.
if ( iNumGlowObjects <= 0 )
return;
//=============================================
// Render the glow colors to _rt_FullFrameFB
//=============================================
// Bloom glow models from _rt_FullFrameFB0 to backbuffer while stenciling out inside of models
{
PIXEvent pixEvent( pRenderContext, "RenderGlowModels" );
RenderGlowModels( pSetup, nSplitScreenSlot, pRenderContext );
}
// Get viewport
int nSrcWidth = pSetup->width;
int nSrcHeight = pSetup->height;
int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
pRenderContext->GetViewport( nViewportX, nViewportY, nViewportWidth, nViewportHeight );
// Get material and texture pointers
ITexture *pRtQuarterSize1 = materials->FindTexture( "_rt_SmallFB1", TEXTURE_GROUP_RENDER_TARGET );
{
//=======================================================================================================//
// At this point, pRtQuarterSize0 is filled with the fully colored glow around everything as solid glowy //
// blobs. Now we need to stencil out the original objects by only writing pixels that have no //
// stencil bits set in the range we care about. //
//=======================================================================================================//
IMaterial *pMatHaloAddToScreen = materials->FindMaterial( "dev/halo_add_to_screen", TEXTURE_GROUP_OTHER, true );
// Do not fade the glows out at all (weight = 1.0)
IMaterialVar *pDimVar = pMatHaloAddToScreen->FindVar( "$C0_X", NULL );
pDimVar->SetFloatValue( 1.0f );
// Set stencil state
ShaderStencilState_t stencilState;
stencilState.m_bEnable = true;
stencilState.m_nWriteMask = 0x0; // We're not changing stencil
stencilState.m_nTestMask = 0xFF;
stencilState.m_nReferenceValue = 0x0;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_EQUAL;
stencilState.m_nWriteMask = 0; // We're not changing stencil
stencilState.m_nReferenceValue = 1;
stencilState.m_nTestMask = 1;
stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_NOTEQUAL;
stencilState.m_PassOp = STENCILOPERATION_KEEP;
stencilState.m_FailOp = STENCILOPERATION_KEEP;
stencilState.m_ZFailOp = STENCILOPERATION_KEEP;
stencilState.SetStencilState( pRenderContext );
stencilState.SetStencilState(pRenderContext);
ITexture* const pRtQuarterSize1 = materials->FindTexture("_rt_SmallFB1", TEXTURE_GROUP_RENDER_TARGET);
IMaterial* const pMatHaloAddToScreen = materials->FindMaterial("dev/halo_add_to_screen", TEXTURE_GROUP_OTHER, true);
// Write to alpha
pRenderContext->OverrideAlphaWriteEnable(true, true);
const int nSrcWidth = pSetup->width;
const int nSrcHeight = pSetup->height;
int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
pRenderContext->GetViewport(nViewportX, nViewportY, nViewportWidth, nViewportHeight);
// Draw quad
pRenderContext->DrawScreenSpaceRectangle( pMatHaloAddToScreen, 0, 0, nViewportWidth, nViewportHeight,
0.0f, -0.5f, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1,
pRenderContext->DrawScreenSpaceRectangle(pMatHaloAddToScreen,
0, 0, nViewportWidth, nViewportHeight,
0, 0, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1,
pRtQuarterSize1->GetActualWidth(),
pRtQuarterSize1->GetActualHeight() );
stencilStateDisable.SetStencilState( pRenderContext );
pRtQuarterSize1->GetActualHeight());
}
// Done with all of our "advanced" 3D rendering.
pRenderContext->SetStencilEnable(false);
pRenderContext->OverrideColorWriteEnable(false, false);
pRenderContext->OverrideAlphaWriteEnable(false, false);
pRenderContext->OverrideDepthEnable(false, false);
pRenderContext->PopRenderTargetAndViewport();
}
void CGlowObjectManager::GlowObjectDefinition_t::DrawModel()

View file

@ -14,7 +14,8 @@
#include "utlvector.h"
#include "mathlib/vector.h"
#ifdef GLOWS_ENABLE
// ZMRCHANGE: Enable glow.
//#ifdef GLOWS_ENABLE
class C_BaseEntity;
class CViewSetup;
@ -117,7 +118,6 @@ public:
private:
void RenderGlowModels( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext );
void ApplyEntityGlowEffects( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext, float flBloomScale, int x, int y, int w, int h );
struct GlowObjectDefinition_t
@ -150,6 +150,10 @@ private:
static const int ENTRY_IN_USE = -2;
};
void DrawGlowVisible( int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext );
void DrawGlowOccluded( int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext );
void DrawGlowAlways( int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext );
CUtlVector< GlowObjectDefinition_t > m_GlowObjectDefinitions;
int m_nFirstFreeSlot;
};
@ -214,6 +218,6 @@ private:
CGlowObject& operator=( const CGlowObject &other );
};
#endif // GLOWS_ENABLE
//#endif // GLOWS_ENABLE
#endif // GLOW_OUTLINE_EFFECT_H

View file

@ -857,7 +857,7 @@ void CCSPlayer::Spawn()
m_applyDeafnessTime = 0.0f;
StockPlayerAmmo();
}
}
void CCSPlayer::ShowViewPortPanel( const char * name, bool bShow, KeyValues *data )
{
@ -1541,6 +1541,10 @@ void CCSPlayer::UpdateMouseoverHints()
}
}
#ifdef GLOWS_ENABLE
ConVar sv_enable_cs_glows("sv_enable_cs_glows", "1");
#endif
void CCSPlayer::PostThink()
{
BaseClass::PostThink();
@ -1597,9 +1601,18 @@ void CCSPlayer::PostThink()
{
StopSound( "Player.AmbientUnderWater" );
SetPlayerUnderwater( false );
}
}
AddGlowEffect();
#ifdef GLOWS_ENABLE
if ( sv_enable_cs_glows.GetBool() )
{
AddGlowEffect();
}
else
{
RemoveGlowEffect();
}
#endif
}

@ -1 +1 @@
Subproject commit 3cd6248acc4b083db1653acd9dbebc351bd63368
Subproject commit 20ff23a3afd4047c486b5af719bfcc29b000d838