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