| 1 | /*  | 
|---|
| 2 |    orxonox - the future of 3D-vertical-scrollers | 
|---|
| 3 |  | 
|---|
| 4 |    Copyright (C) 2004 orx | 
|---|
| 5 |  | 
|---|
| 6 |    This program is free software; you can redistribute it and/or modify | 
|---|
| 7 |    it under the terms of the GNU General Public License as published by | 
|---|
| 8 |    the Free Software Foundation; either version 2, or (at your option) | 
|---|
| 9 |    any later version. | 
|---|
| 10 |  | 
|---|
| 11 |    ### File Specific: | 
|---|
| 12 |    main-programmer: Benjamin Grauer | 
|---|
| 13 |    co-programmer: ... | 
|---|
| 14 |  | 
|---|
| 15 |    TGA-code: borrowed from nehe-Tutorials | 
|---|
| 16 |  | 
|---|
| 17 |    ToDo:  | 
|---|
| 18 |    - free SDL-surface when deleting Material. | 
|---|
| 19 |    - delete imgNameWithPath after use creation. | 
|---|
| 20 | */ | 
|---|
| 21 |  | 
|---|
| 22 | #include "material.h" | 
|---|
| 23 |  | 
|---|
| 24 | // headers only for PathList | 
|---|
| 25 | #include <unistd.h> | 
|---|
| 26 | #include <sys/types.h> | 
|---|
| 27 | #include <sys/stat.h> | 
|---|
| 28 | #include <stdlib.h> | 
|---|
| 29 | #include <fstream> | 
|---|
| 30 |  | 
|---|
| 31 | using namespace std; | 
|---|
| 32 |  | 
|---|
| 33 |  | 
|---|
| 34 | PathList::PathList() | 
|---|
| 35 | { | 
|---|
| 36 |   pathName = NULL; | 
|---|
| 37 |   next = NULL; | 
|---|
| 38 | } | 
|---|
| 39 | PathList::PathList(char* pName) | 
|---|
| 40 | { | 
|---|
| 41 |   pathName = new char [strlen(pName)+1]; | 
|---|
| 42 |   strcpy (pathName, pName); | 
|---|
| 43 |   next = NULL; | 
|---|
| 44 | } | 
|---|
| 45 |  | 
|---|
| 46 | PathList::~PathList() | 
|---|
| 47 | { | 
|---|
| 48 |   if (pathName) | 
|---|
| 49 |     delete []pathName; | 
|---|
| 50 |   if (next) | 
|---|
| 51 |     delete next; | 
|---|
| 52 | } | 
|---|
| 53 |  | 
|---|
| 54 | void PathList::addPath (char* pName) | 
|---|
| 55 | { | 
|---|
| 56 |   if (pName[0] == '\0') | 
|---|
| 57 |     { | 
|---|
| 58 |       if (verbose >=3) | 
|---|
| 59 |         printf("not Adding empty Path to the List.\n"); | 
|---|
| 60 |       return; | 
|---|
| 61 |     } | 
|---|
| 62 |   char* tmpPName = new char[strlen(pName)]; | 
|---|
| 63 |   strncpy(tmpPName, pName, strlen(pName)-1); | 
|---|
| 64 |   tmpPName[strlen(pName)-1] = '\0'; | 
|---|
| 65 |   printf ("%s\n",tmpPName); | 
|---|
| 66 |   if (access (tmpPName, F_OK) == 0) | 
|---|
| 67 |     { | 
|---|
| 68 |       struct stat status; | 
|---|
| 69 |       stat(tmpPName, &status); | 
|---|
| 70 |       if (status.st_mode & S_IFDIR) | 
|---|
| 71 |         { | 
|---|
| 72 |           if (verbose >=2) | 
|---|
| 73 |             printf ("Adding Path %s to the PathList.\n", pName); | 
|---|
| 74 |           PathList* tmpPathList = this; | 
|---|
| 75 |           while (tmpPathList->next) | 
|---|
| 76 |             tmpPathList = tmpPathList->next; | 
|---|
| 77 |           tmpPathList->next = new PathList(pName); | 
|---|
| 78 |         } | 
|---|
| 79 |       else | 
|---|
| 80 |         if (verbose >=1) | 
|---|
| 81 |           printf ("You tried to add non-folder %s to a PathList.\n", tmpPName); | 
|---|
| 82 |     } | 
|---|
| 83 |   else | 
|---|
| 84 |     if (verbose >=1) | 
|---|
| 85 |       printf ("You tried to add non-existing folder %s to a PathList.\n", tmpPName); | 
|---|
| 86 |   delete []tmpPName; | 
|---|
| 87 | } | 
|---|
| 88 |  | 
|---|
| 89 | /** | 
|---|
| 90 |    \brief creates a default Material with no Name | 
|---|
| 91 |    normally you call this to create a material List (for an obj-file) and then append with addMaterial() | 
|---|
| 92 | */ | 
|---|
| 93 | Material::Material() | 
|---|
| 94 | { | 
|---|
| 95 |   init(); | 
|---|
| 96 |    | 
|---|
| 97 |   setName (""); | 
|---|
| 98 | } | 
|---|
| 99 |  | 
|---|
| 100 | /** | 
|---|
| 101 |    \brief creates a Material. | 
|---|
| 102 |    \param mtlName Name of the Material to be added to the Material List | 
|---|
| 103 | */ | 
|---|
| 104 | Material::Material (char* mtlName) | 
|---|
| 105 | { | 
|---|
| 106 |   init(); | 
|---|
| 107 |    | 
|---|
| 108 |   setName (mtlName); | 
|---|
| 109 | } | 
|---|
| 110 |  | 
|---|
| 111 | /**  | 
|---|
| 112 |     \brief deletes a Material | 
|---|
| 113 | */ | 
|---|
| 114 | Material::~Material() | 
|---|
| 115 | { | 
|---|
| 116 |   if (verbose >= 2) | 
|---|
| 117 |     printf ("delete Material %s.\n", name); | 
|---|
| 118 |   if (name) | 
|---|
| 119 |     delete []name; | 
|---|
| 120 |   if (diffuseTextureSet) | 
|---|
| 121 |     glDeleteTextures (1, &diffuseTexture); | 
|---|
| 122 |   if (nextMat) | 
|---|
| 123 |     delete nextMat; | 
|---|
| 124 | } | 
|---|
| 125 |  | 
|---|
| 126 | /** | 
|---|
| 127 |    \brief adds a new Material to the List. | 
|---|
| 128 |    this Function will append a new Material to the end of a Material List. | 
|---|
| 129 |    \param mtlName The name of the Material to be added. | 
|---|
| 130 | */ | 
|---|
| 131 | Material* Material::addMaterial(char* mtlName) | 
|---|
| 132 | { | 
|---|
| 133 |   if (verbose >=2) | 
|---|
| 134 |     printf ("adding Material %s.\n", mtlName); | 
|---|
| 135 |    Material* tmpMat = this; | 
|---|
| 136 |   while (tmpMat->nextMat != NULL) | 
|---|
| 137 |     { | 
|---|
| 138 |       tmpMat = tmpMat->nextMat; | 
|---|
| 139 |     } | 
|---|
| 140 |   tmpMat->nextMat = new Material(mtlName); | 
|---|
| 141 |   return tmpMat->nextMat; | 
|---|
| 142 |    | 
|---|
| 143 | } | 
|---|
| 144 |  | 
|---|
| 145 | /** | 
|---|
| 146 |    \brief initializes a new Material with its default Values | 
|---|
| 147 | */ | 
|---|
| 148 | void Material::init(void) | 
|---|
| 149 | { | 
|---|
| 150 |   if (verbose >= 3) | 
|---|
| 151 |     printf ("initializing new Material.\n"); | 
|---|
| 152 |   nextMat = NULL; | 
|---|
| 153 |   name =""; | 
|---|
| 154 |   setIllum(1); | 
|---|
| 155 |   setDiffuse(0,0,0); | 
|---|
| 156 |   setAmbient(0,0,0); | 
|---|
| 157 |   setSpecular(.5,.5,.5); | 
|---|
| 158 |   setShininess(2.0); | 
|---|
| 159 |   setTransparency(0.0); | 
|---|
| 160 |  | 
|---|
| 161 |   if (!pathList) | 
|---|
| 162 |     pathList = new PathList(""); | 
|---|
| 163 |  | 
|---|
| 164 |  | 
|---|
| 165 |   diffuseTextureSet = false; | 
|---|
| 166 |   ambientTextureSet = false; | 
|---|
| 167 |   specularTextureSet = false; | 
|---|
| 168 |  | 
|---|
| 169 |    | 
|---|
| 170 | } | 
|---|
| 171 |  | 
|---|
| 172 | PathList *Material::pathList = NULL; | 
|---|
| 173 |  | 
|---|
| 174 | /** | 
|---|
| 175 |    \brief Search for a Material called mtlName | 
|---|
| 176 |    \param mtlName the Name of the Material to search for | 
|---|
| 177 |    \returns Material named mtlName if it is found. NULL otherwise. | 
|---|
| 178 | */ | 
|---|
| 179 | Material* Material::search (char* mtlName) | 
|---|
| 180 | { | 
|---|
| 181 |   if (verbose >=3) | 
|---|
| 182 |     printf ("Searching for material %s", mtlName); | 
|---|
| 183 |   Material* searcher = this; | 
|---|
| 184 |   while (searcher != NULL) | 
|---|
| 185 |     { | 
|---|
| 186 |       if (verbose >= 3) | 
|---|
| 187 |         printf ("."); | 
|---|
| 188 |       if (!strcmp (searcher->getName(), mtlName)) | 
|---|
| 189 |         { | 
|---|
| 190 |           if (verbose >= 3) | 
|---|
| 191 |             printf ("found.\n"); | 
|---|
| 192 |           return searcher; | 
|---|
| 193 |         } | 
|---|
| 194 |       searcher = searcher->nextMat; | 
|---|
| 195 |     } | 
|---|
| 196 |   if (verbose >=3) | 
|---|
| 197 |     printf ("not found\n"); | 
|---|
| 198 |   return NULL; | 
|---|
| 199 | } | 
|---|
| 200 |  | 
|---|
| 201 | /** | 
|---|
| 202 |    \brief sets the material with which the following Faces will be painted | 
|---|
| 203 | */ | 
|---|
| 204 | bool Material::select (void) | 
|---|
| 205 | { | 
|---|
| 206 |   // setting diffuse color | 
|---|
| 207 |   //  glColor3f (diffuse[0], diffuse[1], diffuse[2]); | 
|---|
| 208 |   glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); | 
|---|
| 209 |  | 
|---|
| 210 |   // setting ambient color | 
|---|
| 211 |   glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); | 
|---|
| 212 |  | 
|---|
| 213 |   // setting up Sprecular | 
|---|
| 214 |   glMaterialfv(GL_FRONT, GL_SPECULAR, specular); | 
|---|
| 215 |  | 
|---|
| 216 |   // setting up Shininess | 
|---|
| 217 |   glMaterialf(GL_FRONT, GL_SHININESS, shininess); | 
|---|
| 218 |    | 
|---|
| 219 |   // setting illumination Model  | 
|---|
| 220 |   if (illumModel == 1) | 
|---|
| 221 |     glShadeModel(GL_FLAT); | 
|---|
| 222 |   else if (illumModel >= 2) | 
|---|
| 223 |     glShadeModel(GL_SMOOTH); | 
|---|
| 224 |  | 
|---|
| 225 |   if (diffuseTextureSet) | 
|---|
| 226 |     glBindTexture(GL_TEXTURE_2D, diffuseTexture); | 
|---|
| 227 |   else | 
|---|
| 228 |     glBindTexture(GL_TEXTURE_2D, 0); | 
|---|
| 229 |    | 
|---|
| 230 | } | 
|---|
| 231 |  | 
|---|
| 232 |  | 
|---|
| 233 | /** | 
|---|
| 234 |    \brief Set the Name of the Material. (Important for searching) | 
|---|
| 235 |    \param mtlName the Name of the Material to be set. | 
|---|
| 236 | */  | 
|---|
| 237 | void Material::setName (char* mtlName) | 
|---|
| 238 | { | 
|---|
| 239 |   name = new char [strlen(mtlName)+1]; | 
|---|
| 240 |   strcpy(name, mtlName); | 
|---|
| 241 |   if (verbose >= 3) | 
|---|
| 242 |     printf("setting Material Name to %s.\n", name); | 
|---|
| 243 |  | 
|---|
| 244 |   //  printf ("adding new Material: %s, %p\n", this->getName(), this); | 
|---|
| 245 |  | 
|---|
| 246 | } | 
|---|
| 247 | /** | 
|---|
| 248 |    \returns The Name of The Material | 
|---|
| 249 | */ | 
|---|
| 250 | char* Material::getName (void) | 
|---|
| 251 | { | 
|---|
| 252 |   return name; | 
|---|
| 253 | } | 
|---|
| 254 |  | 
|---|
| 255 | /** | 
|---|
| 256 |    \brief Sets the Material Illumination Model.  | 
|---|
| 257 |    \brief illu illumination Model in int form | 
|---|
| 258 | */ | 
|---|
| 259 | void Material::setIllum (int illum) | 
|---|
| 260 | { | 
|---|
| 261 |   if (verbose >= 3) | 
|---|
| 262 |     printf("setting illumModel of Material %s to %i\n", name, illum); | 
|---|
| 263 |   illumModel = illum; | 
|---|
| 264 |   //  printf ("setting illumModel to: %i\n", illumModel); | 
|---|
| 265 | } | 
|---|
| 266 | /** | 
|---|
| 267 |    \brief Sets the Material Illumination Model.  | 
|---|
| 268 |    \brief illu illumination Model in char* form | 
|---|
| 269 | */void Material::setIllum (char* illum) | 
|---|
| 270 | { | 
|---|
| 271 |   setIllum (atoi(illum)); | 
|---|
| 272 | } | 
|---|
| 273 |  | 
|---|
| 274 | /** | 
|---|
| 275 |    \brief Sets the Material Diffuse Color. | 
|---|
| 276 |    \param r Red Color Channel. | 
|---|
| 277 |    \param g Green Color Channel. | 
|---|
| 278 |    \param b Blue Color Channel. | 
|---|
| 279 | */ | 
|---|
| 280 | void Material::setDiffuse (float r, float g, float b) | 
|---|
| 281 | { | 
|---|
| 282 |   if (verbose >= 3) | 
|---|
| 283 |     printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b); | 
|---|
| 284 |   diffuse[0] = r; | 
|---|
| 285 |   diffuse[1] = g; | 
|---|
| 286 |   diffuse[2] = b;   | 
|---|
| 287 |   diffuse[3] = 1.0; | 
|---|
| 288 |  | 
|---|
| 289 | } | 
|---|
| 290 | /** | 
|---|
| 291 |    \brief Sets the Material Diffuse Color. | 
|---|
| 292 |    \param rgb The red, green, blue channel in char format (with spaces between them) | 
|---|
| 293 | */ | 
|---|
| 294 | void Material::setDiffuse (char* rgb) | 
|---|
| 295 | { | 
|---|
| 296 |   float r,g,b; | 
|---|
| 297 |   sscanf (rgb, "%f %f %f", &r, &g, &b); | 
|---|
| 298 |   setDiffuse (r, g, b); | 
|---|
| 299 | } | 
|---|
| 300 |  | 
|---|
| 301 | /** | 
|---|
| 302 |    \brief Sets the Material Ambient Color.  | 
|---|
| 303 |    \param r Red Color Channel. | 
|---|
| 304 |    \param g Green Color Channel. | 
|---|
| 305 |    \param b Blue Color Channel. | 
|---|
| 306 | */ | 
|---|
| 307 | void Material::setAmbient (float r, float g, float b) | 
|---|
| 308 | { | 
|---|
| 309 |   if (verbose >=3) | 
|---|
| 310 |     printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b); | 
|---|
| 311 |   ambient[0] = r; | 
|---|
| 312 |   ambient[1] = g; | 
|---|
| 313 |   ambient[2] = b; | 
|---|
| 314 |   ambient[3] = 1.0; | 
|---|
| 315 | } | 
|---|
| 316 | /** | 
|---|
| 317 |    \brief Sets the Material Ambient Color. | 
|---|
| 318 |    \param rgb The red, green, blue channel in char format (with spaces between them) | 
|---|
| 319 | */ | 
|---|
| 320 | void Material::setAmbient (char* rgb) | 
|---|
| 321 | { | 
|---|
| 322 |   float r,g,b; | 
|---|
| 323 |   sscanf (rgb, "%f %f %f", &r, &g, &b); | 
|---|
| 324 |   setAmbient (r, g, b); | 
|---|
| 325 | } | 
|---|
| 326 |  | 
|---|
| 327 | /** | 
|---|
| 328 |    \brief Sets the Material Specular Color.  | 
|---|
| 329 |    \param r Red Color Channel. | 
|---|
| 330 |    \param g Green Color Channel. | 
|---|
| 331 |    \param b Blue Color Channel. | 
|---|
| 332 | */ | 
|---|
| 333 | void Material::setSpecular (float r, float g, float b) | 
|---|
| 334 | { | 
|---|
| 335 |   if (verbose >= 3) | 
|---|
| 336 |     printf ("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b); | 
|---|
| 337 |   specular[0] = r; | 
|---|
| 338 |   specular[1] = g; | 
|---|
| 339 |   specular[2] = b; | 
|---|
| 340 |   specular[3] = 1.0; | 
|---|
| 341 |  } | 
|---|
| 342 | /** | 
|---|
| 343 |    \brief Sets the Material Specular Color. | 
|---|
| 344 |    \param rgb The red, green, blue channel in char format (with spaces between them) | 
|---|
| 345 | */ | 
|---|
| 346 | void Material::setSpecular (char* rgb) | 
|---|
| 347 | { | 
|---|
| 348 |   float r,g,b; | 
|---|
| 349 |   sscanf (rgb, "%f %f %f", &r, &g, &b); | 
|---|
| 350 |   setSpecular (r, g, b); | 
|---|
| 351 | } | 
|---|
| 352 |  | 
|---|
| 353 | /** | 
|---|
| 354 |    \brief Sets the Material Shininess. | 
|---|
| 355 |    \param shini stes the Shininess from float. | 
|---|
| 356 | */ | 
|---|
| 357 | void Material::setShininess (float shini) | 
|---|
| 358 | { | 
|---|
| 359 |   shininess = shini; | 
|---|
| 360 | } | 
|---|
| 361 | /** | 
|---|
| 362 |    \brief Sets the Material Shininess. | 
|---|
| 363 |    \param shini stes the Shininess from char*. | 
|---|
| 364 | */ | 
|---|
| 365 | void Material::setShininess (char* shini) | 
|---|
| 366 | { | 
|---|
| 367 |   setShininess (atof(shini)); | 
|---|
| 368 | } | 
|---|
| 369 |  | 
|---|
| 370 | /** | 
|---|
| 371 |    \brief Sets the Material Transparency. | 
|---|
| 372 |    \param trans stes the Transparency from int. | 
|---|
| 373 | */ | 
|---|
| 374 | void Material::setTransparency (float trans) | 
|---|
| 375 | { | 
|---|
| 376 |   if (verbose >= 3) | 
|---|
| 377 |     printf ("setting Transparency of Material %s to %f.\n", name, trans); | 
|---|
| 378 |   transparency = trans; | 
|---|
| 379 | } | 
|---|
| 380 | /** | 
|---|
| 381 |    \brief Sets the Material Transparency. | 
|---|
| 382 |    \param trans stes the Transparency from char*. | 
|---|
| 383 | */ | 
|---|
| 384 | void Material::setTransparency (char* trans) | 
|---|
| 385 | { | 
|---|
| 386 |   setTransparency (atof(trans)); | 
|---|
| 387 | } | 
|---|
| 388 |  | 
|---|
| 389 | /** | 
|---|
| 390 |    \brief Adds a Texture Path to the List of already existing Paths | 
|---|
| 391 |    \param pathName The Path to add. | 
|---|
| 392 | */ | 
|---|
| 393 | void Material::addTexturePath(char* pathName) | 
|---|
| 394 | { | 
|---|
| 395 |   pathList->addPath (pathName); | 
|---|
| 396 | } | 
|---|
| 397 |  | 
|---|
| 398 | /** | 
|---|
| 399 |    \brief Searches for a Texture inside one of the defined Paths | 
|---|
| 400 |    \param texName The name of the texture o search for. | 
|---|
| 401 |    \returns pathName+texName if texName was found in the pathList. NULL if the Texture is not found. | 
|---|
| 402 | */ | 
|---|
| 403 | char* Material::searchTextureInPaths(char* texName) const | 
|---|
| 404 | { | 
|---|
| 405 |   char* tmpName = NULL; | 
|---|
| 406 |   PathList* pList = pathList; | 
|---|
| 407 |   while (pList) | 
|---|
| 408 |     { | 
|---|
| 409 |       if (pList->pathName) | 
|---|
| 410 |         { | 
|---|
| 411 |           tmpName = new char [strlen(pList->pathName)+strlen(texName)+1]; | 
|---|
| 412 |           strcpy(tmpName, pList->pathName); | 
|---|
| 413 |         } | 
|---|
| 414 |       else | 
|---|
| 415 |         { | 
|---|
| 416 |           tmpName = new char [strlen(texName)+1]; | 
|---|
| 417 |           tmpName[0]='\0'; | 
|---|
| 418 |         } | 
|---|
| 419 |       strcat(tmpName, texName); | 
|---|
| 420 |       printf("%s\n", tmpName); | 
|---|
| 421 |       if (access (tmpName, F_OK) == 0) | 
|---|
| 422 |         return tmpName; | 
|---|
| 423 |        | 
|---|
| 424 |       if (tmpName) | 
|---|
| 425 |         delete []tmpName; | 
|---|
| 426 |       tmpName = NULL; | 
|---|
| 427 |       pList = pList->next; | 
|---|
| 428 |     } | 
|---|
| 429 |   return NULL; | 
|---|
| 430 | } | 
|---|
| 431 |  | 
|---|
| 432 |  | 
|---|
| 433 | // MAPPING // | 
|---|
| 434 |  | 
|---|
| 435 | /** | 
|---|
| 436 |    \brief Sets the Materials Diffuse Map | 
|---|
| 437 |    \param dMap the Name of the Image to Use | 
|---|
| 438 | */ | 
|---|
| 439 | void Material::setDiffuseMap(char* dMap) | 
|---|
| 440 | { | 
|---|
| 441 |   if (verbose>=2) | 
|---|
| 442 |     printf ("setting Diffuse Map %s\n", dMap); | 
|---|
| 443 |  | 
|---|
| 444 |   //  diffuseTextureSet = loadBMP(dMap, &diffuseTexture); | 
|---|
| 445 |   diffuseTextureSet = loadImage(dMap, &diffuseTexture); | 
|---|
| 446 |  | 
|---|
| 447 | } | 
|---|
| 448 |  | 
|---|
| 449 | /** | 
|---|
| 450 |    \brief Sets the Materials Ambient Map | 
|---|
| 451 |    \param aMap the Name of the Image to Use | 
|---|
| 452 | */ | 
|---|
| 453 | void Material::setAmbientMap(char* aMap) | 
|---|
| 454 | { | 
|---|
| 455 |   SDL_Surface* ambientMap; | 
|---|
| 456 |  | 
|---|
| 457 | } | 
|---|
| 458 |  | 
|---|
| 459 | /** | 
|---|
| 460 |    \brief Sets the Materials Specular Map | 
|---|
| 461 |    \param sMap the Name of the Image to Use | 
|---|
| 462 | */ | 
|---|
| 463 | void Material::setSpecularMap(char* sMap) | 
|---|
| 464 | { | 
|---|
| 465 |   SDL_Surface* specularMap; | 
|---|
| 466 |  | 
|---|
| 467 | } | 
|---|
| 468 |  | 
|---|
| 469 | /** | 
|---|
| 470 |    \brief Sets the Materials Bumpiness | 
|---|
| 471 |    \param bump the Name of the Image to Use | 
|---|
| 472 | */ | 
|---|
| 473 | void Material::setBump(char* bump) | 
|---|
| 474 | { | 
|---|
| 475 |  | 
|---|
| 476 | } | 
|---|
| 477 |  | 
|---|
| 478 | bool Material::loadTexToGL (Image* pImage, GLuint* texture) | 
|---|
| 479 | { | 
|---|
| 480 |   if (verbose >=3) | 
|---|
| 481 |     printf ("Loading texture to OpenGL-Environment.\n"); | 
|---|
| 482 |   glGenTextures(1, texture); | 
|---|
| 483 |   glBindTexture(GL_TEXTURE_2D, *texture); | 
|---|
| 484 |   /* not Working, and not needed.  | 
|---|
| 485 |   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, | 
|---|
| 486 |                 height, 0, GL_BGR, | 
|---|
| 487 |                 GL_UNSIGNED_BYTE, map->pixels ); | 
|---|
| 488 |   */  | 
|---|
| 489 |   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->width, pImage->height, GL_RGB, GL_UNSIGNED_BYTE, pImage->data); | 
|---|
| 490 |    | 
|---|
| 491 |   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); | 
|---|
| 492 |   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);  | 
|---|
| 493 | } | 
|---|
| 494 |  | 
|---|
| 495 |  | 
|---|
| 496 | #ifdef HAVE_SDL_SDL_IMAGE_H | 
|---|
| 497 | bool Material::loadImage(char* imageName, GLuint* texture) | 
|---|
| 498 | { | 
|---|
| 499 |   char* imgNameWithPath = searchTextureInPaths(imageName); | 
|---|
| 500 |   if (imgNameWithPath) | 
|---|
| 501 |     { | 
|---|
| 502 |       SDL_Surface* map; | 
|---|
| 503 |       Image* pImage = new Image; | 
|---|
| 504 |       map=IMG_Load(imgNameWithPath); | 
|---|
| 505 |       if(!map) | 
|---|
| 506 |         { | 
|---|
| 507 |           printf("IMG_Load: %s\n", IMG_GetError()); | 
|---|
| 508 |           return false; | 
|---|
| 509 |         } | 
|---|
| 510 |       pImage->height = map->h; | 
|---|
| 511 |       pImage->width  = map->w; | 
|---|
| 512 |       pImage->data   = (GLubyte*)map->pixels; | 
|---|
| 513 |       if( !IMG_isPNG(SDL_RWFromFile(imgNameWithPath, "rb")) && !IMG_isJPG(SDL_RWFromFile(imgNameWithPath, "rb"))) | 
|---|
| 514 |         for (int i=0;i<map->h * map->w *3;i+=3) | 
|---|
| 515 |           {  | 
|---|
| 516 |             GLuint temp = pImage->data[i]; | 
|---|
| 517 |             pImage->data[i] = pImage->data[i+2]; | 
|---|
| 518 |             pImage->data[i+2] = temp; | 
|---|
| 519 |           } | 
|---|
| 520 |       loadTexToGL (pImage, texture); | 
|---|
| 521 |     } | 
|---|
| 522 |   else | 
|---|
| 523 |     { | 
|---|
| 524 |       if (verbose >=1) | 
|---|
| 525 |         printf ("Image not Found: %s\n", imgNameWithPath); | 
|---|
| 526 |       return false; | 
|---|
| 527 |     } | 
|---|
| 528 | } | 
|---|
| 529 |  | 
|---|
| 530 |  | 
|---|
| 531 | #else /* HAVE_SDL_SDL_IMAGE_H */ | 
|---|
| 532 | /** | 
|---|
| 533 |    \brief Makes the Programm ready to Read-in a texture-File | 
|---|
| 534 |    1. Checks what type of Image should be imported | 
|---|
| 535 |    2. ToDO: Checks where to find the Image | 
|---|
| 536 | */ | 
|---|
| 537 | bool Material::loadImage(char* imageName, GLuint* texture) | 
|---|
| 538 | { | 
|---|
| 539 |   char* imgNameWithPath = searchTextureInPaths(imageName); | 
|---|
| 540 |   if (imgNameWithPath) | 
|---|
| 541 |     { | 
|---|
| 542 |       if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".bmp", 4)) | 
|---|
| 543 |         { | 
|---|
| 544 |           if (verbose >=2) | 
|---|
| 545 |             printf ("Requested bmp-image. Trying to Import.\n"); | 
|---|
| 546 |           return loadBMP(imgNameWithPath, texture); | 
|---|
| 547 |         } | 
|---|
| 548 |        | 
|---|
| 549 |       else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".jpg", 4) || !strncmp(imgNameWithPath+strlen(imgNameWithPath)-5, ".jpg", 5)) | 
|---|
| 550 |         { | 
|---|
| 551 |           if (verbose >=2) | 
|---|
| 552 |             printf ("Requested jpeg-image. Trying to Import\n"); | 
|---|
| 553 |           return loadJPG(imgNameWithPath, texture); | 
|---|
| 554 |         } | 
|---|
| 555 |       else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".tga", 4)) | 
|---|
| 556 |         { | 
|---|
| 557 |           if (verbose >=2) | 
|---|
| 558 |             printf ("Requested tga-image. Trying to Import\n"); | 
|---|
| 559 |           return loadTGA(imgNameWithPath, texture); | 
|---|
| 560 |         } | 
|---|
| 561 |       else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".png", 4)) | 
|---|
| 562 |         { | 
|---|
| 563 |           if (verbose >=2) | 
|---|
| 564 |             printf ("Requested png-image. Trying to Import\n"); | 
|---|
| 565 |           return loadPNG(imgNameWithPath, texture); | 
|---|
| 566 |         } | 
|---|
| 567 |       else | 
|---|
| 568 |         { | 
|---|
| 569 |           if (verbose >=1) | 
|---|
| 570 |             printf ("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imgNameWithPath); | 
|---|
| 571 |           return false; | 
|---|
| 572 |         } | 
|---|
| 573 |     } | 
|---|
| 574 |   else | 
|---|
| 575 |     { | 
|---|
| 576 |       if (verbose >=1) | 
|---|
| 577 |         printf ("Image not Found: %s\n", imgNameWithPath); | 
|---|
| 578 |       return false; | 
|---|
| 579 |     } | 
|---|
| 580 | } | 
|---|
| 581 |  | 
|---|
| 582 | /** | 
|---|
| 583 |    \brief reads in a Windows BMP-file, and imports it to openGL. | 
|---|
| 584 |    \param bmpName The name of the Image to load. | 
|---|
| 585 |    \param texture A pointer to the Texture which should be read to. | 
|---|
| 586 | */ | 
|---|
| 587 | bool Material::loadBMP (char* bmpName, GLuint* texture) | 
|---|
| 588 | { | 
|---|
| 589 |   Image* pImage = new Image; | 
|---|
| 590 |   FILE *file; | 
|---|
| 591 |   unsigned long size;                 // size of the image in bytes. | 
|---|
| 592 |   unsigned long i;                    // standard counter. | 
|---|
| 593 |   unsigned short int planes;          // number of planes in image (must be 1)  | 
|---|
| 594 |   unsigned short int bpp;             // number of bits per pixel (must be 24) | 
|---|
| 595 |   GLuint temp;                          // temporary color storage for bgr-rgb conversion. | 
|---|
| 596 |  | 
|---|
| 597 |   // make sure the file is there. | 
|---|
| 598 |   if ((file = fopen(bmpName, "rb"))==NULL) | 
|---|
| 599 |     { | 
|---|
| 600 |       if (verbose >=1) | 
|---|
| 601 |         printf("File Not Found : %s\n",bmpName); | 
|---|
| 602 |       return false; | 
|---|
| 603 |     } | 
|---|
| 604 |   // seek through the bmp header, up to the width/height: | 
|---|
| 605 |   fseek(file, 18, SEEK_CUR); | 
|---|
| 606 |    | 
|---|
| 607 |   // read the width | 
|---|
| 608 |   if ((i = fread(&pImage->width, 4, 1, file)) != 1)  | 
|---|
| 609 |     { | 
|---|
| 610 |       if (verbose >=1) | 
|---|
| 611 |         printf("Error reading width from %s.\n", bmpName); | 
|---|
| 612 |       return false; | 
|---|
| 613 |     } | 
|---|
| 614 |   // read the height  | 
|---|
| 615 |   if ((i = fread(&pImage->height, 4, 1, file)) != 1)  | 
|---|
| 616 |     { | 
|---|
| 617 |       if (verbose>=1) | 
|---|
| 618 |         printf("Error reading height from %s.\n", bmpName); | 
|---|
| 619 |       return false; | 
|---|
| 620 |     } | 
|---|
| 621 |    | 
|---|
| 622 |   // calculate the size (assuming 24 bits or 3 bytes per pixel). | 
|---|
| 623 |   size = pImage->width * pImage->height * 3; | 
|---|
| 624 |    | 
|---|
| 625 |   // read the planes | 
|---|
| 626 |   if ((fread(&planes, 2, 1, file)) != 1)  | 
|---|
| 627 |     { | 
|---|
| 628 |       if (verbose>=1) | 
|---|
| 629 |         printf("Error reading planes from %s.\n", bmpName); | 
|---|
| 630 |       return false; | 
|---|
| 631 |     } | 
|---|
| 632 |   if (planes != 1)  | 
|---|
| 633 |     { | 
|---|
| 634 |       if (verbose>=1) | 
|---|
| 635 |         printf("Planes from %s is not 1: %u\n", bmpName, planes); | 
|---|
| 636 |       return false; | 
|---|
| 637 |     } | 
|---|
| 638 |    | 
|---|
| 639 |   // read the bpp | 
|---|
| 640 |   if ((i = fread(&bpp, 2, 1, file)) != 1)  | 
|---|
| 641 |     { | 
|---|
| 642 |       if (verbose>=1) | 
|---|
| 643 |         printf("Error reading bpp from %s.\n", bmpName); | 
|---|
| 644 |       return false; | 
|---|
| 645 |     } | 
|---|
| 646 |   if (bpp != 24)  | 
|---|
| 647 |     { | 
|---|
| 648 |       if (verbose>=1) | 
|---|
| 649 |         printf("Bpp from %s is not 24: %u\n", bmpName, bpp); | 
|---|
| 650 |       return false; | 
|---|
| 651 |     } | 
|---|
| 652 |    | 
|---|
| 653 |   // seek past the rest of the bitmap header. | 
|---|
| 654 |   fseek(file, 24, SEEK_CUR); | 
|---|
| 655 |    | 
|---|
| 656 |   // read the data.  | 
|---|
| 657 |   pImage->data = (GLubyte *) malloc(size); | 
|---|
| 658 |   if (pImage->data == NULL)  | 
|---|
| 659 |     { | 
|---|
| 660 |       if (verbose>=1) | 
|---|
| 661 |         printf("Error allocating memory for color-corrected image data"); | 
|---|
| 662 |       return false;      | 
|---|
| 663 |     } | 
|---|
| 664 |    | 
|---|
| 665 |   if ((i = fread(pImage->data, size, 1, file)) != 1)  | 
|---|
| 666 |     { | 
|---|
| 667 |       if (verbose>=1) | 
|---|
| 668 |         printf("Error reading image data from %s.\n", bmpName); | 
|---|
| 669 |       return false; | 
|---|
| 670 |     } | 
|---|
| 671 |   fclose(file); | 
|---|
| 672 |  | 
|---|
| 673 |   // reverse all of the colors. (bgr -> rgb) | 
|---|
| 674 |   for (i=0;i<size;i+=3)  | 
|---|
| 675 |     {  | 
|---|
| 676 |       temp = pImage->data[i]; | 
|---|
| 677 |       pImage->data[i] = pImage->data[i+2]; | 
|---|
| 678 |       pImage->data[i+2] = temp; | 
|---|
| 679 |     } | 
|---|
| 680 |   loadTexToGL (pImage, texture); | 
|---|
| 681 |    | 
|---|
| 682 |   return true; | 
|---|
| 683 |  | 
|---|
| 684 |   if (pImage) | 
|---|
| 685 |     { | 
|---|
| 686 |       if (pImage->data) | 
|---|
| 687 |         { | 
|---|
| 688 |           free(pImage->data); | 
|---|
| 689 |         } | 
|---|
| 690 |        | 
|---|
| 691 |       free(pImage); | 
|---|
| 692 |     } | 
|---|
| 693 |  | 
|---|
| 694 | } | 
|---|
| 695 |  | 
|---|
| 696 | /** | 
|---|
| 697 |    \brief reads in a jpg-file | 
|---|
| 698 |    \param jpgName the Name of the Image to load | 
|---|
| 699 |    \param texture a reference to the Texture to write the image to | 
|---|
| 700 | */ | 
|---|
| 701 | bool Material::loadJPG (char* jpgName, GLuint* texture) | 
|---|
| 702 | { | 
|---|
| 703 | #ifdef HAVE_JPEGLIB_H | 
|---|
| 704 |   struct jpeg_decompress_struct cinfo; | 
|---|
| 705 |   Image *pImage = NULL; | 
|---|
| 706 |   FILE *pFile; | 
|---|
| 707 |    | 
|---|
| 708 |   // Open a file pointer to the jpeg file and check if it was found and opened  | 
|---|
| 709 |   if((pFile = fopen(jpgName, "rb")) == NULL)  | 
|---|
| 710 |     { | 
|---|
| 711 |       // Display an error message saying the file was not found, then return NULL | 
|---|
| 712 |       printf("Unable to load JPG File %s.\n", jpgName); | 
|---|
| 713 |       return false; | 
|---|
| 714 |     } | 
|---|
| 715 |    | 
|---|
| 716 |   // Create an error handler | 
|---|
| 717 |   jpeg_error_mgr jerr; | 
|---|
| 718 |    | 
|---|
| 719 |   // Have our compression info object point to the error handler address | 
|---|
| 720 |   cinfo.err = jpeg_std_error(&jerr); | 
|---|
| 721 |    | 
|---|
| 722 |   // Initialize the decompression object | 
|---|
| 723 |   jpeg_create_decompress(&cinfo); | 
|---|
| 724 |    | 
|---|
| 725 |   // Specify the data source (Our file pointer)  | 
|---|
| 726 |   jpeg_stdio_src(&cinfo, pFile); | 
|---|
| 727 |    | 
|---|
| 728 |   // Allocate the structure that will hold our eventual jpeg data (must free it!) | 
|---|
| 729 |   pImage = (Image*)malloc(sizeof(Image)); | 
|---|
| 730 |    | 
|---|
| 731 |   // DECOFING | 
|---|
| 732 |   // Read in the header of the jpeg file | 
|---|
| 733 |   jpeg_read_header(&cinfo, TRUE); | 
|---|
| 734 |    | 
|---|
| 735 |   // Start to decompress the jpeg file with our compression info | 
|---|
| 736 |   jpeg_start_decompress(&cinfo); | 
|---|
| 737 |    | 
|---|
| 738 |   // Get the image dimensions and row span to read in the pixel data | 
|---|
| 739 |   pImage->rowSpan = cinfo.image_width * cinfo.num_components; | 
|---|
| 740 |   pImage->width   = cinfo.image_width; | 
|---|
| 741 |   pImage->height   = cinfo.image_height; | 
|---|
| 742 |    | 
|---|
| 743 |   // Allocate memory for the pixel buffer | 
|---|
| 744 |   pImage->data = new unsigned char[pImage->rowSpan * pImage->height]; | 
|---|
| 745 |    | 
|---|
| 746 |   // Here we use the library's state variable cinfo.output_scanline as the | 
|---|
| 747 |   // loop counter, so that we don't have to keep track ourselves. | 
|---|
| 748 |    | 
|---|
| 749 |   // Create an array of row pointers | 
|---|
| 750 |   unsigned char** rowPtr = new unsigned char*[pImage->height]; | 
|---|
| 751 |   for (int i = 0; i < pImage->height; i++) | 
|---|
| 752 |     rowPtr[i] = &(pImage->data[i*pImage->rowSpan]); | 
|---|
| 753 |    | 
|---|
| 754 |   // Now comes the juice of our work, here we extract all the pixel data | 
|---|
| 755 |   int rowsRead = 0; | 
|---|
| 756 |   while (cinfo.output_scanline < cinfo.output_height)  | 
|---|
| 757 |     { | 
|---|
| 758 |       // Read in the current row of pixels and increase the rowsRead count | 
|---|
| 759 |       rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead); | 
|---|
| 760 |     } | 
|---|
| 761 |    | 
|---|
| 762 |   // Delete the temporary row pointers | 
|---|
| 763 |   delete [] rowPtr; | 
|---|
| 764 |    | 
|---|
| 765 |   // Finish decompressing the data | 
|---|
| 766 |   jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage); | 
|---|
| 767 |    | 
|---|
| 768 |   // This releases all the stored memory for reading and decoding the jpeg | 
|---|
| 769 |   jpeg_destroy_decompress(&cinfo); | 
|---|
| 770 |    | 
|---|
| 771 |   // Close the file pointer that opened the file | 
|---|
| 772 |   fclose(pFile); | 
|---|
| 773 |    | 
|---|
| 774 |  | 
|---|
| 775 |   if(pImage == NULL) | 
|---|
| 776 |     exit(0); | 
|---|
| 777 |    | 
|---|
| 778 |   loadTexToGL (pImage, texture); | 
|---|
| 779 |   if (pImage) | 
|---|
| 780 |     { | 
|---|
| 781 |       if (pImage->data) | 
|---|
| 782 |         { | 
|---|
| 783 |           free(pImage->data); | 
|---|
| 784 |         } | 
|---|
| 785 |        | 
|---|
| 786 |       free(pImage); | 
|---|
| 787 |     } | 
|---|
| 788 |   return true; | 
|---|
| 789 | #else /* HAVE_JPEGLIB_H */ | 
|---|
| 790 |   if (verbose >=1) | 
|---|
| 791 |     printf ("sorry, but you did not compile with jpeg-support.\nEither install SDL_image or jpeglib, and recompile to see the image\n"); | 
|---|
| 792 |   return false; | 
|---|
| 793 | #endif /* HAVE_JPEGLIB_H */ | 
|---|
| 794 |  | 
|---|
| 795 | } | 
|---|
| 796 |  | 
|---|
| 797 | /** | 
|---|
| 798 |    \brief reads in a tga-file | 
|---|
| 799 |    \param tgaName the Name of the Image to load | 
|---|
| 800 |    \param texture a reference to the Texture to write the image to | 
|---|
| 801 | */ | 
|---|
| 802 | bool Material::loadTGA(const char * tgaName, GLuint* texture) | 
|---|
| 803 | { | 
|---|
| 804 |   typedef struct | 
|---|
| 805 |   { | 
|---|
| 806 |     GLubyte Header[12]; | 
|---|
| 807 |   } TGAHeader; | 
|---|
| 808 |   TGAHeader tgaHeader;                   | 
|---|
| 809 |    | 
|---|
| 810 |   GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header  | 
|---|
| 811 |   GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; // Compressed TGA Header  | 
|---|
| 812 |   FILE * fTGA; | 
|---|
| 813 |   fTGA = fopen(tgaName, "rb"); | 
|---|
| 814 |  | 
|---|
| 815 |   if(fTGA == NULL) | 
|---|
| 816 |     { | 
|---|
| 817 |       printf("Error could not open texture file: %s\n", tgaName); | 
|---|
| 818 |       return false; | 
|---|
| 819 |     } | 
|---|
| 820 |    | 
|---|
| 821 |   if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0) | 
|---|
| 822 |     { | 
|---|
| 823 |       printf("Error could not read file header of %s\n", tgaName); | 
|---|
| 824 |       if(fTGA != NULL) | 
|---|
| 825 |         { | 
|---|
| 826 |           fclose(fTGA); | 
|---|
| 827 |         } | 
|---|
| 828 |       return false; | 
|---|
| 829 |     } | 
|---|
| 830 |    | 
|---|
| 831 |   if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0) | 
|---|
| 832 |     { | 
|---|
| 833 |       loadUncompressedTGA(tgaName, fTGA, texture); | 
|---|
| 834 |       if (fTGA) | 
|---|
| 835 |         fclose (fTGA); | 
|---|
| 836 |     } | 
|---|
| 837 |   else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0) | 
|---|
| 838 |     { | 
|---|
| 839 |       loadCompressedTGA(tgaName, fTGA, texture); | 
|---|
| 840 |         if (fTGA) | 
|---|
| 841 |           fclose (fTGA); | 
|---|
| 842 |     } | 
|---|
| 843 |   else | 
|---|
| 844 |     { | 
|---|
| 845 |       printf("Error TGA file be type 2 or type 10\n"); | 
|---|
| 846 |       if (fTGA) | 
|---|
| 847 |         fclose(fTGA); | 
|---|
| 848 |       return false; | 
|---|
| 849 |     } | 
|---|
| 850 |   return true; | 
|---|
| 851 | } | 
|---|
| 852 |  | 
|---|
| 853 | /** | 
|---|
| 854 |    \brief reads in an uncompressed tga-file | 
|---|
| 855 |    \param filename the Name of the Image to load | 
|---|
| 856 |    \param fTGA a Pointer to a File, that should be read | 
|---|
| 857 |    \param texture a reference to the Texture to write the image to | 
|---|
| 858 | */ | 
|---|
| 859 | bool Material::loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture) | 
|---|
| 860 | { | 
|---|
| 861 |   GLubyte header[6];      // First 6 Useful Bytes From The Header  | 
|---|
| 862 |   GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File  | 
|---|
| 863 |   GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram  | 
|---|
| 864 |   GLuint  temp;           // Temporary Variable | 
|---|
| 865 |   GLuint  type; | 
|---|
| 866 |   GLuint  Height;         // Height of Image  | 
|---|
| 867 |   GLuint  Width;          // Width of Image  | 
|---|
| 868 |   GLuint  Bpp;            // Bits Per Pixel  | 
|---|
| 869 |  | 
|---|
| 870 |   Image* pImage = new Image; | 
|---|
| 871 |   GLuint cswap; | 
|---|
| 872 |   if(fread(header, sizeof(header), 1, fTGA) == 0) | 
|---|
| 873 |     { | 
|---|
| 874 |       printf("Error could not read info header\n"); | 
|---|
| 875 |       return false; | 
|---|
| 876 |     } | 
|---|
| 877 |    | 
|---|
| 878 |   Width = pImage->width  = header[1] * 256 + header[0]; | 
|---|
| 879 |   Height =  pImage->height = header[3] * 256 + header[2]; | 
|---|
| 880 |   Bpp = pImage->bpp = header[4]; | 
|---|
| 881 |   // Make sure all information is valid | 
|---|
| 882 |   if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32))) | 
|---|
| 883 |     { | 
|---|
| 884 |       printf("Error invalid texture information\n"); | 
|---|
| 885 |       return false; | 
|---|
| 886 |     } | 
|---|
| 887 |    | 
|---|
| 888 |   if(pImage->bpp == 24)  | 
|---|
| 889 |     { | 
|---|
| 890 |       pImage->type = GL_RGB; | 
|---|
| 891 |     } | 
|---|
| 892 |   else | 
|---|
| 893 |     { | 
|---|
| 894 |       pImage->type = GL_RGBA; | 
|---|
| 895 |     } | 
|---|
| 896 |    | 
|---|
| 897 |   bytesPerPixel = (Bpp / 8); | 
|---|
| 898 |   imageSize = (bytesPerPixel * Width * Height); | 
|---|
| 899 |   pImage->data = (GLubyte*) malloc(imageSize); | 
|---|
| 900 |    | 
|---|
| 901 |   if(pImage->data == NULL) | 
|---|
| 902 |     { | 
|---|
| 903 |       printf("Error could not allocate memory for image\n"); | 
|---|
| 904 |       return false; | 
|---|
| 905 |     } | 
|---|
| 906 |    | 
|---|
| 907 |   if(fread(pImage->data, 1, imageSize, fTGA) != imageSize) | 
|---|
| 908 |     { | 
|---|
| 909 |       printf("Error could not read image data\n"); | 
|---|
| 910 |       if(pImage->data != NULL) | 
|---|
| 911 |         { | 
|---|
| 912 |           free(pImage->data); | 
|---|
| 913 |         } | 
|---|
| 914 |       return false; | 
|---|
| 915 |     } | 
|---|
| 916 |    | 
|---|
| 917 |   for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel) | 
|---|
| 918 |     { | 
|---|
| 919 |       pImage->data[cswap] ^= pImage->data[cswap+2] ^= | 
|---|
| 920 |         pImage->data[cswap] ^= pImage->data[cswap+2]; | 
|---|
| 921 |     } | 
|---|
| 922 |    | 
|---|
| 923 |   loadTexToGL (pImage, texture); | 
|---|
| 924 |  | 
|---|
| 925 |   return true; | 
|---|
| 926 | } | 
|---|
| 927 |  | 
|---|
| 928 | /** | 
|---|
| 929 |    \brief reads in a compressed tga-file | 
|---|
| 930 |    \param filename the Name of the Image to load | 
|---|
| 931 |    \param fTGA a Pointer to a File, that should be read | 
|---|
| 932 |    \param texture a reference to the Texture to write the image to | 
|---|
| 933 | */ | 
|---|
| 934 | bool Material::loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture) | 
|---|
| 935 | { | 
|---|
| 936 |   GLubyte header[6];      // First 6 Useful Bytes From The Header  | 
|---|
| 937 |   GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File  | 
|---|
| 938 |   GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram  | 
|---|
| 939 |   GLuint  temp;           // Temporary Variable | 
|---|
| 940 |   GLuint  type; | 
|---|
| 941 |   GLuint  Height;         // Height of Image  | 
|---|
| 942 |   GLuint  Width;          // Width of Image  | 
|---|
| 943 |   GLuint  Bpp;            // Bits Per Pixel  | 
|---|
| 944 |  | 
|---|
| 945 |   Image* pImage = new Image; | 
|---|
| 946 |  | 
|---|
| 947 |    | 
|---|
| 948 |   if(fread(header, sizeof(header), 1, fTGA) == 0) | 
|---|
| 949 |     { | 
|---|
| 950 |       printf("Error could not read info header\n"); | 
|---|
| 951 |       return false; | 
|---|
| 952 |     } | 
|---|
| 953 |    | 
|---|
| 954 |   Width = pImage->width  = header[1] * 256 + header[0]; | 
|---|
| 955 |   Height = pImage->height = header[3] * 256 + header[2]; | 
|---|
| 956 |   Bpp = pImage->bpp     = header[4]; | 
|---|
| 957 |  | 
|---|
| 958 |   GLuint pixelcount     = Height * Width; | 
|---|
| 959 |   GLuint currentpixel   = 0; | 
|---|
| 960 |   GLuint currentbyte    = 0; | 
|---|
| 961 |   GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel); | 
|---|
| 962 |  | 
|---|
| 963 |   //Make sure all pImage info is ok  | 
|---|
| 964 |   if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32))) | 
|---|
| 965 |     { | 
|---|
| 966 |       printf("Error Invalid pImage information\n"); | 
|---|
| 967 |       return false; | 
|---|
| 968 |     } | 
|---|
| 969 |    | 
|---|
| 970 |   bytesPerPixel = (Bpp / 8); | 
|---|
| 971 |   imageSize             = (bytesPerPixel * Width * Height); | 
|---|
| 972 |   pImage->data  = (GLubyte*) malloc(imageSize); | 
|---|
| 973 |    | 
|---|
| 974 |   if(pImage->data == NULL) | 
|---|
| 975 |     { | 
|---|
| 976 |       printf("Error could not allocate memory for image\n"); | 
|---|
| 977 |       return false; | 
|---|
| 978 |     } | 
|---|
| 979 |    | 
|---|
| 980 |   do | 
|---|
| 981 |     { | 
|---|
| 982 |       GLubyte chunkheader = 0; | 
|---|
| 983 |        | 
|---|
| 984 |       if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0) | 
|---|
| 985 |         { | 
|---|
| 986 |           printf("Error could not read RLE header\n"); | 
|---|
| 987 |           if(pImage->data != NULL) | 
|---|
| 988 |             { | 
|---|
| 989 |               free(pImage->data); | 
|---|
| 990 |             } | 
|---|
| 991 |           return false; | 
|---|
| 992 |         } | 
|---|
| 993 |       // If the ehader is < 128, it means the that is the number of RAW color packets minus 1  | 
|---|
| 994 |       if(chunkheader < 128) | 
|---|
| 995 |         { | 
|---|
| 996 |           short counter; | 
|---|
| 997 |           chunkheader++; | 
|---|
| 998 |           // Read RAW color values | 
|---|
| 999 |           for(counter = 0; counter < chunkheader; counter++) | 
|---|
| 1000 |             {  | 
|---|
| 1001 |               // Try to read 1 pixel  | 
|---|
| 1002 |               if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) | 
|---|
| 1003 |                 { | 
|---|
| 1004 |                   printf("Error could not read image data\n"); | 
|---|
| 1005 |                   if(colorbuffer != NULL) | 
|---|
| 1006 |                     { | 
|---|
| 1007 |                       free(colorbuffer); | 
|---|
| 1008 |                     } | 
|---|
| 1009 |                    | 
|---|
| 1010 |                   if(pImage->data != NULL) | 
|---|
| 1011 |                     { | 
|---|
| 1012 |                       free(pImage->data); | 
|---|
| 1013 |                     } | 
|---|
| 1014 |                    | 
|---|
| 1015 |                   return false;  | 
|---|
| 1016 |                 } | 
|---|
| 1017 |               // write to memory  | 
|---|
| 1018 |               // Flip R and B vcolor values around in the process  | 
|---|
| 1019 |               pImage->data[currentbyte    ] = colorbuffer[2];                                | 
|---|
| 1020 |               pImage->data[currentbyte + 1] = colorbuffer[1]; | 
|---|
| 1021 |               pImage->data[currentbyte + 2] = colorbuffer[0]; | 
|---|
| 1022 |                | 
|---|
| 1023 |               if(bytesPerPixel == 4) // if its a 32 bpp image  | 
|---|
| 1024 |                 { | 
|---|
| 1025 |                   pImage->data[currentbyte + 3] = colorbuffer[3];// copy the 4th byte  | 
|---|
| 1026 |                 } | 
|---|
| 1027 |                | 
|---|
| 1028 |               currentbyte += bytesPerPixel; | 
|---|
| 1029 |               currentpixel++; | 
|---|
| 1030 |  | 
|---|
| 1031 |               // Make sure we haven't read too many pixels  | 
|---|
| 1032 |               if(currentpixel > pixelcount)      | 
|---|
| 1033 |                 { | 
|---|
| 1034 |                   printf("Error too many pixels read\n"); | 
|---|
| 1035 |                   if(colorbuffer != NULL) | 
|---|
| 1036 |                     { | 
|---|
| 1037 |                       free(colorbuffer); | 
|---|
| 1038 |                     } | 
|---|
| 1039 |                    | 
|---|
| 1040 |                   if(pImage->data != NULL) | 
|---|
| 1041 |                     { | 
|---|
| 1042 |                       free(pImage->data); | 
|---|
| 1043 |                     } | 
|---|
| 1044 |                    | 
|---|
| 1045 |                   return false; | 
|---|
| 1046 |                 } | 
|---|
| 1047 |             } | 
|---|
| 1048 |         } | 
|---|
| 1049 |       // chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times | 
|---|
| 1050 |       else | 
|---|
| 1051 |         { | 
|---|
| 1052 |           short counter; | 
|---|
| 1053 |           chunkheader -= 127;   // Subteact 127 to get rid of the ID bit  | 
|---|
| 1054 |           if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) // Attempt to read following color values  | 
|---|
| 1055 |             { | 
|---|
| 1056 |               printf("Error could not read from file"); | 
|---|
| 1057 |               if(colorbuffer != NULL) | 
|---|
| 1058 |                 { | 
|---|
| 1059 |                   free(colorbuffer); | 
|---|
| 1060 |                 } | 
|---|
| 1061 |                | 
|---|
| 1062 |               if(pImage->data != NULL) | 
|---|
| 1063 |                 { | 
|---|
| 1064 |                   free(pImage->data); | 
|---|
| 1065 |                 } | 
|---|
| 1066 |                | 
|---|
| 1067 |               return false; | 
|---|
| 1068 |             } | 
|---|
| 1069 |            | 
|---|
| 1070 |           for(counter = 0; counter < chunkheader; counter++) //copy the color into the image data as many times as dictated | 
|---|
| 1071 |             {                                                    | 
|---|
| 1072 |               // switch R and B bytes areound while copying | 
|---|
| 1073 |               pImage->data[currentbyte    ] = colorbuffer[2]; | 
|---|
| 1074 |               pImage->data[currentbyte + 1] = colorbuffer[1]; | 
|---|
| 1075 |               pImage->data[currentbyte + 2] = colorbuffer[0]; | 
|---|
| 1076 |                | 
|---|
| 1077 |               if(bytesPerPixel == 4) | 
|---|
| 1078 |                 { | 
|---|
| 1079 |                   pImage->data[currentbyte + 3] = colorbuffer[3]; | 
|---|
| 1080 |                 } | 
|---|
| 1081 |                | 
|---|
| 1082 |               currentbyte += bytesPerPixel; | 
|---|
| 1083 |               currentpixel++; | 
|---|
| 1084 |                | 
|---|
| 1085 |               if(currentpixel > pixelcount) | 
|---|
| 1086 |                 { | 
|---|
| 1087 |                   printf("Error too many pixels read\n"); | 
|---|
| 1088 |                   if(colorbuffer != NULL) | 
|---|
| 1089 |                     { | 
|---|
| 1090 |                       free(colorbuffer); | 
|---|
| 1091 |                     } | 
|---|
| 1092 |                    | 
|---|
| 1093 |                   if(pImage->data != NULL) | 
|---|
| 1094 |                     { | 
|---|
| 1095 |                       free(pImage->data); | 
|---|
| 1096 |                     } | 
|---|
| 1097 |                    | 
|---|
| 1098 |                   return false; | 
|---|
| 1099 |                 } | 
|---|
| 1100 |             } | 
|---|
| 1101 |         } | 
|---|
| 1102 |     } | 
|---|
| 1103 |    | 
|---|
| 1104 |   while(currentpixel < pixelcount);     // Loop while there are still pixels left | 
|---|
| 1105 |  | 
|---|
| 1106 |   loadTexToGL (pImage, texture); | 
|---|
| 1107 |  | 
|---|
| 1108 |   return true; | 
|---|
| 1109 | } | 
|---|
| 1110 |  | 
|---|
| 1111 |  | 
|---|
| 1112 | /* | 
|---|
| 1113 | static int ST_is_power_of_two(unsigned int number) | 
|---|
| 1114 | { | 
|---|
| 1115 |   return (number & (number - 1)) == 0; | 
|---|
| 1116 | } | 
|---|
| 1117 | */ | 
|---|
| 1118 |  | 
|---|
| 1119 | /** | 
|---|
| 1120 |    \brief reads in a png-file | 
|---|
| 1121 |    \param pngName the Name of the Image to load | 
|---|
| 1122 |    \param texture a reference to the Texture to write the image to | 
|---|
| 1123 | */ | 
|---|
| 1124 | bool Material::loadPNG(const char* pngName, GLuint* texture) | 
|---|
| 1125 | { | 
|---|
| 1126 | #ifdef HAVE_PNG_H | 
|---|
| 1127 |   Image* pImage = new Image; | 
|---|
| 1128 |  | 
|---|
| 1129 |   FILE *PNG_file = fopen(pngName, "rb"); | 
|---|
| 1130 |   if (PNG_file == NULL) | 
|---|
| 1131 |     { | 
|---|
| 1132 |       return 0; | 
|---|
| 1133 |     } | 
|---|
| 1134 |    | 
|---|
| 1135 |   GLubyte PNG_header[8]; | 
|---|
| 1136 |    | 
|---|
| 1137 |   fread(PNG_header, 1, 8, PNG_file); | 
|---|
| 1138 |   if (png_sig_cmp(PNG_header, 0, 8) != 0) | 
|---|
| 1139 |     { | 
|---|
| 1140 |       if (verbose >=2) | 
|---|
| 1141 |         printf ("Not Recognized as a pngFile\n"); | 
|---|
| 1142 |       fclose (PNG_file); | 
|---|
| 1143 |       return 0; | 
|---|
| 1144 |     } | 
|---|
| 1145 |    | 
|---|
| 1146 |   png_structp PNG_reader = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | 
|---|
| 1147 |   if (PNG_reader == NULL) | 
|---|
| 1148 |     { | 
|---|
| 1149 |       fclose(PNG_file); | 
|---|
| 1150 |       return 0; | 
|---|
| 1151 |     } | 
|---|
| 1152 |    | 
|---|
| 1153 |   png_infop PNG_info = png_create_info_struct(PNG_reader); | 
|---|
| 1154 |   if (PNG_info == NULL) | 
|---|
| 1155 |     { | 
|---|
| 1156 |       png_destroy_read_struct(&PNG_reader, NULL, NULL); | 
|---|
| 1157 |       fclose(PNG_file); | 
|---|
| 1158 |       return 0; | 
|---|
| 1159 |     } | 
|---|
| 1160 |    | 
|---|
| 1161 |   png_infop PNG_end_info = png_create_info_struct(PNG_reader); | 
|---|
| 1162 |   if (PNG_end_info == NULL) | 
|---|
| 1163 |     { | 
|---|
| 1164 |       png_destroy_read_struct(&PNG_reader, &PNG_info, NULL); | 
|---|
| 1165 |       fclose(PNG_file); | 
|---|
| 1166 |       return 0; | 
|---|
| 1167 |     } | 
|---|
| 1168 |    | 
|---|
| 1169 |   if (setjmp(png_jmpbuf(PNG_reader))) | 
|---|
| 1170 |     { | 
|---|
| 1171 |       png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info); | 
|---|
| 1172 |       fclose(PNG_file); | 
|---|
| 1173 |       return (0); | 
|---|
| 1174 |     } | 
|---|
| 1175 |    | 
|---|
| 1176 |   png_init_io(PNG_reader, PNG_file); | 
|---|
| 1177 |   png_set_sig_bytes(PNG_reader, 8); | 
|---|
| 1178 |    | 
|---|
| 1179 |   png_read_info(PNG_reader, PNG_info); | 
|---|
| 1180 |    | 
|---|
| 1181 |   pImage->width = png_get_image_width(PNG_reader, PNG_info); | 
|---|
| 1182 |   pImage->height = png_get_image_height(PNG_reader, PNG_info); | 
|---|
| 1183 |    | 
|---|
| 1184 |   png_uint_32 bit_depth, color_type; | 
|---|
| 1185 |   bit_depth = png_get_bit_depth(PNG_reader, PNG_info); | 
|---|
| 1186 |   color_type = png_get_color_type(PNG_reader, PNG_info); | 
|---|
| 1187 |    | 
|---|
| 1188 |   if (color_type == PNG_COLOR_TYPE_PALETTE) | 
|---|
| 1189 |     { | 
|---|
| 1190 |       png_set_palette_to_rgb(PNG_reader); | 
|---|
| 1191 |     } | 
|---|
| 1192 |    | 
|---|
| 1193 |   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) | 
|---|
| 1194 |     { | 
|---|
| 1195 |       png_set_gray_1_2_4_to_8(PNG_reader); | 
|---|
| 1196 |     } | 
|---|
| 1197 |    | 
|---|
| 1198 |   if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | 
|---|
| 1199 |     { | 
|---|
| 1200 |       png_set_gray_to_rgb(PNG_reader); | 
|---|
| 1201 |     } | 
|---|
| 1202 |    | 
|---|
| 1203 |   if (png_get_valid(PNG_reader, PNG_info, PNG_INFO_tRNS)) | 
|---|
| 1204 |     { | 
|---|
| 1205 |       png_set_tRNS_to_alpha(PNG_reader); | 
|---|
| 1206 |     } | 
|---|
| 1207 |   else | 
|---|
| 1208 |     { | 
|---|
| 1209 |       png_set_filler(PNG_reader, 0xff, PNG_FILLER_AFTER); | 
|---|
| 1210 |     } | 
|---|
| 1211 |    | 
|---|
| 1212 |   if (bit_depth == 16) | 
|---|
| 1213 |     { | 
|---|
| 1214 |       png_set_strip_16(PNG_reader); | 
|---|
| 1215 |     } | 
|---|
| 1216 |    | 
|---|
| 1217 |   png_read_update_info(PNG_reader, PNG_info); | 
|---|
| 1218 |    | 
|---|
| 1219 |   pImage->data = (png_byte*)malloc(4 * pImage->width * pImage->height); | 
|---|
| 1220 |   png_byte** PNG_rows = (png_byte**)malloc(pImage->height * sizeof(png_byte*)); | 
|---|
| 1221 |    | 
|---|
| 1222 |   unsigned int row; | 
|---|
| 1223 |   for (row = 0; row < pImage->height; ++row) | 
|---|
| 1224 |     { | 
|---|
| 1225 |       PNG_rows[pImage->height - 1 - row] = pImage->data + (row * 4 * pImage->width); | 
|---|
| 1226 |     } | 
|---|
| 1227 |    | 
|---|
| 1228 |   png_read_image(PNG_reader, PNG_rows); | 
|---|
| 1229 |    | 
|---|
| 1230 |   free(PNG_rows); | 
|---|
| 1231 |    | 
|---|
| 1232 |   png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info); | 
|---|
| 1233 |   fclose(PNG_file); | 
|---|
| 1234 |    | 
|---|
| 1235 |   /*  if (!ST_is_power_of_two(pImage->width) || !ST_is_power_of_two(pImage->height)) | 
|---|
| 1236 |     { | 
|---|
| 1237 |       free(pImage->data); | 
|---|
| 1238 |       return 0; | 
|---|
| 1239 |     } | 
|---|
| 1240 |   */ | 
|---|
| 1241 |   loadTexToGL (pImage, texture);   | 
|---|
| 1242 |    | 
|---|
| 1243 |   free(pImage->data); | 
|---|
| 1244 |    | 
|---|
| 1245 |   return true; | 
|---|
| 1246 | #else /* HAVE_PNG_H */ | 
|---|
| 1247 |   if (verbose >=1) | 
|---|
| 1248 |     printf ("sorry, but you did not compile with png-support.\nEither install SDL_image or libpng, and recompile to see the image\n"); | 
|---|
| 1249 |   return false; | 
|---|
| 1250 | #endif /* HAVE_PNG_H */ | 
|---|
| 1251 |  | 
|---|
| 1252 | } | 
|---|
| 1253 |  | 
|---|
| 1254 | #endif /* HAVE_SDL_SDL_IMAGE_H */ | 
|---|