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 {