Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
Color.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under MIT License. See LICENSE.md for details.
3 using System;
4 using System.Globalization;
5 using System.Runtime.InteropServices;
6 using SiliconStudio.Core.Serialization;
7 
8 namespace SiliconStudio.Core.Mathematics
9 {
10  /// <summary>
11  /// Represents a 32-bit color (4 bytes) in the form of RGBA (in byte order: R, G, B, A).
12  /// </summary>
13  [DataContract("Color")]
14  [DataStyle(DataStyle.Compact)]
15  [StructLayout(LayoutKind.Sequential, Size = 4)]
16  public partial struct Color : IEquatable<Color>, IFormattable
17  {
18  private const string toStringFormat = "A:{0} R:{1} G:{2} B:{3}";
19 
20  /// <summary>
21  /// The red component of the color.
22  /// </summary>
23  [DataMember(0)]
24  public byte R;
25 
26  /// <summary>
27  /// The green component of the color.
28  /// </summary>
29  [DataMember(1)]
30  public byte G;
31 
32  /// <summary>
33  /// The blue component of the color.
34  /// </summary>
35  [DataMember(2)]
36  public byte B;
37 
38  /// <summary>
39  /// The alpha component of the color.
40  /// </summary>
41  [DataMember(3)]
42  public byte A;
43 
44  /// <summary>
45  /// Initializes a new instance of the <see cref="Color"/> struct.
46  /// </summary>
47  /// <param name="value">The value that will be assigned to all components.</param>
48  public Color(byte value)
49  {
50  A = R = G = B = value;
51  }
52 
53  /// <summary>
54  /// Initializes a new instance of the <see cref="Color"/> struct.
55  /// </summary>
56  /// <param name="value">The value that will be assigned to all components.</param>
57  public Color(float value)
58  {
59  A = R = G = B = ToByte(value);
60  }
61 
62  /// <summary>
63  /// Initializes a new instance of the <see cref="Color"/> struct.
64  /// </summary>
65  /// <param name="red">The red component of the color.</param>
66  /// <param name="green">The green component of the color.</param>
67  /// <param name="blue">The blue component of the color.</param>
68  /// <param name="alpha">The alpha component of the color.</param>
69  public Color(byte red, byte green, byte blue, byte alpha)
70  {
71  R = red;
72  G = green;
73  B = blue;
74  A = alpha;
75  }
76 
77  /// <summary>
78  /// Initializes a new instance of the <see cref="Color"/> struct. Alpha is set to 255.
79  /// </summary>
80  /// <param name="red">The red component of the color.</param>
81  /// <param name="green">The green component of the color.</param>
82  /// <param name="blue">The blue component of the color.</param>
83  public Color(byte red, byte green, byte blue)
84  {
85  R = red;
86  G = green;
87  B = blue;
88  A = 255;
89  }
90 
91  /// <summary>
92  /// Initializes a new instance of the <see cref="Color"/> struct.
93  /// </summary>
94  /// <param name="red">The red component of the color.</param>
95  /// <param name="green">The green component of the color.</param>
96  /// <param name="blue">The blue component of the color.</param>
97  /// <param name="alpha">The alpha component of the color.</param>
98  public Color(float red, float green, float blue, float alpha)
99  {
100  R = ToByte(red);
101  G = ToByte(green);
102  B = ToByte(blue);
103  A = ToByte(alpha);
104  }
105 
106  /// <summary>
107  /// Initializes a new instance of the <see cref="Color"/> struct. Alpha is set to 255.
108  /// </summary>
109  /// <param name="red">The red component of the color.</param>
110  /// <param name="green">The green component of the color.</param>
111  /// <param name="blue">The blue component of the color.</param>
112  public Color(float red, float green, float blue)
113  {
114  R = ToByte(red);
115  G = ToByte(green);
116  B = ToByte(blue);
117  A = 255;
118  }
119 
120  /// <summary>
121  /// Initializes a new instance of the <see cref="Color"/> struct.
122  /// </summary>
123  /// <param name="value">The red, green, blue, and alpha components of the color.</param>
124  public Color(Vector4 value)
125  {
126  R = ToByte(value.X);
127  G = ToByte(value.Y);
128  B = ToByte(value.Z);
129  A = ToByte(value.W);
130  }
131 
132  /// <summary>
133  /// Initializes a new instance of the <see cref="Color"/> struct.
134  /// </summary>
135  /// <param name="value">The red, green, and blue components of the color.</param>
136  /// <param name="alpha">The alpha component of the color.</param>
137  public Color(Vector3 value, float alpha)
138  {
139  R = ToByte(value.X);
140  G = ToByte(value.Y);
141  B = ToByte(value.Z);
142  A = ToByte(alpha);
143  }
144 
145  /// <summary>
146  /// Initializes a new instance of the <see cref="Color"/> struct. Alpha is set to 255.
147  /// </summary>
148  /// <param name="value">The red, green, and blue components of the color.</param>
149  public Color(Vector3 value)
150  {
151  R = ToByte(value.X);
152  G = ToByte(value.Y);
153  B = ToByte(value.Z);
154  A = 255;
155  }
156 
157  /// <summary>
158  /// Initializes a new instance of the <see cref="Color"/> struct.
159  /// </summary>
160  /// <param name="rgba">A packed integer containing all four color components in RGBA order.</param>
161  public Color(uint rgba)
162  {
163  A = (byte)((rgba >> 24) & 255);
164  B = (byte)((rgba >> 16) & 255);
165  G = (byte)((rgba >> 8) & 255);
166  R = (byte)(rgba & 255);
167  }
168 
169  /// <summary>
170  /// Initializes a new instance of the <see cref="Color"/> struct.
171  /// </summary>
172  /// <param name="rgba">A packed integer containing all four color components in RGBA order.</param>
173  public Color(int rgba)
174  {
175  A = (byte)((rgba >> 24) & 255);
176  B = (byte)((rgba >> 16) & 255);
177  G = (byte)((rgba >> 8) & 255);
178  R = (byte)(rgba & 255);
179  }
180 
181  /// <summary>
182  /// Initializes a new instance of the <see cref="Color"/> struct.
183  /// </summary>
184  /// <param name="values">The values to assign to the red, green, and blue, alpha components of the color. This must be an array with four elements.</param>
185  /// <exception cref="ArgumentNullException">Thrown when <paramref name="values"/> is <c>null</c>.</exception>
186  /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="values"/> contains more or less than four elements.</exception>
187  public Color(float[] values)
188  {
189  if (values == null)
190  throw new ArgumentNullException("values");
191  if (values.Length != 4)
192  throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Color.");
193 
194  R = ToByte(values[0]);
195  G = ToByte(values[1]);
196  B = ToByte(values[2]);
197  A = ToByte(values[3]);
198  }
199 
200  /// <summary>
201  /// Initializes a new instance of the <see cref="Color"/> struct.
202  /// </summary>
203  /// <param name="values">The values to assign to the alpha, red, green, and blue components of the color. This must be an array with four elements.</param>
204  /// <exception cref="ArgumentNullException">Thrown when <paramref name="values"/> is <c>null</c>.</exception>
205  /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="values"/> contains more or less than four elements.</exception>
206  public Color(byte[] values)
207  {
208  if (values == null)
209  throw new ArgumentNullException("values");
210  if (values.Length != 4)
211  throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Color.");
212 
213  R = values[0];
214  G = values[1];
215  B = values[2];
216  A = values[3];
217  }
218 
219  /// <summary>
220  /// Gets or sets the component at the specified index.
221  /// </summary>
222  /// <value>The value of the alpha, red, green, or blue component, depending on the index.</value>
223  /// <param name="index">The index of the component to access. Use 0 for the alpha component, 1 for the red component, 2 for the green component, and 3 for the blue component.</param>
224  /// <returns>The value of the component at the specified index.</returns>
225  /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="index"/> is out of the range [0, 3].</exception>
226  public byte this[int index]
227  {
228  get
229  {
230  switch (index)
231  {
232  case 0: return R;
233  case 1: return G;
234  case 2: return B;
235  case 3: return A;
236  }
237 
238  throw new ArgumentOutOfRangeException("index", "Indices for Color run from 0 to 3, inclusive.");
239  }
240 
241  set
242  {
243  switch (index)
244  {
245  case 0: R = value; break;
246  case 1: G = value; break;
247  case 2: B = value; break;
248  case 3: A = value; break;
249  default: throw new ArgumentOutOfRangeException("index", "Indices for Color run from 0 to 3, inclusive.");
250  }
251  }
252  }
253 
254  /// <summary>
255  /// Converts the color into a packed integer.
256  /// </summary>
257  /// <returns>A packed integer containing all four color components.</returns>
258  public int ToBgra()
259  {
260  int value = B;
261  value |= G << 8;
262  value |= R << 16;
263  value |= A << 24;
264 
265  return (int)value;
266  }
267 
268  /// <summary>
269  /// Converts the color into a packed integer.
270  /// </summary>
271  /// <returns>A packed integer containing all four color components.</returns>
272  public int ToRgba()
273  {
274  int value = R;
275  value |= G << 8;
276  value |= B << 16;
277  value |= A << 24;
278 
279  return (int)value;
280  }
281 
282  /// <summary>
283  /// Converts the color into a packed integer.
284  /// </summary>
285  /// <returns>A packed integer containing all four color components.</returns>
286  public int ToAbgr()
287  {
288  int value = A;
289  value |= B << 8;
290  value |= G << 16;
291  value |= R << 24;
292 
293  return (int)value;
294  }
295 
296  /// <summary>
297  /// Converts the color into a three component vector.
298  /// </summary>
299  /// <returns>A three component vector containing the red, green, and blue components of the color.</returns>
301  {
302  return new Vector3(R / 255.0f, G / 255.0f, B / 255.0f);
303  }
304 
305  /// <summary>
306  /// Converts the color into a three component color.
307  /// </summary>
308  /// <returns>A three component color containing the red, green, and blue components of the color.</returns>
309  public Color3 ToColor3()
310  {
311  return new Color3(R / 255.0f, G / 255.0f, B / 255.0f);
312  }
313 
314  /// <summary>
315  /// Converts the color into a four component vector.
316  /// </summary>
317  /// <returns>A four component vector containing all four color components.</returns>
319  {
320  return new Vector4(R / 255.0f, G / 255.0f, B / 255.0f, A / 255.0f);
321  }
322 
323  /// <summary>
324  /// Creates an array containing the elements of the color.
325  /// </summary>
326  /// <returns>A four-element array containing the components of the color in RGBA order.</returns>
327  public byte[] ToArray()
328  {
329  return new[] { R, G, B, A };
330  }
331 
332  /// <summary>
333  /// Gets the brightness.
334  /// </summary>
335  /// <returns>The Hue-Saturation-Brightness (HSB) saturation for this <see cref="Color"/></returns>
336  public float GetBrightness()
337  {
338  float r = (float)R / 255.0f;
339  float g = (float)G / 255.0f;
340  float b = (float)B / 255.0f;
341 
342  float max, min;
343 
344  max = r; min = r;
345 
346  if (g > max) max = g;
347  if (b > max) max = b;
348 
349  if (g < min) min = g;
350  if (b < min) min = b;
351 
352  return (max + min) / 2;
353  }
354 
355  /// <summary>
356  /// Gets the hue.
357  /// </summary>
358  /// <returns>The Hue-Saturation-Brightness (HSB) saturation for this <see cref="Color"/></returns>
359  public float GetHue()
360  {
361  if (R == G && G == B)
362  return 0; // 0 makes as good an UNDEFINED value as any
363 
364  float r = (float)R / 255.0f;
365  float g = (float)G / 255.0f;
366  float b = (float)B / 255.0f;
367 
368  float max, min;
369  float delta;
370  float hue = 0.0f;
371 
372  max = r; min = r;
373 
374  if (g > max) max = g;
375  if (b > max) max = b;
376 
377  if (g < min) min = g;
378  if (b < min) min = b;
379 
380  delta = max - min;
381 
382  if (r == max)
383  {
384  hue = (g - b) / delta;
385  }
386  else if (g == max)
387  {
388  hue = 2 + (b - r) / delta;
389  }
390  else if (b == max)
391  {
392  hue = 4 + (r - g) / delta;
393  }
394  hue *= 60;
395 
396  if (hue < 0.0f)
397  {
398  hue += 360.0f;
399  }
400  return hue;
401  }
402 
403  /// <summary>
404  /// Gets the saturation.
405  /// </summary>
406  /// <returns>The Hue-Saturation-Brightness (HSB) saturation for this <see cref="Color"/></returns>
407  public float GetSaturation()
408  {
409  float r = (float)R / 255.0f;
410  float g = (float)G / 255.0f;
411  float b = (float)B / 255.0f;
412 
413  float max, min;
414  float l, s = 0;
415 
416  max = r; min = r;
417 
418  if (g > max) max = g;
419  if (b > max) max = b;
420 
421  if (g < min) min = g;
422  if (b < min) min = b;
423 
424  // if max == min, then there is no color and
425  // the saturation is zero.
426  //
427  if (max != min)
428  {
429  l = (max + min) / 2;
430 
431  if (l <= .5)
432  {
433  s = (max - min) / (max + min);
434  }
435  else
436  {
437  s = (max - min) / (2 - max - min);
438  }
439  }
440  return s;
441  }
442 
443  /// <summary>
444  /// Adds two colors.
445  /// </summary>
446  /// <param name="left">The first color to add.</param>
447  /// <param name="right">The second color to add.</param>
448  /// <param name="result">When the method completes, completes the sum of the two colors.</param>
449  public static void Add(ref Color left, ref Color right, out Color result)
450  {
451  result.A = (byte)(left.A + right.A);
452  result.R = (byte)(left.R + right.R);
453  result.G = (byte)(left.G + right.G);
454  result.B = (byte)(left.B + right.B);
455  }
456 
457  /// <summary>
458  /// Adds two colors.
459  /// </summary>
460  /// <param name="left">The first color to add.</param>
461  /// <param name="right">The second color to add.</param>
462  /// <returns>The sum of the two colors.</returns>
463  public static Color Add(Color left, Color right)
464  {
465  return new Color(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A);
466  }
467 
468  /// <summary>
469  /// Subtracts two colors.
470  /// </summary>
471  /// <param name="left">The first color to subtract.</param>
472  /// <param name="right">The second color to subtract.</param>
473  /// <param name="result">WHen the method completes, contains the difference of the two colors.</param>
474  public static void Subtract(ref Color left, ref Color right, out Color result)
475  {
476  result.A = (byte)(left.A - right.A);
477  result.R = (byte)(left.R - right.R);
478  result.G = (byte)(left.G - right.G);
479  result.B = (byte)(left.B - right.B);
480  }
481 
482  /// <summary>
483  /// Subtracts two colors.
484  /// </summary>
485  /// <param name="left">The first color to subtract.</param>
486  /// <param name="right">The second color to subtract</param>
487  /// <returns>The difference of the two colors.</returns>
488  public static Color Subtract(Color left, Color right)
489  {
490  return new Color(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A);
491  }
492 
493  /// <summary>
494  /// Modulates two colors.
495  /// </summary>
496  /// <param name="left">The first color to modulate.</param>
497  /// <param name="right">The second color to modulate.</param>
498  /// <param name="result">When the method completes, contains the modulated color.</param>
499  public static void Modulate(ref Color left, ref Color right, out Color result)
500  {
501  result.A = (byte)(left.A * right.A / 255.0f);
502  result.R = (byte)(left.R * right.R / 255.0f);
503  result.G = (byte)(left.G * right.G / 255.0f);
504  result.B = (byte)(left.B * right.B / 255.0f);
505  }
506 
507  /// <summary>
508  /// Modulates two colors.
509  /// </summary>
510  /// <param name="left">The first color to modulate.</param>
511  /// <param name="right">The second color to modulate.</param>
512  /// <returns>The modulated color.</returns>
513  public static Color Modulate(Color left, Color right)
514  {
515  return new Color(left.R * right.R, left.G * right.G, left.B * right.B, left.A * right.A);
516  }
517 
518  /// <summary>
519  /// Scales a color.
520  /// </summary>
521  /// <param name="value">The color to scale.</param>
522  /// <param name="scale">The amount by which to scale.</param>
523  /// <param name="result">When the method completes, contains the scaled color.</param>
524  public static void Scale(ref Color value, float scale, out Color result)
525  {
526  result.A = (byte)(value.A * scale);
527  result.R = (byte)(value.R * scale);
528  result.G = (byte)(value.G * scale);
529  result.B = (byte)(value.B * scale);
530  }
531 
532  /// <summary>
533  /// Scales a color.
534  /// </summary>
535  /// <param name="value">The color to scale.</param>
536  /// <param name="scale">The amount by which to scale.</param>
537  /// <returns>The scaled color.</returns>
538  public static Color Scale(Color value, float scale)
539  {
540  return new Color((byte)(value.R * scale), (byte)(value.G * scale), (byte)(value.B * scale), (byte)(value.A * scale));
541  }
542 
543  /// <summary>
544  /// Negates a color.
545  /// </summary>
546  /// <param name="value">The color to negate.</param>
547  /// <param name="result">When the method completes, contains the negated color.</param>
548  public static void Negate(ref Color value, out Color result)
549  {
550  result.A = (byte)(255 - value.A);
551  result.R = (byte)(255 - value.R);
552  result.G = (byte)(255 - value.G);
553  result.B = (byte)(255 - value.B);
554  }
555 
556  /// <summary>
557  /// Negates a color.
558  /// </summary>
559  /// <param name="value">The color to negate.</param>
560  /// <returns>The negated color.</returns>
561  public static Color Negate(Color value)
562  {
563  return new Color(255 - value.R, 255 - value.G, 255 - value.B, 255 - value.A);
564  }
565 
566  /// <summary>
567  /// Restricts a value to be within a specified range.
568  /// </summary>
569  /// <param name="value">The value to clamp.</param>
570  /// <param name="min">The minimum value.</param>
571  /// <param name="max">The maximum value.</param>
572  /// <param name="result">When the method completes, contains the clamped value.</param>
573  public static void Clamp(ref Color value, ref Color min, ref Color max, out Color result)
574  {
575  byte alpha = value.A;
576  alpha = (alpha > max.A) ? max.A : alpha;
577  alpha = (alpha < min.A) ? min.A : alpha;
578 
579  byte red = value.R;
580  red = (red > max.R) ? max.R : red;
581  red = (red < min.R) ? min.R : red;
582 
583  byte green = value.G;
584  green = (green > max.G) ? max.G : green;
585  green = (green < min.G) ? min.G : green;
586 
587  byte blue = value.B;
588  blue = (blue > max.B) ? max.B : blue;
589  blue = (blue < min.B) ? min.B : blue;
590 
591  result = new Color(red, green, blue, alpha);
592  }
593 
594  /// <summary>
595  /// Converts the color from a packed BGRA integer.
596  /// </summary>
597  /// <param name="color">A packed integer containing all four color components in BGRA order</param>
598  /// <returns>A color.</returns>
599  public static Color FromBgra(int color)
600  {
601  return new Color((byte)((color >> 16) & 255), (byte)((color >> 8) & 255), (byte)(color & 255), (byte)((color >> 24) & 255));
602  }
603 
604  /// <summary>
605  /// Converts the color from a packed BGRA integer.
606  /// </summary>
607  /// <param name="color">A packed integer containing all four color components in BGRA order</param>
608  /// <returns>A color.</returns>
609  public static Color FromBgra(uint color)
610  {
611  return FromBgra(unchecked((int)color));
612  }
613 
614  /// <summary>
615  /// Converts the color from a packed ABGR integer.
616  /// </summary>
617  /// <param name="color">A packed integer containing all four color components in ABGR order</param>
618  /// <returns>A color.</returns>
619  public static Color FromAbgr(int color)
620  {
621  return new Color((byte)(color >> 24), (byte)(color >> 16), (byte)(color >> 8), (byte)color);
622  }
623 
624  /// <summary>
625  /// Converts the color from a packed ABGR integer.
626  /// </summary>
627  /// <param name="color">A packed integer containing all four color components in ABGR order</param>
628  /// <returns>A color.</returns>
629  public static Color FromAbgr(uint color)
630  {
631  return FromAbgr(unchecked((int)color));
632  }
633 
634  /// <summary>
635  /// Converts the color from a packed BGRA integer.
636  /// </summary>
637  /// <param name="color">A packed integer containing all four color components in RGBA order</param>
638  /// <returns>A color.</returns>
639  public static Color FromRgba(int color)
640  {
641  return new Color(color);
642  }
643 
644  /// <summary>
645  /// Converts the color from a packed BGRA integer.
646  /// </summary>
647  /// <param name="color">A packed integer containing all four color components in RGBA order</param>
648  /// <returns>A color.</returns>
649  public static Color FromRgba(uint color)
650  {
651  return new Color(color);
652  }
653 
654  /// <summary>
655  /// Restricts a value to be within a specified range.
656  /// </summary>
657  /// <param name="value">The value to clamp.</param>
658  /// <param name="min">The minimum value.</param>
659  /// <param name="max">The maximum value.</param>
660  /// <returns>The clamped value.</returns>
661  public static Color Clamp(Color value, Color min, Color max)
662  {
663  Color result;
664  Clamp(ref value, ref min, ref max, out result);
665  return result;
666  }
667 
668  /// <summary>
669  /// Performs a linear interpolation between two colors.
670  /// </summary>
671  /// <param name="start">Start color.</param>
672  /// <param name="end">End color.</param>
673  /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
674  /// <param name="result">When the method completes, contains the linear interpolation of the two colors.</param>
675  /// <remarks>
676  /// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
677  /// </remarks>
678  public static void Lerp(ref Color start, ref Color end, float amount, out Color result)
679  {
680  result.R = MathUtil.Lerp(start.R, end.R, amount);
681  result.G = MathUtil.Lerp(start.G, end.G, amount);
682  result.B = MathUtil.Lerp(start.B, end.B, amount);
683  result.A = MathUtil.Lerp(start.A, end.A, amount);
684  }
685 
686  /// <summary>
687  /// Performs a linear interpolation between two colors.
688  /// </summary>
689  /// <param name="start">Start color.</param>
690  /// <param name="end">End color.</param>
691  /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
692  /// <returns>The linear interpolation of the two colors.</returns>
693  /// <remarks>
694  /// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
695  /// </remarks>
696  public static Color Lerp(Color start, Color end, float amount)
697  {
698  Color result;
699  Lerp(ref start, ref end, amount, out result);
700  return result;
701  }
702 
703  /// <summary>
704  /// Performs a cubic interpolation between two colors.
705  /// </summary>
706  /// <param name="start">Start color.</param>
707  /// <param name="end">End color.</param>
708  /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
709  /// <param name="result">When the method completes, contains the cubic interpolation of the two colors.</param>
710  public static void SmoothStep(ref Color start, ref Color end, float amount, out Color result)
711  {
712  amount = MathUtil.SmoothStep(amount);
713  Lerp(ref start, ref end, amount, out result);
714  }
715 
716  /// <summary>
717  /// Performs a cubic interpolation between two colors.
718  /// </summary>
719  /// <param name="start">Start color.</param>
720  /// <param name="end">End color.</param>
721  /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
722  /// <returns>The cubic interpolation of the two colors.</returns>
723  public static Color SmoothStep(Color start, Color end, float amount)
724  {
725  Color result;
726  SmoothStep(ref start, ref end, amount, out result);
727  return result;
728  }
729 
730  /// <summary>
731  /// Returns a color containing the smallest components of the specified colors.
732  /// </summary>
733  /// <param name="left">The first source color.</param>
734  /// <param name="right">The second source color.</param>
735  /// <param name="result">When the method completes, contains an new color composed of the largest components of the source colors.</param>
736  public static void Max(ref Color left, ref Color right, out Color result)
737  {
738  result.A = (left.A > right.A) ? left.A : right.A;
739  result.R = (left.R > right.R) ? left.R : right.R;
740  result.G = (left.G > right.G) ? left.G : right.G;
741  result.B = (left.B > right.B) ? left.B : right.B;
742  }
743 
744  /// <summary>
745  /// Returns a color containing the largest components of the specified colorss.
746  /// </summary>
747  /// <param name="left">The first source color.</param>
748  /// <param name="right">The second source color.</param>
749  /// <returns>A color containing the largest components of the source colors.</returns>
750  public static Color Max(Color left, Color right)
751  {
752  Color result;
753  Max(ref left, ref right, out result);
754  return result;
755  }
756 
757  /// <summary>
758  /// Returns a color containing the smallest components of the specified colors.
759  /// </summary>
760  /// <param name="left">The first source color.</param>
761  /// <param name="right">The second source color.</param>
762  /// <param name="result">When the method completes, contains an new color composed of the smallest components of the source colors.</param>
763  public static void Min(ref Color left, ref Color right, out Color result)
764  {
765  result.A = (left.A < right.A) ? left.A : right.A;
766  result.R = (left.R < right.R) ? left.R : right.R;
767  result.G = (left.G < right.G) ? left.G : right.G;
768  result.B = (left.B < right.B) ? left.B : right.B;
769  }
770 
771  /// <summary>
772  /// Returns a color containing the smallest components of the specified colors.
773  /// </summary>
774  /// <param name="left">The first source color.</param>
775  /// <param name="right">The second source color.</param>
776  /// <returns>A color containing the smallest components of the source colors.</returns>
777  public static Color Min(Color left, Color right)
778  {
779  Color result;
780  Min(ref left, ref right, out result);
781  return result;
782  }
783 
784  /// <summary>
785  /// Adjusts the contrast of a color.
786  /// </summary>
787  /// <param name="value">The color whose contrast is to be adjusted.</param>
788  /// <param name="contrast">The amount by which to adjust the contrast.</param>
789  /// <param name="result">When the method completes, contains the adjusted color.</param>
790  public static void AdjustContrast(ref Color value, float contrast, out Color result)
791  {
792  result.A = value.A;
793  result.R = ToByte(0.5f + contrast * (value.R / 255.0f - 0.5f));
794  result.G = ToByte(0.5f + contrast * (value.G / 255.0f - 0.5f));
795  result.B = ToByte(0.5f + contrast * (value.B / 255.0f - 0.5f));
796  }
797 
798  /// <summary>
799  /// Adjusts the contrast of a color.
800  /// </summary>
801  /// <param name="value">The color whose contrast is to be adjusted.</param>
802  /// <param name="contrast">The amount by which to adjust the contrast.</param>
803  /// <returns>The adjusted color.</returns>
804  public static Color AdjustContrast(Color value, float contrast)
805  {
806  return new Color(
807  ToByte(0.5f + contrast * (value.R / 255.0f - 0.5f)),
808  ToByte(0.5f + contrast * (value.G / 255.0f - 0.5f)),
809  ToByte(0.5f + contrast * (value.B / 255.0f - 0.5f)),
810  value.A);
811  }
812 
813  /// <summary>
814  /// Adjusts the saturation of a color.
815  /// </summary>
816  /// <param name="value">The color whose saturation is to be adjusted.</param>
817  /// <param name="saturation">The amount by which to adjust the saturation.</param>
818  /// <param name="result">When the method completes, contains the adjusted color.</param>
819  public static void AdjustSaturation(ref Color value, float saturation, out Color result)
820  {
821  float grey = value.R / 255.0f * 0.2125f + value.G / 255.0f * 0.7154f + value.B / 255.0f * 0.0721f;
822 
823  result.A = value.A;
824  result.R = ToByte(grey + saturation * (value.R / 255.0f - grey));
825  result.G = ToByte(grey + saturation * (value.G / 255.0f - grey));
826  result.B = ToByte(grey + saturation * (value.B / 255.0f - grey));
827  }
828 
829  /// <summary>
830  /// Adjusts the saturation of a color.
831  /// </summary>
832  /// <param name="value">The color whose saturation is to be adjusted.</param>
833  /// <param name="saturation">The amount by which to adjust the saturation.</param>
834  /// <returns>The adjusted color.</returns>
835  public static Color AdjustSaturation(Color value, float saturation)
836  {
837  float grey = value.R / 255.0f * 0.2125f + value.G / 255.0f * 0.7154f + value.B / 255.0f * 0.0721f;
838 
839  return new Color(
840  ToByte(grey + saturation * (value.R / 255.0f - grey)),
841  ToByte(grey + saturation * (value.G / 255.0f - grey)),
842  ToByte(grey + saturation * (value.B / 255.0f - grey)),
843  value.A);
844  }
845 
846  /// <summary>
847  /// Adds two colors.
848  /// </summary>
849  /// <param name="left">The first color to add.</param>
850  /// <param name="right">The second color to add.</param>
851  /// <returns>The sum of the two colors.</returns>
852  public static Color operator +(Color left, Color right)
853  {
854  return new Color(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A);
855  }
856 
857  /// <summary>
858  /// Assert a color (return it unchanged).
859  /// </summary>
860  /// <param name="value">The color to assert (unchanged).</param>
861  /// <returns>The asserted (unchanged) color.</returns>
862  public static Color operator +(Color value)
863  {
864  return value;
865  }
866 
867  /// <summary>
868  /// Subtracts two colors.
869  /// </summary>
870  /// <param name="left">The first color to subtract.</param>
871  /// <param name="right">The second color to subtract.</param>
872  /// <returns>The difference of the two colors.</returns>
873  public static Color operator -(Color left, Color right)
874  {
875  return new Color(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A);
876  }
877 
878  /// <summary>
879  /// Negates a color.
880  /// </summary>
881  /// <param name="value">The color to negate.</param>
882  /// <returns>A negated color.</returns>
883  public static Color operator -(Color value)
884  {
885  return new Color(-value.R, -value.G, -value.B, -value.A);
886  }
887 
888  /// <summary>
889  /// Scales a color.
890  /// </summary>
891  /// <param name="scale">The factor by which to scale the color.</param>
892  /// <param name="value">The color to scale.</param>
893  /// <returns>The scaled color.</returns>
894  public static Color operator *(float scale, Color value)
895  {
896  return new Color((byte)(value.R * scale), (byte)(value.G * scale), (byte)(value.B * scale), (byte)(value.A * scale));
897  }
898 
899  /// <summary>
900  /// Scales a color.
901  /// </summary>
902  /// <param name="value">The factor by which to scale the color.</param>
903  /// <param name="scale">The color to scale.</param>
904  /// <returns>The scaled color.</returns>
905  public static Color operator *(Color value, float scale)
906  {
907  return new Color((byte)(value.R * scale), (byte)(value.G * scale), (byte)(value.B * scale), (byte)(value.A * scale));
908  }
909 
910  /// <summary>
911  /// Modulates two colors.
912  /// </summary>
913  /// <param name="left">The first color to modulate.</param>
914  /// <param name="right">The second color to modulate.</param>
915  /// <returns>The modulated color.</returns>
916  public static Color operator *(Color left, Color right)
917  {
918  return new Color((byte)(left.R * right.R / 255.0f), (byte)(left.G * right.G / 255.0f), (byte)(left.B * right.B / 255.0f), (byte)(left.A * right.A / 255.0f));
919  }
920 
921  /// <summary>
922  /// Tests for equality between two objects.
923  /// </summary>
924  /// <param name="left">The first value to compare.</param>
925  /// <param name="right">The second value to compare.</param>
926  /// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
927  public static bool operator ==(Color left, Color right)
928  {
929  return left.Equals(right);
930  }
931 
932  /// <summary>
933  /// Tests for inequality between two objects.
934  /// </summary>
935  /// <param name="left">The first value to compare.</param>
936  /// <param name="right">The second value to compare.</param>
937  /// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
938  public static bool operator !=(Color left, Color right)
939  {
940  return !left.Equals(right);
941  }
942 
943  /// <summary>
944  /// Performs an explicit conversion from <see cref="Color"/> to <see cref="Color3"/>.
945  /// </summary>
946  /// <param name="value">The value.</param>
947  /// <returns>The result of the conversion.</returns>
948  public static explicit operator Color3(Color value)
949  {
950  return value.ToColor3();
951  }
952 
953  /// <summary>
954  /// Performs an explicit conversion from <see cref="Color"/> to <see cref="Vector3"/>.
955  /// </summary>
956  /// <param name="value">The value.</param>
957  /// <returns>The result of the conversion.</returns>
958  public static explicit operator Vector3(Color value)
959  {
960  return new Vector3(value.R / 255.0f, value.G / 255.0f, value.B / 255.0f);
961  }
962 
963  /// <summary>
964  /// Performs an explicit conversion from <see cref="Color"/> to <see cref="Vector4"/>.
965  /// </summary>
966  /// <param name="value">The value.</param>
967  /// <returns>The result of the conversion.</returns>
968  public static explicit operator Vector4(Color value)
969  {
970  return new Vector4(value.R / 255.0f, value.G / 255.0f, value.B / 255.0f, value.A / 255.0f);
971  }
972 
973  /// <summary>
974  /// Convert this instance to a <see cref="Color4"/>
975  /// </summary>
976  /// <returns>The result of the conversion.</returns>
977  public Color4 ToColor4()
978  {
979  return new Color4(R / 255.0f, G / 255.0f, B / 255.0f, A / 255.0f);
980  }
981 
982  /// <summary>
983  /// Performs an implicit conversion from <see cref="Color"/> to <see cref="Color4"/>.
984  /// </summary>
985  /// <param name="value">The value.</param>
986  /// <returns>The result of the conversion.</returns>
987  public static implicit operator Color4(Color value)
988  {
989  return value.ToColor4();
990  }
991 
992  /// <summary>
993  /// Performs an explicit conversion from <see cref="Vector3"/> to <see cref="Color"/>.
994  /// </summary>
995  /// <param name="value">The value.</param>
996  /// <returns>The result of the conversion.</returns>
997  public static explicit operator Color(Vector3 value)
998  {
999  return new Color(value.X, value.Y, value.Z, 1.0f);
1000  }
1001 
1002  /// <summary>
1003  /// Performs an explicit conversion from <see cref="Color3"/> to <see cref="Color"/>.
1004  /// </summary>
1005  /// <param name="value">The value.</param>
1006  /// <returns>The result of the conversion.</returns>
1007  public static explicit operator Color(Color3 value)
1008  {
1009  return new Color(value.R, value.G, value.B, 1.0f);
1010  }
1011 
1012  /// <summary>
1013  /// Performs an explicit conversion from <see cref="Vector4"/> to <see cref="Color"/>.
1014  /// </summary>
1015  /// <param name="value">The value.</param>
1016  /// <returns>The result of the conversion.</returns>
1017  public static explicit operator Color(Vector4 value)
1018  {
1019  return new Color(value.X, value.Y, value.Z, value.W);
1020  }
1021 
1022  /// <summary>
1023  /// Performs an explicit conversion from <see cref="Color4"/> to <see cref="Color"/>.
1024  /// </summary>
1025  /// <param name="value">The value.</param>
1026  /// <returns>The result of the conversion.</returns>
1027  public static explicit operator Color(Color4 value)
1028  {
1029  return new Color(value.R, value.G, value.B, value.A);
1030  }
1031 
1032  /// <summary>
1033  /// Performs an explicit conversion from <see cref="System.Int32"/> to <see cref="Color"/>.
1034  /// </summary>
1035  /// <param name="value">The value.</param>
1036  /// <returns>
1037  /// The result of the conversion.
1038  /// </returns>
1039  public static explicit operator int(Color value)
1040  {
1041  return value.ToRgba();
1042  }
1043 
1044  /// <summary>
1045  /// Performs an explicit conversion from <see cref="System.Int32"/> to <see cref="Color"/>.
1046  /// </summary>
1047  /// <param name="value">The value.</param>
1048  /// <returns>
1049  /// The result of the conversion.
1050  /// </returns>
1051  public static explicit operator Color(int value)
1052  {
1053  return new Color(value);
1054  }
1055 
1056  /// <summary>
1057  /// Returns a <see cref="System.String"/> that represents this instance.
1058  /// </summary>
1059  /// <returns>
1060  /// A <see cref="System.String"/> that represents this instance.
1061  /// </returns>
1062  public override string ToString()
1063  {
1064  return ToString(CultureInfo.CurrentCulture);
1065  }
1066 
1067  /// <summary>
1068  /// Returns a <see cref="System.String"/> that represents this instance.
1069  /// </summary>
1070  /// <param name="format">The format to apply to each channel element (byte).</param>
1071  /// <returns>
1072  /// A <see cref="System.String"/> that represents this instance.
1073  /// </returns>
1074  public string ToString(string format)
1075  {
1076  return ToString(format, CultureInfo.CurrentCulture);
1077  }
1078 
1079  /// <summary>
1080  /// Returns a <see cref="System.String"/> that represents this instance.
1081  /// </summary>
1082  /// <param name="formatProvider">The format provider.</param>
1083  /// <returns>
1084  /// A <see cref="System.String"/> that represents this instance.
1085  /// </returns>
1086  public string ToString(IFormatProvider formatProvider)
1087  {
1088  return string.Format(formatProvider, toStringFormat, A, R, G, B);
1089  }
1090 
1091  /// <summary>
1092  /// Returns a <see cref="System.String"/> that represents this instance.
1093  /// </summary>
1094  /// <param name="format">The format to apply to each channel element (byte).</param>
1095  /// <param name="formatProvider">The format provider.</param>
1096  /// <returns>
1097  /// A <see cref="System.String"/> that represents this instance.
1098  /// </returns>
1099  public string ToString(string format, IFormatProvider formatProvider)
1100  {
1101  if (format == null)
1102  return ToString(formatProvider);
1103 
1104  return string.Format(formatProvider,
1105  toStringFormat,
1106  A.ToString(format, formatProvider),
1107  R.ToString(format, formatProvider),
1108  G.ToString(format, formatProvider),
1109  B.ToString(format, formatProvider));
1110  }
1111 
1112  /// <summary>
1113  /// Returns a hash code for this instance.
1114  /// </summary>
1115  /// <returns>
1116  /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
1117  /// </returns>
1118  public override int GetHashCode()
1119  {
1120  return A.GetHashCode() + R.GetHashCode() + G.GetHashCode() + B.GetHashCode();
1121  }
1122 
1123  /// <summary>
1124  /// Determines whether the specified <see cref="Color"/> is equal to this instance.
1125  /// </summary>
1126  /// <param name="other">The <see cref="Color"/> to compare with this instance.</param>
1127  /// <returns>
1128  /// <c>true</c> if the specified <see cref="Color"/> is equal to this instance; otherwise, <c>false</c>.
1129  /// </returns>
1130  public bool Equals(Color other)
1131  {
1132  return R == other.R && G == other.G && B == other.B && A == other.A;
1133  }
1134 
1135  /// <summary>
1136  /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
1137  /// </summary>
1138  /// <param name="value">The <see cref="System.Object"/> to compare with this instance.</param>
1139  /// <returns>
1140  /// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
1141  /// </returns>
1142  public override bool Equals(object value)
1143  {
1144  if (value == null)
1145  return false;
1146 
1147  if (!ReferenceEquals(value.GetType(), typeof(Color)))
1148  return false;
1149 
1150  return Equals((Color)value);
1151  }
1152 
1153  private static byte ToByte(float component)
1154  {
1155  var value = (int)(component * 255.0f);
1156  return (byte)(value < 0 ? 0 : value > 255 ? 255 : value);
1157  }
1158  }
1159 }
static void AdjustSaturation(ref Color value, float saturation, out Color result)
Adjusts the saturation of a color.
Definition: Color.cs:819
byte B
The blue component of the color.
Definition: Color.cs:36
Color(byte red, byte green, byte blue)
Initializes a new instance of the Color struct. Alpha is set to 255.
Definition: Color.cs:83
FbxDouble3 operator*(double factor, FbxDouble3 vector)
string ToString(string format, IFormatProvider formatProvider)
Returns a System.String that represents this instance.
Definition: Color.cs:1099
bool Equals(Color other)
Determines whether the specified Color is equal to this instance.
Definition: Color.cs:1130
static void Negate(ref Color value, out Color result)
Negates a color.
Definition: Color.cs:548
float Y
The Y component of the vector.
Definition: Vector3.cs:84
float A
The alpha component of the color.
Definition: Color4.cs:78
Color(byte red, byte green, byte blue, byte alpha)
Initializes a new instance of the Color struct.
Definition: Color.cs:69
static void Min(ref Color left, ref Color right, out Color result)
Returns a color containing the smallest components of the specified colors.
Definition: Color.cs:763
Color(float value)
Initializes a new instance of the Color struct.
Definition: Color.cs:57
float W
The W component of the vector.
Definition: Vector4.cs:101
int ToAbgr()
Converts the color into a packed integer.
Definition: Color.cs:286
function b
Color(byte value)
Initializes a new instance of the Color struct.
Definition: Color.cs:48
static Color Scale(Color value, float scale)
Scales a color.
Definition: Color.cs:538
Color(uint rgba)
Initializes a new instance of the Color struct.
Definition: Color.cs:161
Represents a color in the form of rgb.
Definition: Color3.cs:41
Color3 ToColor3()
Converts the color into a three component color.
Definition: Color.cs:309
static Color Clamp(Color value, Color min, Color max)
Restricts a value to be within a specified range.
Definition: Color.cs:661
float B
The blue component of the color.
Definition: Color3.cs:59
static void Lerp(ref Color start, ref Color end, float amount, out Color result)
Performs a linear interpolation between two colors.
Definition: Color.cs:678
float X
The X component of the vector.
Definition: Vector4.cs:83
static Color SmoothStep(Color start, Color end, float amount)
Performs a cubic interpolation between two colors.
Definition: Color.cs:723
static Color FromBgra(int color)
Converts the color from a packed BGRA integer.
Definition: Color.cs:599
float R
The red component of the color.
Definition: Color3.cs:47
string ToString(string format)
Returns a System.String that represents this instance.
Definition: Color.cs:1074
byte R
The red component of the color.
Definition: Color.cs:24
float X
The X component of the vector.
Definition: Vector3.cs:78
Color(Vector3 value)
Initializes a new instance of the Color struct. Alpha is set to 255.
Definition: Color.cs:149
Color(float red, float green, float blue)
Initializes a new instance of the Color struct. Alpha is set to 255.
Definition: Color.cs:112
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
float B
The blue component of the color.
Definition: Color4.cs:72
float GetSaturation()
Gets the saturation.
Definition: Color.cs:407
float G
The green component of the color.
Definition: Color4.cs:66
Color(Vector4 value)
Initializes a new instance of the Color struct.
Definition: Color.cs:124
static Color Subtract(Color left, Color right)
Subtracts two colors.
Definition: Color.cs:488
Represents a color in the form of rgba.
Definition: Color4.cs:42
static Color FromBgra(uint color)
Converts the color from a packed BGRA integer.
Definition: Color.cs:609
static Color FromAbgr(int color)
Converts the color from a packed ABGR integer.
Definition: Color.cs:619
static Color Negate(Color value)
Negates a color.
Definition: Color.cs:561
override int GetHashCode()
Returns a hash code for this instance.
Definition: Color.cs:1118
static void Scale(ref Color value, float scale, out Color result)
Scales a color.
Definition: Color.cs:524
static void Modulate(ref Color left, ref Color right, out Color result)
Modulates two colors.
Definition: Color.cs:499
Represents a four dimensional mathematical vector.
Definition: Vector4.cs:42
byte A
The alpha component of the color.
Definition: Color.cs:42
float R
The red component of the color.
Definition: Color4.cs:60
Vector4 ToVector4()
Converts the color into a four component vector.
Definition: Color.cs:318
SiliconStudio.Core.Mathematics.Color Color
Definition: ColorPicker.cs:14
static Color FromAbgr(uint color)
Converts the color from a packed ABGR integer.
Definition: Color.cs:629
static void Max(ref Color left, ref Color right, out Color result)
Returns a color containing the smallest components of the specified colors.
Definition: Color.cs:736
static Color FromRgba(int color)
Converts the color from a packed BGRA integer.
Definition: Color.cs:639
override string ToString()
Returns a System.String that represents this instance.
Definition: Color.cs:1062
int ToBgra()
Converts the color into a packed integer.
Definition: Color.cs:258
Represents a 32-bit color (4 bytes) in the form of RGBA (in byte order: R, G, B, A).
Definition: Color.cs:16
Color4 ToColor4()
Convert this instance to a Color4
Definition: Color.cs:977
function s(a)
Color(Vector3 value, float alpha)
Initializes a new instance of the Color struct.
Definition: Color.cs:137
byte[] ToArray()
Creates an array containing the elements of the color.
Definition: Color.cs:327
static Color Modulate(Color left, Color right)
Modulates two colors.
Definition: Color.cs:513
static Color Add(Color left, Color right)
Adds two colors.
Definition: Color.cs:463
static Color AdjustContrast(Color value, float contrast)
Adjusts the contrast of a color.
Definition: Color.cs:804
Color(int rgba)
Initializes a new instance of the Color struct.
Definition: Color.cs:173
float Y
The Y component of the vector.
Definition: Vector4.cs:89
int ToRgba()
Converts the color into a packed integer.
Definition: Color.cs:272
static void Clamp(ref Color value, ref Color min, ref Color max, out Color result)
Restricts a value to be within a specified range.
Definition: Color.cs:573
Vector3 ToVector3()
Converts the color into a three component vector.
Definition: Color.cs:300
static Color Lerp(Color start, Color end, float amount)
Performs a linear interpolation between two colors.
Definition: Color.cs:696
float G
The green component of the color.
Definition: Color3.cs:53
SiliconStudio.Core.Mathematics.Vector3 Vector3
static void Subtract(ref Color left, ref Color right, out Color result)
Subtracts two colors.
Definition: Color.cs:474
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
float Z
The Z component of the vector.
Definition: Vector4.cs:95
float GetHue()
Gets the hue.
Definition: Color.cs:359
float Z
The Z component of the vector.
Definition: Vector3.cs:90
Color(float red, float green, float blue, float alpha)
Initializes a new instance of the Color struct.
Definition: Color.cs:98
static void Add(ref Color left, ref Color right, out Color result)
Adds two colors.
Definition: Color.cs:449
static void SmoothStep(ref Color start, ref Color end, float amount, out Color result)
Performs a cubic interpolation between two colors.
Definition: Color.cs:710
static Color FromRgba(uint color)
Converts the color from a packed BGRA integer.
Definition: Color.cs:649
Color(float[] values)
Initializes a new instance of the Color struct.
Definition: Color.cs:187
static Color AdjustSaturation(Color value, float saturation)
Adjusts the saturation of a color.
Definition: Color.cs:835
override bool Equals(object value)
Determines whether the specified System.Object is equal to this instance.
Definition: Color.cs:1142
DataStyle
Specifies the style used for textual serialization when an array/list or a dictionary/map must be ser...
Definition: DataStyle.cs:9
static void AdjustContrast(ref Color value, float contrast, out Color result)
Adjusts the contrast of a color.
Definition: Color.cs:790
byte G
The green component of the color.
Definition: Color.cs:30
static Color Min(Color left, Color right)
Returns a color containing the smallest components of the specified colors.
Definition: Color.cs:777
static Color Max(Color left, Color right)
Returns a color containing the largest components of the specified colorss.
Definition: Color.cs:750
float GetBrightness()
Gets the brightness.
Definition: Color.cs:336
Color(byte[] values)
Initializes a new instance of the Color struct.
Definition: Color.cs:206
string ToString(IFormatProvider formatProvider)
Returns a System.String that represents this instance.
Definition: Color.cs:1086