Hauptseite | Liste aller Namensbereiche | Klassenhierarchie | Alphabetische Liste | Datenstrukturen | Auflistung der Dateien | Datenstruktur-Elemente | Datei-Elemente

TextureManager.cpp

gehe zur Dokumentation dieser Datei
00001 /*
00002 Autor: $Author: kunkel $ State: $State: Exp $
00003 Datum: $Date: 2005/05/30 12:35:25 $
00004 Version: $Revision: 1.1 $
00005 */
00006 
00012 #include "TextureManager.h"
00013 TextureManager ourTextureManager;
00014 
00015 bool TextureManager::check_if_png(FILE *fp) {
00016     unsigned char buf[PNG_BYTES_TO_CHECK];
00017     //falls nicht genug Bytes von der Datei gelesen werden koennen
00018     if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK)
00019         return false;
00020     //Magic Vergleich mittels Libpng
00021     return(!png_sig_cmp(&buf[0], (png_size_t)0, PNG_BYTES_TO_CHECK));
00022 }
00023 
00024 bool TextureManager::read_png(const char *fname, oneTexture & target) {
00025     int width;
00026     int height;
00027     int bit_depth;
00028     png_structp png_ptr;
00029     png_infop info_ptr;
00030 
00031     //Oeffne die Datei
00032     FILE *fp = fopen(fname, "rb");
00033     if(fp == NULL)
00034         return false;
00035 
00036     if(check_if_png(fp) == 0)
00037         return false;
00038 
00039     //Allgemeine png lese struktur erzeugen
00040     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00041     if (png_ptr == NULL) {
00042         fclose(fp);
00043         return false;
00044     }
00045 
00046     //informationsstruktur erzeugen
00047     info_ptr = png_create_info_struct(png_ptr);
00048     if (info_ptr == NULL) {
00049         fclose(fp);
00050         png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
00051         return false;
00052     }
00053 
00054     if (setjmp(png_jmpbuf(png_ptr))) {
00055         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00056         fclose(fp);
00057         return false;
00058     }
00059 
00060     //Datei mit lese struktur verknuepfen
00061     png_init_io(png_ptr, fp);
00062     png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
00063 
00064     // high-level lesen des bildes
00065     png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);
00066     fclose(fp);
00067 
00068     //Information ueber das Bild extrahieren
00069     width = (int)png_get_image_width(png_ptr, info_ptr);
00070     height = (int)png_get_image_height(png_ptr, info_ptr);
00071     bit_depth = png_get_bit_depth(png_ptr, info_ptr);
00072 
00073     if(bit_depth != 8) {
00074         cerr << "WARNUNG ben�ige RGB Bild "<<endl;
00075         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00076         return false;
00077     }
00078 
00079     //bildzeilen in data speichen:
00080     png_bytep * data = png_get_rows(png_ptr, info_ptr);
00081 
00082     //zielinformation setzen:
00083     target.width = width;
00084     target.height = height;
00085 
00086     //Speicher fuer das Bild reservieren:
00087     target.data = new GLbyte[width*height*3];
00088     //umkonvertieren der Information in fuer Opengl verstaendliche
00089     // Information
00090     //Dies ist abhaengig davon wie fuer Opengl die Anordnung im Speicher
00091     // gewaehlt wird.
00092     for(int y=0; y < height; y++) {
00093         for(int x=0; x < width; x++) {
00094             for(int k=0; k < 3; k++)
00095                 target.data[(x+width*y)*3+k] =(GLbyte) data[y][x*3+k];
00096         }
00097     }
00098 
00099     //Freigabe des Speichers von libpng
00100     png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00101     return true;
00102 }
00103 
00104 void TextureManager::createPNGTexture(const string & filename, oneTexture & targetTexture, bool createMipmaps) {
00105     // oeffne das Bild und lese das Bild ein:
00106     if(! read_png(filename.c_str(), targetTexture)) {
00107         cerr <<  "PNG Textur konnte nicht geladen werden: " << filename << endl;
00108         targetTexture.data = 0;
00109         return;
00110     }
00111 
00112     //Anordnung des Bildes im Speicher fuer Opengl festlegen:
00113     glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
00114     //Die Textur soll so um das Objekt gelegt werden das sie wiederholt wird.
00115     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00116     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00117 
00118     // Erzeuge eine Opengl texture und speichere die Opengl textur nummer.
00119     glGenTextures(1, &targetTexture.number);
00120 
00121     // Binde die Texture an die Opengl Textur nummer und initialisiere die Textur
00122     glBindTexture(GL_TEXTURE_2D, targetTexture.number);
00123 
00124     if(createMipmaps) {
00125         //Falls Mipmaps erzeugt werden sollen muss die Qualitaet dieser
00126         // festgelegt werden.
00127         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
00128                         GL_LINEAR_MIPMAP_NEAREST);
00129         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,
00130                         GL_LINEAR_MIPMAP_LINEAR);
00131 
00132         // Erzeuge Mipmaps, es werden verschiedene Texturversionen erzeugt die
00133         //abhaengig von Entfernung angezeigt werden.
00134         gluBuild2DMipmaps(GL_TEXTURE_2D, 3, targetTexture.width,
00135                           targetTexture.height, GL_RGB, GL_UNSIGNED_BYTE,
00136                           targetTexture.data);
00137     } else {
00138         //Das Bild muss 2^k gro�sein !!!
00139         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
00140                          GL_NEAREST);
00141         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
00142                          GL_NEAREST);
00143     }
00144 
00145     //Textur opengl bekannt machen
00146     glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, targetTexture.width,
00147                   targetTexture.height,0, GL_RGB,
00148                   GL_UNSIGNED_BYTE, targetTexture.data);
00149 }
00150 
00151 unsigned short TextureManager::getTextureNumber(const string & tex) {
00152     int free=MAX_TEXTURES;
00153 
00154     for(int i=0; i < MAX_TEXTURES ; i++) {
00155         //naechste freie position ermitteln:
00156         if(textureArray[i].references == 0 && free == MAX_TEXTURES)
00157             free = i;
00158 
00159         //ist textur bereits im speicher ?
00160         if(textureArray[i].references != 0 && tex == textureArray[i].name) {
00161             //textur im Speicher gefunden:
00162             textureArray[i].references++;
00163             return i;
00164         }
00165     }
00166     //Die Textur konnte also nicht im Speicher gefunden werden und muss
00167     // geladen werden:
00168 
00169     if(free == MAX_TEXTURES) {
00170         cerr <<
00171         "WARNING MAX_TEXTURES limit reached !! TEXTURE COULD NOT BE LOADED"
00172         << endl;
00173         return 0;
00174     }
00175 
00176     //Lade die Texture an die freie Stelle im Array:
00177     createPNGTexture(tex,textureArray[free],true);
00178     textureArray[free].references=1;
00179     textureArray[free].name = tex;
00180     return free;
00181 }
00182 
00183 void TextureManager::freeReference(unsigned short texture) {
00184     textureArray[texture].references--;
00185     if(textureArray[texture].references == 0 &&
00186             textureArray[texture].data != 0 ) {
00187         //Freigabe der Textur:
00188         glDeleteTextures(1,& textureArray[texture].number);
00189         delete(textureArray[texture].data);
00190     }
00191 }
00192 
00193 void TextureManager::freeTextures() {
00194     //texturen loeschen
00195     for (int i=0; i<MAX_TEXTURES; i++) {
00196         if(textureArray[i].references > 0) {
00197             textureArray[i].references=1;
00198             freeReference(i);
00199         }
00200     }
00201 }
00202 
00203 GLuint TextureManager::getOpenglTexture(unsigned short num) {
00204     return textureArray[num].number;
00205 }
00206 
00207 TextureManager::~TextureManager() {
00208     //Freigabe der Texturen:
00209     freeTextures();
00210 }
00211 

Erzeugt am Mon May 30 14:31:16 2005 für Sunsystembuildingandsimulation von doxygen 1.3.6