From af924afef435cabd406c94abe270f1c4ab74a2a6 Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Mon, 10 Nov 2014 01:59:53 +0100 Subject: [PATCH 1/6] Add To/From sRGB methods to Color4. --- Source/OpenTK/Graphics/Color4.cs | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/Source/OpenTK/Graphics/Color4.cs b/Source/OpenTK/Graphics/Color4.cs index 972747ac..7ccef161 100644 --- a/Source/OpenTK/Graphics/Color4.cs +++ b/Source/OpenTK/Graphics/Color4.cs @@ -914,6 +914,98 @@ namespace OpenTK.Graphics #endregion + #region Color conversions + + #region sRGB + + /// + /// Converts sRGB color values to RGB color values. + /// + /// + /// Returns the converted color value. + /// + /// + /// Color value to convert in sRGB. + /// + public static Color4 FromSrgb(Color4 srgb) + { + float r, g, b; + + if (srgb.R <= 0.04045f) + { + r = srgb.R / 12.92f; + } + else + { + r = (float)Math.Pow((srgb.R + 0.055f) / (1.0f + 0.055f), 2.4f); + } + + if (srgb.G <= 0.04045f) + { + g = srgb.G / 12.92f; + } + else + { + g = (float)Math.Pow((srgb.G + 0.055f) / (1.0f + 0.055f), 2.4f); + } + + if (srgb.B <= 0.04045f) + { + b = srgb.B / 12.92f; + } + else + { + b = (float)Math.Pow((srgb.B + 0.055f) / (1.0f + 0.055f), 2.4f); + } + + return new Color4(r, g, b, srgb.A); + } + + /// + /// Converts RGB color values to sRGB color values. + /// + /// + /// Returns the converted color value. + /// + /// Color value to convert. + public static Color4 ToSrgb(Color4 rgb) + { + float r, g, b; + + if (rgb.R <= 0.0031308) + { + r = 12.92f * rgb.R; + } + else + { + r = (1.0f + 0.055f) * (float)Math.Pow(rgb.R, 1.0f / 2.4f) - 0.055f; + } + + if (rgb.G <= 0.0031308) + { + g = 12.92f * rgb.G; + } + else + { + g = (1.0f + 0.055f) * (float)Math.Pow(rgb.G, 1.0f / 2.4f) - 0.055f; + } + + if (rgb.B <= 0.0031308) + { + b = 12.92f * rgb.B; + } + else + { + b = (1.0f + 0.055f) * (float)Math.Pow(rgb.B, 1.0f / 2.4f) - 0.055f; + } + + return new Color4(r, g, b, rgb.A); + } + + #endregion + + #endregion + #region IEquatable Members /// From d09b32474ba1582a2a01b41ee3cdcf58f703accc Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Mon, 10 Nov 2014 00:27:13 +0100 Subject: [PATCH 2/6] Add To/From HSL methods to Color4. --- Source/OpenTK/Graphics/Color4.cs | 120 +++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/Source/OpenTK/Graphics/Color4.cs b/Source/OpenTK/Graphics/Color4.cs index 7ccef161..4cbbc555 100644 --- a/Source/OpenTK/Graphics/Color4.cs +++ b/Source/OpenTK/Graphics/Color4.cs @@ -1004,6 +1004,126 @@ namespace OpenTK.Graphics #endregion + #region HSL + + /// + /// Converts HSL color values to RGB color values. + /// + /// + /// Returns the converted color value. + /// + /// + /// Color value to convert in hue, saturation, lightness (HSL). + /// The X element is Hue (H), the Y element is Saturation (S), the Z element is Lightness (L), and the W element is Alpha (which is copied to the output's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + public static Color4 FromHsl(Vector4 hsl) + { + var hue = hsl.X * 360.0f; + var saturation = hsl.Y; + var lightness = hsl.Z; + + var C = (1.0f - Math.Abs(2.0f * lightness - 1.0f)) * saturation; + + var h = hue / 60.0f; + var X = C * (1.0f - Math.Abs(h % 2.0f - 1.0f)); + + float r, g, b; + if (0.0f <= h && h < 1.0f) + { + r = C; + g = X; + b = 0.0f; + } + else if (1.0f <= h && h < 2.0f) + { + r = X; + g = C; + b = 0.0f; + } + else if (2.0f <= h && h < 3.0f) + { + r = 0.0f; + g = C; + b = X; + } + else if (3.0f <= h && h < 4.0f) + { + r = 0.0f; + g = X; + b = C; + } + else if (4.0f <= h && h < 5.0f) + { + r = X; + g = 0.0f; + b = C; + } + else if (5.0f <= h && h < 6.0f) + { + r = C; + g = 0.0f; + b = X; + } + else + { + r = 0.0f; + g = 0.0f; + b = 0.0f; + } + + var m = lightness - (C / 2.0f); + return new Color4(r + m, g + m, b + m, hsl.W); + } + + /// + /// Converts RGB color values to HSL color values. + /// + /// + /// Returns the converted color value. + /// The X element is Hue (H), the Y element is Saturation (S), the Z element is Lightness (L), and the W element is Alpha (a copy of the input's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + /// Color value to convert. + public static Vector4 ToHsl(Color4 rgb) + { + var M = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B)); + var m = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B)); + var C = M - m; + + float h = 0.0f; + if (M == rgb.R) + { + h = ((rgb.G - rgb.B) / C); + } + else if (M == rgb.G) + { + h = ((rgb.B - rgb.R) / C) + 2.0f; + } + else if (M == rgb.B) + { + h = ((rgb.R - rgb.G) / C) + 4.0f; + } + + var hue = h / 6.0f; + if (hue < 0.0f) + { + hue += 1.0f; + } + + var lightness = (M + m) / 2.0f; + + var saturation = 0.0f; + if (0.0f != lightness && lightness != 1.0f) + { + saturation = C / (1.0f - Math.Abs(2.0f * lightness - 1.0f)); + } + + return new Vector4(hue, saturation, lightness, rgb.A); + } + + #endregion + #endregion #region IEquatable Members From 072263f29d13f6ded5147c4d028662f1fd188ffa Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Mon, 10 Nov 2014 01:33:38 +0100 Subject: [PATCH 3/6] Add To/From HSV methods to Color4. --- Source/OpenTK/Graphics/Color4.cs | 114 +++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/Source/OpenTK/Graphics/Color4.cs b/Source/OpenTK/Graphics/Color4.cs index 4cbbc555..5da242fd 100644 --- a/Source/OpenTK/Graphics/Color4.cs +++ b/Source/OpenTK/Graphics/Color4.cs @@ -1124,6 +1124,120 @@ namespace OpenTK.Graphics #endregion + #region HSV + + /// + /// Converts HSV color values to RGB color values. + /// + /// + /// Returns the converted color value. + /// + /// + /// Color value to convert in hue, saturation, value (HSV). + /// The X element is Hue (H), the Y element is Saturation (S), the Z element is Value (V), and the W element is Alpha (which is copied to the output's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + public static Color4 FromHsv(Vector4 hsv) + { + var hue = hsv.X * 360.0f; + var saturation = hsv.Y; + var value = hsv.Z; + + var C = value * saturation; + + var h = hue / 60.0f; + var X = C * (1.0f - Math.Abs(h % 2.0f - 1.0f)); + + float r, g, b; + if (0.0f <= h && h < 1.0f) + { + r = C; + g = X; + b = 0.0f; + } + else if (1.0f <= h && h < 2.0f) + { + r = X; + g = C; + b = 0.0f; + } + else if (2.0f <= h && h < 3.0f) + { + r = 0.0f; + g = C; + b = X; + } + else if (3.0f <= h && h < 4.0f) + { + r = 0.0f; + g = X; + b = C; + } + else if (4.0f <= h && h < 5.0f) + { + r = X; + g = 0.0f; + b = C; + } + else if (5.0f <= h && h < 6.0f) + { + r = C; + g = 0.0f; + b = X; + } + else + { + r = 0.0f; + g = 0.0f; + b = 0.0f; + } + + var m = value - C; + return new Color4(r + m, g + m, b + m, hsv.W); + } + + /// + /// Converts RGB color values to HSV color values. + /// + /// + /// Returns the converted color value. + /// The X element is Hue (H), the Y element is Saturation (S), the Z element is Value (V), and the W element is Alpha (a copy of the input's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + /// Color value to convert. + public static Vector4 ToHsv(Color4 rgb) + { + var M = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B)); + var m = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B)); + var C = M - m; + + float h = 0.0f; + if (M == rgb.R) + { + h = ((rgb.G - rgb.B) / C) % 6.0f; + } + else if (M == rgb.G) + { + h = ((rgb.B - rgb.R) / C) + 2.0f; + } + else if (M == rgb.B) + { + h = ((rgb.R - rgb.G) / C) + 4.0f; + } + + var hue = (h * 60.0f) / 360.0f; + + var saturation = 0.0f; + if (0.0f != M) + { + saturation = C / M; + } + + return new Vector4(hue, saturation, M, rgb.A); + } + + #endregion + #endregion #region IEquatable Members From 679419bb67321536aa8cf40d2a51455762bc0017 Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Mon, 10 Nov 2014 01:37:37 +0100 Subject: [PATCH 4/6] Add To/From XYZ methods to Color4. --- Source/OpenTK/Graphics/Color4.cs | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Source/OpenTK/Graphics/Color4.cs b/Source/OpenTK/Graphics/Color4.cs index 5da242fd..3b136f02 100644 --- a/Source/OpenTK/Graphics/Color4.cs +++ b/Source/OpenTK/Graphics/Color4.cs @@ -1238,6 +1238,46 @@ namespace OpenTK.Graphics #endregion + #region XYZ + + /// + /// Converts XYZ color values to RGB color values. + /// + /// + /// Returns the converted color value. + /// + /// + /// Color value to convert with the trisimulus values of X, Y, and Z in the corresponding element, and the W element with Alpha (which is copied to the output's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + /// Uses the CIE XYZ colorspace. + public static Color4 FromXyz(Vector4 xyz) + { + var r = 0.41847f * xyz.X + -0.15866f * xyz.Y + -0.082835f * xyz.Z; + var g = -0.091169f * xyz.X + 0.25243f * xyz.Y + 0.015708f * xyz.Z; + var b = 0.00092090f * xyz.X + -0.0025498f * xyz.Y + 0.17860f * xyz.Z; + return new Color4(r, g, b, xyz.W); + } + + /// + /// Converts RGB color values to XYZ color values. + /// + /// + /// Returns the converted color value with the trisimulus values of X, Y, and Z in the corresponding element, and the W element with Alpha (a copy of the input's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + /// Color value to convert. + /// Uses the CIE XYZ colorspace. + public static Vector4 ToXyz(Color4 rgb) + { + var x = (0.49f * rgb.R + 0.31f * rgb.G + 0.20f * rgb.B) / 0.17697f; + var y = (0.17697f * rgb.R + 0.81240f * rgb.G + 0.01063f * rgb.B) / 0.17697f; + var z = (0.00f * rgb.R + 0.01f * rgb.G + 0.99f * rgb.B) / 0.17697f; + return new Vector4(x, y, z, rgb.A); + } + + #endregion + #endregion #region IEquatable Members From edcb0664b13ac2ab2024929389853b530d8e04a2 Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Mon, 10 Nov 2014 02:42:12 +0100 Subject: [PATCH 5/6] Add To/From YUV methods to Color4. --- Source/OpenTK/Graphics/Color4.cs | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Source/OpenTK/Graphics/Color4.cs b/Source/OpenTK/Graphics/Color4.cs index 3b136f02..265de069 100644 --- a/Source/OpenTK/Graphics/Color4.cs +++ b/Source/OpenTK/Graphics/Color4.cs @@ -1276,6 +1276,47 @@ namespace OpenTK.Graphics return new Vector4(x, y, z, rgb.A); } + #endregion + + #region YUV + + /// + /// Converts YCbCr color values to RGB color values. + /// + /// + /// Returns the converted color value. + /// + /// + /// Color value to convert in Luma-Chrominance (YCbCr) aka YUV. + /// The X element contains Luma (Y, 0.0 to 1.0), the Y element contains Blue-difference chroma (U, -0.5 to 0.5), the Z element contains the Red-difference chroma (V, -0.5 to 0.5), and the W element contains the Alpha (which is copied to the output's Alpha value). + /// + /// Converts using ITU-R BT.601/CCIR 601 W(r) = 0.299 W(b) = 0.114 U(max) = 0.436 V(max) = 0.615. + public static Color4 FromYcbcr(Vector4 ycbcr) + { + var r = 1.0f * ycbcr.X + 0.0f * ycbcr.Y + 1.402f * ycbcr.Z; + var g = 1.0f * ycbcr.X + -0.344136f * ycbcr.Y + -0.714136f * ycbcr.Z; + var b = 1.0f * ycbcr.X + 1.772f * ycbcr.Y + 0.0f * ycbcr.Z; + return new Color4(r, g, b, ycbcr.W); + } + + /// + /// Converts RGB color values to YUV color values. + /// + /// + /// Returns the converted color value in Luma-Chrominance (YCbCr) aka YUV. + /// The X element contains Luma (Y, 0.0 to 1.0), the Y element contains Blue-difference chroma (U, -0.5 to 0.5), the Z element contains the Red-difference chroma (V, -0.5 to 0.5), and the W element contains the Alpha (a copy of the input's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + /// Color value to convert. + /// Converts using ITU-R BT.601/CCIR 601 W(r) = 0.299 W(b) = 0.114 U(max) = 0.436 V(max) = 0.615. + public static Vector4 ToYcbcr(Color4 rgb) + { + var y = 0.299f * rgb.R + 0.587f * rgb.G + 0.114f * rgb.B; + var u = -0.168736f * rgb.R + -0.331264f * rgb.G + 0.5f * rgb.B; + var v = 0.5f * rgb.R + -0.418688f * rgb.G + -0.081312f * rgb.B; + return new Vector4(y, u, v, rgb.A); + } + #endregion #endregion From c442a18d13065a5ef8b3937939f096e38185185b Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Mon, 10 Nov 2014 03:04:48 +0100 Subject: [PATCH 6/6] Add To/From HCY methods to Color4. --- Source/OpenTK/Graphics/Color4.cs | 108 +++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/Source/OpenTK/Graphics/Color4.cs b/Source/OpenTK/Graphics/Color4.cs index 265de069..3174d701 100644 --- a/Source/OpenTK/Graphics/Color4.cs +++ b/Source/OpenTK/Graphics/Color4.cs @@ -1319,6 +1319,114 @@ namespace OpenTK.Graphics #endregion + #region HCY + + /// + /// Converts HCY color values to RGB color values. + /// + /// + /// Returns the converted color value. + /// + /// + /// Color value to convert in hue, chroma, luminance (HCY). + /// The X element is Hue (H), the Y element is Chroma (C), the Z element is luminance (Y), and the W element is Alpha (which is copied to the output's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + public static Color4 FromHcy(Vector4 hcy) + { + var hue = hcy.X * 360.0f; + var C = hcy.Y; + var luminance = hcy.Z; + + var h = hue / 60.0f; + var X = C * (1.0f - Math.Abs(h % 2.0f - 1.0f)); + + float r, g, b; + if (0.0f <= h && h < 1.0f) + { + r = C; + g = X; + b = 0.0f; + } + else if (1.0f <= h && h < 2.0f) + { + r = X; + g = C; + b = 0.0f; + } + else if (2.0f <= h && h < 3.0f) + { + r = 0.0f; + g = C; + b = X; + } + else if (3.0f <= h && h < 4.0f) + { + r = 0.0f; + g = X; + b = C; + } + else if (4.0f <= h && h < 5.0f) + { + r = X; + g = 0.0f; + b = C; + } + else if (5.0f <= h && h < 6.0f) + { + r = C; + g = 0.0f; + b = X; + } + else + { + r = 0.0f; + g = 0.0f; + b = 0.0f; + } + + var m = luminance - (0.30f * r + 0.59f * g + 0.11f * b); + return new Color4(r + m, g + m, b + m, hcy.W); + } + + /// + /// Converts RGB color values to HCY color values. + /// + /// + /// Returns the converted color value. + /// The X element is Hue (H), the Y element is Chroma (C), the Z element is luminance (Y), and the W element is Alpha (a copy of the input's Alpha value). + /// Each has a range of 0.0 to 1.0. + /// + /// Color value to convert. + public static Vector4 ToHcy(Color4 rgb) + { + var M = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B)); + var m = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B)); + var C = M - m; + + float h = 0.0f; + if (M == rgb.R) + { + h = ((rgb.G - rgb.B) / C) % 6.0f; + } + else if (M == rgb.G) + { + h = ((rgb.B - rgb.R) / C) + 2.0f; + } + else if (M == rgb.B) + { + h = ((rgb.R - rgb.G) / C) + 4.0f; + } + + var hue = (h * 60.0f) / 360.0f; + + var luminance = 0.30f * rgb.R + 0.59f * rgb.G + 0.11f * rgb.B; + + return new Vector4(hue, C, luminance, rgb.A); + } + + #endregion + #endregion #region IEquatable Members