Changeset 3185 in orxonox.OLD for orxonox/trunk/src/material.cc
- Timestamp:
- Dec 15, 2004, 6:24:28 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
orxonox/trunk/src/material.cc
r2853 r3185 12 12 main-programmer: Benjamin Grauer 13 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. 14 20 */ 15 21 16 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 } 17 88 18 89 /** … … 44 115 { 45 116 if (verbose >= 2) 46 printf ("delete Material %s\n", name); 47 if (nextMat != NULL) 117 printf ("delete Material %s.\n", name); 118 if (name) 119 delete []name; 120 if (diffuseTextureSet) 121 glDeleteTextures (1, &diffuseTexture); 122 if (nextMat) 48 123 delete nextMat; 49 124 } … … 57 132 { 58 133 if (verbose >=2) 59 printf ("adding Material %s\n", mtlName); 60 Material* newMat = new Material(mtlName); 61 Material* tmpMat = this; 134 printf ("adding Material %s.\n", mtlName); 135 Material* tmpMat = this; 62 136 while (tmpMat->nextMat != NULL) 63 137 { 64 138 tmpMat = tmpMat->nextMat; 65 139 } 66 tmpMat->nextMat = newMat;67 return newMat;140 tmpMat->nextMat = new Material(mtlName); 141 return tmpMat->nextMat; 68 142 69 143 } … … 75 149 { 76 150 if (verbose >= 3) 77 printf ("initializing new Material \n");151 printf ("initializing new Material.\n"); 78 152 nextMat = NULL; 79 153 name =""; 80 154 setIllum(1); 81 155 setDiffuse(0,0,0); 82 156 setAmbient(0,0,0); 83 setSpecular( 0,0,0);157 setSpecular(.5,.5,.5); 84 158 setShininess(2.0); 85 159 setTransparency(0.0); 86 87 } 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 88 232 89 233 /** … … 93 237 void Material::setName (char* mtlName) 94 238 { 239 name = new char [strlen(mtlName)+1]; 240 strcpy(name, mtlName); 95 241 if (verbose >= 3) 96 printf("setting Material Name to %s ", mtlName);97 strcpy(name, mtlName); 242 printf("setting Material Name to %s.\n", name); 243 98 244 // printf ("adding new Material: %s, %p\n", this->getName(), this); 99 245 … … 114 260 { 115 261 if (verbose >= 3) 116 printf("setting illumModel of Material %s to %i ", name, illum);262 printf("setting illumModel of Material %s to %i\n", name, illum); 117 263 illumModel = illum; 118 264 // printf ("setting illumModel to: %i\n", illumModel); … … 135 281 { 136 282 if (verbose >= 3) 137 printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f \n", name, r, g, b);283 printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b); 138 284 diffuse[0] = r; 139 285 diffuse[1] = g; … … 148 294 void Material::setDiffuse (char* rgb) 149 295 { 150 char r[20],g[20],b[20];151 sscanf (rgb, "% s %s %s", r, g,b);152 setDiffuse ( atof(r), atof(g), atof(b));296 float r,g,b; 297 sscanf (rgb, "%f %f %f", &r, &g, &b); 298 setDiffuse (r, g, b); 153 299 } 154 300 … … 162 308 { 163 309 if (verbose >=3) 164 printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f \n", name, r, g, b);310 printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b); 165 311 ambient[0] = r; 166 312 ambient[1] = g; … … 174 320 void Material::setAmbient (char* rgb) 175 321 { 176 char r[20],g[20],b[20];177 sscanf (rgb, "% s %s %s", r, g,b);178 setAmbient ( atof(r), atof(g), atof(b));322 float r,g,b; 323 sscanf (rgb, "%f %f %f", &r, &g, &b); 324 setAmbient (r, g, b); 179 325 } 180 326 … … 188 334 { 189 335 if (verbose >= 3) 190 printf ("setting Specular Color of Material %s to r=%f g=%f b=%f \n", name, r, g, b);336 printf ("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b); 191 337 specular[0] = r; 192 338 specular[1] = g; … … 200 346 void Material::setSpecular (char* rgb) 201 347 { 202 char r[20],g[20],b[20];203 sscanf (rgb, "% s %s %s", r, g,b);204 setSpecular ( atof(r), atof(g), atof(b));348 float r,g,b; 349 sscanf (rgb, "%f %f %f", &r, &g, &b); 350 setSpecular (r, g, b); 205 351 } 206 352 … … 229 375 { 230 376 if (verbose >= 3) 231 printf ("setting Transparency of Material %s to %f \n", name, trans);377 printf ("setting Transparency of Material %s to %f.\n", name, trans); 232 378 transparency = trans; 233 379 } … … 238 384 void Material::setTransparency (char* trans) 239 385 { 240 char tr[20]; 241 sscanf (trans, "%s", tr); 242 setTransparency (atof(tr)); 243 } 244 245 /** 246 \brief Search for a Material called mtlName 247 \param mtlName the Name of the Material to search for 248 \returns Material named mtlName if it is found. NULL otherwise. 249 */ 250 Material* Material::search (char* mtlName) 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) 251 479 { 252 480 if (verbose >=3) 253 printf ("Searching for material %s", mtlName); 254 Material* searcher = this; 255 while (searcher != NULL) 256 { 257 if (verbose >= 3) 258 printf ("."); 259 if (!strcmp (searcher->getName(), mtlName)) 260 { 261 if (verbose >= 3) 262 printf ("found.\n"); 263 return searcher; 264 } 265 searcher = searcher->nextMat; 266 } 267 return NULL; 268 } 269 270 /** 271 \brief sets the material with which the following Faces will be painted 272 */ 273 bool Material::select (void) 274 { 275 // setting diffuse color 276 // glColor3f (diffuse[0], diffuse[1], diffuse[2]); 277 glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); 278 279 // setting ambient color 280 glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); 281 282 // setting up Sprecular 283 glMaterialfv(GL_FRONT, GL_SPECULAR, specular); 284 285 // setting up Shininess 286 glMaterialf(GL_FRONT, GL_SHININESS, shininess); 287 288 // setting illumination Model 289 if (illumModel == 1) 290 glShadeModel(GL_FLAT); 291 else if (illumModel >= 2) 292 glShadeModel(GL_SMOOTH); 293 } 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 */
Note: See TracChangeset
for help on using the changeset viewer.