mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 21:38:38 +00:00
Core - Simplified and improved render scaling
This commit is contained in:
parent
18359c443f
commit
186d012087
@ -1,5 +1,6 @@
|
||||
using System.Text;
|
||||
using RGB.NET.Core;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
@ -20,4 +21,17 @@ namespace Artemis.Core
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
internal static class RgbRectangleExtensions
|
||||
{
|
||||
public static SKRect ToSKRect(this Rectangle rectangle)
|
||||
{
|
||||
return SKRect.Create(
|
||||
(float) rectangle.Location.X,
|
||||
(float) rectangle.Location.Y,
|
||||
(float) rectangle.Size.Width,
|
||||
(float) rectangle.Size.Height
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -417,7 +417,7 @@ namespace Artemis.Core
|
||||
{
|
||||
SKPath path = new SKPath {FillType = SKPathFillType.Winding};
|
||||
foreach (ArtemisLed artemisLed in Leds)
|
||||
path.AddRect(artemisLed.AbsoluteRenderRectangle);
|
||||
path.AddRect(artemisLed.AbsoluteRectangle);
|
||||
|
||||
Path = path;
|
||||
}
|
||||
|
||||
@ -14,8 +14,8 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class ArtemisDevice : CorePropertyChanged
|
||||
{
|
||||
private SKPath? _renderPath;
|
||||
private SKRect _renderRectangle;
|
||||
private SKPath? _path;
|
||||
private SKRect _rectangle;
|
||||
|
||||
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, ArtemisSurface surface)
|
||||
{
|
||||
@ -58,21 +58,21 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rectangle covering the device, sized to match the render scale
|
||||
/// Gets the rectangle covering the device
|
||||
/// </summary>
|
||||
public SKRect RenderRectangle
|
||||
public SKRect Rectangle
|
||||
{
|
||||
get => _renderRectangle;
|
||||
private set => SetAndNotify(ref _renderRectangle, value);
|
||||
get => _rectangle;
|
||||
private set => SetAndNotify(ref _rectangle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path surrounding the device, sized to match the render scale
|
||||
/// Gets the path surrounding the device
|
||||
/// </summary>
|
||||
public SKPath? RenderPath
|
||||
public SKPath? Path
|
||||
{
|
||||
get => _renderPath;
|
||||
private set => SetAndNotify(ref _renderPath, value);
|
||||
get => _path;
|
||||
private set => SetAndNotify(ref _path, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -239,24 +239,18 @@ namespace Artemis.Core
|
||||
|
||||
internal void CalculateRenderProperties()
|
||||
{
|
||||
RenderRectangle = SKRect.Create(
|
||||
(RgbDevice.Location.X * Surface.Scale).RoundToInt(),
|
||||
(RgbDevice.Location.Y * Surface.Scale).RoundToInt(),
|
||||
(RgbDevice.DeviceRectangle.Size.Width * Surface.Scale).RoundToInt(),
|
||||
(RgbDevice.DeviceRectangle.Size.Height * Surface.Scale).RoundToInt()
|
||||
);
|
||||
|
||||
Rectangle = RgbDevice.DeviceRectangle.ToSKRect();
|
||||
if (!Leds.Any())
|
||||
return;
|
||||
|
||||
foreach (ArtemisLed led in Leds)
|
||||
led.CalculateRenderRectangle();
|
||||
led.CalculateRectangles();
|
||||
|
||||
SKPath path = new SKPath {FillType = SKPathFillType.Winding};
|
||||
foreach (ArtemisLed artemisLed in Leds)
|
||||
path.AddRect(artemisLed.AbsoluteRenderRectangle);
|
||||
path.AddRect(artemisLed.AbsoluteRectangle);
|
||||
|
||||
RenderPath = path;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
@ -8,14 +8,14 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class ArtemisLed : CorePropertyChanged
|
||||
{
|
||||
private SKRect _absoluteRenderRectangle;
|
||||
private SKRect _renderRectangle;
|
||||
private SKRect _absoluteRectangle;
|
||||
private SKRect _rectangle;
|
||||
|
||||
internal ArtemisLed(Led led, ArtemisDevice device)
|
||||
{
|
||||
RgbLed = led;
|
||||
Device = device;
|
||||
CalculateRenderRectangle();
|
||||
CalculateRectangles();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -29,38 +29,27 @@ namespace Artemis.Core
|
||||
public ArtemisDevice Device { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rectangle covering the LED, sized to match the render scale and positioned relative to the
|
||||
/// <see cref="Device" />
|
||||
/// Gets the rectangle covering the LED positioned relative to the<see cref="Device" />
|
||||
/// </summary>
|
||||
public SKRect RenderRectangle
|
||||
public SKRect Rectangle
|
||||
{
|
||||
get => _renderRectangle;
|
||||
private set => SetAndNotify(ref _renderRectangle, value);
|
||||
get => _rectangle;
|
||||
private set => SetAndNotify(ref _rectangle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rectangle covering the LED, sized to match the render scale
|
||||
/// Gets the rectangle covering the LED
|
||||
/// </summary>
|
||||
public SKRect AbsoluteRenderRectangle
|
||||
public SKRect AbsoluteRectangle
|
||||
{
|
||||
get => _absoluteRenderRectangle;
|
||||
private set => SetAndNotify(ref _absoluteRenderRectangle, value);
|
||||
get => _absoluteRectangle;
|
||||
private set => SetAndNotify(ref _absoluteRectangle, value);
|
||||
}
|
||||
|
||||
internal void CalculateRenderRectangle()
|
||||
internal void CalculateRectangles()
|
||||
{
|
||||
RenderRectangle = SKRect.Create(
|
||||
(RgbLed.LedRectangle.Location.X * Device.Surface.Scale).RoundToInt(),
|
||||
(RgbLed.LedRectangle.Location.Y * Device.Surface.Scale).RoundToInt(),
|
||||
(RgbLed.LedRectangle.Size.Width * Device.Surface.Scale).RoundToInt(),
|
||||
(RgbLed.LedRectangle.Size.Height * Device.Surface.Scale).RoundToInt()
|
||||
);
|
||||
AbsoluteRenderRectangle = SKRect.Create(
|
||||
(RgbLed.AbsoluteLedRectangle.Location.X * Device.Surface.Scale).RoundToInt(),
|
||||
(RgbLed.AbsoluteLedRectangle.Location.Y * Device.Surface.Scale).RoundToInt(),
|
||||
(RgbLed.AbsoluteLedRectangle.Size.Width * Device.Surface.Scale).RoundToInt(),
|
||||
(RgbLed.AbsoluteLedRectangle.Size.Height * Device.Surface.Scale).RoundToInt()
|
||||
);
|
||||
Rectangle = RgbLed.LedRectangle.ToSKRect();
|
||||
AbsoluteRectangle = RgbLed.AbsoluteLedRectangle.ToSKRect();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@ -16,28 +16,25 @@ namespace Artemis.Core
|
||||
private ReadOnlyDictionary<Led, ArtemisLed> _ledMap = new ReadOnlyDictionary<Led, ArtemisLed>(new Dictionary<Led, ArtemisLed>());
|
||||
private bool _isActive;
|
||||
private string _name;
|
||||
private double _scale;
|
||||
|
||||
internal ArtemisSurface(RGBSurface rgbSurface, string name, double scale)
|
||||
internal ArtemisSurface(RGBSurface rgbSurface, string name)
|
||||
{
|
||||
SurfaceEntity = new SurfaceEntity {DeviceEntities = new List<DeviceEntity>()};
|
||||
EntityId = Guid.NewGuid();
|
||||
RgbSurface = rgbSurface;
|
||||
|
||||
_name = name;
|
||||
_scale = scale;
|
||||
_isActive = false;
|
||||
|
||||
ApplyToEntity();
|
||||
}
|
||||
|
||||
internal ArtemisSurface(RGBSurface rgbSurface, SurfaceEntity surfaceEntity, double scale)
|
||||
internal ArtemisSurface(RGBSurface rgbSurface, SurfaceEntity surfaceEntity)
|
||||
{
|
||||
SurfaceEntity = surfaceEntity;
|
||||
EntityId = surfaceEntity.Id;
|
||||
RgbSurface = rgbSurface;
|
||||
|
||||
_scale = scale;
|
||||
_name = surfaceEntity.Name;
|
||||
_isActive = surfaceEntity.IsActive;
|
||||
}
|
||||
@ -47,15 +44,6 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public RGBSurface RgbSurface { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale at which this surface is rendered
|
||||
/// </summary>
|
||||
public double Scale
|
||||
{
|
||||
get => _scale;
|
||||
private set => SetAndNotify(ref _scale, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the surface
|
||||
/// </summary>
|
||||
@ -96,19 +84,6 @@ namespace Artemis.Core
|
||||
internal SurfaceEntity SurfaceEntity { get; set; }
|
||||
internal Guid EntityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates the scale of the surface
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void UpdateScale(double value)
|
||||
{
|
||||
Scale = value;
|
||||
foreach (ArtemisDevice device in Devices)
|
||||
device.CalculateRenderProperties();
|
||||
|
||||
OnScaleChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the <see cref="ArtemisLed" /> that corresponds the provided RGB.NET <see cref="Led" />
|
||||
/// </summary>
|
||||
|
||||
@ -41,7 +41,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
pointsPath.AddPoly(new[]
|
||||
{
|
||||
new SKPoint(0, 0),
|
||||
new SKPoint(artemisLed.AbsoluteRenderRectangle.Left - Layer.Bounds.Left, artemisLed.AbsoluteRenderRectangle.Top - Layer.Bounds.Top)
|
||||
new SKPoint(artemisLed.AbsoluteRectangle.Left - Layer.Bounds.Left, artemisLed.AbsoluteRectangle.Top - Layer.Bounds.Top)
|
||||
});
|
||||
}
|
||||
|
||||
@ -61,10 +61,10 @@ namespace Artemis.Core.LayerBrushes
|
||||
ledPaint.Color = GetColor(artemisLed, renderPoint);
|
||||
|
||||
SKRect ledRectangle = SKRect.Create(
|
||||
artemisLed.AbsoluteRenderRectangle.Left - Layer.Bounds.Left,
|
||||
artemisLed.AbsoluteRenderRectangle.Top - Layer.Bounds.Top,
|
||||
artemisLed.AbsoluteRenderRectangle.Width,
|
||||
artemisLed.AbsoluteRenderRectangle.Height
|
||||
artemisLed.AbsoluteRectangle.Left - Layer.Bounds.Left,
|
||||
artemisLed.AbsoluteRectangle.Top - Layer.Bounds.Top,
|
||||
artemisLed.AbsoluteRectangle.Width,
|
||||
artemisLed.AbsoluteRectangle.Height
|
||||
);
|
||||
|
||||
canvas.DrawRect(ledRectangle, ledPaint);
|
||||
|
||||
@ -27,13 +27,14 @@ namespace Artemis.Core.Services
|
||||
private readonly Stopwatch _frameStopWatch;
|
||||
private readonly ILogger _logger;
|
||||
private readonly PluginSetting<LogEventLevel> _loggingLevel;
|
||||
private readonly PluginSetting<double> _renderScale;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly IProfileService _profileService;
|
||||
private readonly IRgbService _rgbService;
|
||||
private readonly ISurfaceService _surfaceService;
|
||||
private List<BaseDataModelExpansion> _dataModelExpansions = new List<BaseDataModelExpansion>();
|
||||
private List<Module> _modules = new List<Module>();
|
||||
|
||||
|
||||
// ReSharper disable UnusedParameter.Local - Storage migration and module service are injected early to ensure it runs before anything else
|
||||
public CoreService(IKernel kernel, ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginManagementService pluginManagementService,
|
||||
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
|
||||
@ -47,6 +48,7 @@ namespace Artemis.Core.Services
|
||||
_surfaceService = surfaceService;
|
||||
_profileService = profileService;
|
||||
_loggingLevel = settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Debug);
|
||||
_renderScale = settingsService.GetSetting("Core.RenderScale", 0.5);
|
||||
_frameStopWatch = new Stopwatch();
|
||||
|
||||
UpdatePluginCache();
|
||||
@ -185,6 +187,7 @@ namespace Artemis.Core.Services
|
||||
|
||||
// Render all active modules
|
||||
using SKCanvas canvas = new SKCanvas(_rgbService.BitmapBrush.Bitmap);
|
||||
canvas.Scale((float) _renderScale.Value);
|
||||
canvas.Clear(new SKColor(0, 0, 0));
|
||||
if (!ModuleRenderingDisabled)
|
||||
// While non-activated modules may be updated above if they expand the main data model, they may never render
|
||||
|
||||
@ -17,6 +17,8 @@ namespace Artemis.Core.Services.Models
|
||||
MarginTop = margin;
|
||||
MarginRight = margin;
|
||||
MarginBottom = margin;
|
||||
|
||||
SurfaceArrangement = null!;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -15,26 +15,23 @@ namespace Artemis.Core.Services
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly PluginSetting<double> _renderScaleSetting;
|
||||
private readonly IRgbService _rgbService;
|
||||
private readonly List<ArtemisSurface> _surfaceConfigurations;
|
||||
private readonly ISurfaceRepository _surfaceRepository;
|
||||
|
||||
public SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, IPluginManagementService pluginManagementService, ISettingsService settingsService)
|
||||
public SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, IPluginManagementService pluginManagementService)
|
||||
{
|
||||
_logger = logger;
|
||||
_surfaceRepository = surfaceRepository;
|
||||
_rgbService = rgbService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_surfaceConfigurations = new List<ArtemisSurface>();
|
||||
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
|
||||
|
||||
// LoadFromRepository is guaranteed to set the ActiveSurface
|
||||
ActiveSurface = null!;
|
||||
LoadFromRepository();
|
||||
|
||||
_rgbService.DeviceLoaded += RgbServiceOnDeviceLoaded;
|
||||
_renderScaleSetting.SettingChanged += RenderScaleSettingOnSettingChanged;
|
||||
}
|
||||
|
||||
public ArtemisSurface ActiveSurface { get; private set; }
|
||||
@ -43,7 +40,7 @@ namespace Artemis.Core.Services
|
||||
public ArtemisSurface CreateSurfaceConfiguration(string name)
|
||||
{
|
||||
// Create a blank config
|
||||
ArtemisSurface configuration = new ArtemisSurface(_rgbService.Surface, name, _renderScaleSetting.Value);
|
||||
ArtemisSurface configuration = new ArtemisSurface(_rgbService.Surface, name);
|
||||
|
||||
// Add all current devices
|
||||
foreach (IRGBDevice rgbDevice in _rgbService.LoadedDevices)
|
||||
@ -133,7 +130,7 @@ namespace Artemis.Core.Services
|
||||
foreach (SurfaceEntity surfaceEntity in configs)
|
||||
{
|
||||
// Create the surface entity
|
||||
ArtemisSurface surfaceConfiguration = new ArtemisSurface(_rgbService.Surface, surfaceEntity, _renderScaleSetting.Value);
|
||||
ArtemisSurface surfaceConfiguration = new ArtemisSurface(_rgbService.Surface, surfaceEntity);
|
||||
foreach (DeviceEntity position in surfaceEntity.DeviceEntities)
|
||||
{
|
||||
IRGBDevice? device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
|
||||
@ -225,15 +222,6 @@ namespace Artemis.Core.Services
|
||||
UpdateSurfaceConfiguration(ActiveSurface, true);
|
||||
}
|
||||
|
||||
private void RenderScaleSettingOnSettingChanged(object? sender, EventArgs e)
|
||||
{
|
||||
foreach (ArtemisSurface surfaceConfiguration in SurfaceConfigurations)
|
||||
{
|
||||
surfaceConfiguration.UpdateScale(_renderScaleSetting.Value);
|
||||
OnSurfaceConfigurationUpdated(new SurfaceConfigurationEventArgs(surfaceConfiguration));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
@ -22,12 +22,11 @@ namespace Artemis.UI.Services
|
||||
public Rect GetLayerBounds(Layer layer)
|
||||
{
|
||||
// Adjust the render rectangle for the difference in render scale
|
||||
double renderScale = _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
||||
return new Rect(
|
||||
layer.Bounds.Left / renderScale * 1,
|
||||
layer.Bounds.Top / renderScale * 1,
|
||||
Math.Max(0, layer.Bounds.Width / renderScale * 1),
|
||||
Math.Max(0, layer.Bounds.Height / renderScale * 1)
|
||||
layer.Bounds.Left,
|
||||
layer.Bounds.Top,
|
||||
Math.Max(0, layer.Bounds.Width),
|
||||
Math.Max(0, layer.Bounds.Height)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user