From 85a45027204fe4fb9d9d7bf9d26ef4fe536eae66 Mon Sep 17 00:00:00 2001 From: LightCat Date: Sun, 7 Apr 2019 11:23:39 +0200 Subject: [PATCH] Glow and Backtrack improvements - Revert to an old state of Glow - add getRealLatency() For Higher backtrack precision - Re-add Missing glow Menu entries - Make Backtrack chams/glow work Regardless if glow/chams is enabled - avoid Calling DrawModelExecute multiple times --- data/menu/nullifiedcat/visuals/glow.xml | 8 + include/hacks/Backtrack.hpp | 1 + include/visual/EffectGlow.hpp | 21 +- src/hacks/Backtrack.cpp | 25 +- src/hooks/CreateMove.cpp | 2 +- src/hooks/visual/DrawModelExecute.cpp | 36 ++- src/visual/EffectChams.cpp | 1 + src/visual/EffectGlow.cpp | 290 +++++++++++++++++++----- 8 files changed, 310 insertions(+), 74 deletions(-) diff --git a/data/menu/nullifiedcat/visuals/glow.xml b/data/menu/nullifiedcat/visuals/glow.xml index fe08ad48..5004855a 100755 --- a/data/menu/nullifiedcat/visuals/glow.xml +++ b/data/menu/nullifiedcat/visuals/glow.xml @@ -2,7 +2,15 @@ + + + + diff --git a/include/hacks/Backtrack.hpp b/include/hacks/Backtrack.hpp index 829223f3..f69f59e3 100644 --- a/include/hacks/Backtrack.hpp +++ b/include/hacks/Backtrack.hpp @@ -66,6 +66,7 @@ extern BacktrackData headPositions[32][66]; extern bool isBacktrackEnabled; extern bool Vischeck_Success; float getLatency(); +float getRealLatency(); int getTicks(); bool ValidTick(BacktrackData &i, CachedEntity *ent); } // namespace hacks::shared::backtrack diff --git a/include/visual/EffectGlow.hpp b/include/visual/EffectGlow.hpp index 23d41852..15817717 100644 --- a/include/visual/EffectGlow.hpp +++ b/include/visual/EffectGlow.hpp @@ -21,7 +21,13 @@ public: { if (init) { + mat_unlit.Shutdown(); mat_unlit_z.Shutdown(); + mat_blit.Shutdown(); + mat_unlit.Shutdown(); + mat_unlit_z.Shutdown(); + mat_blur_x.Shutdown(); + mat_blur_y.Shutdown(); init = false; } } @@ -41,18 +47,27 @@ public: return enabled; } + void StartStenciling(); + void EndStenciling(); void DrawEntity(IClientEntity *entity); + void DrawToStencil(IClientEntity *entity); + void DrawToBuffer(IClientEntity *entity); rgba_t GlowColor(IClientEntity *entity); bool ShouldRenderGlow(IClientEntity *entity); + void RenderGlow(IClientEntity *entity); + void BeginRenderGlow(); + void EndRenderGlow(); public: bool init{ false }; bool drawing{ false }; bool enabled; + float orig_modulation[3]; + CMaterialReference mat_blit; + CMaterialReference mat_blur_x; + CMaterialReference mat_blur_y; + CMaterialReference mat_unlit; CMaterialReference mat_unlit_z; - IMaterial *mat_halo; - IMaterial *mat_glow; - ITexture *mat_fullframe; }; extern EffectGlow g_EffectGlow; diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp index f300fdd6..e4ea0dae 100644 --- a/src/hacks/Backtrack.cpp +++ b/src/hacks/Backtrack.cpp @@ -56,7 +56,9 @@ void AddLatencyToNetchan(INetChannel *ch) if (!isBacktrackEnabled) return; float Latency = *latency; - Latency -= ch->GetAvgLatency(FLOW_OUTGOING) * 1000.0f - 20.0f; + if (Latency > 1000.0f) + Latency = 800.0f; + Latency -= getRealLatency(); if (Latency < 0.0f) Latency = 0.0f; for (auto &seq : sequences) @@ -320,13 +322,28 @@ bool shouldBacktrack() } return false; } - +float getRealLatency() +{ + auto ch = (INetChannel *) g_IEngine->GetNetChannelInfo(); + if (!ch) + return 0.0f; + float Latency = ch->GetLatency(FLOW_OUTGOING); + static auto cl_updaterate = g_ICvar->FindVar("cl_updaterate"); + if (cl_updaterate && cl_updaterate->GetFloat() > 0.001f) + Latency += -0.5f / cl_updaterate->GetFloat(); + else if (!cl_updaterate) + cl_updaterate = g_ICvar->FindVar("cl_updaterate"); + return MAX(0.0f, Latency) * 1000.f; +} float getLatency() { auto ch = (INetChannel *) g_IEngine->GetNetChannelInfo(); if (!ch) return 0; - float Latency = *latency - ch->GetAvgLatency(FLOW_OUTGOING) * 1000.0f - 20.0f; + float Latency = *latency; + if (Latency > 1000.0f) + Latency = 800.0f; + Latency -= getRealLatency(); if (Latency < 0.0f) Latency = 0.0f; return Latency; @@ -334,7 +351,7 @@ float getLatency() int getTicks() { - return max(min(int(*latency / 200.0f * 13.0f) + 12, 65), 12); + return max(min(int(getLatency() / 200.0f * 13.0f) + 12, 65), 12); } bool ValidTick(BacktrackData &i, CachedEntity *ent) diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index f3ce9467..0f0ca9cd 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -436,7 +436,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, CUs INetChannel *ch = (INetChannel *) g_IEngine->GetNetChannelInfo(); if (NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) <= 1.5f) continue; - float latency = ch->GetAvgLatency(MAX_FLOWS); + float latency = hacks::shared::backtrack::getRealLatency(); g_Settings.brute.choke[i].push_back(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) == g_Settings.brute.lastsimtime); g_Settings.brute.last_angles[ent->m_IDX] = NET_VECTOR(RAW_ENT(ent), netvar.m_angEyeAngles); if (!g_Settings.brute.choke[i].empty() && g_Settings.brute.choke[i].size() > 20) diff --git a/src/hooks/visual/DrawModelExecute.cpp b/src/hooks/visual/DrawModelExecute.cpp index 6d48bdf4..b2ec78f3 100644 --- a/src/hooks/visual/DrawModelExecute.cpp +++ b/src/hooks/visual/DrawModelExecute.cpp @@ -16,11 +16,11 @@ static settings::Bool no_hats{ "remove.hats", "false" }; namespace effect_glow { extern settings::Bool enable; -} +} // namespace effect_glow namespace effect_chams { extern settings::Bool enable; -} +} // namespace effect_chams namespace hacks::shared::backtrack { extern settings::Bool backtrack_chams_glow; @@ -37,6 +37,8 @@ DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawMod { return original::DrawModelExecute(this_, state, info, bone); } + if (effect_glow::g_EffectGlow.drawing || effect_chams::g_EffectChams.drawing) + return original::DrawModelExecute(this_, state, info, bone); PROF_SECTION(DrawModelExecute); @@ -60,7 +62,7 @@ DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawMod } } - if (hacks::shared::backtrack::isBacktrackEnabled && hacks::shared::backtrack::backtrack_chams_glow && (effect_glow::enable || effect_chams::enable)) + if (hacks::shared::backtrack::isBacktrackEnabled && hacks::shared::backtrack::backtrack_chams_glow) { const char *name = g_IModelInfo->GetModelName(info.pModel); if (name) @@ -77,7 +79,7 @@ DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawMod // Backup Blend float orig_blend = g_IVRenderView->GetBlend(); // Make Backtrack stuff seethrough - g_IVRenderView->SetBlend(0.999f); + g_IVRenderView->SetBlend(1.0f); // Get Backtrack data for target entity auto head_pos = hacks::shared::backtrack::headPositions[info.entity_index]; // Usable vector instead of ptr to c style array, also used to filter valid and invalid ticks @@ -90,9 +92,35 @@ DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawMod // Crash much? if (usable.size()) { + // Sort std::sort(usable.begin(), usable.end(), [](hacks::shared::backtrack::BacktrackData &a, hacks::shared::backtrack::BacktrackData &b) { return a.tickcount < b.tickcount; }); + // Make our own Chamsish Material + static CMaterialReference mat_lit; + static bool init = false; + if (!init) + { + KeyValues *kv = new KeyValues("VertexLitGeneric"); + kv->SetString("$basetexture", "vgui/white_additive"); + kv->SetInt("$ignorez", 0); + mat_lit.Init("__cathook_dme_lit", kv); + init = true; + } + // Render Chams/Glow stuff + CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); + rgba_t mod_original; + // Save color just in case, then set to white + g_IVRenderView->GetColorModulation(mod_original.rgba); + g_IVRenderView->SetColorModulation(colors::white); + // Important for Depth + ptr->DepthRange(0.0f, 1.0f); + // Apply our material + g_IVModelRender->ForcedMaterialOverride(mat_lit); + // Run Original original::DrawModelExecute(this_, state, info, usable[0].bones); + // Revert + g_IVRenderView->SetColorModulation(mod_original.rgba); + g_IVModelRender->ForcedMaterialOverride(nullptr); } g_IVRenderView->SetBlend(orig_blend); } diff --git a/src/visual/EffectChams.cpp b/src/visual/EffectChams.cpp index 15559593..f5b2ee24 100644 --- a/src/visual/EffectChams.cpp +++ b/src/visual/EffectChams.cpp @@ -30,6 +30,7 @@ static settings::Bool disco_chams{ "chams.disco", "false" }; namespace effect_chams { + settings::Bool enable{ "chams.enable", "false" }; CatCommand fix_black_chams("fix_black_chams", "Fix Black Chams", []() { effect_chams::g_EffectChams.Shutdown(); diff --git a/src/visual/EffectGlow.cpp b/src/visual/EffectGlow.cpp index 9ff1ba14..f5d7c342 100644 --- a/src/visual/EffectGlow.cpp +++ b/src/visual/EffectGlow.cpp @@ -23,6 +23,11 @@ static settings::Bool show_powerups{ "glow.show.powerups", "true" }; static settings::Bool weapons_white{ "glow.white-weapons", "true" }; static settings::Bool glowself{ "glow.self", "true" }; static settings::Bool rainbow{ "glow.self-rainbow", "true" }; +static settings::Int blur_scale{ "glow.blur-scale", "5" }; +// https://puu.sh/vobH4/5da8367aef.png +static settings::Int solid_when{ "glow.solid-when", "0" }; + +IMaterialSystem *materials = nullptr; CScreenSpaceEffectRegistration *CScreenSpaceEffectRegistration::s_pHead = NULL; IScreenSpaceEffectManager *g_pScreenSpaceEffects = nullptr; @@ -79,8 +84,43 @@ struct ShaderStencilState_t } }; -static ShaderStencilState_t SS_First{}; -static ShaderStencilState_t SS_Last{}; +static CTextureReference buffers[4]{}; + +ITexture *GetBuffer(int i) +{ + if (!buffers[i]) + { + ITexture *fullframe; + IF_GAME(IsTF2()) + fullframe = g_IMaterialSystem->FindTexture("_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET); + else fullframe = g_IMaterialSystemHL->FindTexture("_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET); + // char *newname = new char[32]; + std::unique_ptr newname(new char[32]); + std::string name = format("_cathook_buff", i); + strncpy(newname.get(), name.c_str(), 30); + logging::Info("Creating new buffer %d with size %dx%d %s", i, fullframe->GetActualWidth(), fullframe->GetActualHeight(), newname.get()); + + int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_EIGHTBITALPHA; + int renderTargetFlags = CREATERENDERTARGETFLAGS_HDR; + + ITexture *texture; + IF_GAME(IsTF2()) + { + texture = g_IMaterialSystem->CreateNamedRenderTargetTextureEx(newname.get(), fullframe->GetActualWidth(), fullframe->GetActualHeight(), RT_SIZE_LITERAL, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_SEPARATE, textureFlags, renderTargetFlags); + } + else + { + texture = g_IMaterialSystemHL->CreateNamedRenderTargetTextureEx(newname.get(), fullframe->GetActualWidth(), fullframe->GetActualHeight(), RT_SIZE_LITERAL, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_SEPARATE, textureFlags, renderTargetFlags); + } + buffers[i].Init(texture); + } + return buffers[i]; +} + +static ShaderStencilState_t SS_NeverSolid{}; +static ShaderStencilState_t SS_SolidInvisible{}; +static ShaderStencilState_t SS_Null{}; +static ShaderStencilState_t SS_Drawing{}; CatCommand fix_black_glow("fix_black_glow", "Fix Black Glow", []() { effect_glow::g_EffectGlow.Shutdown(); @@ -93,16 +133,10 @@ void EffectGlow::Init() return; logging::Info("Init Glow..."); { - SS_First.m_bEnable = true; - SS_First.m_PassOp = STENCILOPERATION_REPLACE; - SS_First.m_nWriteMask = 1; - SS_First.m_nReferenceValue = 1; - } - { - SS_Last.m_bEnable = true; - SS_Last.m_nWriteMask = 0; // We're not changing stencil - SS_Last.m_nTestMask = 255; - SS_Last.m_CompareFunc = STENCILCOMPARISONFUNCTION_EQUAL; + KeyValues *kv = new KeyValues("UnlitGeneric"); + kv->SetString("$basetexture", "vgui/white_additive"); + kv->SetInt("$ignorez", 0); + mat_unlit.Init("__cathook_glow_unlit", kv); } { KeyValues *kv = new KeyValues("UnlitGeneric"); @@ -110,20 +144,62 @@ void EffectGlow::Init() kv->SetInt("$ignorez", 1); mat_unlit_z.Init("__cathook_glow_unlit_z", kv); } - IF_GAME(IsTF2()) + // Initialize 2 buffers + GetBuffer(1); + GetBuffer(2); { - mat_halo = g_IMaterialSystem->FindMaterial("dev/halo_add_to_screen", TEXTURE_GROUP_OTHER, false); - mat_halo->FindVar("$C0_X", NULL, false)->SetFloatValue(1.0f); - mat_glow = g_IMaterialSystem->FindMaterial("dev/glow_color", TEXTURE_GROUP_OTHER, false); - mat_fullframe = g_IMaterialSystem->FindTexture("_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET); + KeyValues *kv = new KeyValues("UnlitGeneric"); + kv->SetString("$basetexture", "_cathook_buff1"); + kv->SetInt("$additive", 1); + mat_blit.Init("__cathook_glow_blit", TEXTURE_GROUP_CLIENT_EFFECTS, kv); + mat_blit->Refresh(); } - else { - mat_halo = g_IMaterialSystemHL->FindMaterial("dev/halo_add_to_screen", TEXTURE_GROUP_OTHER, false); - mat_halo->FindVar("$C0_X", NULL, false)->SetFloatValue(1.0f); - mat_glow = g_IMaterialSystemHL->FindMaterial("dev/glow_color", TEXTURE_GROUP_OTHER, false); - mat_fullframe = g_IMaterialSystemHL->FindTexture("_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET); + KeyValues *kv = new KeyValues("BlurFilterX"); + kv->SetString("$basetexture", "_cathook_buff1"); + kv->SetInt("$ignorez", 1); + kv->SetInt("$translucent", 1); + kv->SetInt("$alphatest", 1); + mat_blur_x.Init("_cathook_blurx", kv); + mat_blur_x->Refresh(); } + { + KeyValues *kv = new KeyValues("BlurFilterY"); + kv->SetString("$basetexture", "_cathook_buff2"); + kv->SetInt("$bloomamount", 5); + kv->SetInt("$ignorez", 1); + kv->SetInt("$translucent", 1); + kv->SetInt("$alphatest", 1); + mat_blur_y.Init("_cathook_blury", kv); + mat_blur_y->Refresh(); + } + { + SS_NeverSolid.m_bEnable = true; + SS_NeverSolid.m_PassOp = STENCILOPERATION_REPLACE; + SS_NeverSolid.m_FailOp = STENCILOPERATION_KEEP; + SS_NeverSolid.m_ZFailOp = STENCILOPERATION_KEEP; + SS_NeverSolid.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS; + SS_NeverSolid.m_nWriteMask = 1; + SS_NeverSolid.m_nReferenceValue = 1; + } + { + SS_SolidInvisible.m_bEnable = true; + SS_SolidInvisible.m_PassOp = STENCILOPERATION_REPLACE; + SS_SolidInvisible.m_FailOp = STENCILOPERATION_KEEP; + SS_SolidInvisible.m_ZFailOp = STENCILOPERATION_KEEP; + SS_SolidInvisible.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS; + SS_SolidInvisible.m_nWriteMask = 1; + SS_SolidInvisible.m_nReferenceValue = 1; + } + /*case 3: https://puu.sh/vobH4/5da8367aef.png*/ + { + SS_Drawing.m_bEnable = true; + SS_Drawing.m_nReferenceValue = 0; + SS_Drawing.m_nTestMask = 1; + SS_Drawing.m_CompareFunc = STENCILCOMPARISONFUNCTION_EQUAL; + SS_Drawing.m_PassOp = STENCILOPERATION_ZERO; + } + logging::Info("Init done!"); init = true; } @@ -156,14 +232,10 @@ rgba_t EffectGlow::GlowColor(IClientEntity *entity) break; case ENTITY_PLAYER: if (ent->m_IDX == LOCAL_E->m_IDX) - { - if (rainbow) - return colors::RainbowCurrent(); - else if (LOCAL_E->m_iTeam() == TEAM_BLU) + if (LOCAL_E->m_iTeam() == TEAM_BLU) return colors::blu; else return colors::red; - } if (health && playerlist::IsDefault(ent)) { return colors::Health(ent->m_iHealth(), ent->m_iMaxHealth()); @@ -221,13 +293,87 @@ bool EffectGlow::ShouldRenderGlow(IClientEntity *entity) } else if (type >= ITEM_POWERUP_FIRST && type <= ITEM_POWERUP_LAST) { - return *show_powerups; // lol? whoever made it return const char *powerups is psmart + return powerups; } break; } return false; } +void EffectGlow::BeginRenderGlow() +{ + drawing = true; + CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); + ptr->ClearColor4ub(0, 0, 0, 0); + ptr->PushRenderTargetAndViewport(); + ptr->SetRenderTarget(GetBuffer(1)); + ptr->OverrideAlphaWriteEnable(true, true); + g_IVRenderView->SetBlend(0.99f); + ptr->ClearBuffers(true, false); + mat_unlit_z->AlphaModulate(1.0f); + ptr->DepthRange(0.0f, 0.01f); +} + +void EffectGlow::EndRenderGlow() +{ + drawing = false; + CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); + ptr->DepthRange(0.0f, 1.0f); + g_IVModelRender->ForcedMaterialOverride(nullptr); + ptr->PopRenderTargetAndViewport(); +} + +void EffectGlow::StartStenciling() +{ + static ShaderStencilState_t state; + state.Reset(); + state.m_bEnable = true; + CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); + switch (*solid_when) + { + case 0: + SS_NeverSolid.SetStencilState(ptr); + break; + case 2: + SS_SolidInvisible.SetStencilState(ptr); + break; + /*case 3: https://puu.sh/vobH4/5da8367aef.png*/ + default: + break; + } + if (!*solid_when) + { + ptr->DepthRange(0.0f, 0.01f); + } + else + { + ptr->DepthRange(0.0f, 1.0f); + } + g_IVRenderView->SetBlend(0.0f); + mat_unlit->AlphaModulate(1.0f); + g_IVModelRender->ForcedMaterialOverride(*solid_when ? mat_unlit : mat_unlit_z); +} + +void EffectGlow::EndStenciling() +{ + static ShaderStencilState_t state; + state.Reset(); + g_IVModelRender->ForcedMaterialOverride(nullptr); + CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); + state.SetStencilState(ptr); + ptr->DepthRange(0.0f, 1.0f); + g_IVRenderView->SetBlend(1.0f); +} + +void EffectGlow::DrawToStencil(IClientEntity *entity) +{ + DrawEntity(entity); +} + +void EffectGlow::DrawToBuffer(IClientEntity *entity) +{ +} + void EffectGlow::DrawEntity(IClientEntity *entity) { static IClientEntity *attach; @@ -249,59 +395,79 @@ void EffectGlow::DrawEntity(IClientEntity *entity) g_IVRenderView->SetColorModulation(mod_original.rgba); } else + { attach->DrawModel(1); + } } attach = g_IEntityList->GetClientEntity(*(int *) ((uintptr_t) attach + netvar.m_Collision - 20) & 0xFFF); } } +void EffectGlow::RenderGlow(IClientEntity *entity) +{ + CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); + g_IVRenderView->SetColorModulation(GlowColor(entity)); + g_IVModelRender->ForcedMaterialOverride(mat_unlit_z); + DrawEntity(entity); +} + void EffectGlow::Render(int x, int y, int w, int h) { - if (!effect_glow::enable) + if (!enable) return; + static ITexture *orig; + static IClientEntity *ent; + static IMaterialVar *blury_bloomamount; if (!init) Init(); if (!isHackActive() || (g_IEngine->IsTakingScreenshot() && clean_screenshots) || g_Settings.bInvalid) return; CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); - - ptr->ClearColor4ub(0, 0, 0, 255); - ptr->PushRenderTargetAndViewport(mat_fullframe); - ptr->ClearBuffers(true, true); - ptr->OverrideAlphaWriteEnable(true, true); - ptr->PopRenderTargetAndViewport(); - ptr->ClearStencilBufferRectangle(0, 0, w, h, 0); - ptr->DepthRange(0.0f, 0.01f); - - SS_First.SetStencilState(ptr); - - drawing = true; - for (int i = 1; i <= HIGHEST_ENTITY; i++) + orig = ptr->GetRenderTarget(); + BeginRenderGlow(); + for (int i = 1; i < HIGHEST_ENTITY; i++) { - IClientEntity *ent = g_IEntityList->GetClientEntity(i); + ent = g_IEntityList->GetClientEntity(i); if (ent && !ent->IsDormant() && ShouldRenderGlow(ent)) { - ptr->PushRenderTargetAndViewport(mat_fullframe); - g_IVRenderView->SetColorModulation(GlowColor(ent)); - g_IVModelRender->ForcedMaterialOverride(mat_glow); - DrawEntity(ent); - ptr->PopRenderTargetAndViewport(); - - g_IVRenderView->SetBlend(0.0f); - g_IVModelRender->ForcedMaterialOverride(mat_unlit_z); - DrawEntity(ent); - g_IVRenderView->SetBlend(1.0f); + RenderGlow(ent); } } - drawing = false; - - SS_Last.SetStencilState(ptr); - - g_IVModelRender->ForcedMaterialOverride(NULL); - - ptr->DepthRange(0.0f, 1.0f); - ptr->DrawScreenSpaceRectangle(mat_halo, x, y, w, h, 0, 0, w, h, w, h); - ptr->SetStencilEnable(false); + EndRenderGlow(); + if (*solid_when != 1) + { + ptr->ClearStencilBufferRectangle(x, y, w, h, 0); + StartStenciling(); + for (int i = 1; i < HIGHEST_ENTITY; i++) + { + ent = g_IEntityList->GetClientEntity(i); + if (ent && !ent->IsDormant() && ShouldRenderGlow(ent)) + { + DrawToStencil(ent); + } + } + EndStenciling(); + } + ptr->SetRenderTarget(GetBuffer(2)); + ptr->Viewport(x, y, w, h); + ptr->ClearBuffers(true, false); + ptr->DrawScreenSpaceRectangle(mat_blur_x, x, y, w, h, 0, 0, w - 1, h - 1, w, h); + ptr->SetRenderTarget(GetBuffer(1)); + blury_bloomamount = mat_blur_y->FindVar("$bloomamount", nullptr); + blury_bloomamount->SetIntValue((int) blur_scale); + ptr->DrawScreenSpaceRectangle(mat_blur_y, x, y, w, h, 0, 0, w - 1, h - 1, w, h); + ptr->Viewport(x, y, w, h); + ptr->SetRenderTarget(orig); + g_IVRenderView->SetBlend(0.0f); + if (*solid_when != 1) + { + SS_Drawing.SetStencilState(ptr); + } + ptr->DrawScreenSpaceRectangle(mat_blit, x, y, w, h, 0, 0, w - 1, h - 1, w, h); + if (*solid_when != -1) + { + SS_Null.SetStencilState(ptr); + } } EffectGlow g_EffectGlow;