00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LUX_COLORBASE_H
00024 #define LUX_COLORBASE_H
00025
00026 #include "lux.h"
00027
00028 #ifdef WIN32
00029 #undef max
00030 #undef min
00031 #include <limits>
00032 #else
00033 #include <limits.h>
00034 #endif // WIN32
00035
00036 namespace lux
00037 {
00038 class TextureColorBase
00039 {
00040 public:
00041 TextureColorBase(){};
00042 };
00043
00044 template <class T,int colorSamples> class TextureColor : public TextureColorBase {
00045 friend class boost::serialization::access;
00046 public:
00047 TextureColor(T v = 0) {
00048 for (int i = 0; i < colorSamples; ++i)
00049 c[i] = v;
00050 }
00051 TextureColor(T cs[colorSamples]) {
00052 for (int i = 0; i < colorSamples; ++i)
00053 c[i] = cs[i];
00054 }
00055
00056 TextureColor<T,colorSamples> &operator+=(const TextureColor<T,colorSamples> &s2) {
00057 for (int i = 0; i < colorSamples; ++i)
00058 if (c[i] > std::numeric_limits<T>::max() - s2.c[i])
00059 c[i] = std::numeric_limits<T>::max();
00060 else
00061 c[i] += s2.c[i];
00062 return *this;
00063 }
00064 TextureColor<T,colorSamples> &operator-=(const TextureColor<T,colorSamples> &s2) {
00065 for (int i = 0; i < colorSamples; ++i)
00066 if (c[i] < std::numeric_limits<T>::min() + s2.c[i])
00067 c[i] = std::numeric_limits<T>::min();
00068 else
00069 c[i] -= s2.c[i];
00070 return *this;
00071 }
00072 TextureColor<T,colorSamples> operator+(const TextureColor<T,colorSamples> &s2) const {
00073 TextureColor<T,colorSamples> ret = *this;
00074 for (int i = 0; i < colorSamples; ++i)
00075 if (ret.c[i] > std::numeric_limits<T>::max() - s2.c[i])
00076 ret.c[i] = std::numeric_limits<T>::max();
00077 else
00078 ret.c[i] += s2.c[i];
00079 return ret;
00080 }
00081 TextureColor<T,colorSamples> operator-(const TextureColor<T,colorSamples> &s2) const {
00082 TextureColor<T,colorSamples> ret = *this;
00083 for (int i = 0; i < colorSamples; ++i)
00084 if (c[i] < s2.c[i])
00085 ret.c[i] = 0;
00086 else
00087 ret.c[i] -= s2.c[i];
00088 return ret;
00089 }
00090 TextureColor<T,colorSamples> operator/(const TextureColor<T,colorSamples> &s2) const {
00091 TextureColor<T,colorSamples> ret = *this;
00092 for (int i = 0; i < colorSamples; ++i)
00093 ret.c[i] /= s2.c[i];
00094 return ret;
00095 }
00096 TextureColor<T,colorSamples> operator*(const TextureColor<T,colorSamples> &sp) const {
00097 TextureColor<T,colorSamples> ret = *this;
00098 for (int i = 0; i < colorSamples; ++i)
00099 if ((float)ret.c[i]*sp.c[i] > std::numeric_limits<T>::max())
00100 ret.c[i] = std::numeric_limits<T>::max();
00101 else
00102 ret.c[i] *= sp.c[i];
00103 return ret;
00104 }
00105 TextureColor<T,colorSamples> &operator*=(const TextureColor<T,colorSamples> &sp) {
00106 for (int i = 0; i < colorSamples; ++i)
00107 if ((float)c[i]*sp.c[i] > std::numeric_limits<T>::max())
00108 c[i] = std::numeric_limits<T>::max();
00109 else
00110 c[i] *= sp.c[i];
00111 return *this;
00112 }
00113 TextureColor<T,colorSamples> operator*(float a) const {
00114 TextureColor<T,colorSamples> ret = *this;
00115 for (int i = 0; i < colorSamples; ++i)
00116 if (a*ret.c[i] > std::numeric_limits<T>::max())
00117 ret.c[i] = std::numeric_limits<T>::max();
00118 else
00119 ret.c[i] = (T)(a*ret.c[i]);
00120 return ret;
00121 }
00122 TextureColor<T, colorSamples> &operator*=(float a) {
00123 for (int i = 0; i < colorSamples; ++i)
00124 if (a*c[i] > std::numeric_limits<T>::max())
00125 c[i] = std::numeric_limits<T>::max();
00126 else
00127 c[i] *= a;
00128 return *this;
00129 }
00130 friend inline
00131 TextureColor<T,colorSamples> operator*(float a, const TextureColor<T,colorSamples> &s) {
00132 return s * a;
00133 }
00134 TextureColor<T,colorSamples> operator/(float a) const {
00135 return *this * (1.f / a);
00136 }
00137 TextureColor<T,colorSamples> &operator/=(float a) {
00138 float inv = 1.f / a;
00139 for (int i = 0; i < colorSamples; ++i)
00140 c[i] *= inv;
00141 return *this;
00142 }
00143 void AddWeighted(float w, const TextureColor<T,colorSamples> &s) {
00144 for (int i = 0; i < colorSamples; ++i)
00145 c[i] += (T)(w * s.c[i]);
00146 }
00147 bool operator==(const TextureColor<T,colorSamples> &sp) const {
00148 for (int i = 0; i < colorSamples; ++i)
00149 if (c[i] != sp.c[i]) return false;
00150 return true;
00151 }
00152 bool operator!=(const TextureColor<T,colorSamples> &sp) const {
00153 return !(*this == sp);
00154 }
00155 TextureColor<T,colorSamples> operator-() const {
00156 TextureColor<T,colorSamples> ret;
00157 for (int i = 0; i < colorSamples; ++i)
00158 ret.c[i] = -c[i];
00159 return ret;
00160 }
00161 TextureColor<T,colorSamples> Clamp(float low = 0.f,
00162 float high = INFINITY) const {
00163 TextureColor<T,colorSamples> ret;
00164 for (int i = 0; i < colorSamples; ++i)
00165 ret.c[i] = (T)::Clamp((float)c[i], low, high);
00166 return ret;
00167 }
00168
00169 T c[colorSamples];
00170 };
00171 }
00172 #endif // LUX_COLORBASE_H