00001
00009
00010 #ifndef __CTEXTURE__
00011 #define __CTEXTURE__
00012
00013 #define TEXTURE_NAME_SIZE 256
00014 #define TEXTURE_EPSILON 0.0001
00015
00016 #include "CLibTextureException.h"
00017 #include <math.h>
00018 #include <assert.h>
00019
00020 #ifndef ABS
00021 #define ABS(x) ((x)>0.0?(x):-(x))
00022 #endif
00023
00024 class CTexture
00025 {
00026 protected:
00027
00028 char m_szName[TEXTURE_NAME_SIZE];
00029 unsigned char *m_Data;
00030 int m_iWidth,m_iHeight;
00031 bool m_bAlpha;
00032 bool m_bDataOwner;
00033
00034 unsigned char *CTexture::computeNormalsFromRGB(double scale,double norme);
00035
00036 public:
00037
00038
00039 class alpha_functor
00040 {
00041 public:
00042 virtual unsigned char computeAlpha(unsigned char r,unsigned char g,unsigned char b) const =0;
00043 };
00044
00045 class alpha_zero : public alpha_functor
00046 {
00047 public:
00048 unsigned char computeAlpha(unsigned char r,unsigned char g,unsigned char b) const
00049 {return (0);}
00050 };
00051
00052 class alpha_one : public alpha_functor
00053 {
00054 public:
00055 unsigned char computeAlpha(unsigned char r,unsigned char g,unsigned char b) const
00056 {return (255);}
00057 };
00058
00059 class alpha_const : public alpha_functor
00060 {
00061 unsigned char m_ucAlpha;
00062 public:
00063 alpha_const(double c) {m_ucAlpha=(unsigned char)(c*255);}
00064 unsigned char computeAlpha(unsigned char r,unsigned char g,unsigned char b) const
00065 {return (m_ucAlpha);}
00066 };
00067
00068 class alpha_color : public alpha_functor
00069 {
00070 private:
00071 int m_iTolerence;
00072 int m_iR;
00073 int m_iG;
00074 int m_iB;
00075 public:
00076 alpha_color(unsigned char r,unsigned char g,unsigned char b,int t=0)
00077 {
00078 m_iR=(int)r;
00079 m_iG=(int)g;
00080 m_iB=(int)b;
00081 m_iTolerence=t;
00082 }
00083 unsigned char computeAlpha(unsigned char r,unsigned char g,unsigned char b) const
00084 {
00085 if ( ABS((int)r-m_iR) <= m_iTolerence
00086 && ABS((int)g-m_iG) <= m_iTolerence
00087 && ABS((int)b-m_iB) <= m_iTolerence)
00088 return (0);
00089 else
00090 return (255);
00091 }
00092 };
00093
00094
00095 class mipmap_functor
00096 {
00097 public:
00098 virtual void computeAverage(const unsigned char r[4],
00099 const unsigned char g[4],
00100 const unsigned char b[4],
00101 const unsigned char a[4],
00102 unsigned char& _r,unsigned char& _g,unsigned char& _b,unsigned char& _a) const =0;
00103 };
00104
00105 class mipmap_std : public mipmap_functor
00106 {
00107 public:
00108 virtual void computeAverage(const unsigned char r[4],
00109 const unsigned char g[4],
00110 const unsigned char b[4],
00111 const unsigned char a[4],
00112 unsigned char& _r,unsigned char& _g,unsigned char& _b,unsigned char& _a) const
00113 {
00114 _r=(unsigned char)(((int)r[0]+(int)r[1]+(int)r[2]+(int)r[3])/4);
00115 _g=(unsigned char)(((int)g[0]+(int)g[1]+(int)g[2]+(int)g[3])/4);
00116 _b=(unsigned char)(((int)b[0]+(int)b[1]+(int)b[2]+(int)b[3])/4);
00117 _a=(unsigned char)(((int)a[0]+(int)a[1]+(int)a[2]+(int)a[3])/4);
00118 }
00119 };
00120
00121 class mipmap_alpha : public mipmap_functor
00122 {
00123 public:
00124 virtual void computeAverage(const unsigned char r[4],
00125 const unsigned char g[4],
00126 const unsigned char b[4],
00127 const unsigned char a[4],
00128 unsigned char& _r,unsigned char& _g,unsigned char& _b,unsigned char& _a) const
00129 {
00130 int n=0;
00131 int ir=0,ig=0,ib=0,ia=0;
00132 for (int i=0;i<4;i++)
00133 {
00134 if (a[i] > 0)
00135 {
00136 ir+=r[i];
00137 ig+=g[i];
00138 ib+=b[i];
00139 ia+=a[i];
00140 n++;
00141 }
00142 }
00143 if (n > 0)
00144 {
00145 _r=(unsigned char)(ir/n);
00146 _g=(unsigned char)(ig/n);
00147 _b=(unsigned char)(ib/n);
00148 _a=(unsigned char)(ia/n);
00149 }
00150 else
00151 _r=_g=_b=_a=0;
00152 }
00153 };
00154
00155
00156 class copy_functor
00157 {
00158 public:
00159 virtual void copyPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00160 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const = 0;
00161 };
00162
00163 class copy_std : public copy_functor
00164 {
00165 public:
00166 virtual void copyPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00167 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const
00168 {
00169 dr=sr;dg=sg;db=sb;da=sa;
00170 }
00171 };
00172
00173
00174 class convert_functor
00175 {
00176 public:
00177 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00178 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const = 0;
00179 };
00180
00181 class convert_std : public convert_functor
00182 {
00183 public:
00184 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00185 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const
00186 {
00187 dr=sr;dg=sg;db=sb;da=sa;
00188 }
00189 };
00190
00191 class convert_compose : public convert_functor
00192 {
00193 protected:
00194 const convert_functor& cmp0;
00195 const convert_functor& cmp1;
00196 public:
00197 convert_compose(const convert_functor& c0,const convert_functor& c1) : cmp0(c0), cmp1(c1) {}
00198 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00199 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const
00200 {
00201 unsigned char tr,tg,tb,ta;
00202 cmp0.convertPixel(sr,sg,sb,sa,tr,tg,tb,ta);
00203 cmp1.convertPixel(tr,tg,tb,ta,dr,dg,db,da);
00204 }
00205 };
00206
00207 class convert_zero_R : public convert_functor
00208 {
00209 public:
00210 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00211 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const
00212 {
00213 dr=0;dg=sg;db=sb;da=sa;
00214 }
00215 };
00216
00217 class convert_zero_G : public convert_functor
00218 {
00219 public:
00220 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00221 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const
00222 {
00223 dr=sr;dg=0;db=sb;da=sa;
00224 }
00225 };
00226
00227 class convert_zero_B : public convert_functor
00228 {
00229 public:
00230 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00231 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const
00232 {
00233 dr=sr;dg=sg;db=0;da=sa;
00234 }
00235 };
00236
00237 class convert_alpha_premult : public convert_functor
00238 {
00239 public:
00240 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00241 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const
00242 {
00243 double r=((double)sr)*((double)sa)/255.0
00244 double g=((double)sg)*((double)sa)/255.0
00245 double b=((double)sb)*((double)sa)/255.0
00246 dr=(unsigned char)r;
00247 dg=(unsigned char)g;
00248 db=(unsigned char)b;
00249 da=sa;
00250 }
00251 };
00252
00253 class convert_order : public convert_functor
00254 {
00255 protected:
00256 int order[4];
00257 public:
00258 convert_order(int v0,int v1,int v2) {order[0]=v0;order[1]=v1;order[2]=v2;order[3]=3;}
00259 convert_order(int v0,int v1,int v2,int v3) {order[0]=v0;order[1]=v1;order[2]=v2;order[3]=v3;}
00260 virtual void convertPixel(unsigned char s0,unsigned char s1,unsigned char s2,unsigned char s3,
00261 unsigned char& d0,unsigned char& d1,unsigned char& d2,unsigned char& d3) const
00262 {
00263 int values[4];
00264 values[0]=s0;values[1]=s1;values[2]=s2;values[3]=s3;
00265 d0=values[order[0]];d1=values[order[1]];d2=values[order[2]];d3=values[order[3]];
00266 }
00267 };
00268
00269 class convert_one_channel : public convert_functor
00270 {
00271 protected:
00272 float fr,fg,fb,fa;
00273 public:
00274 convert_one_channel(float ffr,float ffg,float ffb,float ffa) : fr(ffr), fg(ffg), fb(ffb), fa(ffa) {}
00275 virtual void convertPixel(unsigned char sr,unsigned char sg,unsigned char sb,unsigned char sa,
00276 unsigned char& dr,unsigned char& dg,unsigned char& db,unsigned char& da) const;
00277 };
00278
00279 class convert_RGB_HSV : public convert_functor
00280 {
00281 public:
00282 virtual void convertPixel(unsigned char,unsigned char,unsigned char,unsigned char,
00283 unsigned char&,unsigned char&,unsigned char&,unsigned char&) const;
00284 };
00285
00286 class convert_HSV_RGB : public convert_functor
00287 {
00288 public:
00289 virtual void convertPixel(unsigned char,unsigned char,unsigned char,unsigned char,
00290 unsigned char&,unsigned char&,unsigned char&,unsigned char&) const;
00291 };
00292
00293 class convert_RGB_YUV : public convert_functor
00294 {
00295 public:
00296 virtual void convertPixel(unsigned char,unsigned char,unsigned char,unsigned char,
00297 unsigned char&,unsigned char&,unsigned char&,unsigned char&) const;
00298 };
00299
00300 class convert_YUV_RGB : public convert_functor
00301 {
00302 public:
00303 virtual void convertPixel(unsigned char,unsigned char,unsigned char,unsigned char,
00304 unsigned char&,unsigned char&,unsigned char&,unsigned char&) const;
00305 };
00306
00307 public:
00308
00309 CTexture();
00310 CTexture(const char *name,int w,int h,bool alpha,unsigned char *data);
00311 CTexture(int w,int h,bool alpha=false);
00312 CTexture(const CTexture&);
00313 CTexture(const CTexture *);
00314 virtual ~CTexture();
00315
00316 virtual void load(){};
00317 virtual void unload();
00318 void save(const char *n);
00319
00321 int getWidth() const {return (m_iWidth);}
00323 int getHeight() const {return (m_iHeight);}
00325 bool isAlpha() const {return (m_bAlpha);}
00327 unsigned char *getData() const {return (m_Data);}
00329 const char *getName() const {return (m_szName);}
00334 void computeNormals(double scale=1.0,double norme=1.0);
00345 void convertToNormal(double scale=1.0,double norme=1.0);
00349 virtual void convert2Alpha(unsigned char r,
00350 unsigned char g,
00351 unsigned char b,
00352 unsigned char tolerence);
00356 virtual void loadAlphaMap(CTexture *);
00360 void loadAlphaMap(const char *);
00364 void computeAlpha(const alpha_functor& af);
00370 CTexture *computeNextMIPMapLevel(const mipmap_functor& mip) const;
00374 CTexture *convolve(CTexture *kernel) const;
00379 void copy(int x,int y,const CTexture *tex,const copy_functor& cpy=copy_std());
00380
00384 void convert(const convert_functor& cnv=convert_std());
00385
00389 CTexture *difference(const CTexture *);
00390
00394 CTexture *extract(int x,int y,int w,int h);
00395
00399 static CTexture *loadTexture(const char *);
00400
00404 static void saveTexture(const CTexture *,const char *);
00405
00409 int memsize() const;
00410
00414 void flipY();
00415
00419 void flipX();
00420
00424 void setDataOwner(bool b) {m_bDataOwner=b;}
00425
00429 unsigned char get(int i,int j,int c) const
00430 {
00431 if (!(i>=0 && i<m_iWidth && j>=0 && j<m_iHeight && c < (isAlpha()?4:3)))
00432 throw CLibTextureException("Access violation (%s)",getName());
00433 return (m_Data[(i+j*m_iWidth)*(isAlpha()?4:3)+c]);
00434 }
00435
00439 unsigned char& set(int i,int j,int c)
00440 {
00441 if (!(i>=0 && i<m_iWidth && j>=0 && j<m_iHeight && c < (isAlpha()?4:3)))
00442 throw CLibTextureException("Access violation (%s)",getName());
00443 return (m_Data[(i+j*m_iWidth)*(isAlpha()?4:3)+c]);
00444 }
00445
00449 unsigned char getmod(int i,int j,int c) const;
00450
00454 unsigned char getclp(int i,int j,int c) const;
00455
00459 unsigned char getlin(double i,double j,int c) const;
00460
00464 unsigned char tex2D(double i,double j,int c) const {return (getlin(i*m_iWidth,j*m_iHeight,c));}
00465
00466
00467
00468
00469
00470 private:
00471
00472
00473 class vertex
00474 {
00475 public:
00476 double x,y,z;
00477
00478 vertex ()
00479 {
00480 x=0;
00481 y=0;
00482 z=0;
00483 }
00484
00485 vertex(double _x,double _y,double _z)
00486 {
00487 x=_x;
00488 y=_y;
00489 z=_z;
00490 }
00491
00492 void normalize()
00493 {
00494 double l=x*x+y*y+z*z;
00495 if (l < TEXTURE_EPSILON*TEXTURE_EPSILON)
00496 CLibTextureException("trying to normalize null vertex !");
00497 l=sqrt(l);
00498 x/=l;
00499 y/=l;
00500 z/=l;
00501 }
00502
00503 vertex cross(const vertex& v)
00504 {
00505 return (vertex(y*v.z - z*v.y,z*v.x - x*v.z,x*v.y - y*v.x));
00506 }
00507 };
00508
00509 };
00510
00511 #endif
00512