00001
00002
00003
00004
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
00018 if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK)
00019 return false;
00020
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
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
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
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
00061 png_init_io(png_ptr, fp);
00062 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
00063
00064
00065 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);
00066 fclose(fp);
00067
00068
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
00080 png_bytep * data = png_get_rows(png_ptr, info_ptr);
00081
00082
00083 target.width = width;
00084 target.height = height;
00085
00086
00087 target.data = new GLbyte[width*height*3];
00088
00089
00090
00091
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
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
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
00113 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
00114
00115 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00116 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00117
00118
00119 glGenTextures(1, &targetTexture.number);
00120
00121
00122 glBindTexture(GL_TEXTURE_2D, targetTexture.number);
00123
00124 if(createMipmaps) {
00125
00126
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
00133
00134 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, targetTexture.width,
00135 targetTexture.height, GL_RGB, GL_UNSIGNED_BYTE,
00136 targetTexture.data);
00137 } else {
00138
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
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
00156 if(textureArray[i].references == 0 && free == MAX_TEXTURES)
00157 free = i;
00158
00159
00160 if(textureArray[i].references != 0 && tex == textureArray[i].name) {
00161
00162 textureArray[i].references++;
00163 return i;
00164 }
00165 }
00166
00167
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
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
00188 glDeleteTextures(1,& textureArray[texture].number);
00189 delete(textureArray[texture].data);
00190 }
00191 }
00192
00193 void TextureManager::freeTextures() {
00194
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
00209 freeTextures();
00210 }
00211