Make MSAA setting work on editor SceneRenderingWidgets (#3539)

* Make MSAA setting work on editor SceneRenderingWidgets

MSAA settings never worked with editor viewport, only on game tab, now with playmode it always takes highest MSAA value from hardware regardless of what

Two things from this PR:
* Pass current engine MSAA setting when creating SceneRenderingWidget swapchain
* Add callback when video settings are changed, recreate swapchain when so

Replicates fine for all SceneRenderingWidgets, applies instantly

https://files.facepunch.com/sampavlovic/1b0311b1/sbox-dev_bjEMrrYe71.mp4

* Push RenderMultisampleType_t nMSAAAmount on interop
This commit is contained in:
Sam Pavlovic
2025-12-03 16:41:38 -03:00
committed by GitHub
parent 9551e9844e
commit ab81dd2357
3 changed files with 30 additions and 3 deletions

View File

@@ -17,7 +17,7 @@ native static class WidgetUtil Native.WidgetUtil
static void PostKeyEvent( QWidget target, int key );
static void PaintSetFont( QPainter painter, string fontName, int size, int weight, bool italic, bool heightInPixels );
static SwapChainHandle_t CreateSwapChain( QWidget target );
static SwapChainHandle_t CreateSwapChain( QWidget target, RenderMultisampleType_t nMSAAAmount );
static void SetWindowNoActivate( QWidget widget );

View File

@@ -1,4 +1,6 @@
using NativeEngine;
using System;
using NativeEngine;
namespace Sandbox.Engine.Settings;
@@ -11,6 +13,7 @@ public partial class RenderSettings
internal CookieContainer VideoSettings { get; } = new( "video", true );
public event Action OnVideoSettingsChanged;
internal RenderQualityProfiles Config { get; } = new();
internal RenderSettings()
@@ -100,6 +103,8 @@ public partial class RenderSettings
{
ApplyVideoMode();
OnVideoSettingsChanged?.Invoke();
VideoSettings.Save();
}

View File

@@ -1,5 +1,7 @@
using System;
using Sandbox.Engine.Settings;
namespace Editor;
/// <summary>
@@ -35,7 +37,8 @@ public class SceneRenderingWidget : Frame
SetFlag( Flag.WA_NoSystemBackground, true );
SetFlag( Flag.WA_OpaquePaintEvent, true );
SwapChain = WidgetUtil.CreateSwapChain( _widget );
SwapChain = WidgetUtil.CreateSwapChain( _widget, RenderSettings.Instance.AntiAliasQuality.ToEngine() );
RenderSettings.Instance.OnVideoSettingsChanged += HandleVideoChanged;
FocusMode = FocusMode.Click; // If we're focused we're probably accepting input, don't let tab blur us
@@ -47,6 +50,7 @@ public class SceneRenderingWidget : Frame
base.NativeShutdown();
All.Remove( this );
RenderSettings.Instance.OnVideoSettingsChanged -= HandleVideoChanged;
// The swapchain might still be in use by native, so defer its destruction until the end of the frame.
// Otherwise, a race condition could occur where render targets are accessed after destruction, causing a delayed crash.
@@ -126,6 +130,8 @@ public class SceneRenderingWidget : Frame
if ( !Scene.IsValid() ) return;
if ( !Visible ) return;
if ( SwapChain == default ) return;
using ( Scene.Push() )
{
using ( GizmoInstance.Push() )
@@ -199,6 +205,22 @@ public class SceneRenderingWidget : Frame
return camera.GetRay( localPosition, Size );
}
internal void HandleVideoChanged()
{
var oldSwapChain = SwapChain;
SwapChain = WidgetUtil.CreateSwapChain( _widget, RenderSettings.Instance.AntiAliasQuality.ToEngine() );
if ( SwapChain == default )
{
SwapChain = oldSwapChain;
return;
}
if ( oldSwapChain != default )
{
EngineLoop.DisposeAtFrameEnd( new Sandbox.Utility.DisposeAction( () => g_pRenderDevice.DestroySwapChain( oldSwapChain ) ) );
}
}
internal static void RenderAll()
{
foreach ( var widget in All )