BambooIsland: C:/Users/easterbunny/Desktop/Echtzeitgraphik-LU/trunk/src/TextureManager.cpp Source File

BambooIsland Abgabe 2

- Main Page
- Related Pages
- Classes
- Files

- File List

# C:/Users/easterbunny/Desktop/Echtzeitgraphik-LU/trunk/src/TextureManager.cpp

    00001 #include <IL/il.h>
    00002 #include <iostream>
    00003 #include <sstream>
    00004 #include "common_gl.h"
    00005 #include "TextureManager.h"
    00006 #include "Logger.h"
    00007
    00008 using namespace std;
    00009
    00010 TextureManager::TextureManager() : m_bDevIL_Initialized(false)
    00011 {
    00012     //initialization of free_units is done with first loadTexture call because we need to make sure that the opengl context is already created
    00013 }
    00014
    00015 TextureManager::~TextureManager()
    00016 {
    00017
    00018 }
    00019
    00020 bool TextureManager::loadTexture(std::string sTextureName, std::string sFilename, bool bAlreadyGammaCorrected)
    00021 {
    00022         if (m_bDevIL_Initialized == false)
    00023         {
    00024                 ilInit();
    00025
    00026                 stringstream puffer;    //for debugging output
    00027                 string puffer2;         //for debugging output
    00028
    00029                 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_iMaxTextureUnits);     //ask opengl how many texture units are available
    00030
    00031                 puffer << m_iMaxTextureUnits;                                       //for debugging output, transform integer to string, read integer in stringstream
    00032                 puffer >> puffer2;                                                  //for debugging output, transform integer to string, write stringstream to string
    00033
    00034
    00035                 for (int a=0; a < m_iMaxTextureUnits; a++)                          //push them all in the free_units queue
    00036                         this->free_units.push_back(a);
    00037
    00038                 Logger::instance()->log(Logger::DEBUG, puffer2 + " texture units available");
    00039                 m_bDevIL_Initialized = true;
    00040
    00041                 Logger::instance()->log(Logger::TRACE, "DevIL initialized");
    00042         }
    00043
    00044         Logger::instance()->log(Logger::TRACE, string("try to load texture from \"") + sFilename + "\"");
    00045
    00046         ILuint DevILID;                         // index für DevIL Textur
    00047
    00048         ilGenImages(1,&DevILID);                        // generieren von IL ID für Texturen
    00049         ilBindImage(DevILID);                   // bestimmten Texturindex als aktell setzen
    00050
    00051         if (!ilLoadImage (sFilename.data()))            // laden der Textur
    00052         {
    00053                 ilDeleteImages(1,&DevILID);             // bei Fehlschlag wieder Index freigeben
    00054                 Logger::instance()->log(Logger::ERROR, string("Could not find texture file \"") + sFilename + "\", loading failed.");
    00055                 return false;
    00056         }
    00057         else
    00058         {
    00059                 long h, w, bpp, f;
    00060                 unsigned char *texdata=0;
    00061                 GLuint OpenGLID;
    00062
    00063                 w=ilGetInteger(IL_IMAGE_WIDTH);             // Breite des Bildes holen
    00064                 h=ilGetInteger(IL_IMAGE_HEIGHT);            // Höhe des Bildes holen
    00065                 bpp=ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); // Farbtiefe des Bildes
    00066                 f=ilGetInteger(IL_IMAGE_FORMAT);            // Format des Bildes z.B. RGB RGBA BGR BGRA usw.
    00067                 texdata=ilGetData();                        // Zeiger auf Bilddaten holen
    00068
    00069                 glGetError();                               // clear error state
    00070                 glGenTextures(1,&OpenGLID);                 // ask for opengl texture-id (returns first free id)
    00071                 glBindTexture(GL_TEXTURE_2D, OpenGLID);
    00072
    00073                 if (bAlreadyGammaCorrected)
    00074                         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, w, h, 0, f, GL_UNSIGNED_BYTE, texdata);
    00075                 else
    00076                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, f, GL_UNSIGNED_BYTE, texdata);
    00077
    00078
    00079                 //activate mipmapping
    00080                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    00081                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    00082                 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    00083
    00084                 float maximumAnisotropy;
    00085                 //get maximum ansitropic filtering value
    00086                 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
    00087
    00088                 //activate 4x ansitropic filtering if possible
    00089                 if (maximumAnisotropy >= 4.0)
    00090                         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4);
    00091                 else
    00092                         Logger::instance()->log(Logger::ERROR, "4x Ansitropic filtering not available by graphic hardware");
    00093
    00094                 glGenerateMipmap(GL_TEXTURE_2D);  //Generate mipmaps now!!!
    00095
    00096                 GLenum error = glGetError();
    00097                 if (error != GL_NO_ERROR)
    00098                         Logger::instance()->log(Logger::ERROR, translateGLerror(error));
    00099
    00100                 this->textures[sTextureName] = OpenGLID;
    00101                 this->textures_in_units[sTextureName] = -1;
    00102
    00103                 Logger::instance()->log(Logger::DEBUG, string("texture from \"") + sFilename + "\" loaded to intern name \"" + sTextureName + "\"");
    00104                 return true;
    00105         }
    00106 }
    00107
    00108
    00109 GLuint TextureManager::useTexture(std::string sTextureName)
    00110 {
    00111     int old_size = this->textures.size();
    00112     GLuint texture_id = this->textures[sTextureName];
    00113
    00114     //if the size of the texture-container NOW is creater than old_size,
    00115     //the [] operator created a new entry in the map, which means that an entry with the given name did not exist
    00116     if (old_size != this->textures.size())
    00117         Logger::instance()->log(Logger::FATAL, string("Texture \"") + sTextureName + "\" could not be found (not loaded?)");
    00118     else
    00119     {
    00120         if (this->free_units.size() == 0)
    00121             Logger::instance()->log(Logger::ERROR, string("no free texture unit to use texture \"") + sTextureName + "\"");
    00122         else
    00123         {
    00124             if (this->textures_in_units[sTextureName] != -1)                //if this texture is currently stored in an unit, return the id of the unit
    00125                 return this->textures_in_units[sTextureName];
    00126             else                                                    //else find a free unit and load the texture in it
    00127             {
    00128
    00129 #ifdef PREVENT_REBINDING_TEXTURE
    00130                 //this block loops through all units and looks if on of the units is marked as free, but has the wanted texture loaded
    00131                 //then we can reuse this unit without reloading the texture in it
    00132                 //but we must erase the unit from the free_units-list
    00133                 for (int a=0; a < this->m_iMaxTextureUnits; a++)
    00134                     if (this->unit_has_texture[a] == texture_id)
    00135                     {
    00136                         for (std::list<GLuint>::iterator it1=free_units.begin(); it1!=free_units.end(); ++it1)
    00137                             if (*it1 == a)
    00138                             {
    00139                                 this->free_units.erase(it1);
    00140                                 break;
    00141                             }
    00142                         this->textures_in_units[sTextureName] = a;
    00143                         return a;
    00144                     }
    00145 #endif
    00146
    00147                 GLuint free_unit = this->getFreeUnit();             //remove unit from free_units queue
    00148                 this->textures_in_units[sTextureName] = free_unit;          //make a note that this texture now is stored in a unit
    00149
    00150 #ifdef PREVENT_REBINDING_TEXTURE
    00151                 this->unit_has_texture[free_unit] = texture_id;     //mark that the texture (texture_id) is stored in this unit, to prevent rebinding the texture in another unit
    00152 #endif
    00153
    00154                 glActiveTexture(GL_TEXTURE0 + free_unit);           //activate given texture unit
    00155                 glBindTexture(GL_TEXTURE_2D, texture_id);           //load texture in this unit
    00156
    00157                 //cout << "use unit: " << free_unit << endl;
    00158
    00159                 return free_unit;
    00160             }
    00161         }
    00162     }
    00163 }
    00164
    00165 void TextureManager::unuseTexture(std::string sTextureName)
    00166 {
    00167     GLint used_unit = this->textures_in_units[sTextureName];    //which unit was used by given texture
    00168
    00169     if (used_unit != -1)
    00170     {
    00171         //cout << "release unit: " << used_unit << endl;
    00172         this->releaseUnit(used_unit);
    00173         this->textures_in_units[sTextureName] = -1;                     //mark texture as "not stored in any unit"
    00174     }
    00175     else
    00176         Logger::instance()->log(Logger::ERROR, string("not possible to release texture unit used by texture \"") + sTextureName + "\", texture was not loaded in any unit!");
    00177 }
    00178
    00179 TextureManager *TextureManager::instance()
    00180 {
    00181     static TextureManager singelton_instance;
    00182     return &singelton_instance;
    00183 }
    00184
    00185 GLuint TextureManager::getFreeUnit()
    00186 {
    00187     GLuint free_unit = this->free_units.front();            //get first free unit
    00188     this->free_units.pop_front();                           //remove unit from free_units queue
    00189
    00190 #ifdef PREVENT_REBINDING_TEXTURE
    00191     this->unit_has_texture[free_unit] = -1;                 //mark that the returned unit has no loaded texture in it
    00192 #endif
    00193
    00194     return free_unit;
    00195 }
    00196
    00197 void TextureManager::releaseUnit(GLuint nUnit)
    00198 {
    00199     this->free_units.push_back(nUnit);
    00200 }
    00201
    00202 void TextureManager::registerManualTexture(std::string sTextureName, GLuint nTextureID)
    00203 {
    00204     this->textures[sTextureName] = nTextureID;
    00205     this->textures_in_units[sTextureName] = -1;
    00206 }

All Classes Functions Variables Enumerations Enumerator