From 688c91b5979704a2a4feaf1b25f3450c3fd99aa9 Mon Sep 17 00:00:00 2001 From: Pok <113675512+Pok27@users.noreply.github.com> Date: Sun, 27 Jul 2025 20:26:17 +0300 Subject: [PATCH] Add scaling filter option (Nearest/Bilinear) (#39111) --- Content.Client/Options/UI/Tabs/GraphicsTab.xaml | 1 + Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs | 10 ++++++++++ Content.Client/UserInterface/Controls/MainViewport.cs | 9 ++++++++- Content.Shared/CCVar/CCVars.Viewport.cs | 3 +++ Resources/Locale/en-US/escape-menu/ui/options-menu.ftl | 3 +++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml index 29279d1733..f764d18b47 100644 --- a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml +++ b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml @@ -25,6 +25,7 @@ + diff --git a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs index efd788c58a..c9c7300155 100644 --- a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs @@ -39,6 +39,14 @@ public sealed partial class GraphicsTab : Control new OptionDropDownCVar.ValueOption(2.00f, Loc.GetString("ui-options-scale-200")), ]); + Control.AddOptionDropDown( + CCVars.ViewportScalingFilterMode, + DropDownFilterMode, + [ + new OptionDropDownCVar.ValueOption("nearest", Loc.GetString("ui-options-filter-nearest")), + new OptionDropDownCVar.ValueOption("bilinear", Loc.GetString("ui-options-filter-bilinear")), + ]); + var vpStretch = Control.AddOptionCheckBox(CCVars.ViewportStretch, ViewportStretchCheckBox); var vpVertFit = Control.AddOptionCheckBox(CCVars.ViewportVerticalFit, ViewportVerticalFitCheckBox); Control.AddOptionSlider( @@ -50,6 +58,7 @@ public sealed partial class GraphicsTab : Control vpStretch.ImmediateValueChanged += _ => UpdateViewportSettingsVisibility(); vpVertFit.ImmediateValueChanged += _ => UpdateViewportSettingsVisibility(); + IntegerScalingCheckBox.OnToggled += _ => UpdateViewportSettingsVisibility(); Control.AddOptionSlider( CCVars.ViewportWidth, @@ -77,6 +86,7 @@ public sealed partial class GraphicsTab : Control IntegerScalingCheckBox.Visible = ViewportStretchCheckBox.Pressed; ViewportVerticalFitCheckBox.Visible = ViewportStretchCheckBox.Pressed; ViewportWidthSlider.Visible = !ViewportStretchCheckBox.Pressed || !ViewportVerticalFitCheckBox.Pressed; + DropDownFilterMode.Visible = !IntegerScalingCheckBox.Pressed && ViewportStretchCheckBox.Pressed; } private void UpdateViewportWidthRange() diff --git a/Content.Client/UserInterface/Controls/MainViewport.cs b/Content.Client/UserInterface/Controls/MainViewport.cs index 721d750115..0e947da7cf 100644 --- a/Content.Client/UserInterface/Controls/MainViewport.cs +++ b/Content.Client/UserInterface/Controls/MainViewport.cs @@ -30,6 +30,8 @@ namespace Content.Client.UserInterface.Controls }; AddChild(Viewport); + + _cfg.OnValueChanged(CCVars.ViewportScalingFilterMode, _ => UpdateCfg(), true); } protected override void EnteredTree() @@ -52,6 +54,7 @@ namespace Content.Client.UserInterface.Controls var renderScaleUp = _cfg.GetCVar(CCVars.ViewportScaleRender); var fixedFactor = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor); var verticalFit = _cfg.GetCVar(CCVars.ViewportVerticalFit); + var filterMode = _cfg.GetCVar(CCVars.ViewportScalingFilterMode); if (stretch) { @@ -60,7 +63,11 @@ namespace Content.Client.UserInterface.Controls { // Did not find a snap, enable stretching. Viewport.FixedStretchSize = null; - Viewport.StretchMode = ScalingViewportStretchMode.Bilinear; + Viewport.StretchMode = filterMode switch + { + "nearest" => ScalingViewportStretchMode.Nearest, + "bilinear" => ScalingViewportStretchMode.Bilinear + }; Viewport.IgnoreDimension = verticalFit ? ScalingViewportIgnoreDimension.Horizontal : ScalingViewportIgnoreDimension.None; if (renderScaleUp) diff --git a/Content.Shared/CCVar/CCVars.Viewport.cs b/Content.Shared/CCVar/CCVars.Viewport.cs index d94394d2a7..74d462f3ce 100644 --- a/Content.Shared/CCVar/CCVars.Viewport.cs +++ b/Content.Shared/CCVar/CCVars.Viewport.cs @@ -30,4 +30,7 @@ public sealed partial class CCVars public static readonly CVarDef ViewportVerticalFit = CVarDef.Create("viewport.vertical_fit", true, CVar.CLIENTONLY | CVar.ARCHIVE); + + public static readonly CVarDef ViewportScalingFilterMode = + CVarDef.Create("viewport.scaling_filter", "nearest", CVar.CLIENTONLY | CVar.ARCHIVE); } diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index f2142efaa2..c7773a54cd 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -92,6 +92,9 @@ ui-options-vp-integer-scaling-tooltip = If this option is enabled, the viewport at specific resolutions. While this results in crisp textures, it also often means that black bars appear at the top/bottom of the screen or that part of the viewport is not visible. +ui-options-filter-label = Scaling filter: +ui-options-filter-nearest = Nearest (no smoothing) +ui-options-filter-bilinear = Bilinear (smoothed) ui-options-vp-vertical-fit = Vertical viewport fitting ui-options-vp-vertical-fit-tooltip = When enabled, the main viewport will ignore the horizontal axis entirely when fitting to your screen. If your screen is smaller than the viewport, then this