11#pragma once
2- #ifndef XRCORE_COLOR_H
3- #define XRCORE_COLOR_H
2+
43#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+ }
715
816// maps unsigned 8 bits/channel to D3DCOLOR
917ICF u32 color_argb (u32 a , u32 r , u32 g , u32 b ) throw ()
1018{ return ((a & 0xff ) << 24 ) | ((r & 0xff ) << 16 ) | ((g & 0xff ) << 8 ) | (b & 0xff ); }
1119ICF u32 color_rgba (u32 r , u32 g , u32 b , u32 a ) throw ()
1220{ 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+ }
1436ICF u32 color_rgba_f (f32 r , f32 g , f32 b , f32 a ) throw ()
1537{ return color_argb_f (a , r , g , b ); }
1638ICF u32 color_xrgb (u32 r , u32 g , u32 b ) { return color_argb (0xff , r , g , b ); }
@@ -26,7 +48,15 @@ struct Fcolor
2648{
2749 float r , g , b , a ;
2850
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+ }
3060 Fcolor & set (float _r , float _g , float _b , float _a )
3161 {
3262 r = _r ;
@@ -35,40 +65,109 @@ struct Fcolor
3565 a = _a ;
3666 return * this ;
3767 };
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 ; }
57140
58141 // SQ magnitude
59- float magnitude_sqr_rgb () const throw ();
142+ float magnitude_sqr_rgb () const throw () { return r * r + g * g + b * b ;}
60143 // 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+ }
63150 // 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 ; }
70171};
71172
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