1
1
#pragma once
2
- #ifndef XRCORE_COLOR_H
3
- #define XRCORE_COLOR_H
2
+
4
3
#include "_types.h"
5
- #include "xrCommon/inlining_macros.h"
6
- #include "xrCore/math_constants.h"
4
+ #include "_std_extensions.h"
5
+ #include "math_constants.h"
6
+
7
+ IC s32 clamp_to_8bit (const s32 val ) throw ()
8
+ {
9
+ if (val < 0 )
10
+ return 0 ;
11
+ if (val > 255 )
12
+ return 255 ;
13
+ return val ;
14
+ }
7
15
8
16
// maps unsigned 8 bits/channel to D3DCOLOR
9
17
ICF u32 color_argb (u32 a , u32 r , u32 g , u32 b ) throw ()
10
18
{ return ((a & 0xff ) << 24 ) | ((r & 0xff ) << 16 ) | ((g & 0xff ) << 8 ) | (b & 0xff ); }
11
19
ICF u32 color_rgba (u32 r , u32 g , u32 b , u32 a ) throw ()
12
20
{ return color_argb (a , r , g , b ); }
13
- u32 color_argb_f (f32 a , f32 r , f32 g , f32 b ) throw ();
21
+ ICF u32 color_argb_f (f32 a , f32 r , f32 g , f32 b ) throw ()
22
+ {
23
+ #if 0
24
+ s32 _r = clampr (iFloor (r * 255.f ), 0 , 255 );
25
+ s32 _g = clampr (iFloor (g * 255.f ), 0 , 255 );
26
+ s32 _b = clampr (iFloor (b * 255.f ), 0 , 255 );
27
+ s32 _a = clampr (iFloor (a * 255.f ), 0 , 255 );
28
+ #else
29
+ s32 _r = clamp_to_8bit (iFloor (r * 255.f ));
30
+ s32 _g = clamp_to_8bit (iFloor (g * 255.f ));
31
+ s32 _b = clamp_to_8bit (iFloor (b * 255.f ));
32
+ s32 _a = clamp_to_8bit (iFloor (a * 255.f ));
33
+ #endif
34
+ return color_argb (_a , _r , _g , _b );
35
+ }
14
36
ICF u32 color_rgba_f (f32 r , f32 g , f32 b , f32 a ) throw ()
15
37
{ return color_argb_f (a , r , g , b ); }
16
38
ICF u32 color_xrgb (u32 r , u32 g , u32 b ) { return color_argb (0xff , r , g , b ); }
@@ -26,7 +48,15 @@ struct Fcolor
26
48
{
27
49
float r , g , b , a ;
28
50
29
- Fcolor & set (u32 dw ) throw ();
51
+ Fcolor & set (u32 dw ) throw ()
52
+ {
53
+ const float f = float (1.0 ) / float (255.0 );
54
+ a = f * float ((dw >> 24 ) & 0xff );
55
+ r = f * float ((dw >> 16 ) & 0xff );
56
+ g = f * float ((dw >> 8 ) & 0xff );
57
+ b = f * float ((dw >> 0 ) & 0xff );
58
+ return * this ;
59
+ }
30
60
Fcolor & set (float _r , float _g , float _b , float _a )
31
61
{
32
62
r = _r ;
@@ -35,40 +65,109 @@ struct Fcolor
35
65
a = _a ;
36
66
return * this ;
37
67
};
38
- Fcolor & set (const Fcolor & rhs ) throw ();
39
- u32 get () const throw ();
40
- u32 get_windows () const throw (); // Get color as a Windows DWORD value.
41
- Fcolor & set_windows (u32 dw ) throw (); // Set color from a Windows DWORD color value.
42
- Fcolor & adjust_contrast (float f ) throw (); // >1 - contrast will be increased
43
- Fcolor & adjust_contrast (const Fcolor & in , float f ) throw (); // >1 - contrast will be increased
44
- Fcolor & adjust_saturation (float s ) throw ();
45
- Fcolor & adjust_saturation (const Fcolor & in , float s ) throw ();
46
- Fcolor & modulate (Fcolor & in ) throw ();
47
- Fcolor & modulate (const Fcolor & in1 , const Fcolor & in2 ) throw ();
48
- Fcolor & negative (const Fcolor & in ) throw ();
49
- Fcolor & negative () throw ();
50
- Fcolor & sub_rgb (float s ) throw ();
51
- Fcolor & add_rgb (float s ) throw ();
52
- Fcolor & add_rgba (float s ) throw ();
53
- Fcolor & mul_rgba (float s ) throw ();
54
- Fcolor & mul_rgb (float s ) throw ();
55
- Fcolor & mul_rgba (const Fcolor & c , float s ) throw ();
56
- Fcolor & mul_rgb (const Fcolor & c , float s ) throw ();
68
+ Fcolor & set (const Fcolor & rhs ) throw ()
69
+ {
70
+ r = rhs .r ;
71
+ g = rhs .g ;
72
+ b = rhs .b ;
73
+ a = rhs .a ;
74
+ return * this ;
75
+ }
76
+ u32 get () const throw () { return color_rgba_f (r , g , b , a ); }
77
+ u32 get_windows () const throw () // Get color as a Windows DWORD value.
78
+ {
79
+ u8 _a , _r , _g , _b ;
80
+ _a = u8 (a * 255.f );
81
+ _r = u8 (r * 255.f );
82
+ _g = u8 (g * 255.f );
83
+ _b = u8 (b * 255.f );
84
+ return (u32 )(_a << 24 ) | (_b << 16 ) | (_g << 8 ) | _r ;
85
+ }
86
+ Fcolor & set_windows (u32 dw ) throw () // Set color from a Windows DWORD color value.
87
+ {
88
+ const float f = 1.0f / 255.0f ;
89
+ a = f * (float )(u8 )(dw >> 24 );
90
+ b = f * (float )(u8 )(dw >> 16 );
91
+ g = f * (float )(u8 )(dw >> 8 );
92
+ r = f * (float )(u8 )(dw >> 0 );
93
+ return * this ;
94
+ }
95
+ Fcolor & adjust_contrast (float f ) throw () // >1 - contrast will be increased
96
+ {
97
+ r = 0.5f + f * (r - 0.5f ) ;
98
+ g = 0.5f + f * (g - 0.5f );
99
+ b = 0.5f + f * (b - 0.5f );
100
+ return * this ;
101
+ }
102
+ Fcolor & adjust_contrast (const Fcolor & in , float f ) throw () // >1 - contrast will be increased
103
+ {
104
+ r = 0.5f + f * (in .r - 0.5f );
105
+ g = 0.5f + f * (in .g - 0.5f );
106
+ b = 0.5f + f * (in .b - 0.5f );
107
+ return * this ;
108
+ }
109
+ Fcolor & adjust_saturation (float s ) throw ()
110
+ {
111
+ // Approximate values for each component's contribution to luminance.
112
+ // Based upon the NTSC standard described in ITU-R Recommendation BT.709.
113
+ float grey = r * 0.2125f + g * 0.7154f + b * 0.0721f ;
114
+ r = grey + s * (r - grey );
115
+ g = grey + s * (g - grey );
116
+ b = grey + s * (b - grey );
117
+ return * this ;
118
+ }
119
+ Fcolor & adjust_saturation (const Fcolor & in , float s ) throw ()
120
+ {
121
+ // Approximate values for each component's contribution to luminance.
122
+ // Based upon the NTSC standard described in ITU-R Recommendation BT.709.
123
+ float grey = in .r * 0.2125f + in .g * 0.7154f + in .b * 0.0721f ;
124
+ r = grey + s * (in .r - grey );
125
+ g = grey + s * (in .g - grey );
126
+ b = grey + s * (in .b - grey );
127
+ return * this ;
128
+ }
129
+ Fcolor & modulate (Fcolor & in ) throw () { r *= in .r ; g *= in .g ; b *= in .b ; a *= in .a ; return * this ; }
130
+ Fcolor & modulate (const Fcolor & in1 , const Fcolor & in2 ) throw () { r = in1 .r * in2 .r ; g = in1 .g * in2 .g ; b = in1 .b * in2 .b ; a = in1 .a * in2 .a ; return * this ; }
131
+ Fcolor & negative (const Fcolor & in ) throw () { r = 1.0f - in .r ; g = 1.0f - in .g ; b = 1.0f - in .b ; a = 1.0f - in .a ; return * this ; }
132
+ Fcolor & negative () throw () { r = 1.0f - r ; g = 1.0f - g ; b = 1.0f - b ; a = 1.0f - a ; return * this ; }
133
+ Fcolor & sub_rgb (float s ) throw () { r -= s ; g -= s ; b -= s ; return * this ; }
134
+ Fcolor & add_rgb (float s ) throw () { r += s ; g += s ; b += s ; return * this ; }
135
+ Fcolor & add_rgba (float s ) throw () { r += s ; g += s ; b += s ; a += s ; return * this ; }
136
+ Fcolor & mul_rgba (float s ) throw () { r *= s ; g *= s ; b *= s ; a *= s ; return * this ; }
137
+ Fcolor & mul_rgb (float s ) throw () { r *= s ; g *= s ; b *= s ; return * this ; }
138
+ Fcolor & mul_rgba (const Fcolor & c , float s ) throw () { r = c .r * s ; g = c .g * s ; b = c .b * s ; a = c .a * s ; return * this ; }
139
+ Fcolor & mul_rgb (const Fcolor & c , float s ) throw () { r = c .r * s ; g = c .g * s ; b = c .b * s ; return * this ; }
57
140
58
141
// SQ magnitude
59
- float magnitude_sqr_rgb () const throw ();
142
+ float magnitude_sqr_rgb () const throw () { return r * r + g * g + b * b ;}
60
143
// magnitude
61
- float magnitude_rgb () const throw ();
62
- float intensity () const throw ();
144
+ float magnitude_rgb () const throw () { return _sqrt (magnitude_sqr_rgb ()); }
145
+ float intensity () const throw ()
146
+ {
147
+ // XXX: Use the component percentages from adjust_saturation()?
148
+ return (r + g + b ) / 3.f ;
149
+ }
63
150
// Normalize
64
- Fcolor & normalize_rgb ();
65
- Fcolor & normalize_rgb (const Fcolor & c );
66
- Fcolor & lerp (const Fcolor & c1 , const Fcolor & c2 , float t ) throw ();
67
- Fcolor & lerp (const Fcolor & c1 , const Fcolor & c2 , const Fcolor & c3 , float t );
68
- bool similar_rgba (const Fcolor & v , float E = EPS_L ) const throw ();
69
- bool similar_rgb (const Fcolor & v , float E = EPS_L ) const throw ();
151
+ Fcolor & normalize_rgb () throw () { VERIFY ( magnitude_sqr_rgb () > EPS_S ) ; return mul_rgb ( 1.f / magnitude_rgb ()); }
152
+ Fcolor & normalize_rgb (const Fcolor & c ) throw () { VERIFY (c .magnitude_sqr_rgb () > EPS_S ); return mul_rgb (c , 1.f / c .magnitude_rgb ()); }
153
+ Fcolor & lerp (const Fcolor & c1 , const Fcolor & c2 , float t ) throw ()
154
+ {
155
+ float invt = 1.f - t ;
156
+ r = c1 .r * invt + c2 .r * t ;
157
+ g = c1 .g * invt + c2 .g * t ;
158
+ b = c1 .b * invt + c2 .b * t ;
159
+ a = c1 .a * invt + c2 .a * t ;
160
+ return * this ;
161
+ }
162
+ Fcolor & lerp (const Fcolor & c1 , const Fcolor & c2 , const Fcolor & c3 , float t ) throw ()
163
+ {
164
+ if (t > .5f )
165
+ return lerp (c2 , c3 , t * 2.f - 1.f );
166
+ else
167
+ return lerp (c1 , c2 , t * 2.f );
168
+ }
169
+ bool similar_rgba (const Fcolor & v , float E = EPS_L ) const throw () { return _abs (r - v .r ) < E && _abs (g - v .g ) < E && _abs (b - v .b ) < E && _abs (a - v .a ) < E ; }
170
+ bool similar_rgb (const Fcolor & v , float E = EPS_L ) const throw () { return _abs (r - v .r ) < E && _abs (g - v .g ) < E && _abs (b - v .b ) < E ; }
70
171
};
71
172
72
- bool _valid (const Fcolor & c );
73
-
74
- #endif // XRCORE_COLOR_H
173
+ IC bool _valid (const Fcolor & c ) throw () { return _valid (c .r ) && _valid (c .g ) && _valid (c .b ) && _valid (c .a ); }
0 commit comments