mirror of
https://github.com/DarthAffe/CUE.NET.git
synced 2025-12-12 16:58:29 +00:00
Refactored brushes to perform a multi-pass rendering.
This allows effects to change the calculated values.
This commit is contained in:
parent
ba80ef9848
commit
8d32c73b6d
@ -1,6 +1,9 @@
|
||||
// ReSharper disable VirtualMemberNeverOverriden.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using CUE.NET.Devices.Keyboard.Enums;
|
||||
using CUE.NET.Effects;
|
||||
using CUE.NET.Helper;
|
||||
@ -29,6 +32,16 @@ namespace CUE.NET.Brushes
|
||||
/// </summary>
|
||||
public float Opacity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Rectangle used in the last render pass.
|
||||
/// </summary>
|
||||
public RectangleF RenderedRectangle { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary containing all colors for points calculated in the last render pass.
|
||||
/// </summary>
|
||||
public Dictionary<BrushRenderTarget, Color> RenderedTargets { get; } = new Dictionary<BrushRenderTarget, Color>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -48,13 +61,36 @@ namespace CUE.NET.Brushes
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Performas the render pass of the brush and calculates the raw colors for all requested points.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="renderTargets">The targets (keys/points) of which the color should be calculated.</param>
|
||||
public virtual void PerformRender(RectangleF rectangle, IEnumerable<BrushRenderTarget> renderTargets)
|
||||
{
|
||||
RenderedRectangle = rectangle;
|
||||
RenderedTargets.Clear();
|
||||
|
||||
foreach (BrushRenderTarget point in renderTargets)
|
||||
RenderedTargets[point] = GetColorAtPoint(rectangle, point);
|
||||
}
|
||||
/// <summary>
|
||||
/// Performs the finalize pass of the brush and calculates the final colors for all previously calculated points.
|
||||
/// </summary>
|
||||
public virtual void PerformFinalize()
|
||||
{
|
||||
List<BrushRenderTarget> renderTargets = RenderedTargets.Keys.ToList();
|
||||
foreach (BrushRenderTarget renderTarget in renderTargets)
|
||||
RenderedTargets[renderTarget] = FinalizeColor(RenderedTargets[renderTarget]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <param name="renderTarget">The target (key/point) from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
public abstract Color GetColorAtPoint(RectangleF rectangle, PointF point);
|
||||
protected abstract Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget);
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes the color by appliing the overall brightness and opacity.<br/>
|
||||
|
||||
29
Brushes/BrushRenderTarget.cs
Normal file
29
Brushes/BrushRenderTarget.cs
Normal file
@ -0,0 +1,29 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
using System.Drawing;
|
||||
using CUE.NET.Devices.Keyboard.Enums;
|
||||
|
||||
namespace CUE.NET.Brushes
|
||||
{
|
||||
public class BrushRenderTarget
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public CorsairKeyboardKeyId Key { get; }
|
||||
|
||||
public PointF Point { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public BrushRenderTarget(CorsairKeyboardKeyId key, PointF point)
|
||||
{
|
||||
this.Point = point;
|
||||
this.Key = key;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
// ReSharper disable UnusedMemberInSuper.Global
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using CUE.NET.Devices.Keyboard.Enums;
|
||||
using CUE.NET.Effects;
|
||||
@ -27,11 +28,25 @@ namespace CUE.NET.Brushes
|
||||
float Opacity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// Gets the Rectangle used in the last render pass.
|
||||
/// </summary>
|
||||
RectangleF RenderedRectangle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary containing all colors for points calculated in the last render pass.
|
||||
/// </summary>
|
||||
Dictionary<BrushRenderTarget, Color> RenderedTargets { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Performas the render pass of the brush and calculates the raw colors for all requested points.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
Color GetColorAtPoint(RectangleF rectangle, PointF point);
|
||||
/// <param name="renderTargets">The targets (keys/points) of which the color should be calculated.</param>
|
||||
void PerformRender(RectangleF rectangle, IEnumerable<BrushRenderTarget> renderTargets);
|
||||
|
||||
/// <summary>
|
||||
/// Performs the finalize pass of the brush and calculates the final colors for all previously calculated points.
|
||||
/// </summary>
|
||||
void PerformFinalize();
|
||||
}
|
||||
}
|
||||
@ -61,12 +61,12 @@ namespace CUE.NET.Brushes
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point getting the color of the key at the given point.
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <returns>The color of the key at the specified point.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
/// <param name="renderTarget">The target (key/point) from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
|
||||
{
|
||||
if (Image == null || Image.Width == 0 || Image.Height == 0)
|
||||
return Color.Transparent;
|
||||
@ -75,13 +75,13 @@ namespace CUE.NET.Brushes
|
||||
float scaleX = Image.Width / rectangle.Width;
|
||||
float scaleY = Image.Height / rectangle.Height;
|
||||
|
||||
int x = (int)(point.X * scaleX);
|
||||
int y = (int)(point.Y * scaleY);
|
||||
int x = (int)(renderTarget.Point.X * scaleX);
|
||||
int y = (int)(renderTarget.Point.Y * scaleY);
|
||||
|
||||
x = Math.Max(0, Math.Min(x, Image.Width - 1));
|
||||
y = Math.Max(0, Math.Min(y, Image.Height - 1));
|
||||
|
||||
return FinalizeColor(Image.GetPixel(x, y));
|
||||
return Image.GetPixel(x, y);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -74,17 +74,17 @@ namespace CUE.NET.Brushes
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <param name="renderTarget">The target (key/point) from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
|
||||
{
|
||||
if (Gradient == null) return Color.Transparent;
|
||||
|
||||
PointF startPoint = new PointF(StartPoint.X * rectangle.Width, StartPoint.Y * rectangle.Height);
|
||||
PointF endPoint = new PointF(EndPoint.X * rectangle.Width, EndPoint.Y * rectangle.Height);
|
||||
|
||||
float offset = GradientHelper.CalculateLinearGradientOffset(startPoint, endPoint, point);
|
||||
return FinalizeColor(Gradient.GetColor(offset));
|
||||
float offset = GradientHelper.CalculateLinearGradientOffset(startPoint, endPoint, renderTarget.Point);
|
||||
return Gradient.GetColor(offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -34,21 +34,18 @@ namespace CUE.NET.Brushes
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point getting the color of the key at the given point.
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <returns>The color of the key at the specified point.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
/// <param name="renderTarget">The target (key/point) from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
|
||||
{
|
||||
CorsairKey key = CueSDK.KeyboardSDK[point];
|
||||
CorsairKey key = CueSDK.KeyboardSDK[renderTarget.Key];
|
||||
if (key == null) return Color.Transparent;
|
||||
|
||||
Color color;
|
||||
if (!_keyLights.TryGetValue(key.KeyId, out color))
|
||||
return Color.Transparent;
|
||||
|
||||
return FinalizeColor(color);
|
||||
return !_keyLights.TryGetValue(key.KeyId, out color) ? Color.Transparent : color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -66,9 +66,9 @@ namespace CUE.NET.Brushes
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <param name="renderTarget">The target (key/point) from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
|
||||
{
|
||||
if(Gradient == null) return Color.Transparent;
|
||||
|
||||
@ -81,9 +81,9 @@ namespace CUE.NET.Brushes
|
||||
GradientHelper.CalculateDistance(new PointF(rectangle.X, rectangle.Y + rectangle.Height), centerPoint)),
|
||||
GradientHelper.CalculateDistance(new PointF(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height), centerPoint));
|
||||
|
||||
float distance = GradientHelper.CalculateDistance(point, centerPoint);
|
||||
float distance = GradientHelper.CalculateDistance(renderTarget.Point, centerPoint);
|
||||
float offset = distance / refDistance;
|
||||
return FinalizeColor(Gradient.GetColor(offset));
|
||||
return Gradient.GetColor(offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -24,14 +24,14 @@ namespace CUE.NET.Brushes
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random color.
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">This value isn't used.</param>
|
||||
/// <param name="point">This value isn't used.</param>
|
||||
/// <returns>A random color.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="renderTarget">The target (key/point) from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
|
||||
{
|
||||
return FinalizeColor(ColorHelper.ColorFromHSV((float)_random.NextDouble() * 360f, 1, 1));
|
||||
return ColorHelper.ColorFromHSV((float)_random.NextDouble() * 360f, 1, 1);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -37,14 +37,14 @@ namespace CUE.NET.Brushes
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Color" /> of the brush.
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">This value isn't used.</param>
|
||||
/// <param name="point">This value isn't used.</param>
|
||||
/// <returns>The <see cref="Color" /> of the brush.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="renderTarget">The target (key/point) from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
|
||||
{
|
||||
return FinalizeColor(Color);
|
||||
return Color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Brushes\ImageBrush.cs" />
|
||||
<Compile Include="Brushes\ProfileBrush.cs" />
|
||||
<Compile Include="Brushes\BrushRenderTarget.cs" />
|
||||
<Compile Include="Devices\Generic\Enums\CorsairAccessMode.cs" />
|
||||
<Compile Include="Devices\Generic\Enums\CorsairDeviceCaps.cs" />
|
||||
<Compile Include="Devices\Generic\Enums\CorsairDeviceType.cs" />
|
||||
|
||||
@ -169,8 +169,7 @@ namespace CUE.NET.Devices.Generic
|
||||
public void Update(bool flushLeds = false)
|
||||
{
|
||||
OnUpdating();
|
||||
|
||||
DeviceUpdateEffects();
|
||||
|
||||
DeviceUpdate();
|
||||
|
||||
ICollection<LedUpateRequest> ledsToUpdate = (flushLeds ? Leds : Leds.Where(x => x.Value.IsDirty)).Select(x => new LedUpateRequest(x.Key, x.Value.RequestedColor)).ToList();
|
||||
@ -187,11 +186,6 @@ namespace CUE.NET.Devices.Generic
|
||||
/// Performs device specific updates.
|
||||
/// </summary>
|
||||
protected abstract void DeviceUpdate();
|
||||
|
||||
/// <summary>
|
||||
/// Performs device specific updates effect-updates.
|
||||
/// </summary>
|
||||
protected abstract void DeviceUpdateEffects();
|
||||
|
||||
private void UpdateLeds(ICollection<LedUpateRequest> updateRequests)
|
||||
{
|
||||
|
||||
@ -76,11 +76,6 @@ namespace CUE.NET.Devices.Headset
|
||||
//TODO DarthAffe 21.08.2016: Create something fancy for headsets
|
||||
}
|
||||
|
||||
protected override void DeviceUpdateEffects()
|
||||
{
|
||||
//TODO DarthAffe 21.08.2016: Create something fancy for headsets
|
||||
}
|
||||
|
||||
#region IEnumerable
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -130,10 +130,16 @@ namespace CUE.NET.Devices.Keyboard
|
||||
#region Update
|
||||
|
||||
/// <summary>
|
||||
/// Updates all brushes on the keyboard and on groups.
|
||||
/// Updates all brushes and groups on the keyboard.
|
||||
/// </summary>
|
||||
protected override void DeviceUpdate()
|
||||
{
|
||||
lock (_keyGroups)
|
||||
{
|
||||
foreach (IKeyGroup keyGroup in _keyGroups)
|
||||
keyGroup.UpdateEffects();
|
||||
}
|
||||
|
||||
if (Brush != null)
|
||||
ApplyBrush(this.ToList(), Brush);
|
||||
|
||||
@ -144,11 +150,6 @@ namespace CUE.NET.Devices.Keyboard
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DeviceUpdateEffects()
|
||||
{
|
||||
UpdateEffects();
|
||||
}
|
||||
|
||||
// ReSharper disable once MemberCanBeMadeStatic.Local - idc
|
||||
private void ApplyBrush(ICollection<CorsairKey> keys, IBrush brush)
|
||||
{
|
||||
@ -162,16 +163,20 @@ namespace CUE.NET.Devices.Keyboard
|
||||
float offsetY = -brushRectangle.Y;
|
||||
brushRectangle.X = 0;
|
||||
brushRectangle.Y = 0;
|
||||
foreach (CorsairKey key in keys)
|
||||
key.Led.Color = brush.GetColorAtPoint(brushRectangle, key.KeyRectangle.GetCenter(offsetX, offsetY));
|
||||
brush.PerformRender(brushRectangle, keys.Select(x => new BrushRenderTarget(x.KeyId, x.KeyRectangle.GetCenter(offsetX, offsetY))));
|
||||
break;
|
||||
case BrushCalculationMode.Absolute:
|
||||
foreach (CorsairKey key in keys)
|
||||
key.Led.Color = brush.GetColorAtPoint(KeyboardRectangle, key.KeyRectangle.GetCenter());
|
||||
brush.PerformRender(KeyboardRectangle, keys.Select(x => new BrushRenderTarget(x.KeyId, x.KeyRectangle.GetCenter())));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
brush.UpdateEffects();
|
||||
brush.PerformFinalize();
|
||||
|
||||
foreach (KeyValuePair<BrushRenderTarget, Color> renders in brush.RenderedTargets)
|
||||
_keys[renders.Key.Key].Led.Color = renders.Value;
|
||||
}
|
||||
// ReSharper disable once CatchAllClause
|
||||
catch (Exception ex) { OnException(ex); }
|
||||
@ -184,30 +189,6 @@ namespace CUE.NET.Devices.Keyboard
|
||||
|
||||
#endregion
|
||||
|
||||
public void UpdateEffects()
|
||||
{
|
||||
lock (_keyGroups)
|
||||
{
|
||||
foreach (IKeyGroup keyGroup in _keyGroups)
|
||||
{
|
||||
keyGroup.UpdateEffects();
|
||||
keyGroup.Brush.UpdateEffects();
|
||||
}
|
||||
}
|
||||
|
||||
Brush.UpdateEffects();
|
||||
}
|
||||
|
||||
public void AddEffect(IEffect<IKeyGroup> effect)
|
||||
{
|
||||
throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead.");
|
||||
}
|
||||
|
||||
public void RemoveEffect(IEffect<IKeyGroup> effect)
|
||||
{
|
||||
throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the given keygroup.
|
||||
/// </summary>
|
||||
@ -259,6 +240,25 @@ namespace CUE.NET.Devices.Keyboard
|
||||
}
|
||||
}
|
||||
|
||||
#region Effects
|
||||
|
||||
public void UpdateEffects()
|
||||
{
|
||||
throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead.");
|
||||
}
|
||||
|
||||
public void AddEffect(IEffect<IKeyGroup> effect)
|
||||
{
|
||||
throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead.");
|
||||
}
|
||||
|
||||
public void RemoveEffect(IEffect<IKeyGroup> effect)
|
||||
{
|
||||
throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -99,11 +99,6 @@ namespace CUE.NET.Devices.Mouse
|
||||
//TODO DarthAffe 21.08.2016: Create something fancy for mice
|
||||
}
|
||||
|
||||
protected override void DeviceUpdateEffects()
|
||||
{
|
||||
//TODO DarthAffe 21.08.2016: Create something fancy for mice
|
||||
}
|
||||
|
||||
#region IEnumerable
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -28,17 +28,17 @@ namespace Example_AudioAnalyzer_full
|
||||
|
||||
#region Methods
|
||||
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
|
||||
{
|
||||
if (_soundDataProcessor?.BarValues == null) return Color.Transparent;
|
||||
|
||||
// This logic is also stolen from AterialDawn
|
||||
int barSampleIndex = (int)Math.Floor(_soundDataProcessor.BarValues.Length * (point.X / (rectangle.X + rectangle.Width))); // Calculate bar sampling index
|
||||
int barSampleIndex = (int)Math.Floor(_soundDataProcessor.BarValues.Length * (renderTarget.Point.X / (rectangle.X + rectangle.Width))); // Calculate bar sampling index
|
||||
float curBarHeight = 1f - Utility.Clamp(_soundDataProcessor.BarValues[barSampleIndex], 0f, 1f); // Invert this value since the keyboard is laid out with topleft being point 0,0
|
||||
float verticalPos = (point.Y / rectangle.Height);
|
||||
float verticalPos = (renderTarget.Point.Y / rectangle.Height);
|
||||
|
||||
// If the barHeight is lower than the vertical pos currently calculated return the brush value. Otherwise do nothing by returning transparent.
|
||||
return curBarHeight <= verticalPos ? base.GetColorAtPoint(rectangle, point) : Color.Transparent;
|
||||
return curBarHeight <= verticalPos ? base.GetColorAtPoint(rectangle, renderTarget) : Color.Transparent;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user