1 /** color functions and utilities */ 2 3 module re.gfx.color_ext; 4 5 import re.gfx.raytypes; 6 import re.math; 7 import std.math; 8 static import raylib; 9 10 // - color functions 11 12 pragma(inline) { 13 /// gets a color that is white with a given alpha 14 public Color color_alpha_white(float alpha) { 15 return raylib.ColorFromNormalized(raylib.Vector4(1, 1, 1, alpha)); 16 } 17 18 /// gets a color from floats 19 public Color color_alpha_white(float r, float g, float b, float a = 1) { 20 return raylib.ColorFromNormalized(raylib.Vector4(r, g, b, a)); 21 } 22 23 /// fades a color 24 public Color color_fade(Color color, float fade) { 25 return raylib.Fade(color, fade); 26 } 27 28 /// gets a color from hsv 29 public Color color_hsv(float h, float s, float v) { 30 return raylib.ColorFromHSV(h, s, v); 31 } 32 33 /// gets a color from rgb 34 public Color color_rgb(float r, float g, float b, float a = 1.0) { 35 return raylib.ColorFromNormalized(Vector4(r, g, b, a)); 36 } 37 38 /// gets a color from rgb 39 public Color color_rgb(ubyte r, ubyte g, ubyte b, ubyte a = 255) { 40 return Color(r, g, b, 255); 41 } 42 43 /// gets a color from rgb in a single value 44 public Color color_rgb(ubyte v) { 45 return color_rgb(v, v, v); 46 } 47 } 48 49 /// color blending algorithm - from https://stackoverflow.com/a/39924008/13240621 50 public Color color_blend(Color c1, Color c2, float mix) { 51 // Mix [0..1] 52 // 0 --> all c1 53 // 0.5 --> equal mix of c1 and c2 54 // 1 --> all c2 55 56 // Invert sRGB gamma compression 57 c1 = inverse_srgb_companding(c1); 58 c2 = inverse_srgb_companding(c2); 59 60 Color result; 61 result.r = cast(ubyte)(c1.r * (1 - mix) + c2.r * (mix)); 62 result.g = cast(ubyte)(c1.g * (1 - mix) + c2.g * (mix)); 63 result.b = cast(ubyte)(c1.b * (1 - mix) + c2.b * (mix)); 64 65 // Reapply sRGB gamma compression 66 result = srgb_companding(result); 67 68 return result; 69 } 70 71 private Color inverse_srgb_companding(Color c) { 72 // Convert color from 0..255 to 0..1 73 float r = c.r / 255; 74 float g = c.g / 255; 75 float b = c.b / 255; 76 77 // Inverse Red, Green, and Blue 78 if (r > 0.04045) 79 r = pow((r + 0.055) / 1.055, 2.4); 80 else 81 r = r / 12.92; 82 if (g > 0.04045) 83 g = pow((g + 0.055) / 1.055, 2.4); 84 else 85 g = g / 12.92; 86 if (b > 0.04045) 87 b = pow((b + 0.055) / 1.055, 2.4); 88 else 89 b = b / 12.92; 90 91 // Convert 0..1 back into 0..255 92 Color result; 93 result.r = cast(ubyte)(r * 255); 94 result.g = cast(ubyte)(g * 255); 95 result.b = cast(ubyte)(b * 255); 96 97 return result; 98 } 99 100 private Color srgb_companding(Color c) { 101 // Convert color from 0..255 to 0..1 102 float r = c.r / 255; 103 float g = c.g / 255; 104 float b = c.b / 255; 105 106 // Apply companding to Red, Green, and Blue 107 if (r > 0.0031308) 108 r = 1.055 * pow(r, 1 / 2.4) - 0.055; 109 else 110 r = r * 12.92; 111 if (g > 0.0031308) 112 g = 1.055 * pow(g, 1 / 2.4) - 0.055; 113 else 114 g = g * 12.92; 115 if (b > 0.0031308) 116 b = 1.055 * pow(b, 1 / 2.4) - 0.055; 117 else 118 b = b * 12.92; 119 120 // Convert 0..1 back into 0..255 121 Color result; 122 result.r = cast(ubyte)(r * 255); 123 result.g = cast(ubyte)(g * 255); 124 result.b = cast(ubyte)(b * 255); 125 126 return result; 127 }