diff --git a/src/EffectGlow.cpp b/src/EffectGlow.cpp index ab3cc11b..559f309b 100644 --- a/src/EffectGlow.cpp +++ b/src/EffectGlow.cpp @@ -35,31 +35,145 @@ static CatVar buildings(CV_SWITCH, "glow_buildings", "0", "Buildings"); static CatVar stickies(CV_SWITCH, "glow_stickies", "0", "Stickies"); static CatVar teammate_buildings(CV_SWITCH, "glow_teammate_buildings", "0", "Teammate Buildings"); + +struct ShaderStencilState_t +{ + bool m_bEnable; + StencilOperation_t m_FailOp; + StencilOperation_t m_ZFailOp; + StencilOperation_t m_PassOp; + StencilComparisonFunction_t m_CompareFunc; + int m_nReferenceValue; + uint32 m_nTestMask; + uint32 m_nWriteMask; + + ShaderStencilState_t() { + m_bEnable = false; + m_PassOp = m_FailOp = m_ZFailOp = STENCILOPERATION_KEEP; + m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS; + m_nReferenceValue = 0; + m_nTestMask = m_nWriteMask = 0xFFFFFFFF; + } + + void SetStencilState(CMatRenderContextPtr &pRenderContext) const { + 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 ); + } +}; + +static CTextureReference buffers[4] {}; + +ITexture* GetBuffer(int i) { + if (!buffers[i]) { + ITexture* fullframe = g_IMaterialSystem->FindTexture("_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET); + char* newname = new char[32]; + std::string name = format("_cathook_buff", i); + strncpy(newname, name.c_str(), 30); + logging::Info("Creating new buffer %d with size %dx%d %s", i, fullframe->GetActualWidth(), fullframe->GetActualHeight(), newname); + + int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_EIGHTBITALPHA; + int renderTargetFlags = CREATERENDERTARGETFLAGS_HDR; + + ITexture* texture = g_IMaterialSystem->CreateNamedRenderTargetTextureEx( newname, 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 {}; + void EffectGlow::Init() { - logging::Info("Init EffectChams..."); + logging::Info("Init Glow..."); { KeyValues* kv = new KeyValues("UnlitGeneric"); kv->SetString("$basetexture", "vgui/white_additive"); kv->SetInt("$ignorez", 0); - mat_unlit.Init("__cathook_echams_unlit", kv); + mat_unlit.Init("__cathook_glow_unlit", kv); } { KeyValues* kv = new KeyValues("UnlitGeneric"); kv->SetString("$basetexture", "vgui/white_additive"); kv->SetInt("$ignorez", 1); - mat_unlit_z.Init("__cathook_echams_unlit_z", kv); + mat_unlit_z.Init("__cathook_glow_unlit_z", kv); } + // Initialize 2 buffers + GetBuffer(1); + GetBuffer(2); + { + 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(); + } + { + 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; } -int EffectGlow::ChamsColor(IClientEntity* entity) { +int EffectGlow::GlowColor(IClientEntity* entity) { CachedEntity* ent = ENTITY(entity->entindex()); if (CE_BAD(ent)) return colors::white; if (vfunc(entity, 0xBE, 0)(entity)) { IClientEntity* owner = vfunc(entity, 0x1C3, 0)(entity); if (owner) { - return ChamsColor(owner); + return GlowColor(owner); } } switch (ent->m_Type) { @@ -82,7 +196,7 @@ int EffectGlow::ChamsColor(IClientEntity* entity) { return colors::EntityF(ent); } -bool EffectGlow::ShouldRenderChams(IClientEntity* entity) { +bool EffectGlow::ShouldRenderGlow(IClientEntity* entity) { if (!enable) return false; if (entity->entindex() < 0) return false; CachedEntity* ent = ENTITY(entity->entindex()); @@ -126,107 +240,24 @@ bool EffectGlow::ShouldRenderChams(IClientEntity* entity) { return false; } -struct ShaderStencilState_t -{ - bool m_bEnable; - StencilOperation_t m_FailOp; - StencilOperation_t m_ZFailOp; - StencilOperation_t m_PassOp; - StencilComparisonFunction_t m_CompareFunc; - int m_nReferenceValue; - uint32 m_nTestMask; - uint32 m_nWriteMask; - - ShaderStencilState_t() - { - m_bEnable = false; - m_PassOp = m_FailOp = m_ZFailOp = STENCILOPERATION_KEEP; - m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS; - m_nReferenceValue = 0; - m_nTestMask = m_nWriteMask = 0xFFFFFFFF; - } - - 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 ); - } -}; - -static CTextureReference buffers[4] {}; - -ITexture* GetBuffer(int i) { - if (!buffers[i]) { - ITexture* fullframe = g_IMaterialSystem->FindTexture("_rt_FullFrameFB", TEXTURE_GROUP_RENDER_TARGET); - char* newname = new char[32]; - std::string name = format("_cathook_buff", i); - strncpy(newname, name.c_str(), 30); - logging::Info("Creating new buffer %d with size %dx%d %s", i, fullframe->GetActualWidth(), fullframe->GetActualHeight(), newname); - - int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_EIGHTBITALPHA; - int renderTargetFlags = CREATERENDERTARGETFLAGS_HDR; - - ITexture* texture = g_IMaterialSystem->CreateNamedRenderTargetTextureEx( newname, fullframe->GetActualWidth(), fullframe->GetActualHeight(), RT_SIZE_LITERAL, IMAGE_FORMAT_RGBA8888, - MATERIAL_RT_DEPTH_SEPARATE, textureFlags, renderTargetFlags ); - buffers[i].Init(texture); - //buffers[i].InitRenderTarget(fullframe->GetActualWidth(), fullframe->GetActualHeight(), RenderTargetSizeMode_t::RT_SIZE_FULL_FRAME_BUFFER, IMAGE_FORMAT_ABGR8888, MaterialRenderTargetDepth_t::MATERIAL_RT_DEPTH_SEPARATE, true, newname); - } - return buffers[i]; -} - -IMaterial* GetBlurX() { - static CMaterialReference blur; - if (!blur) { - GetBuffer(1); - KeyValues* kv = new KeyValues("BlurFilterX"); - kv->SetString("$basetexture", "_cathook_buff1"); - kv->SetInt("$ignorez", 1); - kv->SetInt("$translucent", 1); - kv->SetInt("$alphatest", 1); - blur.Init("_cathook_blurx", kv); - blur->Refresh(); - } - return blur; -} - -IMaterial* GetBlurY() { - static CMaterialReference blur; - if (!blur) { - GetBuffer(2); - 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); - blur.Init("_cathook_blury", kv); - blur->Refresh(); - } - return blur; -} - - -void EffectGlow::BeginRenderChams() { +void EffectGlow::BeginRenderGlow() { drawing = true; CMatRenderContextPtr ptr(vfunc(g_IMaterialSystem, 100, 0)(g_IMaterialSystem)); ptr->ClearColor4ub(0, 0, 0, 0); ptr->PushRenderTargetAndViewport(); ptr->SetRenderTarget(GetBuffer(1)); - //ptr->Viewport(x, y, w, h); 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); + g_IVModelRender->ForcedMaterialOverride(mat_unlit_z); } -void EffectGlow::EndRenderChams() { +void EffectGlow::EndRenderGlow() { drawing = false; CMatRenderContextPtr ptr(vfunc(g_IMaterialSystem, 100, 0)(g_IMaterialSystem)); + ptr->DepthRange(0.0f, 1.0f); g_IVModelRender->ForcedMaterialOverride(nullptr); ptr->PopRenderTargetAndViewport(); } @@ -239,27 +270,16 @@ static CatVar solid_when(solid_when_enum, "glow_solid_when", "0", "Solid when", void EffectGlow::StartStenciling() { ShaderStencilState_t state; state.m_bEnable = true; + CMatRenderContextPtr ptr(g_IMaterialSystem->GetRenderContext()); switch ((int)solid_when) { case 0: - state.m_PassOp = STENCILOPERATION_REPLACE; - state.m_FailOp = STENCILOPERATION_KEEP; - state.m_ZFailOp = STENCILOPERATION_KEEP; + SS_NeverSolid.SetStencilState(ptr); break; case 2: - state.m_PassOp = STENCILOPERATION_REPLACE; - state.m_FailOp = STENCILOPERATION_KEEP; - state.m_ZFailOp = STENCILOPERATION_KEEP; + SS_SolidInvisible.SetStencilState(ptr); break; - /*case 3: https://puu.sh/vobH4/5da8367aef.png - state.m_PassOp = STENCILOPERATION_KEEP; - state.m_FailOp = STENCILOPERATION_KEEP; - state.m_ZFailOp = STENCILOPERATION_REPLACE;*/ + /*case 3: https://puu.sh/vobH4/5da8367aef.png*/ } - state.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS; - state.m_nWriteMask = 1; - state.m_nReferenceValue = 1; - CMatRenderContextPtr ptr(g_IMaterialSystem->GetRenderContext()); - state.SetStencilState(ptr); if (!solid_when) { ptr->DepthRange(0.0f, 0.01f); } else { @@ -298,18 +318,14 @@ void EffectGlow::DrawEntity(IClientEntity* entity) { } } -void EffectGlow::RenderChams(IClientEntity* entity) { +void EffectGlow::RenderGlow(IClientEntity* entity) { CMatRenderContextPtr ptr(g_IMaterialSystem->GetRenderContext()); - int color = ChamsColor(entity); + int color = GlowColor(entity); unsigned char _b = (color >> 16) & 0xFF; unsigned char _g = (color >> 8) & 0xFF; unsigned char _r = (color) & 0xFF; float color_1[] = { (float)_r / 255.0f, (float)_g / 255.0f, (float)_b / 255.0f }; - float color_2[] = { color_1[0] * 0.6f, color_1[1] * 0.6f, color_1[2] * 0.6f }; - mat_unlit_z->AlphaModulate(1.0f); - ptr->DepthRange(0.0f, 0.01f); g_IVRenderView->SetColorModulation(color_1); - g_IVModelRender->ForcedMaterialOverride(mat_unlit_z); DrawEntity(entity); } @@ -319,20 +335,20 @@ void EffectGlow::Render(int x, int y, int w, int h) { if (!enable) return; CMatRenderContextPtr ptr(g_IMaterialSystem->GetRenderContext()); ITexture* orig = ptr->GetRenderTarget(); - BeginRenderChams(); + BeginRenderGlow(); for (int i = 1; i < HIGHEST_ENTITY; i++) { IClientEntity* ent = g_IEntityList->GetClientEntity(i); - if (ent && !ent->IsDormant() && ShouldRenderChams(ent)) { - RenderChams(ent); + if (ent && !ent->IsDormant() && ShouldRenderGlow(ent)) { + RenderGlow(ent); } } - EndRenderChams(); + EndRenderGlow(); if ((int)solid_when != 1) { ptr->ClearStencilBufferRectangle(x, y, w, h, 0); StartStenciling(); for (int i = 1; i < HIGHEST_ENTITY; i++) { IClientEntity* ent = g_IEntityList->GetClientEntity(i); - if (ent && !ent->IsDormant() && ShouldRenderChams(ent)) { + if (ent && !ent->IsDormant() && ShouldRenderGlow(ent)) { DrawToStencil(ent); } } @@ -341,36 +357,20 @@ void EffectGlow::Render(int x, int y, int w, int h) { ptr->SetRenderTarget(GetBuffer(2)); ptr->Viewport(x, y, w, h); ptr->ClearBuffers(true, false); - ptr->DrawScreenSpaceRectangle(GetBlurX(), x, y, w, h, 0, 0, w - 1, h - 1, w, h); - static CMaterialReference blitmat; - if (!blitmat) { - KeyValues *kv = new KeyValues( "UnlitGeneric" ); - kv->SetString( "$basetexture", "_cathook_buff1" ); - kv->SetInt( "$additive", 1 ); - blitmat.Init( "_cathook_composite", TEXTURE_GROUP_CLIENT_EFFECTS, kv ); - blitmat->Refresh(); - } + ptr->DrawScreenSpaceRectangle(mat_blur_x, x, y, w, h, 0, 0, w - 1, h - 1, w, h); ptr->SetRenderTarget(GetBuffer(1)); - IMaterial* blury = GetBlurY(); - static IMaterialVar* blury_bloomamount = blury->FindVar("$bloomamount", nullptr); + static IMaterialVar* blury_bloomamount = mat_blur_y->FindVar("$bloomamount", nullptr); blury_bloomamount->SetIntValue((int)blur_scale); - ptr->DrawScreenSpaceRectangle(GetBlurY(), x, y, w, h, 0, 0, w - 1, h - 1, w, h); + 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 ((int)solid_when != 1) { - ShaderStencilState_t state {}; - state.m_bEnable = true; - state.m_nReferenceValue = 0; - state.m_nTestMask = 1; - state.m_CompareFunc = STENCILCOMPARISONFUNCTION_EQUAL; - state.m_PassOp = STENCILOPERATION_ZERO; - state.SetStencilState(ptr); + SS_Drawing.SetStencilState(ptr); } - ptr->DrawScreenSpaceRectangle(blitmat, x, y, w, h, 0, 0, w - 1, h - 1, w, h); + ptr->DrawScreenSpaceRectangle(mat_blit, x, y, w, h, 0, 0, w - 1, h - 1, w, h); if ((int)solid_when != -1) { - static ShaderStencilState_t zeroStencil {}; - zeroStencil.SetStencilState(ptr); + SS_Null.SetStencilState(ptr); } } diff --git a/src/EffectGlow.hpp b/src/EffectGlow.hpp index fca05613..fa8ec3ae 100644 --- a/src/EffectGlow.hpp +++ b/src/EffectGlow.hpp @@ -29,16 +29,19 @@ public: void DrawEntity(IClientEntity* entity); void DrawToStencil(IClientEntity* entity); void DrawToBuffer(IClientEntity* entity); - int ChamsColor(IClientEntity* entity); - bool ShouldRenderChams(IClientEntity* entity); - void RenderChams(IClientEntity* entity); - void BeginRenderChams(); - void EndRenderChams(); + int 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; }; diff --git a/src/hack.cpp b/src/hack.cpp index 9839a79a..94bde264 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -191,7 +191,6 @@ void hack::Initialize() { // logging::Info("%s", reg->m_pEffectName); //} g_pScreenSpaceEffects->EnableScreenSpaceEffect("_cathook_glow"); - effect_glow::g_EffectGlow.Init(); logging::Info("SSE enabled.."); }