diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs
new file mode 100644
index 00000000..eeab6a61
--- /dev/null
+++ b/src/Graphics/Color.cs
@@ -0,0 +1,1886 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using System.Diagnostics;
+using System.Text;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Describes a 32-bit packed color.
+ ///
+ [Serializable]
+ [DebuggerDisplay("{DebugDisplayString,nq}")]
+ public struct Color : IEquatable, IPackedVector, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Gets or sets the blue component.
+ ///
+ public byte B
+ {
+ get
+ {
+ unchecked
+ {
+ return (byte) (this.packedValue >> 16);
+ }
+ }
+ set
+ {
+ this.packedValue = (this.packedValue & 0xff00ffff) | ((uint) value << 16);
+ }
+ }
+
+ ///
+ /// Gets or sets the green component.
+ ///
+ public byte G
+ {
+ get
+ {
+ unchecked
+ {
+ return (byte) (this.packedValue >> 8);
+ }
+ }
+ set
+ {
+ this.packedValue = (this.packedValue & 0xffff00ff) | ((uint) value << 8);
+ }
+ }
+
+ ///
+ /// Gets or sets the red component.
+ ///
+ public byte R
+ {
+ get
+ {
+ unchecked
+ {
+ return (byte) (this.packedValue);
+ }
+ }
+ set
+ {
+ this.packedValue = (this.packedValue & 0xffffff00) | value;
+ }
+ }
+
+ ///
+ /// Gets or sets the alpha component.
+ ///
+ public byte A
+ {
+ get
+ {
+ unchecked
+ {
+ return (byte) (this.packedValue >> 24);
+ }
+ }
+ set
+ {
+ this.packedValue = (this.packedValue & 0x00ffffff) | ((uint) value << 24);
+ }
+ }
+
+ ///
+ /// Gets or sets packed value of this .
+ ///
+ public UInt32 PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Public Static Color Properties
+
+ ///
+ /// Transparent color (R:0,G:0,B:0,A:0).
+ ///
+ public static Color Transparent
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// AliceBlue color (R:240,G:248,B:255,A:255).
+ ///
+ public static Color AliceBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// AntiqueWhite color (R:250,G:235,B:215,A:255).
+ ///
+ public static Color AntiqueWhite
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Aqua color (R:0,G:255,B:255,A:255).
+ ///
+ public static Color Aqua
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Aquamarine color (R:127,G:255,B:212,A:255).
+ ///
+ public static Color Aquamarine
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Azure color (R:240,G:255,B:255,A:255).
+ ///
+ public static Color Azure
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Beige color (R:245,G:245,B:220,A:255).
+ ///
+ public static Color Beige
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Bisque color (R:255,G:228,B:196,A:255).
+ ///
+ public static Color Bisque
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Black color (R:0,G:0,B:0,A:255).
+ ///
+ public static Color Black
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// BlanchedAlmond color (R:255,G:235,B:205,A:255).
+ ///
+ public static Color BlanchedAlmond
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Blue color (R:0,G:0,B:255,A:255).
+ ///
+ public static Color Blue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// BlueViolet color (R:138,G:43,B:226,A:255).
+ ///
+ public static Color BlueViolet
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Brown color (R:165,G:42,B:42,A:255).
+ ///
+ public static Color Brown
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// BurlyWood color (R:222,G:184,B:135,A:255).
+ ///
+ public static Color BurlyWood
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// CadetBlue color (R:95,G:158,B:160,A:255).
+ ///
+ public static Color CadetBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Chartreuse color (R:127,G:255,B:0,A:255).
+ ///
+ public static Color Chartreuse
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Chocolate color (R:210,G:105,B:30,A:255).
+ ///
+ public static Color Chocolate
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Coral color (R:255,G:127,B:80,A:255).
+ ///
+ public static Color Coral
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// CornflowerBlue color (R:100,G:149,B:237,A:255).
+ ///
+ public static Color CornflowerBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Cornsilk color (R:255,G:248,B:220,A:255).
+ ///
+ public static Color Cornsilk
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Crimson color (R:220,G:20,B:60,A:255).
+ ///
+ public static Color Crimson
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Cyan color (R:0,G:255,B:255,A:255).
+ ///
+ public static Color Cyan
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkBlue color (R:0,G:0,B:139,A:255).
+ ///
+ public static Color DarkBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkCyan color (R:0,G:139,B:139,A:255).
+ ///
+ public static Color DarkCyan
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkGoldenrod color (R:184,G:134,B:11,A:255).
+ ///
+ public static Color DarkGoldenrod
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkGray color (R:169,G:169,B:169,A:255).
+ ///
+ public static Color DarkGray
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkGreen color (R:0,G:100,B:0,A:255).
+ ///
+ public static Color DarkGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkKhaki color (R:189,G:183,B:107,A:255).
+ ///
+ public static Color DarkKhaki
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkMagenta color (R:139,G:0,B:139,A:255).
+ ///
+ public static Color DarkMagenta
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkOliveGreen color (R:85,G:107,B:47,A:255).
+ ///
+ public static Color DarkOliveGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkOrange color (R:255,G:140,B:0,A:255).
+ ///
+ public static Color DarkOrange
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkOrchid color (R:153,G:50,B:204,A:255).
+ ///
+ public static Color DarkOrchid
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkRed color (R:139,G:0,B:0,A:255).
+ ///
+ public static Color DarkRed
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkSalmon color (R:233,G:150,B:122,A:255).
+ ///
+ public static Color DarkSalmon
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkSeaGreen color (R:143,G:188,B:139,A:255).
+ ///
+ public static Color DarkSeaGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkSlateBlue color (R:72,G:61,B:139,A:255).
+ ///
+ public static Color DarkSlateBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkSlateGray color (R:47,G:79,B:79,A:255).
+ ///
+ public static Color DarkSlateGray
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkTurquoise color (R:0,G:206,B:209,A:255).
+ ///
+ public static Color DarkTurquoise
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DarkViolet color (R:148,G:0,B:211,A:255).
+ ///
+ public static Color DarkViolet
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DeepPink color (R:255,G:20,B:147,A:255).
+ ///
+ public static Color DeepPink
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DeepSkyBlue color (R:0,G:191,B:255,A:255).
+ ///
+ public static Color DeepSkyBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DimGray color (R:105,G:105,B:105,A:255).
+ ///
+ public static Color DimGray
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// DodgerBlue color (R:30,G:144,B:255,A:255).
+ ///
+ public static Color DodgerBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Firebrick color (R:178,G:34,B:34,A:255).
+ ///
+ public static Color Firebrick
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// FloralWhite color (R:255,G:250,B:240,A:255).
+ ///
+ public static Color FloralWhite
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// ForestGreen color (R:34,G:139,B:34,A:255).
+ ///
+ public static Color ForestGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Fuchsia color (R:255,G:0,B:255,A:255).
+ ///
+ public static Color Fuchsia
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Gainsboro color (R:220,G:220,B:220,A:255).
+ ///
+ public static Color Gainsboro
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// GhostWhite color (R:248,G:248,B:255,A:255).
+ ///
+ public static Color GhostWhite
+ {
+ get;
+ private set;
+ }
+ ///
+ /// Gold color (R:255,G:215,B:0,A:255).
+ ///
+ public static Color Gold
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Goldenrod color (R:218,G:165,B:32,A:255).
+ ///
+ public static Color Goldenrod
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Gray color (R:128,G:128,B:128,A:255).
+ ///
+ public static Color Gray
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Green color (R:0,G:128,B:0,A:255).
+ ///
+ public static Color Green
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// GreenYellow color (R:173,G:255,B:47,A:255).
+ ///
+ public static Color GreenYellow
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Honeydew color (R:240,G:255,B:240,A:255).
+ ///
+ public static Color Honeydew
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// HotPink color (R:255,G:105,B:180,A:255).
+ ///
+ public static Color HotPink
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// IndianRed color (R:205,G:92,B:92,A:255).
+ ///
+ public static Color IndianRed
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Indigo color (R:75,G:0,B:130,A:255).
+ ///
+ public static Color Indigo
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Ivory color (R:255,G:255,B:240,A:255).
+ ///
+ public static Color Ivory
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Khaki color (R:240,G:230,B:140,A:255).
+ ///
+ public static Color Khaki
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Lavender color (R:230,G:230,B:250,A:255).
+ ///
+ public static Color Lavender
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LavenderBlush color (R:255,G:240,B:245,A:255).
+ ///
+ public static Color LavenderBlush
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LawnGreen color (R:124,G:252,B:0,A:255).
+ ///
+ public static Color LawnGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LemonChiffon color (R:255,G:250,B:205,A:255).
+ ///
+ public static Color LemonChiffon
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightBlue color (R:173,G:216,B:230,A:255).
+ ///
+ public static Color LightBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightCoral color (R:240,G:128,B:128,A:255).
+ ///
+ public static Color LightCoral
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightCyan color (R:224,G:255,B:255,A:255).
+ ///
+ public static Color LightCyan
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightGoldenrodYellow color (R:250,G:250,B:210,A:255).
+ ///
+ public static Color LightGoldenrodYellow
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightGray color (R:211,G:211,B:211,A:255).
+ ///
+ public static Color LightGray
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightGreen color (R:144,G:238,B:144,A:255).
+ ///
+ public static Color LightGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightPink color (R:255,G:182,B:193,A:255).
+ ///
+ public static Color LightPink
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightSalmon color (R:255,G:160,B:122,A:255).
+ ///
+ public static Color LightSalmon
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightSeaGreen color (R:32,G:178,B:170,A:255).
+ ///
+ public static Color LightSeaGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightSkyBlue color (R:135,G:206,B:250,A:255).
+ ///
+ public static Color LightSkyBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightSlateGray color (R:119,G:136,B:153,A:255).
+ ///
+ public static Color LightSlateGray
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightSteelBlue color (R:176,G:196,B:222,A:255).
+ ///
+ public static Color LightSteelBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LightYellow color (R:255,G:255,B:224,A:255).
+ ///
+ public static Color LightYellow
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Lime color (R:0,G:255,B:0,A:255).
+ ///
+ public static Color Lime
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// LimeGreen color (R:50,G:205,B:50,A:255).
+ ///
+ public static Color LimeGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Linen color (R:250,G:240,B:230,A:255).
+ ///
+ public static Color Linen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Magenta color (R:255,G:0,B:255,A:255).
+ ///
+ public static Color Magenta
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Maroon color (R:128,G:0,B:0,A:255).
+ ///
+ public static Color Maroon
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumAquamarine color (R:102,G:205,B:170,A:255).
+ ///
+ public static Color MediumAquamarine
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumBlue color (R:0,G:0,B:205,A:255).
+ ///
+ public static Color MediumBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumOrchid color (R:186,G:85,B:211,A:255).
+ ///
+ public static Color MediumOrchid
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumPurple color (R:147,G:112,B:219,A:255).
+ ///
+ public static Color MediumPurple
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumSeaGreen color (R:60,G:179,B:113,A:255).
+ ///
+ public static Color MediumSeaGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumSlateBlue color (R:123,G:104,B:238,A:255).
+ ///
+ public static Color MediumSlateBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumSpringGreen color (R:0,G:250,B:154,A:255).
+ ///
+ public static Color MediumSpringGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumTurquoise color (R:72,G:209,B:204,A:255).
+ ///
+ public static Color MediumTurquoise
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MediumVioletRed color (R:199,G:21,B:133,A:255).
+ ///
+ public static Color MediumVioletRed
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MidnightBlue color (R:25,G:25,B:112,A:255).
+ ///
+ public static Color MidnightBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MintCream color (R:245,G:255,B:250,A:255).
+ ///
+ public static Color MintCream
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// MistyRose color (R:255,G:228,B:225,A:255).
+ ///
+ public static Color MistyRose
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Moccasin color (R:255,G:228,B:181,A:255).
+ ///
+ public static Color Moccasin
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// NavajoWhite color (R:255,G:222,B:173,A:255).
+ ///
+ public static Color NavajoWhite
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Navy color (R:0,G:0,B:128,A:255).
+ ///
+ public static Color Navy
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// OldLace color (R:253,G:245,B:230,A:255).
+ ///
+ public static Color OldLace
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Olive color (R:128,G:128,B:0,A:255).
+ ///
+ public static Color Olive
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// OliveDrab color (R:107,G:142,B:35,A:255).
+ ///
+ public static Color OliveDrab
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Orange color (R:255,G:165,B:0,A:255).
+ ///
+ public static Color Orange
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// OrangeRed color (R:255,G:69,B:0,A:255).
+ ///
+ public static Color OrangeRed
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Orchid color (R:218,G:112,B:214,A:255).
+ ///
+ public static Color Orchid
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// PaleGoldenrod color (R:238,G:232,B:170,A:255).
+ ///
+ public static Color PaleGoldenrod
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// PaleGreen color (R:152,G:251,B:152,A:255).
+ ///
+ public static Color PaleGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// PaleTurquoise color (R:175,G:238,B:238,A:255).
+ ///
+ public static Color PaleTurquoise
+ {
+ get;
+ private set;
+ }
+ ///
+ /// PaleVioletRed color (R:219,G:112,B:147,A:255).
+ ///
+ public static Color PaleVioletRed
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// PapayaWhip color (R:255,G:239,B:213,A:255).
+ ///
+ public static Color PapayaWhip
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// PeachPuff color (R:255,G:218,B:185,A:255).
+ ///
+ public static Color PeachPuff
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Peru color (R:205,G:133,B:63,A:255).
+ ///
+ public static Color Peru
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Pink color (R:255,G:192,B:203,A:255).
+ ///
+ public static Color Pink
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Plum color (R:221,G:160,B:221,A:255).
+ ///
+ public static Color Plum
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// PowderBlue color (R:176,G:224,B:230,A:255).
+ ///
+ public static Color PowderBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Purple color (R:128,G:0,B:128,A:255).
+ ///
+ public static Color Purple
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Red color (R:255,G:0,B:0,A:255).
+ ///
+ public static Color Red
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// RosyBrown color (R:188,G:143,B:143,A:255).
+ ///
+ public static Color RosyBrown
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// RoyalBlue color (R:65,G:105,B:225,A:255).
+ ///
+ public static Color RoyalBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SaddleBrown color (R:139,G:69,B:19,A:255).
+ ///
+ public static Color SaddleBrown
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Salmon color (R:250,G:128,B:114,A:255).
+ ///
+ public static Color Salmon
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SandyBrown color (R:244,G:164,B:96,A:255).
+ ///
+ public static Color SandyBrown
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SeaGreen color (R:46,G:139,B:87,A:255).
+ ///
+ public static Color SeaGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SeaShell color (R:255,G:245,B:238,A:255).
+ ///
+ public static Color SeaShell
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Sienna color (R:160,G:82,B:45,A:255).
+ ///
+ public static Color Sienna
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Silver color (R:192,G:192,B:192,A:255).
+ ///
+ public static Color Silver
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SkyBlue color (R:135,G:206,B:235,A:255).
+ ///
+ public static Color SkyBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SlateBlue color (R:106,G:90,B:205,A:255).
+ ///
+ public static Color SlateBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SlateGray color (R:112,G:128,B:144,A:255).
+ ///
+ public static Color SlateGray
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Snow color (R:255,G:250,B:250,A:255).
+ ///
+ public static Color Snow
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SpringGreen color (R:0,G:255,B:127,A:255).
+ ///
+ public static Color SpringGreen
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// SteelBlue color (R:70,G:130,B:180,A:255).
+ ///
+ public static Color SteelBlue
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Tan color (R:210,G:180,B:140,A:255).
+ ///
+ public static Color Tan
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Teal color (R:0,G:128,B:128,A:255).
+ ///
+ public static Color Teal
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Thistle color (R:216,G:191,B:216,A:255).
+ ///
+ public static Color Thistle
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Tomato color (R:255,G:99,B:71,A:255).
+ ///
+ public static Color Tomato
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Turquoise color (R:64,G:224,B:208,A:255).
+ ///
+ public static Color Turquoise
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Violet color (R:238,G:130,B:238,A:255).
+ ///
+ public static Color Violet
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Wheat color (R:245,G:222,B:179,A:255).
+ ///
+ public static Color Wheat
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// White color (R:255,G:255,B:255,A:255).
+ ///
+ public static Color White
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// WhiteSmoke color (R:245,G:245,B:245,A:255).
+ ///
+ public static Color WhiteSmoke
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Yellow color (R:255,G:255,B:0,A:255).
+ ///
+ public static Color Yellow
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// YellowGreen color (R:154,G:205,B:50,A:255).
+ ///
+ public static Color YellowGreen
+ {
+ get;
+ private set;
+ }
+
+ #endregion
+
+ #region Internal Properties
+
+ internal string DebugDisplayString
+ {
+ get
+ {
+ return string.Concat(
+ R.ToString(), " ",
+ G.ToString(), " ",
+ B.ToString(), " ",
+ A.ToString()
+ );
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ // ARGB. Keep this name as it is used by XNA games in reflection!
+ private uint packedValue;
+
+ #endregion
+
+ #region Private Static Constructors
+
+ static Color()
+ {
+ Transparent = new Color(0);
+ AliceBlue = new Color(0xfffff8f0);
+ AntiqueWhite = new Color(0xffd7ebfa);
+ Aqua = new Color(0xffffff00);
+ Aquamarine = new Color(0xffd4ff7f);
+ Azure = new Color(0xfffffff0);
+ Beige = new Color(0xffdcf5f5);
+ Bisque = new Color(0xffc4e4ff);
+ Black = new Color(0xff000000);
+ BlanchedAlmond = new Color(0xffcdebff);
+ Blue = new Color(0xffff0000);
+ BlueViolet = new Color(0xffe22b8a);
+ Brown = new Color(0xff2a2aa5);
+ BurlyWood = new Color(0xff87b8de);
+ CadetBlue = new Color(0xffa09e5f);
+ Chartreuse = new Color(0xff00ff7f);
+ Chocolate = new Color(0xff1e69d2);
+ Coral = new Color(0xff507fff);
+ CornflowerBlue = new Color(0xffed9564);
+ Cornsilk = new Color(0xffdcf8ff);
+ Crimson = new Color(0xff3c14dc);
+ Cyan = new Color(0xffffff00);
+ DarkBlue = new Color(0xff8b0000);
+ DarkCyan = new Color(0xff8b8b00);
+ DarkGoldenrod = new Color(0xff0b86b8);
+ DarkGray = new Color(0xffa9a9a9);
+ DarkGreen = new Color(0xff006400);
+ DarkKhaki = new Color(0xff6bb7bd);
+ DarkMagenta = new Color(0xff8b008b);
+ DarkOliveGreen = new Color(0xff2f6b55);
+ DarkOrange = new Color(0xff008cff);
+ DarkOrchid = new Color(0xffcc3299);
+ DarkRed = new Color(0xff00008b);
+ DarkSalmon = new Color(0xff7a96e9);
+ DarkSeaGreen = new Color(0xff8bbc8f);
+ DarkSlateBlue = new Color(0xff8b3d48);
+ DarkSlateGray = new Color(0xff4f4f2f);
+ DarkTurquoise = new Color(0xffd1ce00);
+ DarkViolet = new Color(0xffd30094);
+ DeepPink = new Color(0xff9314ff);
+ DeepSkyBlue = new Color(0xffffbf00);
+ DimGray = new Color(0xff696969);
+ DodgerBlue = new Color(0xffff901e);
+ Firebrick = new Color(0xff2222b2);
+ FloralWhite = new Color(0xfff0faff);
+ ForestGreen = new Color(0xff228b22);
+ Fuchsia = new Color(0xffff00ff);
+ Gainsboro = new Color(0xffdcdcdc);
+ GhostWhite = new Color(0xfffff8f8);
+ Gold = new Color(0xff00d7ff);
+ Goldenrod = new Color(0xff20a5da);
+ Gray = new Color(0xff808080);
+ Green = new Color(0xff008000);
+ GreenYellow = new Color(0xff2fffad);
+ Honeydew = new Color(0xfff0fff0);
+ HotPink = new Color(0xffb469ff);
+ IndianRed = new Color(0xff5c5ccd);
+ Indigo = new Color(0xff82004b);
+ Ivory = new Color(0xfff0ffff);
+ Khaki = new Color(0xff8ce6f0);
+ Lavender = new Color(0xfffae6e6);
+ LavenderBlush = new Color(0xfff5f0ff);
+ LawnGreen = new Color(0xff00fc7c);
+ LemonChiffon = new Color(0xffcdfaff);
+ LightBlue = new Color(0xffe6d8ad);
+ LightCoral = new Color(0xff8080f0);
+ LightCyan = new Color(0xffffffe0);
+ LightGoldenrodYellow = new Color(0xffd2fafa);
+ LightGray = new Color(0xffd3d3d3);
+ LightGreen = new Color(0xff90ee90);
+ LightPink = new Color(0xffc1b6ff);
+ LightSalmon = new Color(0xff7aa0ff);
+ LightSeaGreen = new Color(0xffaab220);
+ LightSkyBlue = new Color(0xffface87);
+ LightSlateGray = new Color(0xff998877);
+ LightSteelBlue = new Color(0xffdec4b0);
+ LightYellow = new Color(0xffe0ffff);
+ Lime = new Color(0xff00ff00);
+ LimeGreen = new Color(0xff32cd32);
+ Linen = new Color(0xffe6f0fa);
+ Magenta = new Color(0xffff00ff);
+ Maroon = new Color(0xff000080);
+ MediumAquamarine = new Color(0xffaacd66);
+ MediumBlue = new Color(0xffcd0000);
+ MediumOrchid = new Color(0xffd355ba);
+ MediumPurple = new Color(0xffdb7093);
+ MediumSeaGreen = new Color(0xff71b33c);
+ MediumSlateBlue = new Color(0xffee687b);
+ MediumSpringGreen = new Color(0xff9afa00);
+ MediumTurquoise = new Color(0xffccd148);
+ MediumVioletRed = new Color(0xff8515c7);
+ MidnightBlue = new Color(0xff701919);
+ MintCream = new Color(0xfffafff5);
+ MistyRose = new Color(0xffe1e4ff);
+ Moccasin = new Color(0xffb5e4ff);
+ NavajoWhite = new Color(0xffaddeff);
+ Navy = new Color(0xff800000);
+ OldLace = new Color(0xffe6f5fd);
+ Olive = new Color(0xff008080);
+ OliveDrab = new Color(0xff238e6b);
+ Orange = new Color(0xff00a5ff);
+ OrangeRed = new Color(0xff0045ff);
+ Orchid = new Color(0xffd670da);
+ PaleGoldenrod = new Color(0xffaae8ee);
+ PaleGreen = new Color(0xff98fb98);
+ PaleTurquoise = new Color(0xffeeeeaf);
+ PaleVioletRed = new Color(0xff9370db);
+ PapayaWhip = new Color(0xffd5efff);
+ PeachPuff = new Color(0xffb9daff);
+ Peru = new Color(0xff3f85cd);
+ Pink = new Color(0xffcbc0ff);
+ Plum = new Color(0xffdda0dd);
+ PowderBlue = new Color(0xffe6e0b0);
+ Purple = new Color(0xff800080);
+ Red = new Color(0xff0000ff);
+ RosyBrown = new Color(0xff8f8fbc);
+ RoyalBlue = new Color(0xffe16941);
+ SaddleBrown = new Color(0xff13458b);
+ Salmon= new Color(0xff7280fa);
+ SandyBrown = new Color(0xff60a4f4);
+ SeaGreen = new Color(0xff578b2e);
+ SeaShell = new Color(0xffeef5ff);
+ Sienna = new Color(0xff2d52a0);
+ Silver = new Color(0xffc0c0c0);
+ SkyBlue = new Color(0xffebce87);
+ SlateBlue= new Color(0xffcd5a6a);
+ SlateGray= new Color(0xff908070);
+ Snow= new Color(0xfffafaff);
+ SpringGreen= new Color(0xff7fff00);
+ SteelBlue= new Color(0xffb48246);
+ Tan= new Color(0xff8cb4d2);
+ Teal= new Color(0xff808000);
+ Thistle= new Color(0xffd8bfd8);
+ Tomato= new Color(0xff4763ff);
+ Turquoise= new Color(0xffd0e040);
+ Violet= new Color(0xffee82ee);
+ Wheat= new Color(0xffb3def5);
+ White= new Color(uint.MaxValue);
+ WhiteSmoke= new Color(0xfff5f5f5);
+ Yellow = new Color(0xff00ffff);
+ YellowGreen = new Color(0xff32cd9a);
+ }
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Creates a new instance of struct.
+ ///
+ /// A representing a color.
+ public Color(Vector4 color)
+ {
+ packedValue = 0;
+
+ R = (byte) MathHelper.Clamp(color.X * 255, Byte.MinValue, Byte.MaxValue);
+ G = (byte) MathHelper.Clamp(color.Y * 255, Byte.MinValue, Byte.MaxValue);
+ B = (byte) MathHelper.Clamp(color.Z * 255, Byte.MinValue, Byte.MaxValue);
+ A = (byte) MathHelper.Clamp(color.W * 255, Byte.MinValue, Byte.MaxValue);
+ }
+
+ ///
+ /// Constructs an RGBA color from the XYZW unit length components of a vector.
+ ///
+ /// A representing a color.
+ public Color(Vector3 color)
+ {
+ packedValue = 0;
+
+ R = (byte) MathHelper.Clamp(color.X * 255, Byte.MinValue, Byte.MaxValue);
+ G = (byte) MathHelper.Clamp(color.Y * 255, Byte.MinValue, Byte.MaxValue);
+ B = (byte) MathHelper.Clamp(color.Z * 255, Byte.MinValue, Byte.MaxValue);
+ A = 255;
+ }
+
+ ///
+ /// Constructs an RGBA color from scalars which representing red, green and blue values. Alpha value will be opaque.
+ ///
+ /// Red component value from 0.0f to 1.0f.
+ /// Green component value from 0.0f to 1.0f.
+ /// Blue component value from 0.0f to 1.0f.
+ public Color(float r, float g, float b)
+ {
+ packedValue = 0;
+
+ R = (byte) MathHelper.Clamp(r * 255, Byte.MinValue, Byte.MaxValue);
+ G = (byte) MathHelper.Clamp(g * 255, Byte.MinValue, Byte.MaxValue);
+ B = (byte) MathHelper.Clamp(b * 255, Byte.MinValue, Byte.MaxValue);
+ A = 255;
+ }
+
+ ///
+ /// Constructs an RGBA color from scalars which representing red, green and blue values. Alpha value will be opaque.
+ ///
+ /// Red component value from 0 to 255.
+ /// Green component value from 0 to 255.
+ /// Blue component value from 0 to 255.
+ public Color(int r, int g, int b)
+ {
+ packedValue = 0;
+ R = (byte) MathHelper.Clamp(r, Byte.MinValue, Byte.MaxValue);
+ G = (byte) MathHelper.Clamp(g, Byte.MinValue, Byte.MaxValue);
+ B = (byte) MathHelper.Clamp(b, Byte.MinValue, Byte.MaxValue);
+ A = (byte)255;
+ }
+
+ ///
+ /// Constructs an RGBA color from scalars which representing red, green, blue and alpha values.
+ ///
+ /// Red component value from 0 to 255.
+ /// Green component value from 0 to 255.
+ /// Blue component value from 0 to 255.
+ /// Alpha component value from 0 to 255.
+ public Color(int r, int g, int b, int alpha)
+ {
+ packedValue = 0;
+ R = (byte) MathHelper.Clamp(r, Byte.MinValue, Byte.MaxValue);
+ G = (byte) MathHelper.Clamp(g, Byte.MinValue, Byte.MaxValue);
+ B = (byte) MathHelper.Clamp(b, Byte.MinValue, Byte.MaxValue);
+ A = (byte) MathHelper.Clamp(alpha, Byte.MinValue, Byte.MaxValue);
+ }
+
+ ///
+ /// Constructs an RGBA color from scalars which representing red, green, blue and alpha values.
+ ///
+ /// Red component value from 0.0f to 1.0f.
+ /// Green component value from 0.0f to 1.0f.
+ /// Blue component value from 0.0f to 1.0f.
+ /// Alpha component value from 0.0f to 1.0f.
+ public Color(float r, float g, float b, float alpha)
+ {
+ packedValue = 0;
+
+ R = (byte) MathHelper.Clamp(r * 255, Byte.MinValue, Byte.MaxValue);
+ G = (byte) MathHelper.Clamp(g * 255, Byte.MinValue, Byte.MaxValue);
+ B = (byte) MathHelper.Clamp(b * 255, Byte.MinValue, Byte.MaxValue);
+ A = (byte) MathHelper.Clamp(alpha * 255, Byte.MinValue, Byte.MaxValue);
+ }
+
+ #endregion
+
+ #region Private Constructors
+
+ private Color(uint packedValue)
+ {
+ this.packedValue = packedValue;
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Compares whether current instance is equal to specified .
+ ///
+ /// The to compare.
+ /// true if the instances are equal; false otherwise.
+ public bool Equals(Color other)
+ {
+ return this.PackedValue == other.PackedValue;
+ }
+
+ ///
+ /// Gets a representation for this object.
+ ///
+ /// A representation for this object.
+ public Vector3 ToVector3()
+ {
+ return new Vector3(R / 255.0f, G / 255.0f, B / 255.0f);
+ }
+
+ ///
+ /// Gets a representation for this object.
+ ///
+ /// A representation for this object.
+ public Vector4 ToVector4()
+ {
+ return new Vector4(R / 255.0f, G / 255.0f, B / 255.0f, A / 255.0f);
+ }
+
+ #endregion
+
+ #region Public Static Methods
+
+ ///
+ /// Performs linear interpolation of .
+ ///
+ /// Source .
+ /// Destination .
+ /// Interpolation factor.
+ /// Interpolated .
+ public static Color Lerp(Color value1, Color value2, float amount)
+ {
+ amount = MathHelper.Clamp(amount, 0.0f, 1.0f);
+ return new Color(
+ (int) MathHelper.Lerp(value1.R, value2.R, amount),
+ (int) MathHelper.Lerp(value1.G, value2.G, amount),
+ (int) MathHelper.Lerp(value1.B, value2.B, amount),
+ (int) MathHelper.Lerp(value1.A, value2.A, amount)
+ );
+ }
+
+ ///
+ /// Translate a non-premultipled alpha to a
+ /// that contains premultiplied alpha.
+ ///
+ /// A representing color.
+ /// A which contains premultiplied alpha data.
+ public static Color FromNonPremultiplied(Vector4 vector)
+ {
+ return new Color(
+ vector.X * vector.W,
+ vector.Y * vector.W,
+ vector.Z * vector.W,
+ vector.W
+ );
+ }
+
+ ///
+ /// Translate a non-premultipled alpha to a
+ /// that contains premultiplied alpha.
+ ///
+ /// Red component value.
+ /// Green component value.
+ /// Blue component value.
+ /// Alpha component value.
+ /// A which contains premultiplied alpha data.
+ public static Color FromNonPremultiplied(int r, int g, int b, int a)
+ {
+ return new Color(
+ (r * a / 255),
+ (g * a / 255),
+ (b * a / 255),
+ a
+ );
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares whether two instances are equal.
+ ///
+ /// instance on the left of the equal sign.
+ /// instance on the right of the equal sign.
+ /// True if the instances are equal; false otherwise.
+ public static bool operator ==(Color a, Color b)
+ {
+ return ( a.A == b.A &&
+ a.R == b.R &&
+ a.G == b.G &&
+ a.B == b.B );
+ }
+
+ ///
+ /// Compares whether two instances are not equal.
+ ///
+ ///
+ /// instance on the left of the not equal sign.
+ ///
+ ///
+ /// instance on the right of the not equal sign.
+ ///
+ ///
+ /// True if the instances are not equal; false otherwise.
+ ///
+ public static bool operator !=(Color a, Color b)
+ {
+ return !(a == b);
+ }
+
+ ///
+ /// Gets the hash code of this .
+ ///
+ /// Hash code of this .
+ public override int GetHashCode()
+ {
+ return this.packedValue.GetHashCode();
+ }
+
+ ///
+ /// Compares whether current instance is equal to specified object.
+ ///
+ /// The to compare.
+ /// True if the instances are equal; false otherwise.
+ public override bool Equals(object obj)
+ {
+ return ((obj is Color) && this.Equals((Color) obj));
+ }
+
+ ///
+ /// Multiply by value.
+ ///
+ /// Source .
+ /// Multiplicator.
+ /// Multiplication result.
+ public static Color Multiply(Color value, float scale)
+ {
+ return new Color(
+ (int) (value.R * scale),
+ (int) (value.G * scale),
+ (int) (value.B * scale),
+ (int) (value.A * scale)
+ );
+ }
+
+ ///
+ /// Multiply by value.
+ ///
+ /// Source .
+ /// Multiplicator.
+ /// Multiplication result.
+ public static Color operator *(Color value, float scale)
+ {
+ return new Color(
+ (int) (value.R * scale),
+ (int) (value.G * scale),
+ (int) (value.B * scale),
+ (int) (value.A * scale)
+ );
+ }
+
+ ///
+ /// Returns a representation of this in the format:
+ /// {R:[red] G:[green] B:[blue] A:[alpha]}
+ ///
+ /// representation of this .
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder(25);
+ sb.Append("{R:");
+ sb.Append(R);
+ sb.Append(" G:");
+ sb.Append(G);
+ sb.Append(" B:");
+ sb.Append(B);
+ sb.Append(" A:");
+ sb.Append(A);
+ sb.Append("}");
+ return sb.ToString();
+ }
+
+ #endregion
+
+ #region IPackedVector Member
+
+ ///
+ /// Pack a four-component color from a vector format into the format of a color object.
+ ///
+ /// A four-component color.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ // Should we round here?
+ R = (byte) (vector.X * 255.0f);
+ G = (byte) (vector.Y * 255.0f);
+ B = (byte) (vector.Z * 255.0f);
+ A = (byte) (vector.W * 255.0f);
+ }
+
+ #endregion
+
+ }
+}
diff --git a/src/Graphics/PackedVector/Alpha8.cs b/src/Graphics/PackedVector/Alpha8.cs
new file mode 100644
index 00000000..8139bae3
--- /dev/null
+++ b/src/Graphics/PackedVector/Alpha8.cs
@@ -0,0 +1,171 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing unsigned normalized values ranging from 0 to 1.
+ /// The x and z components use 5 bits, and the y component uses 6 bits.
+ ///
+ public struct Alpha8 : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Gets and sets the packed value.
+ ///
+ public byte PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private byte packedValue;
+
+ #endregion
+
+ #region Public Constructor
+
+ ///
+ /// Creates a new instance of Alpha8.
+ ///
+ /// The alpha component
+ public Alpha8(float alpha)
+ {
+ packedValue = Pack(alpha);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Gets the packed vector in float format.
+ ///
+ /// The packed vector in Vector3 format
+ public float ToAlpha()
+ {
+ return (float) (packedValue / 255.0f);
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed vector from a Vector4.
+ ///
+ /// Vector containing the components.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.W);
+ }
+
+ ///
+ /// Gets the packed vector in Vector4 format.
+ ///
+ /// The packed vector in Vector4 format
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ (float) (packedValue / 255.0f)
+ );
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares an object with the packed vector.
+ ///
+ /// The object to compare.
+ /// True if the object is equal to the packed vector.
+ public override bool Equals(object obj)
+ {
+ return (obj is Alpha8) && Equals((Alpha8) obj);
+ }
+
+ ///
+ /// Compares another Bgra5551 packed vector with the packed vector.
+ ///
+ /// The Bgra5551 packed vector to compare.
+ /// True if the packed vectors are equal.
+ public bool Equals(Alpha8 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ ///
+ /// Gets a string representation of the packed vector.
+ ///
+ /// A string representation of the packed vector.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets a hash code of the packed vector.
+ ///
+ /// The hash code for the packed vector.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(Alpha8 lhs, Alpha8 rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(Alpha8 lhs, Alpha8 rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static byte Pack(float alpha)
+ {
+ return (byte) System.Math.Round(
+ MathHelper.Clamp(alpha, 0, 1) * 255.0f
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Bgr565.cs b/src/Graphics/PackedVector/Bgr565.cs
new file mode 100644
index 00000000..416c49c3
--- /dev/null
+++ b/src/Graphics/PackedVector/Bgr565.cs
@@ -0,0 +1,185 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing unsigned normalized values ranging from 0 to 1.
+ /// The x and z components use 5 bits, and the y component uses 6 bits.
+ ///
+ public struct Bgr565 : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Gets and sets the packed value.
+ ///
+ public ushort PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ushort packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Creates a new instance of Bgr565.
+ ///
+ /// The x component
+ /// The y component
+ /// The z component
+ public Bgr565(float x, float y, float z)
+ {
+ packedValue = Pack(x, y, z);
+ }
+
+ ///
+ /// Creates a new instance of Bgr565.
+ ///
+ ///
+ /// Vector containing the components for the packed vector.
+ ///
+ public Bgr565(Vector3 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Gets the packed vector in Vector3 format.
+ ///
+ /// The packed vector in Vector3 format
+ public Vector3 ToVector3()
+ {
+ return new Vector3(
+ (packedValue >> 11) / 31.0f,
+ ((packedValue >> 5) & 0x3F) / 63.0f,
+ (packedValue & 0x1F) / 31.0f
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed vector from a Vector4.
+ ///
+ /// Vector containing the components.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ Pack(vector.X, vector.Y, vector.Z);
+ }
+
+ ///
+ /// Gets the packed vector in Vector4 format.
+ ///
+ /// The packed vector in Vector4 format
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(ToVector3(), 1.0f);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares an object with the packed vector.
+ ///
+ /// The object to compare.
+ /// True if the object is equal to the packed vector.
+ public override bool Equals(object obj)
+ {
+ return (obj is Bgr565) && Equals((Bgr565) obj);
+ }
+
+ ///
+ /// Compares another Bgr565 packed vector with the packed vector.
+ ///
+ /// The Bgr565 packed vector to compare.
+ /// True if the packed vectors are equal.
+ public bool Equals(Bgr565 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ ///
+ /// Gets a string representation of the packed vector.
+ ///
+ /// A string representation of the packed vector.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets a hash code of the packed vector.
+ ///
+ /// The hash code for the packed vector.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(Bgr565 lhs, Bgr565 rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(Bgr565 lhs, Bgr565 rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static ushort Pack(float x, float y, float z)
+ {
+ return (ushort) (
+ (((ushort) System.Math.Round(MathHelper.Clamp(x, 0, 1) * 31.0f)) << 11) |
+ (((ushort) System.Math.Round(MathHelper.Clamp(y, 0, 1) * 63.0f)) << 5) |
+ ((ushort) System.Math.Round(MathHelper.Clamp(z, 0, 1) * 31.0f))
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Bgra4444.cs b/src/Graphics/PackedVector/Bgra4444.cs
new file mode 100644
index 00000000..96f62f89
--- /dev/null
+++ b/src/Graphics/PackedVector/Bgra4444.cs
@@ -0,0 +1,179 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing unsigned normalized values, ranging from 0 to 1, using
+ /// 4 bits each for x, y, z, and w.
+ ///
+ public struct Bgra4444 : IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ ///
+ /// Gets and sets the packed value.
+ ///
+ public ushort PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ushort packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Creates a new instance of Bgra4444.
+ ///
+ /// The x component
+ /// The y component
+ /// The z component
+ /// The w component
+ public Bgra4444(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ ///
+ /// Creates a new instance of Bgra4444.
+ ///
+ ///
+ /// Vector containing the components for the packed vector.
+ ///
+ public Bgra4444(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Gets the packed vector in Vector4 format.
+ ///
+ /// The packed vector in Vector4 format
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ ((packedValue >> 8) & 0x0F) / 15.0f,
+ ((packedValue >> 4) & 0x0F) / 15.0f,
+ (packedValue & 0x0F) / 15.0f,
+ (packedValue >> 12) / 15.0f
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed vector from a Vector4.
+ ///
+ /// Vector containing the components.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares an object with the packed vector.
+ ///
+ /// The object to compare.
+ /// True if the object is equal to the packed vector.
+ public override bool Equals(object obj)
+ {
+ return (obj is Bgra4444) && Equals((Bgra4444) obj);
+ }
+
+ ///
+ /// Compares another Bgra4444 packed vector with the packed vector.
+ ///
+ /// The Bgra4444 packed vector to compare.
+ /// True if the packed vectors are equal.
+ public bool Equals(Bgra4444 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ ///
+ /// Gets a string representation of the packed vector.
+ ///
+ /// A string representation of the packed vector.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets a hash code of the packed vector.
+ ///
+ /// The hash code for the packed vector.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(Bgra4444 lhs, Bgra4444 rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(Bgra4444 lhs, Bgra4444 rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static ushort Pack(float x, float y, float z, float w)
+ {
+ return (ushort) (
+ (((ushort) System.Math.Round(MathHelper.Clamp(x, 0, 1) * 15.0f)) << 8) |
+ (((ushort) System.Math.Round(MathHelper.Clamp(y, 0, 1) * 15.0f)) << 4) |
+ ((ushort) System.Math.Round(MathHelper.Clamp(z, 0, 1) * 15.0f)) |
+ (((ushort) System.Math.Round(MathHelper.Clamp(w, 0, 1) * 15.0f)) << 12)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Bgra5551.cs b/src/Graphics/PackedVector/Bgra5551.cs
new file mode 100644
index 00000000..84bcce16
--- /dev/null
+++ b/src/Graphics/PackedVector/Bgra5551.cs
@@ -0,0 +1,179 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing unsigned normalized values ranging from 0 to 1.
+ /// The x and z components use 5 bits, and the y component uses 6 bits.
+ ///
+ public struct Bgra5551 : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Gets and sets the packed value.
+ ///
+ public ushort PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ushort packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Creates a new instance of Bgra5551.
+ ///
+ /// The x component
+ /// The y component
+ /// The z component
+ /// The w component
+ public Bgra5551(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ ///
+ /// Creates a new instance of Bgra5551.
+ ///
+ ///
+ /// Vector containing the components for the packed vector.
+ ///
+ public Bgra5551(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Gets the packed vector in Vector4 format.
+ ///
+ /// The packed vector in Vector4 format
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ ((packedValue >> 10) & 0x1F) / 31.0f,
+ ((packedValue >> 5) & 0x1F) / 31.0f,
+ (packedValue & 0x1F) / 31.0f,
+ (float) (packedValue >> 15)
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed vector from a Vector4.
+ ///
+ /// Vector containing the components.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares an object with the packed vector.
+ ///
+ /// The object to compare.
+ /// True if the object is equal to the packed vector.
+ public override bool Equals(object obj)
+ {
+ return (obj is Bgra5551) && Equals((Bgra5551) obj);
+ }
+
+ ///
+ /// Compares another Bgra5551 packed vector with the packed vector.
+ ///
+ /// The Bgra5551 packed vector to compare.
+ /// True if the packed vectors are equal.
+ public bool Equals(Bgra5551 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ ///
+ /// Gets a string representation of the packed vector.
+ ///
+ /// A string representation of the packed vector.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets a hash code of the packed vector.
+ ///
+ /// The hash code for the packed vector.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(Bgra5551 lhs, Bgra5551 rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(Bgra5551 lhs, Bgra5551 rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static ushort Pack(float x, float y, float z, float w)
+ {
+ return (ushort) (
+ (((ushort) System.Math.Round(MathHelper.Clamp(x, 0, 1) * 31.0f)) << 10) |
+ (((ushort) System.Math.Round(MathHelper.Clamp(y, 0, 1) * 31.0f)) << 5) |
+ ((ushort) System.Math.Round(MathHelper.Clamp(z, 0, 1) * 31.0f)) |
+ ((ushort) System.Math.Round(MathHelper.Clamp(w, 0, 1)) << 15)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Byte4.cs b/src/Graphics/PackedVector/Byte4.cs
new file mode 100644
index 00000000..03c08bd8
--- /dev/null
+++ b/src/Graphics/PackedVector/Byte4.cs
@@ -0,0 +1,204 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing four 8-bit unsigned integer values, ranging from 0 to 255.
+ ///
+ public struct Byte4 : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Directly gets or sets the packed representation of the value.
+ ///
+ /// The packed representation of the value.
+ public uint PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private uint packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Initializes a new instance of the Byte4 class.
+ ///
+ ///
+ /// A vector containing the initial values for the components of the Byte4 structure.
+ ///
+ public Byte4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ ///
+ /// Initializes a new instance of the Byte4 class.
+ ///
+ /// Initial value for the x component.
+ /// Initial value for the y component.
+ /// Initial value for the z component.
+ /// Initial value for the w component.
+ public Byte4(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Expands the packed representation into a Vector4.
+ ///
+ /// The expanded vector.
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ (packedValue & 0xFF),
+ ((packedValue >> 8) & 0xFF),
+ ((packedValue >> 16) & 0xFF),
+ (packedValue >> 24)
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed representation from a Vector4.
+ ///
+ /// The vector to create the packed representation from.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares the current instance of a class to another instance to determine
+ /// whether they are different.
+ ///
+ /// The object to the left of the equality operator.
+ /// The object to the right of the equality operator.
+ /// True if the objects are different; false otherwise.
+ public static bool operator !=(Byte4 a, Byte4 b)
+ {
+ return a.packedValue != b.packedValue;
+ }
+
+ ///
+ /// Compares the current instance of a class to another instance to determine
+ /// whether they are the same.
+ ///
+ /// The object to the left of the equality operator.
+ /// The object to the right of the equality operator.
+ /// True if the objects are the same; false otherwise.
+ public static bool operator ==(Byte4 a, Byte4 b)
+ {
+ return a.packedValue == b.packedValue;
+ }
+
+ ///
+ /// Returns a value that indicates whether the current instance is equal to a
+ /// specified object.
+ ///
+ /// The object with which to make the comparison.
+ ///
+ /// True if the current instance is equal to the specified object; false otherwise.
+ ///
+ public override bool Equals(object obj)
+ {
+ return (obj is Byte4) && Equals((Byte4) obj);
+ }
+
+ ///
+ /// Returns a value that indicates whether the current instance is equal to a
+ /// specified object.
+ ///
+ /// The object with which to make the comparison.
+ ///
+ /// True if the current instance is equal to the specified object; false otherwise.
+ ///
+ public bool Equals(Byte4 other)
+ {
+ return this == other;
+ }
+
+ ///
+ /// Gets the hash code for the current instance.
+ ///
+ /// Hash code for the instance.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ ///
+ /// Returns a string representation of the current instance.
+ ///
+ /// String that represents the object.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ ///
+ /// Packs a vector into a uint.
+ ///
+ /// The vector containing the values to pack.
+ /// The ulong containing the packed values.
+ static uint Pack(float x, float y, float z, float w)
+ {
+ return (uint) (
+ ((uint) System.Math.Round(MathHelper.Clamp(x, 0, 255))) |
+ ((uint) System.Math.Round(MathHelper.Clamp(y, 0, 255)) << 8) |
+ ((uint) System.Math.Round(MathHelper.Clamp(z, 0, 255)) << 16) |
+ ((uint) System.Math.Round(MathHelper.Clamp(w, 0, 255)) << 24)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/HalfSingle.cs b/src/Graphics/PackedVector/HalfSingle.cs
new file mode 100644
index 00000000..245af11d
--- /dev/null
+++ b/src/Graphics/PackedVector/HalfSingle.cs
@@ -0,0 +1,114 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ public struct HalfSingle : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ public ushort PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ushort packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public HalfSingle(float single)
+ {
+ packedValue = HalfTypeHelper.Convert(single);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public float ToSingle()
+ {
+ return HalfTypeHelper.Convert(packedValue);
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = HalfTypeHelper.Convert(vector.X);
+ }
+
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(ToSingle(), 0.0f, 0.0f, 1.0f);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ public override bool Equals(object obj)
+ {
+ return (obj is HalfSingle) && Equals((HalfSingle) obj);
+ }
+
+ public bool Equals(HalfSingle other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(HalfSingle lhs, HalfSingle rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(HalfSingle lhs, HalfSingle rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/HalfTypeHelper.cs b/src/Graphics/PackedVector/HalfTypeHelper.cs
new file mode 100644
index 00000000..857e7ac8
--- /dev/null
+++ b/src/Graphics/PackedVector/HalfTypeHelper.cs
@@ -0,0 +1,139 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using System.Runtime.InteropServices;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ internal static class HalfTypeHelper
+ {
+ #region Private Struct uif
+
+ [StructLayout(LayoutKind.Explicit)]
+ private struct uif
+ {
+ [FieldOffset(0)]
+ public float f;
+ [FieldOffset(0)]
+ public int i;
+ [FieldOffset(0)]
+ public uint u;
+ }
+
+ #endregion
+
+ #region Internal Static Methods
+
+ internal static ushort Convert(float f)
+ {
+ uif uif = new uif();
+ uif.f = f;
+ return Convert(uif.i);
+ }
+
+ internal static ushort Convert(int i)
+ {
+ int s = (i >> 16) & 0x00008000;
+ int e = ((i >> 23) & 0x000000ff) - (127 - 15);
+ int m = i & 0x007fffff;
+
+ if (e <= 0)
+ {
+ if (e < -10)
+ {
+ return (ushort) s;
+ }
+
+ m = m | 0x00800000;
+
+ int t = 14 - e;
+ int a = (1 << (t - 1)) - 1;
+ int b = (m >> t) & 1;
+
+ m = (m + a + b) >> t;
+
+ return (ushort) (s | m);
+ }
+ else if (e == 0xff - (127 - 15))
+ {
+ if (m == 0)
+ {
+ return (ushort) (s | 0x7c00);
+ }
+ else
+ {
+ m >>= 13;
+ return (ushort) (s | 0x7c00 | m | ((m == 0) ? 1 : 0));
+ }
+ }
+ else
+ {
+ m = m + 0x00000fff + ((m >> 13) & 1);
+
+ if ((m & 0x00800000) != 0)
+ {
+ m = 0;
+ e += 1;
+ }
+
+ if (e > 30)
+ {
+ return (ushort) (s | 0x7c00);
+ }
+
+ return (ushort) (s | (e << 10) | (m >> 13));
+ }
+ }
+
+ internal static float Convert(ushort value)
+ {
+ uint rst;
+ uint mantissa = (uint)(value & 1023);
+ uint exp = 0xfffffff2;
+
+ if ((value & -33792) == 0)
+ {
+ if (mantissa != 0)
+ {
+ while ((mantissa & 1024) == 0)
+ {
+ exp--;
+ mantissa = mantissa << 1;
+ }
+ mantissa &= 0xfffffbff;
+ rst = ((uint) ((((uint) value & 0x8000) << 16) | ((exp + 127) << 23))) | (mantissa << 13);
+ }
+ else
+ {
+ rst = (uint) ((value & 0x8000) << 16);
+ }
+ }
+ else
+ {
+ rst = (uint) (((((uint) value & 0x8000) << 16) | ((((((uint) value >> 10) & 0x1f) - 15) + 127) << 23)) | (mantissa << 13));
+ }
+
+ uif uif = new uif();
+ uif.u = rst;
+ return uif.f;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/HalfVector2.cs b/src/Graphics/PackedVector/HalfVector2.cs
new file mode 100644
index 00000000..7a6d0bcf
--- /dev/null
+++ b/src/Graphics/PackedVector/HalfVector2.cs
@@ -0,0 +1,134 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ public struct HalfVector2 : IPackedVector, IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ public uint PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private uint packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public HalfVector2(float x, float y)
+ {
+ packedValue = PackHelper(x, y);
+ }
+
+ public HalfVector2(Vector2 vector)
+ {
+ packedValue = PackHelper(vector.X, vector.Y);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public Vector2 ToVector2()
+ {
+ Vector2 vector;
+ vector.X = HalfTypeHelper.Convert((ushort) packedValue);
+ vector.Y = HalfTypeHelper.Convert((ushort) (packedValue >> 0x10));
+ return vector;
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = PackHelper(vector.X, vector.Y);
+ }
+
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(ToVector2(), 0.0f, 1.0f);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return ((obj is HalfVector2) && Equals((HalfVector2) obj));
+ }
+
+ public bool Equals(HalfVector2 other)
+ {
+ return packedValue.Equals(other.packedValue);
+ }
+
+ public static bool operator ==(HalfVector2 a, HalfVector2 b)
+ {
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(HalfVector2 a, HalfVector2 b)
+ {
+ return !a.Equals(b);
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static uint PackHelper(float vectorX, float vectorY)
+ {
+ return (uint) (
+ HalfTypeHelper.Convert(vectorX) |
+ ((uint) (HalfTypeHelper.Convert(vectorY) << 0x10))
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/HalfVector4.cs b/src/Graphics/PackedVector/HalfVector4.cs
new file mode 100644
index 00000000..e99d1c4d
--- /dev/null
+++ b/src/Graphics/PackedVector/HalfVector4.cs
@@ -0,0 +1,205 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing four 16-bit floating-point values.
+ ///
+ public struct HalfVector4 : IPackedVector, IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ ///
+ /// Directly gets or sets the packed representation of the value.
+ ///
+ /// The packed representation of the value.
+ public ulong PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ulong packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Initializes a new instance of the HalfVector4 structure.
+ ///
+ /// Initial value for the x component.
+ /// Initial value for the y component.
+ /// Initial value for the z component.
+ /// Initial value for the q component.
+ public HalfVector4(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ ///
+ /// Initializes a new instance of the HalfVector4 structure.
+ ///
+ ///
+ /// A vector containing the initial values for the components of the HalfVector4
+ /// structure.
+ ///
+ public HalfVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Expands the packed representation into a Vector4.
+ ///
+ /// The expanded vector.
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ HalfTypeHelper.Convert((ushort) packedValue),
+ HalfTypeHelper.Convert((ushort) (packedValue >> 0x10)),
+ HalfTypeHelper.Convert((ushort) (packedValue >> 0x20)),
+ HalfTypeHelper.Convert((ushort) (packedValue >> 0x30))
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed representation from a Vector4.
+ ///
+ /// The vector to create the packed representation from.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Returns a string representation of the current instance.
+ ///
+ /// String that represents the object.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets the hash code for the current instance.
+ ///
+ /// Hash code for the instance.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ ///
+ /// Returns a value that indicates whether the current instance is equal to a
+ /// specified object.
+ ///
+ /// The object with which to make the comparison.
+ ///
+ /// True if the current instance is equal to the specified object; false otherwise.
+ ///
+ public override bool Equals(object obj)
+ {
+ return ((obj is HalfVector4) && Equals((HalfVector4) obj));
+ }
+
+ ///
+ /// Returns a value that indicates whether the current instance is equal to a
+ /// specified object.
+ ///
+ /// The object with which to make the comparison.
+ ///
+ /// True if the current instance is equal to the specified object; false otherwise.
+ ///
+ public bool Equals(HalfVector4 other)
+ {
+ return packedValue.Equals(other.packedValue);
+ }
+
+ ///
+ /// Compares the current instance of a class to another instance to determine
+ /// whether they are the same.
+ ///
+ /// The object to the left of the equality operator.
+ /// The object to the right of the equality operator.
+ /// True if the objects are the same; false otherwise.
+ public static bool operator ==(HalfVector4 a, HalfVector4 b)
+ {
+ return a.Equals(b);
+ }
+
+ ///
+ /// Compares the current instance of a class to another instance to determine
+ /// whether they are different.
+ ///
+ /// The object to the left of the equality operator.
+ /// The object to the right of the equality operator.
+ /// True if the objects are different; false otherwise.
+ public static bool operator !=(HalfVector4 a, HalfVector4 b)
+ {
+ return !a.Equals(b);
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ ///
+ /// Packs a vector into a ulong.
+ ///
+ /// The vector containing the values to pack.
+ /// The ulong containing the packed values.
+ private static ulong Pack(float x, float y, float z, float w)
+ {
+ return (ulong) (
+ ((ulong) HalfTypeHelper.Convert(x)) |
+ (((ulong) HalfTypeHelper.Convert(y) << 0x10)) |
+ (((ulong) HalfTypeHelper.Convert(z) << 0x20)) |
+ (((ulong) HalfTypeHelper.Convert(w) << 0x30))
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/IPackedVector.cs b/src/Graphics/PackedVector/IPackedVector.cs
new file mode 100644
index 00000000..8a107201
--- /dev/null
+++ b/src/Graphics/PackedVector/IPackedVector.cs
@@ -0,0 +1,39 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+using MoonWorks.Math;
+
+namespace MoonWorks.Graphics
+{
+ // http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.packedvector.ipackedvector.aspx
+ public interface IPackedVector
+ {
+ void PackFromVector4(Vector4 vector);
+
+ Vector4 ToVector4();
+ }
+
+ // PackedVector Generic interface
+ // http://msdn.microsoft.com/en-us/library/bb197661.aspx
+ public interface IPackedVector : IPackedVector
+ {
+ TPacked PackedValue
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/src/Graphics/PackedVector/NormalizedByte2.cs b/src/Graphics/PackedVector/NormalizedByte2.cs
new file mode 100644
index 00000000..8ed0933f
--- /dev/null
+++ b/src/Graphics/PackedVector/NormalizedByte2.cs
@@ -0,0 +1,142 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ public struct NormalizedByte2 : IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ public ushort PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ushort packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public NormalizedByte2(Vector2 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ public NormalizedByte2(float x, float y)
+ {
+ packedValue = Pack(x, y);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public Vector2 ToVector2()
+ {
+ return new Vector2(
+ ((sbyte) (packedValue & 0xFF)) / 127.0f,
+ ((sbyte) ((packedValue >> 8) & 0xFF)) / 127.0f
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(ToVector2(), 0.0f, 1.0f);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ public static bool operator !=(NormalizedByte2 a, NormalizedByte2 b)
+ {
+ return a.packedValue != b.packedValue;
+ }
+
+ public static bool operator ==(NormalizedByte2 a, NormalizedByte2 b)
+ {
+ return a.packedValue == b.packedValue;
+ }
+
+ public override bool Equals(object obj)
+ {
+ return (obj is NormalizedByte2) && Equals((NormalizedByte2) obj);
+ }
+
+ public bool Equals(NormalizedByte2 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static ushort Pack(float x, float y)
+ {
+ int byte2 = (
+ ((ushort)
+ System.Math.Round(MathHelper.Clamp(x, -1.0f, 1.0f) * 127.0f)
+ )
+ ) & 0x00FF;
+ int byte1 = (
+ ((ushort)
+ System.Math.Round(MathHelper.Clamp(y, -1.0f, 1.0f) * 127.0f)
+ ) << 8
+ ) & 0xFF00;
+
+ return (ushort) (byte2 | byte1);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/NormalizedByte4.cs b/src/Graphics/PackedVector/NormalizedByte4.cs
new file mode 100644
index 00000000..af8c434d
--- /dev/null
+++ b/src/Graphics/PackedVector/NormalizedByte4.cs
@@ -0,0 +1,147 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ public struct NormalizedByte4 : IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ public uint PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private uint packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public NormalizedByte4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ public NormalizedByte4(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ ((sbyte) (packedValue & 0xFF)) / 127.0f,
+ ((sbyte) ((packedValue >> 8) & 0xFF)) / 127.0f,
+ ((sbyte) ((packedValue >> 16) & 0xFF)) / 127.0f,
+ ((sbyte) ((packedValue >> 24) & 0xFF)) / 127.0f
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ public static bool operator !=(NormalizedByte4 a, NormalizedByte4 b)
+ {
+ return a.packedValue != b.packedValue;
+ }
+
+ public static bool operator ==(NormalizedByte4 a, NormalizedByte4 b)
+ {
+ return a.packedValue == b.packedValue;
+ }
+
+ public override bool Equals(object obj)
+ {
+ return (obj is NormalizedByte4) && Equals((NormalizedByte4) obj);
+ }
+
+ public bool Equals(NormalizedByte4 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static uint Pack(float x, float y, float z, float w)
+ {
+ uint byte4 = (
+ (uint) System.Math.Round(MathHelper.Clamp(x, -1.0f, 1.0f) * 127.0f)
+ ) & 0x000000FF;
+ uint byte3 = (
+ (
+ (uint) System.Math.Round(MathHelper.Clamp(y, -1.0f, 1.0f) * 127.0f)
+ ) << 8
+ ) & 0x0000FF00;
+ uint byte2 = (
+ (
+ (uint) System.Math.Round(MathHelper.Clamp(z, -1.0f, 1.0f) * 127.0f)
+ ) << 16
+ ) & 0x00FF0000;
+ uint byte1 = (
+ (
+ (uint) System.Math.Round(MathHelper.Clamp(w, -1.0f, 1.0f) * 127.0f)
+ ) << 24
+ ) & 0xFF000000;
+
+ return byte4 | byte3 | byte2 | byte1;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/NormalizedShort2.cs b/src/Graphics/PackedVector/NormalizedShort2.cs
new file mode 100644
index 00000000..82595ec7
--- /dev/null
+++ b/src/Graphics/PackedVector/NormalizedShort2.cs
@@ -0,0 +1,151 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ public struct NormalizedShort2 : IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ public uint PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private uint packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public NormalizedShort2(Vector2 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ public NormalizedShort2(float x, float y)
+ {
+ packedValue = Pack(x, y);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public Vector2 ToVector2()
+ {
+ const float maxVal = 0x7FFF;
+
+ return new Vector2(
+ (short) (packedValue & 0xFFFF) / maxVal,
+ (short) (packedValue >> 0x10) / maxVal
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(ToVector2(), 0.0f, 1.0f);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ public static bool operator !=(NormalizedShort2 a, NormalizedShort2 b)
+ {
+ return !a.Equals(b);
+ }
+
+ public static bool operator ==(NormalizedShort2 a, NormalizedShort2 b)
+ {
+ return a.Equals(b);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return (obj is NormalizedShort2) && Equals((NormalizedShort2) obj);
+ }
+
+ public bool Equals(NormalizedShort2 other)
+ {
+ return packedValue.Equals(other.packedValue);
+ }
+
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static uint Pack(float x, float y)
+ {
+ const float max = 0x7FFF;
+ const float min = -max;
+
+ uint word2 = (uint) (
+ (int) MathHelper.Clamp(
+ (float) System.Math.Round(x * max),
+ min,
+ max
+ ) & 0xFFFF
+ );
+ uint word1 = (uint) ((
+ (int) MathHelper.Clamp(
+ (float) System.Math.Round(y * max),
+ min,
+ max
+ ) & 0xFFFF
+ ) << 0x10);
+
+ return (word2 | word1);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/NormalizedShort4.cs b/src/Graphics/PackedVector/NormalizedShort4.cs
new file mode 100644
index 00000000..401874a3
--- /dev/null
+++ b/src/Graphics/PackedVector/NormalizedShort4.cs
@@ -0,0 +1,162 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ public struct NormalizedShort4 : IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ public ulong PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ulong packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public NormalizedShort4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ public NormalizedShort4(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public Vector4 ToVector4()
+ {
+ const float maxVal = 0x7FFF;
+
+ return new Vector4(
+ ((short) (packedValue & 0xFFFF)) / maxVal,
+ ((short) ((packedValue >> 0x10) & 0xFFFF)) / maxVal,
+ ((short) ((packedValue >> 0x20) & 0xFFFF)) / maxVal,
+ ((short) ((packedValue >> 0x30) & 0xFFFF)) / maxVal
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ public static bool operator !=(NormalizedShort4 a, NormalizedShort4 b)
+ {
+ return !a.Equals(b);
+ }
+
+ public static bool operator ==(NormalizedShort4 a, NormalizedShort4 b)
+ {
+ return a.Equals(b);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return (obj is NormalizedShort4) && Equals((NormalizedShort4) obj);
+ }
+
+ public bool Equals(NormalizedShort4 other)
+ {
+ return packedValue.Equals(other.packedValue);
+ }
+
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static ulong Pack(float x, float y, float z, float w)
+ {
+ const float max = 0x7FFF;
+ const float min = -max;
+
+ ulong word4 = (
+ (ulong) MathHelper.Clamp(
+ (float) System.Math.Round(x * max),
+ min,
+ max
+ ) & 0xFFFF
+ );
+ ulong word3 = (
+ (ulong) MathHelper.Clamp(
+ (float) System.Math.Round(y * max),
+ min,
+ max
+ ) & 0xFFFF
+ ) << 0x10;
+ ulong word2 = (
+ (ulong) MathHelper.Clamp(
+ (float) System.Math.Round(z * max),
+ min,
+ max
+ ) & 0xFFFF
+ ) << 0x20;
+ ulong word1 = (
+ (ulong) MathHelper.Clamp(
+ (float) System.Math.Round(w * max),
+ min,
+ max
+ ) & 0xFFFF
+ ) << 0x30;
+
+ return (word4 | word3 | word2 | word1);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Rg32.cs b/src/Graphics/PackedVector/Rg32.cs
new file mode 100644
index 00000000..cfda3cfb
--- /dev/null
+++ b/src/Graphics/PackedVector/Rg32.cs
@@ -0,0 +1,182 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing unsigned normalized values ranging from 0 to 1.
+ /// The x and z components use 5 bits, and the y component uses 6 bits.
+ ///
+ public struct Rg32 : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Gets and sets the packed value.
+ ///
+ public uint PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private uint packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Creates a new instance of Rg32.
+ ///
+ /// The x component
+ /// The y component
+ public Rg32(float x, float y)
+ {
+ packedValue = Pack(x, y);
+ }
+
+ ///
+ /// Creates a new instance of Rg32.
+ ///
+ ///
+ /// Vector containing the components for the packed vector.
+ ///
+ public Rg32(Vector2 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Gets the packed vector in Vector2 format.
+ ///
+ /// The packed vector in Vector2 format
+ public Vector2 ToVector2()
+ {
+ return new Vector2(
+ (packedValue & 0xFFFF) / 65535.0f,
+ (packedValue >> 16) / 65535.0f
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed vector from a Vector4.
+ ///
+ /// Vector containing the components.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ ///
+ /// Gets the packed vector in Vector4 format.
+ ///
+ /// The packed vector in Vector4 format
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(ToVector2(), 0.0f, 1.0f);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares an object with the packed vector.
+ ///
+ /// The object to compare.
+ /// True if the object is equal to the packed vector.
+ public override bool Equals(object obj)
+ {
+ return (obj is Rg32) && Equals((Rg32) obj);
+ }
+
+ ///
+ /// Compares another Rg32 packed vector with the packed vector.
+ ///
+ /// The Rg32 packed vector to compare.
+ /// True if the packed vectors are equal.
+ public bool Equals(Rg32 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ ///
+ /// Gets a string representation of the packed vector.
+ ///
+ /// A string representation of the packed vector.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets a hash code of the packed vector.
+ ///
+ /// The hash code for the packed vector.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(Rg32 lhs, Rg32 rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(Rg32 lhs, Rg32 rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static uint Pack(float x, float y)
+ {
+ return (uint) (
+ ((uint) System.Math.Round(MathHelper.Clamp(x, 0, 1) * 65535.0f)) |
+ (((uint) System.Math.Round(MathHelper.Clamp(y, 0, 1) * 65535.0f)) << 16)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Rgba1010102.cs b/src/Graphics/PackedVector/Rgba1010102.cs
new file mode 100644
index 00000000..bedd3346
--- /dev/null
+++ b/src/Graphics/PackedVector/Rgba1010102.cs
@@ -0,0 +1,179 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing unsigned normalized values ranging from 0 to 1.
+ /// The x and z components use 5 bits, and the y component uses 6 bits.
+ ///
+ public struct Rgba1010102 : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Gets and sets the packed value.
+ ///
+ public uint PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private uint packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Creates a new instance of Rgba1010102.
+ ///
+ /// The x component
+ /// The y component
+ /// The z component
+ /// The w component
+ public Rgba1010102(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ ///
+ /// Creates a new instance of Rgba1010102.
+ ///
+ ///
+ /// Vector containing the components for the packed vector.
+ ///
+ public Rgba1010102(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Gets the packed vector in Vector4 format.
+ ///
+ /// The packed vector in Vector4 format
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ (packedValue & 0x03FF) / 1023.0f,
+ ((packedValue >> 10) & 0x03FF) / 1023.0f,
+ ((packedValue >> 20) & 0x03FF) / 1023.0f,
+ (packedValue >> 30) / 3.0f
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed vector from a Vector4.
+ ///
+ /// Vector containing the components.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares an object with the packed vector.
+ ///
+ /// The object to compare.
+ /// True if the object is equal to the packed vector.
+ public override bool Equals(object obj)
+ {
+ return (obj is Rgba1010102) && Equals((Rgba1010102) obj);
+ }
+
+ ///
+ /// Compares another Rgba1010102 packed vector with the packed vector.
+ ///
+ /// The Rgba1010102 packed vector to compare.
+ /// True if the packed vectors are equal.
+ public bool Equals(Rgba1010102 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ ///
+ /// Gets a string representation of the packed vector.
+ ///
+ /// A string representation of the packed vector.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets a hash code of the packed vector.
+ ///
+ /// The hash code for the packed vector.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(Rgba1010102 lhs, Rgba1010102 rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(Rgba1010102 lhs, Rgba1010102 rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static uint Pack(float x, float y, float z, float w)
+ {
+ return (uint) (
+ ((uint) System.Math.Round(MathHelper.Clamp(x, 0, 1) * 1023.0f)) |
+ ((uint) System.Math.Round(MathHelper.Clamp(y, 0, 1) * 1023.0f) << 10) |
+ ((uint) System.Math.Round(MathHelper.Clamp(z, 0, 1) * 1023.0f) << 20) |
+ ((uint) System.Math.Round(MathHelper.Clamp(w, 0, 1) * 3.0f) << 30)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Rgba64.cs b/src/Graphics/PackedVector/Rgba64.cs
new file mode 100644
index 00000000..7d5bb30f
--- /dev/null
+++ b/src/Graphics/PackedVector/Rgba64.cs
@@ -0,0 +1,179 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing unsigned normalized values ranging from 0 to 1.
+ /// The x and z components use 5 bits, and the y component uses 6 bits.
+ ///
+ public struct Rgba64 : IPackedVector, IEquatable, IPackedVector
+ {
+ #region Public Properties
+
+ ///
+ /// Gets and sets the packed value.
+ ///
+ public ulong PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ulong packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Creates a new instance of Rgba64.
+ ///
+ /// The x component
+ /// The y component
+ /// The z component
+ /// The w component
+ public Rgba64(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ ///
+ /// Creates a new instance of Rgba64.
+ ///
+ ///
+ /// Vector containing the components for the packed vector.
+ ///
+ public Rgba64(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Gets the packed vector in Vector4 format.
+ ///
+ /// The packed vector in Vector4 format
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ (packedValue & 0xFFFF) / 65535.0f,
+ ((packedValue >> 16) & 0xFFFF) / 65535.0f,
+ ((packedValue >> 32) & 0xFFFF) / 65535.0f,
+ (packedValue >> 48) / 65535.0f
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed vector from a Vector4.
+ ///
+ /// Vector containing the components.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares an object with the packed vector.
+ ///
+ /// The object to compare.
+ /// True if the object is equal to the packed vector.
+ public override bool Equals(object obj)
+ {
+ return (obj is Rgba64) && Equals((Rgba64) obj);
+ }
+
+ ///
+ /// Compares another Rgba64 packed vector with the packed vector.
+ ///
+ /// The Rgba64 packed vector to compare.
+ /// True if the packed vectors are equal.
+ public bool Equals(Rgba64 other)
+ {
+ return packedValue == other.packedValue;
+ }
+
+ ///
+ /// Gets a string representation of the packed vector.
+ ///
+ /// A string representation of the packed vector.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ ///
+ /// Gets a hash code of the packed vector.
+ ///
+ /// The hash code for the packed vector.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public static bool operator ==(Rgba64 lhs, Rgba64 rhs)
+ {
+ return lhs.packedValue == rhs.packedValue;
+ }
+
+ public static bool operator !=(Rgba64 lhs, Rgba64 rhs)
+ {
+ return lhs.packedValue != rhs.packedValue;
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static ulong Pack(float x, float y, float z, float w)
+ {
+ return (ulong) (
+ ((ulong) System.Math.Round(MathHelper.Clamp(x, 0, 1) * 65535.0f)) |
+ (((ulong) System.Math.Round(MathHelper.Clamp(y, 0, 1) * 65535.0f)) << 16) |
+ (((ulong) System.Math.Round(MathHelper.Clamp(z, 0, 1) * 65535.0f)) << 32) |
+ (((ulong) System.Math.Round(MathHelper.Clamp(w, 0, 1) * 65535.0f)) << 48)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Short2.cs b/src/Graphics/PackedVector/Short2.cs
new file mode 100644
index 00000000..5577eb3a
--- /dev/null
+++ b/src/Graphics/PackedVector/Short2.cs
@@ -0,0 +1,134 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ public struct Short2 : IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ public uint PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private uint packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ public Short2(Vector2 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ public Short2(float x, float y)
+ {
+ packedValue = Pack(x, y);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public Vector2 ToVector2()
+ {
+ return new Vector2(
+ (short) (packedValue & 0xFFFF),
+ (short) (packedValue >> 16)
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y);
+ }
+
+ Vector4 IPackedVector.ToVector4()
+ {
+ return new Vector4(ToVector2(), 0.0f, 1.0f);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ public static bool operator !=(Short2 a, Short2 b)
+ {
+ return a.packedValue != b.packedValue;
+ }
+
+ public static bool operator ==(Short2 a, Short2 b)
+ {
+ return a.packedValue == b.packedValue;
+ }
+
+ public override bool Equals(object obj)
+ {
+ return (obj is Short2) && Equals((Short2) obj);
+ }
+
+ public bool Equals(Short2 other)
+ {
+ return this == other;
+ }
+
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ private static uint Pack(float x, float y)
+ {
+ return (uint) (
+ ((int) System.Math.Round(MathHelper.Clamp(x, -32768, 32767)) & 0x0000FFFF) |
+ (((int) System.Math.Round(MathHelper.Clamp(y, -32768, 32767))) << 16)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/PackedVector/Short4.cs b/src/Graphics/PackedVector/Short4.cs
new file mode 100644
index 00000000..da0e1e44
--- /dev/null
+++ b/src/Graphics/PackedVector/Short4.cs
@@ -0,0 +1,204 @@
+#region License
+
+/* MoonWorks - Game Development Framework
+ * Copyright 2021 Evan Hemsley
+ */
+
+/* Derived from code by Ethan Lee (Copyright 2009-2021).
+ * Released under the Microsoft Public License.
+ * See fna.LICENSE for details.
+
+ * Derived from code by the Mono.Xna Team (Copyright 2006).
+ * Released under the MIT License. See monoxna.LICENSE for details.
+ */
+
+#endregion
+
+#region Using Statements
+using System;
+using MoonWorks.Math;
+#endregion
+
+namespace MoonWorks.Graphics
+{
+ ///
+ /// Packed vector type containing four 16-bit signed integer values.
+ ///
+ public struct Short4 : IPackedVector, IEquatable
+ {
+ #region Public Properties
+
+ ///
+ /// Directly gets or sets the packed representation of the value.
+ ///
+ /// The packed representation of the value.
+ public ulong PackedValue
+ {
+ get
+ {
+ return packedValue;
+ }
+ set
+ {
+ packedValue = value;
+ }
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ private ulong packedValue;
+
+ #endregion
+
+ #region Public Constructors
+
+ ///
+ /// Initializes a new instance of the Short4 class.
+ ///
+ ///
+ /// A vector containing the initial values for the components of the Short4 structure.
+ ///
+ public Short4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ ///
+ /// Initializes a new instance of the Short4 class.
+ ///
+ /// Initial value for the x component.
+ /// Initial value for the y component.
+ /// Initial value for the z component.
+ /// Initial value for the w component.
+ public Short4(float x, float y, float z, float w)
+ {
+ packedValue = Pack(x, y, z, w);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Expands the packed representation into a Vector4.
+ ///
+ /// The expanded vector.
+ public Vector4 ToVector4()
+ {
+ return new Vector4(
+ (short) (packedValue & 0xFFFF),
+ (short) ((packedValue >> 16) & 0xFFFF),
+ (short) ((packedValue >> 32) & 0xFFFF),
+ (short) (packedValue >> 48)
+ );
+ }
+
+ #endregion
+
+ #region IPackedVector Methods
+
+ ///
+ /// Sets the packed representation from a Vector4.
+ ///
+ /// The vector to create the packed representation from.
+ void IPackedVector.PackFromVector4(Vector4 vector)
+ {
+ packedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
+ }
+
+ #endregion
+
+ #region Public Static Operators and Override Methods
+
+ ///
+ /// Compares the current instance of a class to another instance to determine
+ /// whether they are different.
+ ///
+ /// The object to the left of the equality operator.
+ /// The object to the right of the equality operator.
+ /// True if the objects are different; false otherwise.
+ public static bool operator !=(Short4 a, Short4 b)
+ {
+ return a.PackedValue != b.PackedValue;
+ }
+
+ ///
+ /// Compares the current instance of a class to another instance to determine
+ /// whether they are the same.
+ ///
+ /// The object to the left of the equality operator.
+ /// The object to the right of the equality operator.
+ /// True if the objects are the same; false otherwise.
+ public static bool operator ==(Short4 a, Short4 b)
+ {
+ return a.PackedValue == b.PackedValue;
+ }
+
+ ///
+ /// Returns a value that indicates whether the current instance is equal to a
+ /// specified object.
+ ///
+ /// The object with which to make the comparison.
+ ///
+ /// True if the current instance is equal to the specified object; false otherwise.
+ ///
+ public override bool Equals(object obj)
+ {
+ return (obj is Short4) && Equals((Short4) obj);
+ }
+
+ ///
+ /// Returns a value that indicates whether the current instance is equal to a
+ /// specified object.
+ ///
+ /// The object with which to make the comparison.
+ ///
+ /// True if the current instance is equal to the specified object; false otherwise.
+ ///
+ public bool Equals(Short4 other)
+ {
+ return this == other;
+ }
+
+ ///
+ /// Gets the hash code for the current instance.
+ ///
+ /// Hash code for the instance.
+ public override int GetHashCode()
+ {
+ return packedValue.GetHashCode();
+ }
+
+ ///
+ /// Returns a string representation of the current instance.
+ ///
+ /// String that represents the object.
+ public override string ToString()
+ {
+ return packedValue.ToString("X");
+ }
+
+ #endregion
+
+ #region Private Static Pack Method
+
+ ///
+ /// Packs a vector into a ulong.
+ ///
+ /// The vector containing the values to pack.
+ /// The ulong containing the packed values.
+ static ulong Pack(float x, float y, float z, float w)
+ {
+ return (ulong) (
+ ((long) System.Math.Round(MathHelper.Clamp(x, -32768, 32767)) & 0xFFFF ) |
+ (((long) System.Math.Round(MathHelper.Clamp(y, -32768, 32767)) << 16) & 0xFFFF0000) |
+ (((long) System.Math.Round(MathHelper.Clamp(z, -32768, 32767)) << 32) & 0xFFFF00000000) |
+ ((long) System.Math.Round(MathHelper.Clamp(w, -32768, 32767)) << 48)
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Graphics/RefreshStructs.cs b/src/Graphics/RefreshStructs.cs
index 355d71b6..85390c7b 100644
--- a/src/Graphics/RefreshStructs.cs
+++ b/src/Graphics/RefreshStructs.cs
@@ -6,15 +6,6 @@ using System.Runtime.InteropServices;
*/
namespace MoonWorks.Graphics
{
- [StructLayout(LayoutKind.Sequential)]
- public struct Color
- {
- public byte r;
- public byte g;
- public byte b;
- public byte a;
- }
-
[StructLayout(LayoutKind.Sequential)]
public struct DepthStencilValue
{