OSDN Git Service

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