preliminary support for obj files
[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 + c2.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 c1.a *= c2.a;
110 return c1;
111 }
112
113 /*
114 * Scale a color by some scalar coefficient.
115 */
116 INLINE_MAYBE
117 color_t color_scale(color_t c, scal_t k)
118 {
119 c.r *= k;
120 c.g *= k;
121 c.b *= k;
122 c.a *= k;
123 return c;
124 }
125
126 /*
127 * Scale a color by another color and some scalar coefficient.
128 */
129 INLINE_MAYBE
130 color_t color_scale2(color_t c1, color_t c2, scal_t k)
131 {
132 return color_scale(color_mult(c1, c2), k);
133 }
134
135 /*
136 * Clamp a color's channels to the normal range of 0.0 to 1.0.
137 */
138 INLINE_MAYBE
139 color_t color_clamp(color_t c)
140 {
141 c.r = scal_clamp(c.r, S(0.0), S(1.0));
142 c.g = scal_clamp(c.g, S(0.0), S(1.0));
143 c.b = scal_clamp(c.b, S(0.0), S(1.0));
144 c.a = scal_clamp(c.a, S(0.0), S(1.0));
145 return c;
146 }
147
148
149 /*
150 * Interpolate smoothly between two colors with an alpha value.
151 */
152 INLINE_MAYBE
153 color_t color_interp(color_t c1, color_t c2, scal_t a)
154 {
155 return color_new(c1.r * (S(1.0) - a) + c2.r * a,
156 c1.g * (S(1.0) - a) + c2.g * a,
157 c1.b * (S(1.0) - a) + c2.b * a,
158 c1.a * (S(1.0) - a) + c2.a * a);
159 }
160
161 /*
162 * Interpolate smoothly between three colors with barycentric coordinates.
163 */
164 INLINE_MAYBE
165 color_t color_interp2(color_t c1, color_t c2, color_t c3, scal_t b[3])
166 {
167 return color_new(c1.r * b[0] + c2.r * b[1] + c3.r * b[2],
168 c1.g * b[0] + c2.g * b[1] + c3.g * b[2],
169 c1.b * b[0] + c2.b * b[1] + c3.b * b[2],
170 S(1.0));
171 }
172
173
174 /*
175 * Define integer types for a 32-bit RGBA color representation.
176 */
177 typedef uint8_t rgbachan_t;
178 typedef uint32_t rgba_t;
179
180 /*
181 * Create a new color from a 32-bit RGBA value.
182 */
183 INLINE_MAYBE
184 color_t color_from_rgba(rgba_t n)
185 {
186 colorchan_t r = (colorchan_t)UNPACK(n, 3) / S(255.0);
187 colorchan_t g = (colorchan_t)UNPACK(n, 2) / S(255.0);
188 colorchan_t b = (colorchan_t)UNPACK(n, 1) / S(255.0);
189 colorchan_t a = (colorchan_t)UNPACK(n, 0) / S(255.0);
190 return color_new(r, g, b, a);
191 }
192
193 /*
194 * Split a color into 8-bit RGBA channels.
195 */
196 INLINE_MAYBE
197 void color_split(color_t c, rgbachan_t* r, rgbachan_t* g, rgbachan_t* b, rgbachan_t* a)
198 {
199 if (r) *r = (rgbachan_t)(c.r * S(255.0));
200 if (g) *g = (rgbachan_t)(c.g * S(255.0));
201 if (b) *b = (rgbachan_t)(c.b * S(255.0));
202 if (a) *a = (rgbachan_t)(c.a * S(255.0));
203 }
204
205 /*
206 * Convert a color to a 32-bit RGBA value.
207 */
208 INLINE_MAYBE
209 rgba_t rgba_from_color(color_t c)
210 {
211 rgbachan_t r, g, b, a;
212 color_split(c, &r, &g, &b, &a);
213 return ((rgba_t)r << 24) | ((rgba_t)g << 16) | ((rgba_t)b << 8) | (rgba_t)a;
214 }
215
216
217 #endif // _COLOR_H_
218
This page took 0.050079 seconds and 4 git commands to generate.