Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

glt/texture.cpp

Go to the documentation of this file.
00001 #include "texture.h"
00002 
00015 #include <glt/gl.h>
00016 #include <glt/glu.h>
00017 #include <glt/error.h>
00018 
00019 #include <misc/compress.h>
00020 #include <misc/image.h>
00021 
00022 #if !defined(NDEBUG)
00023 #include <iostream>
00024 #endif
00025 
00026 #include <cassert>
00027 #include <cstdio>
00028 #include <string>
00029 using namespace std;
00030 
00032 
00033 GltTexture::GltTexture(const GLenum target)
00034 :
00035     _target(target),
00036     _components(0),
00037     _width(0),
00038     _height(0),
00039     _border(0),
00040     _format(0),
00041     _type(0),
00042     _alignment(0),
00043     _wrapS(GL_REPEAT),
00044     _wrapT(GL_REPEAT),
00045     _filterMin(GL_LINEAR),
00046     _filterMag(GL_LINEAR),
00047     _gamma(1.0),
00048     _hue(0.0),
00049     _saturation(0.0),
00050     _value(0.0),
00051 
00052     _id(0)
00053 {
00054 }
00055 
00056 GltTexture::GltTexture(const GltTexture &)
00057 {
00058     // Can't copy textures
00059     assert(0);
00060 }
00061 
00062 GltTexture::~GltTexture()
00063 {
00064     #if !defined(NDEBUG)
00065     if (_id)
00066         cerr << "WARNING: Potential OpenGL texture leak (" << this << ")" << endl;
00067     #endif
00068 
00069     clear();
00070 }
00071 
00072 GltTexture &
00073 GltTexture::operator=(const GltTexture &)
00074 {
00075     // Can't copy textures
00076     assert(0);
00077     return *this;
00078 }
00079 
00080 void 
00081 GltTexture::setWrap(const GLenum s,const GLenum t)
00082 {
00083     _wrapS = s;
00084     _wrapT = t;
00085 
00086     if (_id!=0)
00087     {
00088         glPushAttrib(GL_TEXTURE_BIT);
00089             glBindTexture(_target,_id);
00090             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,_wrapS);
00091             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,_wrapT);
00092         glPopAttrib();
00093     }
00094 }
00095 
00096 void 
00097 GltTexture::setFilter(const GLenum min,const GLenum mag)
00098 {
00099     _filterMin = min;
00100     _filterMag = mag;
00101 
00102     if (_id!=0)
00103     {
00104         glPushAttrib(GL_TEXTURE_BIT);
00105             glBindTexture(_target,_id);
00106             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,_filterMin);
00107             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,_filterMag); 
00108         glPopAttrib();
00109     }
00110 }
00111 
00112 void 
00113 GltTexture::setGamma(const real gamma)
00114 {
00115     _gamma = gamma;
00116 }
00117 
00118 void 
00119 GltTexture::setHSVAdjust(const real hue,const real saturation,const real value)
00120 {
00121     _hue = hue;
00122     _saturation = saturation;
00123     _value = value;
00124 }
00125 
00126 bool
00127 GltTexture::init(const void *data,const bool mipmap)
00128 {
00129     GLERROR
00130 
00131     clear();
00132 
00133     if (!data)
00134         return true;
00135 
00136     // Extract the header
00137 
00138     int type,width,height,alignment,compressed;
00139     void *pixels = getHeader((const byte *) data,type,width,height,alignment,compressed);
00140     bool deletePixels = false;
00141 
00142     // If the header is valid, initialise texture
00143 
00144     assert(pixels);
00145 
00146     if (pixels)
00147     {
00148         switch (type)
00149         {
00150         case TEXTURE_TYPE_RGB:          _components = 3; _format = GL_RGB;             break;   
00151         case TEXTURE_TYPE_RGBA:         _components = 4; _format = GL_RGBA;            break;   
00152         case TEXTURE_TYPE_GREY:         _components = 1; _format = GL_LUMINANCE;       break;   
00153         case TEXTURE_TYPE_GREYA:        _components = 2; _format = GL_LUMINANCE_ALPHA; break;
00154         case TEXTURE_TYPE_ALPHA:        _components = 1; _format = GL_ALPHA;           break;
00155         case TEXTURE_TYPE_BITMAP:       _components = 1; _format = TEXTURE_TYPE_BITMAP;break;
00156         case TEXTURE_TYPE_INDEXED_RGB:  _components = 3; _format = GL_RGB;             break;
00157         case TEXTURE_TYPE_INDEXED_RGBA: _components = 4; _format = GL_RGBA;            break;
00158         default: assert(0); break;
00159         }
00160 
00161         if (compressed)
00162         {
00163             string tmp;
00164             bool ok = decompress(tmp,pixels);
00165 
00166             assert(ok);
00167             assert(tmp.size());
00168 
00169             if (ok && tmp.size())
00170             {
00171                 const int n = width*height*_components;
00172                 pixels = new unsigned char[n];
00173                 deletePixels = true;
00174 
00175                 if (type==TEXTURE_TYPE_INDEXED_RGB)
00176                 {
00177                     string rgb;
00178                     indexed2rgb(rgb,tmp);
00179 
00180                     if (_gamma!=1.0)
00181                         adjustGamma(rgb,_gamma);
00182                     
00183                     if (_hue!=0.0 || _saturation!=0.0 || _value!=0.0)
00184                         adjustHSV(rgb,width,height,_hue,_saturation,_value);
00185 
00186                     memcpy(pixels,rgb.c_str(),n);
00187 
00188                     /* TODO - Deal with indexed data */
00189                 }
00190                 else
00191                 {
00192                     if (_gamma!=1.0)
00193                         adjustGamma(tmp,_gamma);
00194                     
00195                     if (_hue!=0.0 || _saturation!=0.0 || _value!=0.0)
00196                         adjustHSV(tmp,width,height,_hue,_saturation,_value);
00197 
00198                     memcpy(pixels,tmp.c_str(),n);
00199                 }
00200             }
00201         }
00202 
00203         /* TODO - Deal with uncompressed indexed data */
00204 
00205         _width = width;
00206         _height = height;
00207 
00208         _type = GL_UNSIGNED_BYTE;
00209     }
00210 
00211     assert(_components!=0);
00212 
00213     if (pixels && _components!=0)
00214     {   
00215         GLERROR
00216 
00217         if (_target==GL_TEXTURE_2D)
00218         {
00219             glGenTextures(1,&_id);
00220             glBindTexture(GL_TEXTURE_2D,_id);
00221             glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
00222             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,_filterMin);
00223             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,_filterMag); 
00224             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrapS);
00225             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrapT);
00226         }
00227 
00228         if (mipmap)
00229             gluBuild2DMipmaps(_target,_components,_width,_height,_format,_type,pixels);
00230         else
00231             glTexImage2D(_target,0,_components,_width,_height,_border,_format,_type,pixels);
00232 
00233         if (deletePixels)
00234             delete [] (unsigned char *) pixels;
00235 
00236         GLERROR
00237 
00238         return true;
00239     }
00240 
00241     GLERROR
00242 
00243     return false;
00244 }
00245 
00246 bool 
00247 GltTexture::init(const GLsizei width,const GLsizei height,const std::string &image,const bool mipmap)
00248 {
00249     clear();
00250 
00251     GLenum mode = 0;
00252     int    channels = 0;
00253 
00254     if (width*height  == (GLsizei)image.size()) { mode = GL_LUMINANCE;       channels = 1; }
00255     if (width*height*2== (GLsizei)image.size()) { mode = GL_LUMINANCE_ALPHA; channels = 2; }
00256     if (width*height*3== (GLsizei)image.size()) { mode = GL_RGB;             channels = 3; }
00257     if (width*height*4== (GLsizei)image.size()) { mode = GL_RGBA;            channels = 3; }
00258 
00259     if (!mode || !channels)
00260         return false;
00261 
00262     if (_target==GL_TEXTURE_2D)
00263     {
00264         glGenTextures(1,&_id);
00265         glBindTexture(GL_TEXTURE_2D,_id);
00266         glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
00267         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,_filterMin);
00268         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,_filterMag); 
00269         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrapS);
00270         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrapT);
00271     }
00272 
00273     if (mipmap)
00274         gluBuild2DMipmaps(_target,channels,width,height,mode,GL_UNSIGNED_BYTE,image.data());
00275     else
00276         glTexImage2D(_target,0,channels,width,height,0,mode,GL_UNSIGNED_BYTE,image.data());
00277 
00278     return true;
00279 }
00280 
00281 bool 
00282 GltTexture::init(const GLsizei width,const GLsizei height,const byte *image,const GLsizei channels,const bool mipmap)
00283 {
00284     clear();
00285 
00286     GLenum mode = 0;
00287 
00288     switch (channels)
00289     {
00290         case 1: mode = GL_LUMINANCE;       break;
00291         case 2: mode = GL_LUMINANCE_ALPHA; break;
00292         case 3: mode = GL_RGB;             break;
00293         case 4: mode = GL_RGBA;            break;
00294         default: return false;
00295     }
00296 
00297     if (_target==GL_TEXTURE_2D)
00298     {
00299         glGenTextures(1,&_id);
00300         glBindTexture(GL_TEXTURE_2D,_id);
00301         glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
00302         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,_filterMin);
00303         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,_filterMag); 
00304         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrapS);
00305         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrapT);
00306     }
00307 
00308     if (mipmap)
00309         gluBuild2DMipmaps(_target,channels,width,height,mode,GL_UNSIGNED_BYTE,image);
00310     else
00311         glTexImage2D(_target,0,channels,width,height,0,mode,GL_UNSIGNED_BYTE,image);
00312 
00313     return true;
00314 }
00315 
00316 void 
00317 GltTexture::clear()
00318 {
00319     if (_id)
00320         glDeleteTextures(1,&_id);
00321 
00322     _id = 0;
00323     _components = 0;
00324     _width = 0;
00325     _height = 0;
00326     _border = 0;
00327     _format = 0;
00328     _type = 0;
00329     _alignment = 0;
00330 }
00331 
00332 void 
00333 GltTexture::set() const
00334 {
00335     if (_id!=0 && _target==GL_TEXTURE_2D)
00336         glBindTexture(_target,_id);
00337 }
00338 
00339 const GLsizei &GltTexture::width()  const { return _width; }
00340 const GLsizei &GltTexture::height() const { return _height; }
00341 const GLuint   GltTexture::id()     const { return _id; }
00342 
00344 
00345 // Create variable-length header for texture data
00346 
00347 bool GltTexture::makeHeader
00348 (
00349     string &header,
00350     const int            type,
00351     const int            width,
00352     const int            height,
00353     const int            alignment,
00354     const int            compressed
00355 )
00356 {
00357     // 11 characters is big enough for integer 2^32 + \0
00358 
00359     char buffer[5+11+11+11+11+11];
00360     sprintf(buffer,"GLTT %u %u %u %u %u",type,width,height,alignment,compressed);
00361     header = buffer;
00362     header += '\0';
00363 
00364     return true;
00365 }
00366 
00367 // Decode variable-length header for texture data
00368 
00369 void *GltTexture::getHeader
00370 (
00371     const void * const data,
00372     int            &type,
00373     int            &width,
00374     int            &height,
00375     int            &alignment,
00376     int            &compressed
00377 )
00378 {
00379     const char * const h = (const char * const) data;
00380     
00381     if (h[0]=='G' && h[1]=='L' && h[2]=='T' && h[3]=='T' && h[4]==' ')
00382     {
00383         if (sscanf(h+5,"%i %i %i %i %i",&type,&width,&height,&alignment,&compressed)==5)
00384             return (void *) (h + strlen(h) + 1);
00385     }
00386 
00387     return NULL;
00388 }
00389 

Generated on Tue Nov 5 11:11:03 2002 for GLT by doxygen1.2.18