From 22c23af4fddaa9384f20f3c08671690333da23fd Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Tue, 22 Sep 2015 23:12:19 +0200 Subject: [PATCH] Added color-blending --- CUE.NET.csproj | 1 + Devices/Generic/CorsairLed.cs | 3 +- Examples/SimpleDevTest/Program.cs | 71 ++++++++++++++++++++----------- Helper/ColorHelper.cs | 49 +++++++++++++++++++++ 4 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 Helper/ColorHelper.cs diff --git a/CUE.NET.csproj b/CUE.NET.csproj index 6e6d9b8..9cd2868 100644 --- a/CUE.NET.csproj +++ b/CUE.NET.csproj @@ -88,6 +88,7 @@ + diff --git a/Devices/Generic/CorsairLed.cs b/Devices/Generic/CorsairLed.cs index 41a75e2..930862d 100644 --- a/Devices/Generic/CorsairLed.cs +++ b/Devices/Generic/CorsairLed.cs @@ -1,4 +1,5 @@ using System.Drawing; +using CUE.NET.Helper; namespace CUE.NET.Devices.Generic { @@ -19,7 +20,7 @@ namespace CUE.NET.Devices.Generic { if (!IsLocked) { - RequestedColor = value; + RequestedColor = RequestedColor.Blend(value); IsUpdated = true; } } diff --git a/Examples/SimpleDevTest/Program.cs b/Examples/SimpleDevTest/Program.cs index 68eb344..782d4a1 100644 --- a/Examples/SimpleDevTest/Program.cs +++ b/Examples/SimpleDevTest/Program.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Drawing; using System.Threading; using System.Threading.Tasks; @@ -48,10 +47,10 @@ namespace SimpleDevTest keyboard[CorsairKeyboardKeyId.G].Led.Color = Color.Green; keyboard['B'].Led.Color = Color.Blue; - // Lock the 'r', 'g', 'b' keys. We want them to stay like this forever - keyboard['R'].Led.IsLocked = true; - keyboard['G'].Led.IsLocked = true; - keyboard['B'].Led.IsLocked = true; + // Lock the 'r', 'g', 'b' keys. We want them to stay like this forever (commented since it looks quite stupid later, but feel free tu uncomment this) + //keyboard['R'].Led.IsLocked = true; + //keyboard['G'].Led.IsLocked = true; + //keyboard['B'].Led.IsLocked = true; // Ink the letters of 'white' white ListKeyGroup whiteGroup = new ListKeyGroup(keyboard, CorsairKeyboardKeyId.W, CorsairKeyboardKeyId.H, CorsairKeyboardKeyId.I, CorsairKeyboardKeyId.T, CorsairKeyboardKeyId.E) @@ -73,11 +72,11 @@ namespace SimpleDevTest // --------------------------------------------------------------------------- - // Now let us move a orange point random over the keyboard + // Now let us move some points random over the keyboard // Something like this could become some sort of effect // Initialize needed stuff - const float SPEED = 8f; // mm/tick + const float SPEED = 4f; // mm/tick Random random = new Random(); // Remove all the groups we created above to clear the keyboard @@ -96,30 +95,54 @@ namespace SimpleDevTest Thread.Sleep(200); } - // Set keyboard 'background' to something fancy - keyboard.Brush = new SolidColorBrush(Color.DarkSlateBlue); + // Set keyboard 'background' to something neutral + keyboard.Brush = new SolidColorBrush(Color.Black); - // Spawn our point (rectangle since circles are too hard to calculate :p) in the top-left corner (right over G1 or on ESC depending on your keyboard) - RectangleF point = new RectangleF(keyboard.KeyboardRectangle.X, keyboard.KeyboardRectangle.Y, 40, 40); + // Define how many points we have + const int NUM_POINTS = 6; - // Create a new KeyGroup to represent our point on the keyboard - RectangleKeyGroup pointGroup = new RectangleKeyGroup(keyboard, point, 0.1f) - { Brush = new SolidColorBrush(Color.Orange) }; + // The points we want to draw (rectangle since circles are too hard to calculate :p) + RectangleF[] points = new RectangleF[NUM_POINTS]; + + // KeyGroups which represents our point on the keyboard + RectangleKeyGroup[] pointGroups = new RectangleKeyGroup[NUM_POINTS]; // Target of our movement - PointF target = new PointF(point.X, point.Y); + PointF[] targets = new PointF[NUM_POINTS]; + + // Initialize all the stuff + for (int i = 0; i < NUM_POINTS; i++) + { + // Spawn our point in the top-left corner (right over G1 or on ESC depending on your keyboard) + points[i] = new RectangleF(keyboard.KeyboardRectangle.X, keyboard.KeyboardRectangle.Y, 60, 60); + pointGroups[i] = new RectangleKeyGroup(keyboard, points[i], 0.1f) { Brush = new SolidColorBrush(Color.White) }; + targets[i] = new PointF(points[i].X, points[i].Y); + } + + // We set colors manually since white points are kinda boring (notice, that we use alpha values) + pointGroups[0].Brush = new SolidColorBrush(Color.FromArgb(127, 255, 0, 0)); + pointGroups[1].Brush = new SolidColorBrush(Color.FromArgb(127, 0, 255, 0)); + pointGroups[2].Brush = new SolidColorBrush(Color.FromArgb(127, 0, 0, 255)); + pointGroups[3].Brush = new SolidColorBrush(Color.FromArgb(127, 255, 0, 255)); + pointGroups[4].Brush = new SolidColorBrush(Color.FromArgb(127, 255, 255, 0)); + pointGroups[5].Brush = new SolidColorBrush(Color.FromArgb(127, 0, 255, 255)); + while (true) { - // Choose new target if we arrived - if (point.Contains(target)) - target = new PointF((float)(keyboard.KeyboardRectangle.X + (random.NextDouble() * keyboard.KeyboardRectangle.Width)), - (float)(keyboard.KeyboardRectangle.Y + (random.NextDouble() * keyboard.KeyboardRectangle.Height))); - else - // Calculate movement - point.Location = Interpolate(point.Location, target, SPEED); // It would be better to calculate from the center of our rectangle but the easy way is enough here + // Calculate all the points + for (int i = 0; i < NUM_POINTS; i++) + { + // Choose new target if we arrived + if (points[i].Contains(targets[i])) + targets[i] = new PointF((float)(keyboard.KeyboardRectangle.X + (random.NextDouble() * keyboard.KeyboardRectangle.Width)), + (float)(keyboard.KeyboardRectangle.Y + (random.NextDouble() * keyboard.KeyboardRectangle.Height))); + else + // Calculate movement + points[i].Location = Interpolate(points[i].Location, targets[i], SPEED); // It would be better to calculate from the center of our rectangle but the easy way is enough here - // Move our rectangle to the new position - pointGroup.Rectangle = point; + // Move our rectangle to the new position + pointGroups[i].Rectangle = points[i]; + } // Update changed leds keyboard.UpdateLeds(); diff --git a/Helper/ColorHelper.cs b/Helper/ColorHelper.cs new file mode 100644 index 0000000..7ee8fab --- /dev/null +++ b/Helper/ColorHelper.cs @@ -0,0 +1,49 @@ +// ReSharper disable MemberCanBePrivate.Global + +using System.Drawing; + +namespace CUE.NET.Helper +{ + public static class ColorHelper + { + public static float GetFloatA(this Color color) + { + return color.A / 255f; + } + + public static float GetFloatR(this Color color) + { + return color.R / 255f; + } + + public static float GetFloatG(this Color color) + { + return color.G / 255f; + } + + public static float GetFloatB(this Color color) + { + return color.B / 255f; + } + + public static Color Blend(this Color bg, Color fg) + { + if (fg.A == 255) + return fg; + + if (fg.A == 0) + return bg; + + float resultA = (1 - (1 - fg.GetFloatA()) * (1 - bg.GetFloatA())); + float resultR = (fg.GetFloatR() * fg.GetFloatA() / resultA + bg.GetFloatR() * bg.GetFloatA() * (1 - fg.GetFloatA()) / resultA); + float resultG = (fg.GetFloatG() * fg.GetFloatA() / resultA + bg.GetFloatG() * bg.GetFloatA() * (1 - fg.GetFloatA()) / resultA); + float resultB = (fg.GetFloatB() * fg.GetFloatA() / resultA + bg.GetFloatB() * bg.GetFloatA() * (1 - fg.GetFloatA()) / resultA); + return CreateColorFromFloat(resultA, resultR, resultG, resultB); + } + + public static Color CreateColorFromFloat(float a, float r, float g, float b) + { + return Color.FromArgb((int)(a * 255), (int)(r * 255), (int)(g * 255), (int)(b * 255)); + } + } +}