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