From a8912076d343319bac4d5ef664cc75197fe105ed Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Fri, 17 Apr 2020 19:16:53 +0200 Subject: [PATCH] Noise brush - Added option to map noise to a gradient Color brush - Only show gradient/color option when applicable Gradient picker - Design tweaks --- .../Models/Profile/ColorGradient.cs | 12 +++ src/Artemis.Core/Ninject/CoreModule.cs | 19 ++++- .../Plugins/LayerBrush/LayerBrush.cs | 23 +++++- .../Controls/DeviceVisualizer.cs | 9 +-- .../Controls/GradientPicker.xaml | 15 ++-- .../GradientEditor/GradientEditorView.xaml | 18 +++-- .../Visualization/ProfileViewModel.cs | 31 ++++---- src/Artemis.sln | 39 ++++++---- .../ColorBrush.cs | 39 ++++++---- .../NoiseBrush.cs | 78 ++++++++++++++++--- 10 files changed, 201 insertions(+), 82 deletions(-) diff --git a/src/Artemis.Core/Models/Profile/ColorGradient.cs b/src/Artemis.Core/Models/Profile/ColorGradient.cs index 874c6a11e..36b48c397 100644 --- a/src/Artemis.Core/Models/Profile/ColorGradient.cs +++ b/src/Artemis.Core/Models/Profile/ColorGradient.cs @@ -69,6 +69,18 @@ namespace Artemis.Core.Models.Profile (byte) ((position - before.Position) * (after.Color.Alpha - before.Color.Alpha) / (after.Position - before.Position) + before.Color.Alpha) ); } + + /// + /// [PH] Looping through HSV, adds 8 rainbow colors + /// + public void MakeFabulous() + { + for (var i = 0; i < 9; i++) + { + var color = i != 8 ? SKColor.FromHsv(i * 32, 100, 100) : SKColor.FromHsv(0, 100, 100); + Stops.Add(new ColorGradientStop(color, 0.125f * i)); + } + } } public class ColorGradientStop : INotifyPropertyChanged diff --git a/src/Artemis.Core/Ninject/CoreModule.cs b/src/Artemis.Core/Ninject/CoreModule.cs index 646e9b031..123f2076e 100644 --- a/src/Artemis.Core/Ninject/CoreModule.cs +++ b/src/Artemis.Core/Ninject/CoreModule.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using Artemis.Core.Exceptions; using Artemis.Core.Models.Profile.KeyframeEngines; using Artemis.Core.Plugins.Models; @@ -45,7 +46,21 @@ namespace Artemis.Core.Ninject if (!Directory.Exists(Constants.DataFolder)) Directory.CreateDirectory(Constants.DataFolder); - return new LiteRepository(Constants.ConnectionString); + try + { + return new LiteRepository(Constants.ConnectionString); + } + catch (LiteException e) + { + // I don't like this way of error reporting, now I need to use reflection if I want a meaningful error code + if (e.ErrorCode != LiteException.INVALID_DATABASE) + throw new ArtemisCoreException($"LiteDB threw error code {e.ErrorCode}. See inner exception for more details", e); + + // If the DB is invalid it's probably LiteDB v4 (TODO: we'll have to do something better later) + File.Delete($"{Constants.DataFolder}\\database.db"); + return new LiteRepository(Constants.ConnectionString); + } + }).InSingletonScope(); // Bind all repositories as singletons diff --git a/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs index e65b8461f..0ebbb4194 100644 --- a/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs +++ b/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Services.Interfaces; @@ -76,15 +77,31 @@ namespace Artemis.Core.Plugins.LayerBrush /// The layer property protected LayerProperty RegisterLayerProperty(string id, string name, string description, T defaultValue = default) { - var property = new LayerProperty( - Layer, Descriptor.LayerBrushProvider.PluginInfo, Layer.Properties.BrushReference.Parent, id, name, description - ) {Value = defaultValue}; + var property = new LayerProperty(Layer, Descriptor.LayerBrushProvider.PluginInfo, Layer.Properties.BrushReference.Parent, id, name, description) + { + Value = defaultValue + }; + Layer.Properties.RegisterLayerProperty(property); // It's fine if this is null, it'll be picked up by SetLayerService later _layerService?.InstantiateKeyframeEngine(property); return property; } + /// + /// Allows you to remove layer properties previously added by using . + /// + /// + /// + protected void UnRegisterLayerProperty(LayerProperty layerProperty) + { + if (layerProperty == null) + return; + + if (Layer.Properties.Any(p => p == layerProperty)) + Layer.Properties.RemoveLayerProperty(layerProperty); + } + internal void SetLayerService(ILayerService layerService) { _layerService = layerService; diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index 918cfdbab..c106546d1 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -27,7 +27,7 @@ namespace Artemis.UI.Shared.Controls _backingStore = new DrawingGroup(); _deviceVisualizerLeds = new List(); - SubscribeToSurfaceUpdate(); + RGBSurface.Instance.Updated += RgbSurfaceOnUpdated; Unloaded += (sender, args) => Dispose(); } @@ -131,12 +131,7 @@ namespace Artemis.UI.Shared.Controls bitmapBrush.Freeze(); _backingStore.OpacityMask = bitmapBrush; } - - private void SubscribeToSurfaceUpdate() - { - RGBSurface.Instance.Updated += RgbSurfaceOnUpdated; - } - + private void RgbSurfaceOnUpdated(UpdatedEventArgs e) { Dispatcher.Invoke(() => diff --git a/src/Artemis.UI.Shared/Controls/GradientPicker.xaml b/src/Artemis.UI.Shared/Controls/GradientPicker.xaml index 9c74ca645..32ed02fcf 100644 --- a/src/Artemis.UI.Shared/Controls/GradientPicker.xaml +++ b/src/Artemis.UI.Shared/Controls/GradientPicker.xaml @@ -35,16 +35,15 @@ - - - - - + + + + + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorView.xaml b/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorView.xaml index 82881cf69..987666aab 100644 --- a/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorView.xaml +++ b/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorView.xaml @@ -15,7 +15,7 @@ Background="{DynamicResource MaterialDesignPaper}" FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto" Width="500" - Height="600" + Height="500" ResizeMode="NoResize" Icon="/Resources/Images/Logo/logo-512.png" FadeContentIfInactive="False" @@ -26,9 +26,13 @@ - - - + + + + + + + Gradient saving not implemented yet @@ -39,7 +43,7 @@ - + Gradient @@ -106,6 +110,6 @@ - - + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs index bbc9c8d1a..c0b0a4002 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs @@ -155,25 +155,22 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization { Execute.PostToUIThread(() => { - lock (CanvasViewModels) + var layerViewModels = CanvasViewModels.Where(vm => vm is ProfileLayerViewModel).Cast().ToList(); + var layers = _profileEditorService.SelectedProfile?.GetAllLayers() ?? new List(); + + // Add new layers missing a VM + foreach (var layer in layers) { - var layerViewModels = CanvasViewModels.Where(vm => vm is ProfileLayerViewModel).Cast().ToList(); - var layers = _profileEditorService.SelectedProfile?.GetAllLayers() ?? new List(); + if (layerViewModels.All(vm => vm.Layer != layer)) + CanvasViewModels.Add(_profileLayerVmFactory.Create(layer)); + } - // Add new layers missing a VM - foreach (var layer in layers) - { - if (layerViewModels.All(vm => vm.Layer != layer)) - CanvasViewModels.Add(_profileLayerVmFactory.Create(layer)); - } - - // Remove layers that no longer exist - var toRemove = layerViewModels.Where(vm => !layers.Contains(vm.Layer)); - foreach (var profileLayerViewModel in toRemove) - { - profileLayerViewModel.Dispose(); - CanvasViewModels.Remove(profileLayerViewModel); - } + // Remove layers that no longer exist + var toRemove = layerViewModels.Where(vm => !layers.Contains(vm.Layer)); + foreach (var profileLayerViewModel in toRemove) + { + profileLayerViewModel.Dispose(); + CanvasViewModels.Remove(profileLayerViewModel); } }); } diff --git a/src/Artemis.sln b/src/Artemis.sln index f3967c70c..cc15ae5e9 100644 --- a/src/Artemis.sln +++ b/src/Artemis.sln @@ -60,6 +60,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.Plugins.Devices.Ste EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.Plugins.Devices.WS281X", "Plugins\Artemis.Plugins.Devices.WS281X\Artemis.Plugins.Devices.WS281X.csproj", "{A46F278A-FC2C-4342-8455-994D957DDA03}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{88792A7E-F037-4280-81D3-B131508EF1D8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LayerBrushes", "LayerBrushes", "{A311DC47-42A2-4DD4-B921-50FBF7A33F41}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{B258A061-FA19-4835-8DC4-E9C3AE3664A0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -225,21 +231,24 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {E592F239-FAA0-4840-9C85-46E5867D06D5} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {0F288A66-6EB0-4589-8595-E33A3A3EAEA2} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {A779B2F8-C253-4C4B-8634-6EB8F594E96D} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {235A45C7-24AD-4F47-B9D4-CD67E610A04D} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {7F4C7AB0-4C9B-452D-AFED-34544C903DEF} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {C6BDB6D9-062D-4C28-A280-F3BD6197F07F} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {DCF7C321-95DC-4507-BB61-A7C5356E58EC} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {8DC7960F-6DDF-4007-A155-17E124F39374} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {AB80F106-5444-46AA-A255-F765DD2F04F1} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {07678400-2FE1-4C6E-A8D4-4F9F3C0630EA} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {D004FEC9-0CF8-4828-B620-95DBA73201A3} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {36C10640-A31F-4DEE-9F0E-9B9E3F12753D} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {26902C94-3EBC-4132-B7F0-FFCAB8E150DA} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {FA5815D3-EA87-4A64-AD6C-A5AE96C61F29} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} - {A46F278A-FC2C-4342-8455-994D957DDA03} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} + {E592F239-FAA0-4840-9C85-46E5867D06D5} = {B258A061-FA19-4835-8DC4-E9C3AE3664A0} + {0F288A66-6EB0-4589-8595-E33A3A3EAEA2} = {A311DC47-42A2-4DD4-B921-50FBF7A33F41} + {A779B2F8-C253-4C4B-8634-6EB8F594E96D} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {235A45C7-24AD-4F47-B9D4-CD67E610A04D} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {7F4C7AB0-4C9B-452D-AFED-34544C903DEF} = {A311DC47-42A2-4DD4-B921-50FBF7A33F41} + {C6BDB6D9-062D-4C28-A280-F3BD6197F07F} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {DCF7C321-95DC-4507-BB61-A7C5356E58EC} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {8DC7960F-6DDF-4007-A155-17E124F39374} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {AB80F106-5444-46AA-A255-F765DD2F04F1} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {07678400-2FE1-4C6E-A8D4-4F9F3C0630EA} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {D004FEC9-0CF8-4828-B620-95DBA73201A3} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {36C10640-A31F-4DEE-9F0E-9B9E3F12753D} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {26902C94-3EBC-4132-B7F0-FFCAB8E150DA} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {FA5815D3-EA87-4A64-AD6C-A5AE96C61F29} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {A46F278A-FC2C-4342-8455-994D957DDA03} = {88792A7E-F037-4280-81D3-B131508EF1D8} + {88792A7E-F037-4280-81D3-B131508EF1D8} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} + {A311DC47-42A2-4DD4-B921-50FBF7A33F41} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} + {B258A061-FA19-4835-8DC4-E9C3AE3664A0} = {E830A02B-A7E5-4A6B-943F-76B0A542630C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C203080A-4473-4CC2-844B-F552EA43D66A} diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs index ba35d170a..405b5acf6 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs @@ -17,24 +17,37 @@ namespace Artemis.Plugins.LayerBrushes.Color public ColorBrush(Layer layer, LayerBrushDescriptor descriptor) : base(layer, descriptor) { - ColorProperty = RegisterLayerProperty("Brush.Color", "Color", "The color of the brush", new SKColor(255, 0, 0)); - GradientProperty = RegisterLayerProperty("Brush.Gradient", "Gradient", "The gradient of the brush", new ColorGradient()); GradientTypeProperty = RegisterLayerProperty("Brush.GradientType", "Gradient type", "The type of color brush to draw"); GradientTypeProperty.CanUseKeyframes = false; - CreateShader(_shaderBounds); + UpdateColorProperties(); + Layer.RenderPropertiesUpdated += (sender, args) => CreateShader(_shaderBounds); - GradientTypeProperty.ValueChanged += (sender, args) => CreateShader(_shaderBounds); - GradientProperty.ValueChanged += (sender, args) => CreateShader(_shaderBounds); - GradientProperty.Value.PropertyChanged += (sender, args) => CreateShader(_shaderBounds); - if (!GradientProperty.Value.Stops.Any()) + GradientTypeProperty.ValueChanged += (sender, args) => UpdateColorProperties(); + } + + private void UpdateColorProperties() + { + Layer.Properties.RemoveLayerProperty(ColorProperty); + ColorProperty = null; + Layer.Properties.RemoveLayerProperty(GradientProperty); + GradientProperty = null; + + if (GradientTypeProperty.Value == GradientType.Solid) { - for (var i = 0; i < 9; i++) - { - var color = i != 8 ? SKColor.FromHsv(i * 32, 100, 100) : SKColor.FromHsv(0, 100, 100); - GradientProperty.Value.Stops.Add(new ColorGradientStop(color, 0.125f * i)); - } + ColorProperty = RegisterLayerProperty("Brush.Color", "Color", "The color of the brush", new SKColor(255, 0, 0)); + ColorProperty.ValueChanged += (sender, args) => CreateShader(_shaderBounds); } + else + { + GradientProperty = RegisterLayerProperty("Brush.Gradient", "Gradient", "The gradient of the brush", new ColorGradient()); + GradientProperty.Value.PropertyChanged += (sender, args) => CreateShader(_shaderBounds); + + if (!GradientProperty.Value.Stops.Any()) + GradientProperty.Value.MakeFabulous(); + } + + CreateShader(_shaderBounds); } public LayerProperty ColorProperty { get; set; } @@ -44,7 +57,7 @@ namespace Artemis.Plugins.LayerBrushes.Color public override void Update(double deltaTime) { // Only recreate the shader if the color changed - if (_color != ColorProperty.CurrentValue) + if (ColorProperty != null && _color != ColorProperty.CurrentValue) { _color = ColorProperty.CurrentValue; CreateShader(_shaderBounds); diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs index 4ca46a9c7..5f6e66c14 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs @@ -1,4 +1,6 @@ using System; +using System.ComponentModel; +using System.Linq; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Plugins.LayerBrush; @@ -19,6 +21,7 @@ namespace Artemis.Plugins.LayerBrushes.Noise private float _x; private float _y; private float _z; + private SKColor[] _colorMap; public NoiseBrush(Layer layer, LayerBrushDescriptor descriptor, IRgbService rgbService) : base(layer, descriptor) { @@ -28,8 +31,10 @@ namespace Artemis.Plugins.LayerBrushes.Noise _z = Rand.Next(0, 4096); _noise = new OpenSimplexNoise(Rand.Next(0, 4096)); - MainColorProperty = RegisterLayerProperty("Brush.MainColor", "Main color", "The main color of the noise", new SKColor(255, 0, 0)); - SecondaryColorProperty = RegisterLayerProperty("Brush.SecondaryColor", "Secondary color", "The secondary color of the noise", new SKColor(0, 0, 255)); + ColorTypeProperty = RegisterLayerProperty("Brush.ColorType", "Color mapping type", "The way the noise is converted to colors", ColorMappingType.Simple); + ColorTypeProperty.ValueChanged += (sender, args) => UpdateColorProperties(); + UpdateColorProperties(); + ScaleProperty = RegisterLayerProperty("Brush.Scale", "Scale", "The scale of the noise.", new SKSize(100, 100)); ScaleProperty.MinInputValue = 0f; HardnessProperty = RegisterLayerProperty("Brush.Hardness", "Hardness", "The hardness of the noise, lower means there are gradients in the noise, higher means hard lines", 500f); @@ -46,13 +51,41 @@ namespace Artemis.Plugins.LayerBrushes.Noise DetermineRenderScale(); } + + public LayerProperty ColorTypeProperty { get; set; } public LayerProperty MainColorProperty { get; set; } public LayerProperty SecondaryColorProperty { get; set; } + public LayerProperty GradientColorProperty { get; set; } + public LayerProperty ScaleProperty { get; set; } public LayerProperty HardnessProperty { get; set; } public LayerProperty ScrollSpeedProperty { get; set; } public LayerProperty AnimationSpeedProperty { get; set; } + + private void UpdateColorProperties() + { + UnRegisterLayerProperty(MainColorProperty); + UnRegisterLayerProperty(SecondaryColorProperty); + UnRegisterLayerProperty(GradientColorProperty); + if (GradientColorProperty != null) + GradientColorProperty.Value.PropertyChanged -= CreateColorMap; + if (ColorTypeProperty.Value == ColorMappingType.Simple) + { + MainColorProperty = RegisterLayerProperty("Brush.MainColor", "Main color", "The main color of the noise", new SKColor(255, 0, 0)); + SecondaryColorProperty = RegisterLayerProperty("Brush.SecondaryColor", "Secondary color", "The secondary color of the noise", new SKColor(0, 0, 255)); + } + else + { + GradientColorProperty = RegisterLayerProperty("Brush.GradientColor", "Noise gradient map", "The gradient the noise will map it's value to", new ColorGradient()); + if (!GradientColorProperty.Value.Stops.Any()) + GradientColorProperty.Value.MakeFabulous(); + + GradientColorProperty.Value.PropertyChanged += CreateColorMap; + CreateColorMap(null, null); + } + } + public override void Update(double deltaTime) { _x += ScrollSpeedProperty.CurrentValue.X / 500f / (float) deltaTime; @@ -73,9 +106,10 @@ namespace Artemis.Plugins.LayerBrushes.Noise public override void Render(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint) { - var mainColor = MainColorProperty.CurrentValue; + var mainColor = MainColorProperty?.CurrentValue; + var gradientColor = GradientColorProperty?.CurrentValue; var scale = ScaleProperty.CurrentValue; - var opacity = (float) Math.Round(mainColor.Alpha / 255.0, 2, MidpointRounding.AwayFromZero); + var opacity = mainColor != null ? (float) Math.Round(mainColor.Value.Alpha / 255.0, 2, MidpointRounding.AwayFromZero) : 0; var hardness = 127 + HardnessProperty.CurrentValue; // Scale down the render path to avoid computing a value for every pixel @@ -96,7 +130,15 @@ namespace Artemis.Plugins.LayerBrushes.Noise var v = _noise.Evaluate(evalX, evalY, _z); var alpha = (byte) Math.Max(0, Math.Min(255, v * hardness)); - _bitmap.SetPixel(x, y, new SKColor(mainColor.Red, mainColor.Green, mainColor.Blue, (byte) (alpha * opacity))); + if (ColorTypeProperty.Value == ColorMappingType.Simple && mainColor != null) + { + _bitmap.SetPixel(x, y, new SKColor(mainColor.Value.Red, mainColor.Value.Green, mainColor.Value.Blue, (byte) (alpha * opacity))); + } + else if (gradientColor != null && _colorMap.Length == 101) + { + var color = _colorMap[(int) Math.Round(alpha / 255f * 100, MidpointRounding.AwayFromZero)]; + _bitmap.SetPixel(x, y, new SKColor(color.Red, color.Green, color.Blue, 255)); + } } } @@ -105,15 +147,18 @@ namespace Artemis.Plugins.LayerBrushes.Noise SKMatrix.MakeTranslation(path.Bounds.Left, path.Bounds.Top), SKMatrix.MakeScale(1f / _renderScale, 1f / _renderScale) ); - using (var backgroundShader = SKShader.CreateColor(SecondaryColorProperty.CurrentValue)) - using (var foregroundShader = SKShader.CreateBitmap(_bitmap, SKShaderTileMode.Clamp, SKShaderTileMode.Clamp, bitmapTransform)) + + canvas.ClipPath(path); + if (ColorTypeProperty.Value == ColorMappingType.Simple) { - canvas.ClipPath(path); + using var backgroundShader = SKShader.CreateColor(SecondaryColorProperty.CurrentValue); paint.Shader = backgroundShader; canvas.DrawRect(path.Bounds, paint); - paint.Shader = foregroundShader; - canvas.DrawRect(path.Bounds, paint); } + + using var foregroundShader = SKShader.CreateBitmap(_bitmap, SKShaderTileMode.Clamp, SKShaderTileMode.Clamp, bitmapTransform); + paint.Shader = foregroundShader; + canvas.DrawRect(path.Bounds, paint); } @@ -132,5 +177,18 @@ namespace Artemis.Plugins.LayerBrushes.Noise _bitmap = new SKBitmap(new SKImageInfo(width, height)); } } + + private void CreateColorMap(object sender, EventArgs e) + { + _colorMap = new SKColor[101]; + for (var i = 0; i < 101; i++) + _colorMap[i] = GradientColorProperty.Value.GetColor(i / 100f); + } + } + + public enum ColorMappingType + { + Simple, + Gradient } } \ No newline at end of file