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 
32 /// color blending algorithm - from https://stackoverflow.com/a/39924008/13240621
33 public Color color_blend(Color c1, Color c2, float mix) {
34     // Mix [0..1]
35     //  0   --> all c1
36     //  0.5 --> equal mix of c1 and c2
37     //  1   --> all c2
38 
39     // Invert sRGB gamma compression
40     c1 = inverse_srgb_companding(c1);
41     c2 = inverse_srgb_companding(c2);
42 
43     Color result;
44     result.r = cast(ubyte)(c1.r * (1 - mix) + c2.r * (mix));
45     result.g = cast(ubyte)(c1.g * (1 - mix) + c2.g * (mix));
46     result.b = cast(ubyte)(c1.b * (1 - mix) + c2.b * (mix));
47 
48     // Reapply sRGB gamma compression
49     result = srgb_companding(result);
50 
51     return result;
52 }
53 
54 private Color inverse_srgb_companding(Color c) {
55     // Convert color from 0..255 to 0..1
56     float r = c.r / 255;
57     float g = c.g / 255;
58     float b = c.b / 255;
59 
60     // Inverse Red, Green, and Blue
61     if (r > 0.04045)
62         r = pow((r + 0.055) / 1.055, 2.4);
63     else
64         r = r / 12.92;
65     if (g > 0.04045)
66         g = pow((g + 0.055) / 1.055, 2.4);
67     else
68         g = g / 12.92;
69     if (b > 0.04045)
70         b = pow((b + 0.055) / 1.055, 2.4);
71     else
72         b = b / 12.92;
73 
74     // Convert 0..1 back into 0..255
75     Color result;
76     result.r = cast(ubyte)(r * 255);
77     result.g = cast(ubyte)(g * 255);
78     result.b = cast(ubyte)(b * 255);
79 
80     return result;
81 }
82 
83 private Color srgb_companding(Color c) {
84     // Convert color from 0..255 to 0..1
85     float r = c.r / 255;
86     float g = c.g / 255;
87     float b = c.b / 255;
88 
89     // Apply companding to Red, Green, and Blue
90     if (r > 0.0031308)
91         r = 1.055 * pow(r, 1 / 2.4) - 0.055;
92     else
93         r = r * 12.92;
94     if (g > 0.0031308)
95         g = 1.055 * pow(g, 1 / 2.4) - 0.055;
96     else
97         g = g * 12.92;
98     if (b > 0.0031308)
99         b = 1.055 * pow(b, 1 / 2.4) - 0.055;
100     else
101         b = b * 12.92;
102 
103     // Convert 0..1 back into 0..255
104     Color result;
105     result.r = cast(ubyte)(r * 255);
106     result.g = cast(ubyte)(g * 255);
107     result.b = cast(ubyte)(b * 255);
108 
109     return result;
110 }