]> Dogcows Code - chaz/rasterize/blob - color.h
import project 3 files; added blending
[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 * Print the color to stdout.
69 */
70 INLINE_MAYBE
71 void color_print(color_t c)
72 {
73 #if (SCALAR_SIZE == 8)
74 const char* fmt = "[ %9.5lf %9.5lf %9.5lf %9.5lf ]";
75 #else
76 const char* fmt = "[ %9.5f %9.5f %9.5f %9.5f ]";
77 #endif
78 printf(fmt, c.r, c.g, c.b, c.a);
79 }
80
81
82 /*
83 * Add two colors together.
84 */
85 INLINE_MAYBE
86 color_t color_add(color_t c1, color_t c2)
87 {
88 return color_new(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b, c1.a);
89 }
90
91 /*
92 * Add three colors together.
93 */
94 INLINE_MAYBE
95 color_t color_add2(color_t c1, color_t c2, color_t c3)
96 {
97 return color_add(color_add(c1, c2), c3);
98 }
99
100 /*
101 * Multiply two colors together.
102 */
103 INLINE_MAYBE
104 color_t color_mult(color_t c1, color_t c2)
105 {
106 c1.r *= c2.r;
107 c1.g *= c2.g;
108 c1.b *= c2.b;
109 return c1;
110 }
111
112 /*
113 * Scale a color by some scalar coefficient.
114 */
115 INLINE_MAYBE
116 color_t color_scale(color_t c, scal_t k)
117 {
118 c.r *= k;
119 c.g *= k;
120 c.b *= k;
121 return c;
122 }
123
124 /*
125 * Scale a color by another color and some scalar coefficient.
126 */
127 INLINE_MAYBE
128 color_t color_scale2(color_t c1, color_t c2, scal_t k)
129 {
130 return color_scale(color_mult(c1, c2), k);
131 }
132
133 INLINE_MAYBE
134 color_t color_blend(color_t d, color_t s)
135 {
136 d.r = (S(1.0) - s.a) * d.r + s.a * s.r;
137 d.g = (S(1.0) - s.a) * d.g + s.a * s.g;
138 d.b = (S(1.0) - s.a) * d.b + s.a * s.b;
139 return d;
140 }
141
142 /*
143 * Clamp a color's channels to the normal range of 0.0 to 1.0.
144 */
145 INLINE_MAYBE
146 color_t color_clamp(color_t c)
147 {
148 c.r = scal_clamp(c.r, S(0.0), S(1.0));
149 c.g = scal_clamp(c.g, S(0.0), S(1.0));
150 c.b = scal_clamp(c.b, S(0.0), S(1.0));
151 c.a = scal_clamp(c.a, S(0.0), S(1.0));
152 return c;
153 }
154
155
156 /*
157 * Interpolate smoothly between two colors with an alpha value.
158 */
159 INLINE_MAYBE
160 color_t color_interp(color_t c1, color_t c2, scal_t a)
161 {
162 return color_new(c1.r * (S(1.0) - a) + c2.r * a,
163 c1.g * (S(1.0) - a) + c2.g * a,
164 c1.b * (S(1.0) - a) + c2.b * a, c1.a);
165 }
166
167 /*
168 * Interpolate smoothly between three colors with barycentric coordinates.
169 */
170 INLINE_MAYBE
171 color_t color_interp2(color_t c1, color_t c2, color_t c3, scal_t b[3])
172 {
173 return color_new(c1.r * b[0] + c2.r * b[1] + c3.r * b[2],
174 c1.g * b[0] + c2.g * b[1] + c3.g * b[2],
175 c1.b * b[0] + c2.b * b[1] + c3.b * b[2], c1.a);
176 }
177
178
179 /*
180 * Define integer types for a 32-bit RGBA color representation.
181 */
182 typedef uint8_t rgbachan_t;
183 typedef uint32_t rgba_t;
184
185 /*
186 * Create a new color from a 32-bit RGBA value.
187 */
188 INLINE_MAYBE
189 color_t color_from_rgba(rgba_t n)
190 {
191 colorchan_t r = (colorchan_t)UNPACK(n, 3) / S(255.0);
192 colorchan_t g = (colorchan_t)UNPACK(n, 2) / S(255.0);
193 colorchan_t b = (colorchan_t)UNPACK(n, 1) / S(255.0);
194 colorchan_t a = (colorchan_t)UNPACK(n, 0) / S(255.0);
195 return color_new(r, g, b, a);
196 }
197
198 /*
199 * Split a color into 8-bit RGBA channels.
200 */
201 INLINE_MAYBE
202 void color_split(color_t c, rgbachan_t* r, rgbachan_t* g, rgbachan_t* b, rgbachan_t* a)
203 {
204 if (r) *r = (rgbachan_t)(c.r * S(255.0));
205 if (g) *g = (rgbachan_t)(c.g * S(255.0));
206 if (b) *b = (rgbachan_t)(c.b * S(255.0));
207 if (a) *a = (rgbachan_t)(c.a * S(255.0));
208 }
209
210 /*
211 * Convert a color to a 32-bit RGBA value.
212 */
213 INLINE_MAYBE
214 rgba_t rgba_from_color(color_t c)
215 {
216 rgbachan_t r, g, b, a;
217 color_split(c, &r, &g, &b, &a);
218 return ((rgba_t)r << 24) | ((rgba_t)g << 16) | ((rgba_t)b << 8) | (rgba_t)a;
219 }
220
221
222 #endif // _COLOR_H_
223
This page took 0.041161 seconds and 4 git commands to generate.