forked from eu07/maszyna
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcolor.h
128 lines (109 loc) · 3.56 KB
/
color.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#pragma once
namespace colors {
glm::vec4 const none{ 0.f, 0.f, 0.f, 1.f };
glm::vec4 const white{ 1.f, 1.f, 1.f, 1.f };
glm::vec4 const shadow{ 0.25f, 0.30f, 0.35f, 1.f };
glm::vec4 const uitextred{ 164.0f / 255.0f, 84.0f / 255.0f, 84.0f / 255.0f, 1.f };
glm::vec4 const uitextorange{ 164.0f / 255.0f, 132.0f / 255.0f, 84.0f / 255.0f, 1.f };
glm::vec4 const uitextgreen{ 84.0f / 255.0f, 164.0f / 255.0f, 132.0f / 255.0f, 1.f };
inline
glm::vec3
XYZtoRGB( glm::vec3 const &XYZ ) {
// M^-1 for Adobe RGB from http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html
float const mi[ 3 ][ 3 ] = { 2.041369f, -0.969266f, 0.0134474f, -0.5649464f, 1.8760108f, -0.1183897f, -0.3446944f, 0.041556f, 1.0154096f };
// m^-1 for sRGB:
// float const mi[ 3 ][ 3 ] = { 3.240479f, -0.969256f, 0.055648f, -1.53715f, 1.875991f, -0.204043f, -0.49853f, 0.041556f, 1.057311f };
return glm::vec3{
XYZ.x*mi[ 0 ][ 0 ] + XYZ.y*mi[ 1 ][ 0 ] + XYZ.z*mi[ 2 ][ 0 ],
XYZ.x*mi[ 0 ][ 1 ] + XYZ.y*mi[ 1 ][ 1 ] + XYZ.z*mi[ 2 ][ 1 ],
XYZ.x*mi[ 0 ][ 2 ] + XYZ.y*mi[ 1 ][ 2 ] + XYZ.z*mi[ 2 ][ 2 ] };
}
inline
glm::vec3
RGBtoHSV( glm::vec3 const &RGB ) {
glm::vec3 hsv;
float const max = std::max( std::max( RGB.r, RGB.g ), RGB.b );
float const min = std::min( std::min( RGB.r, RGB.g ), RGB.b );
float const delta = max - min;
hsv.z = max; // v
if( delta < 0.00001 ) {
hsv.y = 0;
hsv.x = 0; // undefined, maybe nan?
return hsv;
}
if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash
hsv.y = ( delta / max ); // s
}
else {
// if max is 0, then r = g = b = 0
// s = 0, v is undefined
hsv.y = 0.0;
hsv.x = NAN; // its now undefined
return hsv;
}
if( RGB.r >= max ) // > is bogus, just keeps compilor happy
hsv.x = ( RGB.g - RGB.b ) / delta; // between yellow & magenta
else
if( RGB.g >= max )
hsv.x = 2.f + ( RGB.g - RGB.r ) / delta; // between cyan & yellow
else
hsv.x = 4.f + ( RGB.r - RGB.g ) / delta; // between magenta & cyan
hsv.x *= 60.0; // degrees
if( hsv.x < 0.0 )
hsv.x += 360.0;
return hsv;
}
inline
glm::vec3
HSVtoRGB( glm::vec3 const &HSV ) {
glm::vec3 rgb;
if( HSV.y <= 0.0 ) { // < is bogus, just shuts up warnings
rgb.r = HSV.z;
rgb.g = HSV.z;
rgb.b = HSV.z;
return rgb;
}
float hh = HSV.x;
if( hh >= 360.0 ) hh = 0.0;
hh /= 60.0;
int const i = (int)hh;
float const ff = hh - i;
float const p = HSV.z * ( 1.f - HSV.y );
float const q = HSV.z * ( 1.f - ( HSV.y * ff ) );
float const t = HSV.z * ( 1.f - ( HSV.y * ( 1.f - ff ) ) );
switch( i ) {
case 0:
rgb.r = HSV.z;
rgb.g = t;
rgb.b = p;
break;
case 1:
rgb.r = q;
rgb.g = HSV.z;
rgb.b = p;
break;
case 2:
rgb.r = p;
rgb.g = HSV.z;
rgb.b = t;
break;
case 3:
rgb.r = p;
rgb.g = q;
rgb.b = HSV.z;
break;
case 4:
rgb.r = t;
rgb.g = p;
rgb.b = HSV.z;
break;
case 5:
default:
rgb.r = HSV.z;
rgb.g = p;
rgb.b = q;
break;
}
return rgb;
}
} // namespace colors