Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #ifdef _WIN32
00019 #define WIN32_LEAN_AND_MEAN
00020 #include <windows.h>
00021 #endif // _WIN32
00022 
00023 #include <GL/glew.h>
00024 #include <GL/gl.h>
00025 #include <GL/glu.h>
00026 #include <iostream>
00027 #include <stdexcept>
00028 
00029 #include "Texture.h"
00030 #include "Image.h"
00031 
00032 using std::cout;
00033 using std::cerr;
00034 using std::endl;
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 Texture::Texture ()
00050   : _handle (0), _flags (kDefault),
00051     _standardCoordSystem (true), _fail (true)
00052 {
00053   
00054   GLenum err = glGetError ();
00055   if (GL_NO_ERROR != err)
00056     cerr << "OpenGL Error: " << gluErrorString (err)
00057          << " [Texture::Texture]" << endl;
00058 }
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 Texture::~Texture ()
00068 {
00069   
00070   if (glIsTexture(_handle))
00071     glDeleteTextures (1, &_handle);
00072 }
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 void
00082 Texture::bind () const
00083 {
00084   glBindTexture (target (), _handle);
00085 }
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 GLint
00096 Texture::getCompressionFormat (GLint internalFormat)
00097 {
00098   if (!GLEW_EXT_texture_compression_s3tc ||
00099       !GLEW_ARB_texture_compression)
00100     
00101     return internalFormat;
00102 
00103   switch (internalFormat)
00104     {
00105     case 1:
00106       return GL_COMPRESSED_LUMINANCE;
00107 
00108     case 2:
00109       return GL_COMPRESSED_LUMINANCE_ALPHA;
00110 
00111     case 3:
00112       return GL_COMPRESSED_RGB;
00113 
00114     case 4:
00115       return GL_COMPRESSED_RGBA;
00116 
00117     default:
00118       
00119       throw std::invalid_argument ("Texture::getCompressionFormat: "
00120                                    "Bad internal format");
00121     }
00122 }
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 GLint
00133 Texture::getInternalFormat (GLint components)
00134 {
00135   if (_flags & kCompress)
00136     return getCompressionFormat (components);
00137   else
00138     return components;
00139 }
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 Texture2D::Texture2D ()
00157   : Texture ()
00158 {
00159 }
00160 
00161 
00162 Texture2D::Texture2D (const string &filename, TextureFlags flags)
00163 {
00164   try
00165     {
00166       
00167       ImageBuffer ibuff (filename);
00168       auto_ptr<Image> img (ImageFactory::createImage (ibuff));
00169 
00170       
00171       create (img.get (), flags);
00172     }
00173   catch (std::exception &err)
00174     {
00175       cerr << "Error: Couldn't create texture 2D from "
00176            << filename << endl;
00177       cerr << "Reason: " << err.what () << endl;
00178     }
00179 }
00180 
00181 
00182 Texture2D::Texture2D (const Image *img, TextureFlags flags)
00183 {
00184   try
00185     {
00186       
00187       create (img, flags);
00188     }
00189   catch (std::exception &err)
00190     {
00191       cerr << "Error: Couldn't create texture 2D from "
00192            << img->name () << endl;
00193       cerr << "Reason: " << err.what () << endl;
00194     }
00195 }
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 void
00205 Texture2D::create (const Image *img, TextureFlags flags)
00206 {
00207   if (!img->pixels ())
00208     throw std::runtime_error ("Invalid image data");
00209 
00210   
00211   _name = img->name ();
00212   _flags = flags;
00213   _standardCoordSystem = img->stdCoordSystem ();
00214 
00215   
00216   glGenTextures (1, &_handle);
00217   glBindTexture (target (), _handle);
00218 
00219   
00220   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00221   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00222   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00223   glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00224 
00225   
00226   if (GLEW_SGIS_generate_mipmap && img->isPowerOfTwo ())
00227     {
00228       
00229       glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
00230       glHint (GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
00231 
00232       glTexImage2D (GL_TEXTURE_2D, 0, getInternalFormat (img->components ()),
00233                     img->width (), img->height (), 0, img->format (),
00234                     GL_UNSIGNED_BYTE, img->pixels ());
00235     }
00236   else
00237     {
00238       
00239       
00240       gluBuild2DMipmaps (GL_TEXTURE_2D, getInternalFormat (img->components ()),
00241                          img->width (), img->height (), img->format (),
00242                          GL_UNSIGNED_BYTE, img->pixels ());
00243     }
00244 
00245   
00246   GLenum err = glGetError ();
00247   if (GL_NO_ERROR == err)
00248      _fail = false;
00249   else
00250       cerr << "OpenGL Error: " << gluErrorString (err)
00251            << " [Texture2D::create ()]" << endl;
00252 }