]> Dogcows Code - chaz/rasterize/blob - color.h
add opengl support
[chaz/rasterize] / color.h
1
2 /*
3 * CS5600 University of Utah
4 * Charles McGarvey
5 * mcgarvey@eng.utah.edu
6 */
7
8 #ifndef _COLOR_H_
9 #define _COLOR_H_
10
11 #include "common.h"
12
13
14 /*
15 * A color channel will be the same as a scalar.
16 */
17 typedef scal_t colorchan_t;
18
19 /*
20 * A color class.
21 * Colors are represented by RGBA values between 0.0 and 1.0.
22 */
23 struct color
24 {
25 colorchan_t r;
26 colorchan_t g;
27 colorchan_t b;
28 colorchan_t a;
29 };
30 typedef struct color color_t;
31
32 /*
33 * Initialize a color.
34 */
35 INLINE_MAYBE
36 void color_init(color_t* c, colorchan_t r, colorchan_t g, colorchan_t b, colorchan_t a)
37 {
38 c->r = r;
39 c->g = g;
40 c->b = b;
41 c->a = a;
42 }
43
44
45 /*
46 * Create a new color, copied by value.
47 */
48 INLINE_MAYBE
49 color_t color_new(colorchan_t r, colorchan_t g, colorchan_t b, colorchan_t a)
50 {
51 color_t c;
52 color_init(&c, r, g, b, a);
53 return c;
54 }
55
56 #define COLOR_CLEAR color_new(S(0.0), S(0.0), S(0.0), S(0.0))
57 #define COLOR_BLACK color_new(S(0.0), S(0.0), S(0.0), S(1.0))
58 #define COLOR_RED color_new(S(1.0), S(0.0), S(0.0), S(1.0))
59 #define COLOR_GREEN color_new(S(0.0), S(1.0), S(0.0), S(1.0))
60 #define COLOR_BLUE color_new(S(0.0), S(0.0), S(1.0), S(1.0))
61 #define COLOR_YELLOW color_new(S(1.0), S(1.0), S(0.0), S(1.0))
62 #define COLOR_MAGENTA color_new(S(1.0), S(0.0), S(1.0), S(1.0))
63 #define COLOR_CYAN color_new(S(0.0), S(1.0), S(1.0), S(1.0))
64 #define COLOR_WHITE color_new(S(1.0), S(1.0), S(1.0), S(1.0))
65
66
67 /*
68 * Get a pointer to the color data.
69 */
70 INLINE_MAYBE
71 const scal_t* color_data(const color_t* c)
72 {
73 return &c->r;
74 }
75
76
77 /*
78 * Print the color to stdout.
79 */
80 INLINE_MAYBE
81 void color_print(color_t c)
82 {
83 #if (SCALAR_SIZE == 8)
84 const char* fmt = "[ %9.5lf %9.5lf %9.5lf %9.5lf ]";
85 #else
86 const char* fmt = "[ %9.5f %9.5f %9.5f %9.5f ]";
87 #endif
88 printf(fmt, c.r, c.g, c.b, c.a);
89 }
90
91
92 /*
93 * Add two colors together.
94 */
95 INLINE_MAYBE
96 color_t color_add(color_t c1, color_t c2)
97 {
98 return color_new(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b, c1.a);
99 }
100
101 /*
102 * Add three colors together.
103 */
104 INLINE_MAYBE
105 color_t color_add2(color_t c1, color_t c2, color_t c3)
106 {
107 return color_add(color_add(c1, c2), c3);
108 }
109
110 /*
111 * Multiply two colors together.
112 */
113 INLINE_MAYBE
114 color_t color_mult(color_t c1, color_t c2)
115 {
116 c1.r *= c2.r;
117 c1.g *= c2.g;
118 c1.b *= c2.b;
119 return c1;
120 }
121
122 /*
123 * Scale a color by some scalar coefficient.
124 */
125 INLINE_MAYBE
126 color_t color_scale(color_t c, scal_t k)
127 {
128 c.r *= k;
129 c.g *= k;
130 c.b *= k;
131 return c;
132 }
133
134 /*
135 * Scale a color by another color and some scalar coefficient.
136 */
137 INLINE_MAYBE
138 color_t color_scale2(color_t c1, color_t c2, scal_t k)
139 {
140 return color_scale(color_mult(c1, c2), k);
141 }
142
143 INLINE_MAYBE
144 color_t color_blend(color_t d, color_t s)
145 {
146 d.r = (S(1.0) - s.a) * d.r + s.a * s.r;
147 d.g = (S(1.0) - s.a) * d.g + s.a * s.g;
148 d.b = (S(1.0) - s.a) * d.b + s.a * s.b;
149 return d;
150 }
151
152 /*
153 * Clamp a color's channels to the normal range of 0.0 to 1.0.
154 */
155 INLINE_MAYBE
156 color_t color_clamp(color_t c)
157 {
158 c.r = scal_clamp(c.r, S(0.0), S(1.0));
159 c.g = scal_clamp(c.g, S(0.0), S(1.0));
160 c.b = scal_clamp(c.b, S(0.0), S(1.0));
161 c.a = scal_clamp(c.a, S(0.0), S(1.0));
162 return c;
163 }
164
165
166 /*
167 * Interpolate smoothly between two colors with an alpha value.
168 */
169 INLINE_MAYBE
170 color_t color_interp(color_t c1, color_t c2, scal_t a)
171 {
172 return color_new(c1.r * (S(1.0) - a) + c2.r * a,
173 c1.g * (S(1.0) - a) + c2.g * a,
174 c1.b * (S(1.0) - a) + c2.b * a, c1.a);
175 }
176
177 /*
178 * Interpolate smoothly between three colors with barycentric coordinates.
179 */
180 INLINE_MAYBE
181 color_t color_interp2(color_t c1, color_t c2, color_t c3, scal_t b[3])
182 {
183 return color_new(c1.r * b[0] + c2.r * b[1] + c3.r * b[2],
184 c1.g * b[0] + c2.g * b[1] + c3.g * b[2],
185 c1.b * b[0] + c2.b * b[1] + c3.b * b[2], c1.a);
186 }
187
188
189 /*
190 * Define integer types for a 32-bit RGBA color representation.
191 */
192 typedef uint8_t rgbachan_t;
193 typedef uint32_t rgba_t;
194
195 /*
196 * Split a color into 8-bit RGBA channels.
197 */
198 INLINE_MAYBE
199 void color_split(color_t c, rgbachan_t* r, rgbachan_t* g, rgbachan_t* b, rgbachan_t* a)
200 {
201 if (r) *r = (rgbachan_t)(c.r * S(255.0));
202 if (g) *g = (rgbachan_t)(c.g * S(255.0));
203 if (b) *b = (rgbachan_t)(c.b * S(255.0));
204 if (a) *a = (rgbachan_t)(c.a * S(255.0));
205 }
206
207 /*
208 * Create a new color from a 32-bit RGBA value.
209 */
210 INLINE_MAYBE
211 color_t color_from_rgba(rgba_t n)
212 {
213 union {
214 rgba_t rgba;
215 struct {
216 rgbachan_t r, g, b, a;
217 } chan;
218 } u;
219 u.rgba = n;
220 colorchan_t r = (colorchan_t)u.chan.r / S(255.0);
221 colorchan_t g = (colorchan_t)u.chan.g / S(255.0);
222 colorchan_t b = (colorchan_t)u.chan.b / S(255.0);
223 colorchan_t a = (colorchan_t)u.chan.a / S(255.0);
224 return color_new(r, g, b, a);
225 }
226
227 /*
228 * Convert a color to a 32-bit RGBA value.
229 */
230 INLINE_MAYBE
231 rgba_t rgba_from_color(color_t c)
232 {
233 union {
234 rgba_t rgba;
235 struct {
236 rgbachan_t r, g, b, a;
237 } chan;
238 } u;
239 color_split(c, &u.chan.r, &u.chan.g, &u.chan.b, &u.chan.a);
240 return u.rgba;
241 }
242
243
244 #endif // _COLOR_H_
245
This page took 0.040456 seconds and 4 git commands to generate.