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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
#pragma once
#include "typedef.h"
#include <math.h>
struct CLR {
F32 r, g, b, a;
static const CLR WHITE( F32 a_ = 1.f ) { return { 1.f, 1.f, 1.f, a_ }; }
static const CLR BLACK( F32 a_ = 1.f ) { return { 0.f, 0.f, 0.f, a_ }; }
static const CLR RED( F32 a_ = 1.f ) { return { 1.f, 0.f, 0.f, a_ }; }
static const CLR GREEN( F32 a_ = 1.f ) { return { 0.f, 1.f, 0.f, a_ }; }
static const CLR BLUE( F32 a_ = 1.f ) { return { 0.f, 0.f, 1.f, a_ }; }
static const CLR YELLOW( F32 a_ = 1.f ) { return { 1.f, 1.f, 0.f, a_ }; }
static const CLR MAGENTA( F32 a_ = 1.f ) { return { 1.f, 0.f, 1.f, a_ }; }
static const CLR CYAN( F32 a_ = 1.f ) { return { 0.f, 1.f, 1.f, a_ }; }
// slow accurate blend, looks prettier but cache maybe if possible
static CLR blend( const CLR& c1, const CLR& c2, float t = 0.5f ) {
F32 c1r = c1.r * c1.r;
F32 c1g = c1.g * c1.g;
F32 c1b = c1.b * c1.b;
F32 c1a = c1.a * c1.a;
F32 c2r = c2.r * c2.r;
F32 c2g = c2.g * c2.g;
F32 c2b = c2.b * c2.b;
F32 c2a = c2.a * c2.a;
return {
sqrtf( ( c2r * t ) + ( c1r * ( 1.f - t ) ) ),
sqrtf( ( c2g * t ) + ( c1g * ( 1.f - t ) ) ),
sqrtf( ( c2b * t ) + ( c1b * ( 1.f - t ) ) ),
sqrtf( ( c2a * t ) + ( c1a * ( 1.f - t ) ) )
};
}
// fast inaccurate blend
static CLR blend_root( const CLR& c1, const CLR& c2, float t = 0.5f ) {
return {
( c2.r * t ) + ( c1.r * ( 1.f - t ) ),
( c2.g * t ) + ( c1.g * ( 1.f - t ) ),
( c2.b * t ) + ( c1.b * ( 1.f - t ) ),
( c2.a * t ) + ( c1.a * ( 1.f - t ) )
};
}
static CLR from_hsb( F32 hue, F32 saturation, F32 brightness ) {
CLR c;
if( saturation <= 0.0f ) {
c.r = c.g = c.b = brightness;
return c;
}
I32 h = (I32)( hue * 6 );
F32 f = hue * 6 - h;
F32 p = brightness * ( 1 - saturation );
F32 q = brightness * ( 1 - f * saturation );
F32 t = brightness * ( 1 - (1 - f) * saturation );
switch( h % 6 ) {
case 0:
c.r = brightness; c.g = t; c.b = p;
return c;
case 1:
c.r = q; c.g = brightness; c.b = p;
return c;
case 2:
c.r = p; c.g = brightness; c.b = t;
return c;
case 3:
c.r = p; c.g = q; c.b = brightness;
return c;
case 4:
c.r = t; c.g = p; c.b = brightness;
return c;
case 5:
c.r = brightness; c.g = p; c.b = q;
return c;
}
return c;
}
CLR operator+( const CLR& c2 ) {
return { this->r + c2.r, this->g + c2.g, this->b + c2.b, this->a + c2.a };
}
CLR operator-( const CLR& c2 ) {
return { this->r - c2.r, this->g - c2.g, this->b - c2.b, this->a - c2.a };
}
CLR operator*( const CLR& c2 ) {
return { this->r * c2.r, this->g * c2.g, this->b * c2.b, this->a * c2.a };
}
CLR operator/( const CLR& c2 ) {
F32 r = (c2.r != 0.0f) ? this->r / c2.r : 0.0f;
F32 g = (c2.g != 0.0f) ? this->g / c2.g : 0.0f;
F32 b = (c2.b != 0.0f) ? this->b / c2.b : 0.0f;
F32 a = (c2.a != 0.0f) ? this->a / c2.a : 0.0f;
return { r, g, b, a };
}
CLR& operator+=( const CLR& c2 ) {
r += c2.r;
g += c2.g;
b += c2.b;
a += c2.a;
return *this;
}
CLR& operator-=( const CLR& c2 ) {
r -= c2.r;
g -= c2.g;
b -= c2.b;
a -= c2.a;
return *this;
}
CLR& operator*=( const CLR& c2 ) {
r *= c2.r;
g *= c2.g;
b *= c2.b;
a *= c2.a;
return *this;
}
CLR& operator/=( const CLR& c2 ) {
if( c2.r != 0.0f ) { r /= c2.r; }
else { r = 0.0f; }
if( c2.g != 0.0f ) { g /= c2.g; }
else { g = 0.0f; }
if( c2.b != 0.0f ) { b /= c2.b; }
else { b = 0.0f; }
if( c2.a != 0.0f ) { a /= c2.a; }
else { a = 0.0f; }
return *this;
}
CLR operator*( F32 f ) {
return { r * f, g * f, b * f, a * f };
}
CLR operator/( F32 f ) {
if( f != 0.0f )
return { this->r / f, this->g / f, this->b / f, this->a / f };
else
return { 0.0f, 0.0f, 0.0f, 0.0f };
}
CLR& operator*=( F32 f ) {
r *= f; g *= f; b *= f;
return *this;
}
CLR& operator/=( F32 f ) {
if( f != 0.0f ) {
r /= f;
g /= f;
b /= f;
}
else {
r = g = b = a = 0.f;
}
return *this;
}
};
|