OSDN Git Service

Move parameter reading to routine constructor.
[android-x86/external-swiftshader.git] / src / Renderer / Color.hpp
1 // SwiftShader Software Renderer\r
2 //\r
3 // Copyright(c) 2005-2011 TransGaming Inc.\r
4 //\r
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,\r
6 // transcribed, stored in a retrieval system, translated into any human or computer\r
7 // language by any means, or disclosed to third parties without the explicit written\r
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express\r
9 // or implied, including but not limited to any patent rights, are granted to you.\r
10 //\r
11 \r
12 #ifndef sw_Color_hpp\r
13 #define sw_Color_hpp\r
14 \r
15 #include "Common/Types.hpp"\r
16 #include "Common/Math.hpp"\r
17 \r
18 namespace sw\r
19 {\r
20         template<class T>\r
21         struct Color\r
22         {\r
23                 Color();\r
24                 \r
25                 Color(const Color<byte> &c);\r
26                 Color(const Color<short> &c);\r
27                 Color(const Color<float> &c);\r
28                 \r
29                 Color(int c);\r
30                 Color(unsigned short c);\r
31                 Color(unsigned long c);\r
32                 Color(unsigned int c);\r
33                 \r
34                 Color(T r, T g, T b, T a = 1);\r
35 \r
36                 operator unsigned int() const;\r
37 \r
38                 T &operator[](int i);\r
39                 const T &operator[](int i) const;\r
40 \r
41                 Color<T> operator+() const;\r
42                 Color<T> operator-() const;\r
43 \r
44                 Color<T>& operator=(const Color<T>& c);\r
45 \r
46                 Color<T> &operator+=(const Color<T> &c);\r
47                 Color<T> &operator*=(float l);\r
48 \r
49                 static Color<T> gradient(const Color<T> &c1, const Color<T>  &c2, float d);\r
50                 static Color<T> shade(const Color<T> &c1, const Color<T>  &c2, float d);\r
51 \r
52                 template<class S>\r
53                 friend Color<S> operator+(const Color<S> &c1, const Color<S> &c2);\r
54                 template<class S>\r
55                 friend Color<S> operator-(const Color<S> &c1, const Color<S> &c2);\r
56 \r
57                 template<class S>\r
58                 friend Color<S> operator*(float l, const Color<S> &c);\r
59                 template<class S>\r
60                 friend Color<S> operator*(const Color<S> &c1, const Color<S> &c2);\r
61                 template<class S>\r
62                 friend Color<S> operator/(const Color<S> &c, float l);\r
63 \r
64                 T r;\r
65                 T g;\r
66                 T b;\r
67                 T a;\r
68         };\r
69 }\r
70 \r
71 #include "Common/Math.hpp"\r
72 \r
73 namespace sw\r
74 {\r
75         template<class T>\r
76         inline Color<T>::Color()\r
77         {\r
78         }\r
79 \r
80         template<>\r
81         inline Color<byte>::Color(const Color<byte> &c)\r
82         {\r
83                 r = c.r;\r
84                 g = c.g;\r
85                 b = c.b;\r
86                 a = c.a;\r
87         }\r
88 \r
89         template<>\r
90         inline Color<byte>::Color(const Color<short> &c)\r
91         {\r
92                 r = clamp(c.r >> 4, 0, 255);\r
93                 g = clamp(c.g >> 4, 0, 255);\r
94                 b = clamp(c.b >> 4, 0, 255);\r
95                 a = clamp(c.a >> 4, 0, 255);\r
96         }\r
97 \r
98         template<>\r
99         inline Color<byte>::Color(const Color<float> &c)\r
100         {\r
101                 r = ifloor(clamp(c.r * 256.0f, 0.0f, 255.0f));\r
102                 g = ifloor(clamp(c.g * 256.0f, 0.0f, 255.0f));\r
103                 b = ifloor(clamp(c.b * 256.0f, 0.0f, 255.0f));\r
104                 a = ifloor(clamp(c.a * 256.0f, 0.0f, 255.0f));\r
105         }\r
106 \r
107         template<>\r
108         inline Color<short>::Color(const Color<short> &c)\r
109         {\r
110                 r = c.r;\r
111                 g = c.g;\r
112                 b = c.b;\r
113                 a = c.a;\r
114         }\r
115 \r
116         template<>\r
117         inline Color<short>::Color(const Color<byte> &c)\r
118         {\r
119                 r = c.r << 4;\r
120                 g = c.g << 4;\r
121                 b = c.b << 4;\r
122                 a = c.a << 4;\r
123         }\r
124 \r
125         template<>\r
126         inline Color<float>::Color(const Color<float> &c)\r
127         {\r
128                 r = c.r;\r
129                 g = c.g;\r
130                 b = c.b;\r
131                 a = c.a;\r
132         }\r
133 \r
134         template<>\r
135         inline Color<short>::Color(const Color<float> &c)\r
136         {\r
137                 r = iround(clamp(c.r * 4095.0f, -4096.0f, 4095.0f));\r
138                 g = iround(clamp(c.g * 4095.0f, -4096.0f, 4095.0f));\r
139                 b = iround(clamp(c.b * 4095.0f, -4096.0f, 4095.0f));\r
140                 a = iround(clamp(c.a * 4095.0f, -4096.0f, 4095.0f));\r
141         }\r
142 \r
143         template<>\r
144         inline Color<float>::Color(const Color<byte> &c)\r
145         {\r
146                 r = c.r / 255.0f;\r
147                 g = c.g / 255.0f;\r
148                 b = c.b / 255.0f;\r
149                 a = c.a / 255.0f;\r
150         }\r
151 \r
152         template<>\r
153         inline Color<float>::Color(const Color<short> &c)\r
154         {\r
155                 r = c.r / 4095.0f;\r
156                 g = c.g / 4095.0f;\r
157                 b = c.b / 4095.0f;\r
158                 a = c.a / 4095.0f;\r
159         }\r
160 \r
161         template<>\r
162         inline Color<float>::Color(unsigned short c)\r
163         {\r
164                 r = (float)(c & 0xF800) / (float)0xF800;\r
165                 g = (float)(c & 0x07E0) / (float)0x07E0;\r
166                 b = (float)(c & 0x001F) / (float)0x001F;\r
167                 a = 1;\r
168         }\r
169 \r
170         template<>\r
171         inline Color<short>::Color(unsigned short c)\r
172         {\r
173                 // 4.12 fixed-point format\r
174                 r = ((c & 0xF800) >> 4) + ((c & 0xF800) >> 9) + ((c & 0xF800) >> 14);\r
175                 g = ((c & 0x07E0) << 1) + ((c & 0x07E0) >> 5);\r
176                 b = ((c & 0x001F) << 7) + ((c & 0x001F) << 2) + ((c & 0x001F) >> 3);\r
177                 a = 0x1000;\r
178         }\r
179 \r
180         template<>\r
181         inline Color<byte>::Color(unsigned short c)\r
182         {\r
183                 r = (byte)(((c & 0xF800) >> 8) + ((c & 0xE000) >> 13));\r
184                 g = (byte)(((c & 0x07E0) >> 3) + ((c & 0x0600) >> 9));\r
185                 b = (byte)(((c & 0x001F) << 3) + ((c & 0x001C) >> 2));\r
186                 a = 0xFF;\r
187         }\r
188 \r
189         template<>\r
190         inline Color<float>::Color(int c)\r
191         {\r
192                 const float d = 1.0f / 255.0f;\r
193 \r
194                 r = (float)((c & 0x00FF0000) >> 16) * d;\r
195                 g = (float)((c & 0x0000FF00) >> 8) * d;\r
196                 b = (float)((c & 0x000000FF) >> 0) * d;\r
197                 a = (float)((c & 0xFF000000) >> 24) * d;\r
198         }\r
199 \r
200         template<>\r
201         inline Color<short>::Color(int c)\r
202         {\r
203                 // 4.12 fixed-point format\r
204                 r = (short)((c & 0x00FF0000) >> 12);\r
205                 g = (short)((c & 0x0000FF00) >> 4);\r
206                 b = (short)((c & 0x000000FF) << 4);\r
207                 a = (short)((c & 0xFF000000) >> 20);\r
208         }\r
209 \r
210         template<>\r
211         inline Color<byte>::Color(int c)\r
212         {\r
213                 r = (byte)((c & 0x00FF0000) >> 16);\r
214                 g = (byte)((c & 0x0000FF00) >> 8);\r
215                 b = (byte)((c & 0x000000FF) >> 0);\r
216                 a = (byte)((c & 0xFF000000) >> 24);\r
217         }\r
218 \r
219         template<>\r
220         inline Color<float>::Color(unsigned int c)\r
221         {\r
222                 const float d = 1.0f / 255.0f;\r
223 \r
224                 r = (float)((c & 0x00FF0000) >> 16) * d;\r
225                 g = (float)((c & 0x0000FF00) >> 8) * d;\r
226                 b = (float)((c & 0x000000FF) >> 0) * d;\r
227                 a = (float)((c & 0xFF000000) >> 24) * d;\r
228         }\r
229 \r
230         template<>\r
231         inline Color<short>::Color(unsigned int c)\r
232         {\r
233                 // 4.12 fixed-point format\r
234                 r = (short)((c & 0x00FF0000) >> 12);\r
235                 g = (short)((c & 0x0000FF00) >> 4);\r
236                 b = (short)((c & 0x000000FF) << 4);\r
237                 a = (short)((c & 0xFF000000) >> 20);\r
238         }\r
239 \r
240         template<>\r
241         inline Color<byte>::Color(unsigned int c)\r
242         {\r
243                 r = (byte)((c & 0x00FF0000) >> 16);\r
244                 g = (byte)((c & 0x0000FF00) >> 8);\r
245                 b = (byte)((c & 0x000000FF) >> 0);\r
246                 a = (byte)((c & 0xFF000000) >> 24);\r
247         }\r
248 \r
249         template<>\r
250         inline Color<float>::Color(unsigned long c)\r
251         {\r
252                 const float d = 1.0f / 255.0f;\r
253 \r
254                 r = (float)((c & 0x00FF0000) >> 16) * d;\r
255                 g = (float)((c & 0x0000FF00) >> 8) * d;\r
256                 b = (float)((c & 0x000000FF) >> 0) * d;\r
257                 a = (float)((c & 0xFF000000) >> 24) * d;\r
258         }\r
259 \r
260         template<>\r
261         inline Color<short>::Color(unsigned long c)\r
262         {\r
263                 // 4.12 fixed-point format\r
264                 r = (short)((c & 0x00FF0000) >> 12);\r
265                 g = (short)((c & 0x0000FF00) >> 4);\r
266                 b = (short)((c & 0x000000FF) << 4);\r
267                 a = (short)((c & 0xFF000000) >> 20);\r
268         }\r
269 \r
270         template<>\r
271         inline Color<byte>::Color(unsigned long c)\r
272         {\r
273                 r = (byte)((c & 0x00FF0000) >> 16);\r
274                 g = (byte)((c & 0x0000FF00) >> 8);\r
275                 b = (byte)((c & 0x000000FF) >> 0);\r
276                 a = (byte)((c & 0xFF000000) >> 24);\r
277         }\r
278 \r
279         template<class T>\r
280         inline Color<T>::Color(T r_, T g_, T b_, T a_)\r
281         {\r
282                 r = r_;\r
283                 g = g_;\r
284                 b = b_;\r
285                 a = a_;\r
286         }\r
287 \r
288         template<>\r
289         inline Color<float>::operator unsigned int() const\r
290         {\r
291                 return ((unsigned int)min(b * 255.0f, 255.0f) << 0) |\r
292                        ((unsigned int)min(g * 255.0f, 255.0f) << 8) |\r
293                        ((unsigned int)min(r * 255.0f, 255.0f) << 16) |\r
294                        ((unsigned int)min(a * 255.0f, 255.0f) << 24);\r
295         }\r
296 \r
297         template<>\r
298         inline Color<short>::operator unsigned int() const\r
299         {\r
300                 return ((unsigned int)min(b >> 4, 255) << 0) |\r
301                        ((unsigned int)min(g >> 4, 255) << 8) |\r
302                        ((unsigned int)min(r >> 4, 255) << 16) |\r
303                        ((unsigned int)min(a >> 4, 255) << 24);\r
304         }\r
305 \r
306         template<>\r
307         inline Color<byte>::operator unsigned int() const\r
308         {\r
309                 return (b << 0) +\r
310                        (g << 8) +\r
311                        (r << 16) +\r
312                            (a << 24);\r
313         }\r
314 \r
315         template<class T>\r
316         inline T &Color<T>::operator[](int i)\r
317         {\r
318                 return (&r)[i];\r
319         }\r
320 \r
321         template<class T>\r
322         inline const T &Color<T>::operator[](int i) const\r
323         {\r
324                 return (&r)[i];\r
325         }\r
326 \r
327         template<class T>\r
328         inline Color<T> Color<T>::operator+() const\r
329         {\r
330                 return *this;\r
331         }\r
332 \r
333         template<class T>\r
334         inline Color<T> Color<T>::operator-() const\r
335         {\r
336                 return Color(-r, -g, -b, -a);\r
337         }\r
338 \r
339         template<class T>\r
340         inline Color<T> &Color<T>::operator=(const Color& c)\r
341         {\r
342                 r = c.r;\r
343                 g = c.g;\r
344                 b = c.b;\r
345                 a = c.a;\r
346 \r
347                 return *this;\r
348         }\r
349 \r
350         template<class T>\r
351         inline Color<T> &Color<T>::operator+=(const Color &c)\r
352         {\r
353                 r += c.r;\r
354                 g += c.g;\r
355                 b += c.b;\r
356                 a += c.a;\r
357 \r
358                 return *this;\r
359         }\r
360 \r
361         template<class T>\r
362         inline Color<T> &Color<T>::operator*=(float l)\r
363         {\r
364                 *this = l * *this;\r
365 \r
366                 return *this;\r
367         }\r
368 \r
369         template<class T>\r
370         inline Color<T> operator+(const Color<T> &c1, const Color<T> &c2)\r
371         {\r
372                 return Color<T>(c1.r + c2.r,\r
373                                 c1.g + c2.g,\r
374                                 c1.b + c2.b,\r
375                                 c1.a + c2.a);   \r
376         }\r
377 \r
378         template<class T>\r
379         inline Color<T> operator-(const Color<T> &c1, const Color<T> &c2)\r
380         {\r
381                 return Color<T>(c1.r - c2.r,\r
382                                 c1.g - c2.g,\r
383                                 c1.b - c2.b,\r
384                                 c1.a - c2.a);   \r
385         }\r
386 \r
387         template<class T>\r
388         inline Color<T> operator*(float l, const Color<T> &c)\r
389         {\r
390                 T r = (T)(l * c.r);\r
391                 T g = (T)(l * c.g);\r
392                 T b = (T)(l * c.b);\r
393                 T a = (T)(l * c.a);\r
394 \r
395                 return Color<T>(r, g, b, a);\r
396         }\r
397 \r
398         template<class T>\r
399         inline Color<T> operator*(const Color<T> &c1, const Color<T> &c2)\r
400         {\r
401                 T r = c1.r * c2.r;\r
402                 T g = c1.g * c2.g;\r
403                 T b = c1.b * c2.b;\r
404                 T a = c1.a * c2.a;\r
405 \r
406                 return Color<T>(r, g, b, a);\r
407         }\r
408 \r
409         template<>\r
410         inline Color<short> operator*(const Color<short> &c1, const Color<short> &c2)\r
411         {\r
412                 short r = c1.r * c2.r >> 12;\r
413                 short g = c1.g * c2.g >> 12;\r
414                 short b = c1.b * c2.b >> 12;\r
415                 short a = c1.a * c2.a >> 12;\r
416 \r
417                 return Color<short>(r, g, b, a);\r
418         }\r
419 \r
420         template<>\r
421         inline Color<byte> operator*(const Color<byte> &c1, const Color<byte> &c2)\r
422         {\r
423                 byte r = c1.r * c2.r >> 8;\r
424                 byte g = c1.g * c2.g >> 8;\r
425                 byte b = c1.b * c2.b >> 8;\r
426                 byte a = c1.a * c2.a >> 8;\r
427 \r
428                 return Color<byte>(r, g, b, a);\r
429         }\r
430 \r
431         template<class T>\r
432         inline Color<T> operator/(const Color<T> &c, float l)\r
433         {\r
434                 l = 1.0f / l; \r
435 \r
436                 T r = (T)(l * c.r);\r
437                 T g = (T)(l * c.g);\r
438                 T b = (T)(l * c.b);\r
439                 T a = (T)(l * c.a);\r
440 \r
441                 return Color<T>(r, g, b, a);\r
442         }\r
443 \r
444         template<class T>\r
445         inline Color<T> Color<T>::gradient(const Color<T> &c1, const Color<T> &c2, float d)\r
446         {\r
447                 d = 1.0f / d; \r
448 \r
449                 T r = (c2.r - c1.r) * d;\r
450                 T g = (c2.g - c1.g) * d;\r
451                 T b = (c2.b - c1.b) * d;\r
452                 T a = (c2.a - c1.a) * d;\r
453 \r
454                 return Color<T>(r, g, b, a);\r
455         }\r
456 \r
457         template<class T>\r
458         inline Color<T> Color<T>::shade(const Color<T> &c1, const Color<T>  &c2, float d)\r
459         {\r
460                 T r = c1.r + (T)(d * (c2.r - c1.r));\r
461                 T g = c1.g + (T)(d * (c2.g - c1.g));\r
462                 T b = c1.b + (T)(d * (c2.b - c1.b));\r
463                 T a = c1.a + (T)(d * (c2.a - c1.a));\r
464 \r
465                 return Color<T>(r, g, b, a);\r
466         }\r
467 }\r
468 \r
469 #endif   // sw_Color_hpp\r