- Timestamp:
- Dec 15, 2004, 6:24:28 PM (20 years ago)
- Location:
- orxonox/trunk/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
orxonox/trunk/src/array.cc
r2866 r3185 33 33 printf("deleting array\n"); 34 34 Entry* walker = firstEntry; 35 Entry* last;36 while (walker != NULL)35 Entry* previous; 36 while (walker) 37 37 { 38 last= walker;38 previous = walker; 39 39 walker = walker->next; 40 delete last;40 delete previous; 41 41 } 42 42 if (finalized) 43 delete [] 43 delete []array; 44 44 } 45 45 … … 67 67 { 68 68 if (verbose >= 3) 69 printf ("Finalizing array. \n");69 printf ("Finalizing array. Length: %i\n", entryCount); 70 70 if ((array = (GLfloat*)malloc( entryCount* sizeof(GLfloat))) == NULL) 71 71 // if ((array = new GLfloat [entryCount]) == NULL) -
orxonox/trunk/src/array.h
r2853 r3185 11 11 extern int verbose; //!< will be obsolete soon 12 12 13 #include <GL/gl.h> 14 #include <GL/glu.h> 13 #include "stdincl.h" 15 14 #include <fstream> 16 15 -
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 */ -
orxonox/trunk/src/material.h
r2853 r3185 9 9 extern int verbose; //!< will be obsolete soon. 10 10 11 #include <GL/gl.h> 12 #include <GL/glu.h> 13 #include <stdlib.h> 14 #include <fstream> 11 #include "stdincl.h" 12 13 #if HAVE_CONFIG_H 14 #include <config.h> 15 #endif /* HAVE_CONFIG_H */ 16 17 #ifdef HAVE_SDL_SDL_IMAGE_H 18 #include <SDL/SDL_image.h> 19 #else 20 // IMAGE LIBS // 21 #ifdef HAVE_JPEGLIB_H 22 extern "C"{ // This has to be done, because not a c++ lib 23 #include <jpeglib.h> 24 } 25 #endif /* HAVE_JPEGLIB_H */ 26 #ifdef HAVE_PNG_H 27 #include <png.h> 28 #endif /* HAVE_PNG_H */ 29 #endif /* HAVE_SDL_SDL_IMAGE_H */ 30 31 class PathList 32 { 33 public: 34 PathList(); 35 PathList(char* pName); 36 37 ~PathList(); 38 void addPath (char* pName); 39 char* pathName; 40 PathList* next; 41 }; 42 15 43 16 44 //! Class to handle Materials. … … 21 49 Material (char* mtlName); 22 50 Material* addMaterial(char* mtlName); 51 ~Material (); 52 void init(void); 23 53 24 void init(void); 25 ~Material (); 26 54 Material* search (char* mtlName); 55 bool select (void); 27 56 28 57 void setName (char* mtlName); … … 41 70 void setTransparency (char* trans); 42 71 43 Material* search (char* mtlName);44 72 45 bool select (void); 46 47 Material* nextMat; //!< pointer to the Next Material of the List. NULL if no next exists. 73 74 void addTexturePath(char* pathName); 75 char* searchTextureInPaths(char* texName) const; 76 // MAPPING // 77 void setDiffuseMap(char* dMap); 78 void setAmbientMap(char* aMap); 79 void setSpecularMap(char* sMap); 80 void setBump(char* bump); 48 81 49 82 private: 50 char name [50]; 83 struct Image 84 { 85 int rowSpan; 86 GLuint width; 87 GLuint height; 88 GLuint bpp; 89 GLuint type; 90 GLubyte *data; 91 }; 92 93 94 char* name; 51 95 int illumModel; 52 96 float diffuse [4]; … … 56 100 float transparency; 57 101 102 static PathList* pathList; 103 104 GLuint diffuseTexture; 105 GLuint ambientTexture; 106 GLuint specularTexture; 107 108 bool diffuseTextureSet; 109 bool ambientTextureSet; 110 bool specularTextureSet; 111 112 Material* nextMat; //!< pointer to the Next Material of the List. NULL if no next exists. 113 114 // TEXTURING 115 bool loadTexToGL (Image* pImage, GLuint* texture); 116 117 bool loadImage(char* imageName, GLuint* texture); 118 #ifndef HAVE_SDL_SDL_IMAGE_H 119 120 bool loadBMP (char* bmpName, GLuint* texture); 121 122 bool loadJPG (char* jpgName, GLuint* texture); 123 124 /// TGA /// 125 126 bool loadTGA(const char * tgaName, GLuint* texture); 127 bool loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture); 128 bool loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture); 129 130 bool loadPNG(const char* pngName, GLuint* texture); 131 #endif 58 132 }; 59 133 #endif -
orxonox/trunk/src/object.cc
r2935 r3185 17 17 18 18 #include "object.h" 19 using namespace std; 19 20 20 21 /** … … 29 30 BoxObject(); 30 31 31 finalize(); 32 importToGL (); 33 34 cleanup(); 32 35 } 33 36 … … 42 45 importFile (fileName); 43 46 44 finalize(); 47 importToGL (); 48 49 cleanup(); 45 50 } 46 51 … … 50 55 \param scaling The factor that the object will be scaled with. 51 56 */ 52 53 57 Object::Object(char* fileName, float scaling) 54 58 { … … 58 62 importFile (fileName); 59 63 60 finalize(); 64 importToGL (); 65 66 cleanup(); 61 67 } 62 68 … … 67 73 { 68 74 if (verbose >= 2) 69 printf ("Deleting display List .\n");75 printf ("Deleting display Lists.\n"); 70 76 Group* walker = firstGroup; 71 77 while (walker != NULL) 72 78 { 73 79 glDeleteLists (walker->listNumber, 1); 74 Group* lastWalker = walker; 75 walker = walker->nextGroup; 76 delete lastWalker; 77 } 78 } 79 80 /** 80 Group* delWalker = walker; 81 walker = walker->next; 82 delete delWalker; 83 } 84 85 if (objPath) 86 delete []objPath; 87 if (objFileName) 88 delete []objFileName; 89 if (mtlFileName) 90 delete []mtlFileName; 91 92 if (verbose >=2) 93 printf("Deleting Materials.\n"); 94 if (material) 95 delete material; 96 } 97 98 99 /** 100 \brief Draws the Objects of all Groups. 101 It does this by just calling the Lists that must have been created earlier. 102 */ 103 void Object::draw (void) const 104 { 105 if (verbose >=2) 106 printf("drawing the 3D-Objects\n"); 107 Group* walker = firstGroup; 108 while (walker != NULL) 109 { 110 if (verbose >= 3) 111 printf ("Drawing object %s\n", walker->name); 112 glCallList (walker->listNumber); 113 walker = walker->next; 114 } 115 } 116 117 /** 118 \brief Draws the Object number groupNumber 119 It does this by just calling the List that must have been created earlier. 120 \param groupNumber The number of the group that will be displayed. 121 */ 122 void Object::draw (int groupNumber) const 123 { 124 if (groupNumber >= groupCount) 125 { 126 if (verbose>=1) 127 printf ("You requested object number %i, but this File only contains of %i Objects.\n", groupNumber-1, groupCount); 128 return; 129 } 130 if (verbose >=2) 131 printf("drawing the requested 3D-Objects if found.\n"); 132 Group* walker = firstGroup; 133 int counter = 0; 134 while (walker != NULL) 135 { 136 if (counter == groupNumber) 137 { 138 if (verbose >= 2) 139 printf ("Drawing object number %i named %s\n", counter, walker->name); 140 glCallList (walker->listNumber); 141 return; 142 } 143 ++counter; 144 walker = walker->next; 145 } 146 if (verbose >= 1) 147 printf("Object number %i in %s not Found.\n", groupNumber, objFileName); 148 return; 149 150 } 151 152 /** 153 \brief Draws the Object with a specific groupName 154 It does this by just calling the List that must have been created earlier. 155 \param groupName The name of the group that will be displayed. 156 */ 157 void Object::draw (char* groupName) const 158 { 159 if (verbose >=2) 160 printf("drawing the requested 3D-Objects if found.\n"); 161 Group* walker = firstGroup; 162 while (walker != NULL) 163 { 164 if (!strcmp(walker->name, groupName)) 165 { 166 if (verbose >= 2) 167 printf ("Drawing object %s\n", walker->name); 168 glCallList (walker->listNumber); 169 return; 170 } 171 walker = walker->next; 172 } 173 if (verbose >= 2) 174 printf("Object Named %s in %s not Found.\n", groupName, objFileName); 175 return; 176 } 177 178 /** 179 \returns Count of the Objects in this File 180 */ 181 int Object::getGroupCount (void) const 182 { 183 return groupCount; 184 } 185 186 /** 81 187 \brief initializes the Object 82 188 This Function initializes all the needed arrays, Lists and clientStates … … 92 198 groupCount = 0; 93 199 94 initGroup (currentGroup); 95 mtlFileName = ""; 200 initGroup (firstGroup); 201 objPath = NULL; 202 objFileName = NULL; 203 mtlFileName = NULL; 96 204 scaleFactor = 1; 97 205 material = new Material(); 98 206 99 glEnableClientState (GL_VERTEX_ARRAY); 100 // glEnableClientState (GL_NORMAL_ARRAY); 101 // glEnableClientState (GL_TEXTURE_COORD_ARRAY); 102 207 vertices = new Array(); 208 vTexture = new Array(); 209 normals = new Array(); 103 210 104 211 return true; 105 }106 107 /**108 \brief Imports a obj file and handles the the relative location109 \param fileName The file to import110 */111 bool Object::importFile (char* fileName)112 {113 if (verbose >=3)114 printf("preparing to read in file: %s\n", fileName);115 objFileName = fileName;116 this->readFromObjFile (objFileName);117 return true;118 }119 120 /**121 \brief finalizes an Object.122 This funcion is needed, to close the glList and all the other lists.123 */124 bool Object::finalize(void)125 {126 // if (verbose >=3)127 printf("finalizing the 3D-Object\n");128 finalizeGroup (currentGroup);129 if (material != NULL)130 delete material;131 return true;132 }133 134 /**135 \brief Draws the Objects of all Groups.136 It does this by just calling the Lists that must have been created earlier.137 */138 void Object::draw (void)139 {140 if (verbose >=2)141 printf("drawing the 3D-Objects\n");142 Group* walker = firstGroup;143 while (walker != NULL)144 {145 if (verbose >= 3)146 printf ("Drawing object %s\n", walker->name);147 glCallList (walker->listNumber);148 walker = walker->nextGroup;149 }150 }151 152 /**153 \brief Draws the Object number groupNumber154 It does this by just calling the List that must have been created earlier.155 \param groupNumber The number of the group that will be displayed.156 */157 void Object::draw (int groupNumber)158 {159 if (groupNumber >= groupCount)160 {161 if (verbose>=2)162 printf ("You requested object number %i, but this File only contains of %i Objects.\n", groupNumber-1, groupCount);163 return;164 }165 if (verbose >=2)166 printf("drawing the requested 3D-Objects if found.\n");167 Group* walker = firstGroup;168 int counter = 0;169 while (walker != NULL)170 {171 if (counter == groupNumber)172 {173 if (verbose >= 2)174 printf ("Drawing object number %s named %s\n", counter, walker->name);175 glCallList (walker->listNumber);176 return;177 }178 ++counter;179 walker = walker->nextGroup;180 }181 if (verbose >= 2)182 printf("Object number %i in %s not Found.\n", groupNumber, objFileName);183 return;184 185 }186 187 /**188 \brief Draws the Object with a specific groupname189 It does this by just calling the List that must have been created earlier.190 \param groupName The name of the group that will be displayed.191 */192 void Object::draw (char* groupName)193 {194 if (verbose >=2)195 printf("drawing the requested 3D-Objects if found.\n");196 Group* walker = firstGroup;197 while (walker != NULL)198 {199 if (!strcmp(walker->name, groupName))200 {201 if (verbose >= 2)202 printf ("Drawing object %s\n", walker->name);203 glCallList (walker->listNumber);204 return;205 }206 walker = walker->nextGroup;207 }208 if (verbose >= 2)209 printf("Object Named %s in %s not Found.\n", groupName, objFileName);210 return;211 }212 213 /**214 \returns Count of the Objects in this File215 */216 int Object::getGroupCount (void)217 {218 return groupCount;219 212 } 220 213 … … 228 221 group->name = ""; 229 222 group->faceMode = -1; 230 group->faceCount =0; 231 if ((group->listNumber = glGenLists(1)) == 0 ) 232 { 233 printf ("list could not be created for this Object\n"); 234 return false; 235 } 223 group->faceCount = 0; 224 group->next = NULL; 225 226 group->firstFace = new Face; 227 initFace (group->firstFace); 228 group->currentFace = group->firstFace; 229 } 230 231 /** 232 \brief initializes a new Face. (sets default Values) 233 */ 234 bool Object::initFace (Face* face) 235 { 236 face->vertexCount = 0; 237 238 face->firstElem = NULL; 236 239 237 if (groupCount == 0) 238 { 239 group->firstVertex = 0; 240 group->firstNormal = 0; 241 group->firstNormal = 0; 242 } 243 else 244 { 245 group->firstVertex = currentGroup->firstVertex + currentGroup->vertices->getCount()/3; 246 group->firstNormal = currentGroup->firstNormal + currentGroup->normals->getCount()/3; 247 group->firstVertexTexture = currentGroup->firstVertexTexture + currentGroup->vTexture->getCount()/2; 248 } 240 face->materialString = NULL; 241 242 face->next = NULL; 243 244 return true; 245 } 246 247 /** 248 \brief finalizes an Object. 249 This funcion is needed, to delete all the Lists, and arrays that are no more needed because they are already imported into openGL. This will be applied at the end of the importing Process. 250 */ 251 bool Object::cleanup(void) 252 { 249 253 if (verbose >=2) 250 printf ("Creating new Arrays, with starting points v:%i, vt:%i, vn:%i .\n", group->firstVertex, group->firstVertexTexture, group->firstNormal); 251 group->vertices = new Array(); 252 group->normals = new Array(); 253 group->vTexture = new Array(); 254 255 glNewList (group->listNumber, GL_COMPILE); 256 } 257 258 /** 259 \brief finalizes a Group. 260 \param group the group to finalize. 261 */ 262 bool Object::finalizeGroup(Group* group) 263 { 254 printf("cleaning up the 3D-Object to save Memory.\n"); 255 256 if (vertices != NULL) 257 delete vertices; 258 if (vTexture != NULL) 259 delete vTexture; 260 if (normals != NULL) 261 delete normals; 262 263 cleanupGroup(firstGroup); 264 return true; 265 } 266 267 /** 268 \brief Cleans up all groups starting from group. 269 \param group the first Group to clean 270 */ 271 bool Object::cleanupGroup (Group* group) 272 { 273 if (verbose>=4) 274 printf ("Cleaning up group\n"); 275 if (group->firstFace != NULL) 276 { 277 cleanupFace (group->firstFace); 278 delete group->firstFace; 279 } 280 281 if (group->next !=NULL) 282 cleanupGroup (group->next); 283 return true; 284 } 285 286 /** 287 \brief Cleans up all Faces starting from face. 288 \param face the first face to clean 289 */ 290 bool Object::cleanupFace (Face* face) 291 { 292 if (verbose>=4) 293 printf ("Cleaning up Face\n"); 294 295 if (face->materialString != NULL) 296 delete []face->materialString; 297 if (face->firstElem != NULL) 298 { 299 cleanupFaceElement(face->firstElem); 300 delete face->firstElem; 301 } 302 303 if (face->next != NULL) 304 { 305 cleanupFace (face->next); 306 delete face->next; 307 } 308 309 } 310 311 312 /** 313 \brief Cleans up all FaceElements starting from faceElem. 314 \param faceElem the first FaceElement to clean. 315 */ 316 bool Object::cleanupFaceElement(FaceElement* faceElem) 317 { 318 if (faceElem->next != NULL) 319 { 320 cleanupFaceElement (faceElem->next); 321 delete faceElem->next; 322 } 323 } 324 325 /** 326 \brief Imports a obj file and handles the the relative location 327 \param fileName The file to import 328 */ 329 bool Object::importFile (char* fileName) 330 { 331 if (verbose >=3) 332 printf("preparing to read in file: %s\n", fileName); 333 334 335 #ifdef __WIN32__ 336 // win32 path reading 337 char pathSplitter= '\\'; 338 #else /* __WIN32__ */ 339 // unix path reading 340 char pathSplitter='/'; 341 #endif /* __WIN32__ */ 342 char* tmpName = fileName; 343 if (tmpName[0] == pathSplitter) 344 tmpName++; 345 char* name = tmpName; 346 while (( tmpName = strchr (tmpName+1, pathSplitter))) 347 { 348 name = tmpName+1; 349 } 350 objPath = new char[name-fileName]; 351 strncpy(objPath, fileName, name-fileName); 352 objPath[name-fileName] = '\0'; 264 353 if (verbose >=2) 265 printf ("Finalize group %s.\n", group->name); 266 glEnd(); 267 glEndList(); 268 } 269 /** 270 \brief deletes the Arrays of the Group to save space. 271 \param group the group to delete the arrays from. 272 */ 273 bool Object::cleanupGroup(Group* group) 274 { 275 if (verbose >=2) 276 printf ("cleaning up group %s.\n", group->name); 354 if (strlen(objPath)> 0) 355 { 356 printf("Resolved file %s to folder: %s.\n", name, objPath); 357 } 358 else 359 printf("Resolved file %s.\n", name); 277 360 278 delete group->vertices; 279 delete group->normals; 280 delete group->vTexture; 361 if (material) 362 material->addTexturePath(objPath); 363 objFileName = new char[strlen(name)+1]; 364 strcpy (objFileName, name); 365 this->readFromObjFile (); 366 return true; 281 367 } 282 368 … … 284 370 \brief Reads in the .obj File and sets all the Values. 285 371 This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks 286 \param fileName the File that will be parsed (.obj-file) 287 */ 288 bool Object::readFromObjFile (char* fileName) 289 { 290 OBJ_FILE = new ifstream(fileName); 291 if (!OBJ_FILE->is_open()) 372 */ 373 bool Object::readFromObjFile (void) 374 { 375 char* fileName = new char [strlen(objPath)+strlen(objFileName)+1]; 376 if (objFileName != NULL && !strcmp(objFileName, "")) 377 return false; 378 strcpy(fileName, objPath); 379 strcat(fileName, objFileName); 380 381 ifstream* OBJ_FILE = new ifstream(fileName); 382 if (OBJ_FILE->fail()) 292 383 { 293 384 if (verbose >=1) 294 385 printf ("unable to open .OBJ file: %s\n Loading Box Object instead.\n", fileName); 295 386 BoxObject(); 387 delete []fileName; 296 388 return false; 297 389 } 298 objFileName = fileName; 390 if (verbose >=2) 391 printf ("Reading from opened file %s\n", fileName); 299 392 char Buffer[10000]; 300 393 while(!OBJ_FILE->eof()) … … 317 410 } 318 411 319 else if (!strncmp(Buffer, "mtllib ", 6))412 else if (!strncmp(Buffer, "mtllib ", 7)) 320 413 { 321 414 readMtlLib (Buffer+7); 322 415 } 323 416 324 else if (!strncmp(Buffer, "usemtl ", 6))417 else if (!strncmp(Buffer, "usemtl ", 7)) 325 418 { 326 419 readUseMtl (Buffer+7); … … 328 421 329 422 // case VertexNormal 330 else if (!strncmp(Buffer, "vn ", 2))423 else if (!strncmp(Buffer, "vn ", 3)) 331 424 { 332 425 readVertexNormal(Buffer+3); … … 334 427 335 428 // case VertexTextureCoordinate 336 else if (!strncmp(Buffer, "vt ", 2))429 else if (!strncmp(Buffer, "vt ", 3)) 337 430 { 338 431 readVertexTexture(Buffer+3); 339 432 } 340 433 // case group 341 else if (!strncmp(Buffer, "g ", 1))434 else if (!strncmp(Buffer, "g ", 2)) 342 435 { 343 436 readGroup (Buffer+2); 344 437 } 438 else if (!strncmp(Buffer, "s ", 2)) 439 { 440 if (verbose >= 2) 441 printf("smoothing groups not supportet yet. line: %s\n", Buffer); 442 } 345 443 } 346 444 OBJ_FILE->close(); 445 delete []fileName; 347 446 return true; 447 448 } 449 450 /** 451 \brief parses a group String 452 This function initializes a new Group. 453 With it you should be able to import .obj-files with more than one Objects inside. 454 \param groupString the new Group to create 455 */ 456 bool Object::readGroup (char* groupString) 457 { 458 if (verbose >=3) 459 printf ("Read Group: %s.\n", groupString); 460 if (groupCount != 0 && currentGroup->faceCount>0) 461 { 462 // finalizeGroup(currentGroup); 463 currentGroup = currentGroup->next = new Group; 464 initGroup(currentGroup); 465 } 466 // setting the group name if not default. 467 if (strcmp(groupString, "default")) 468 { 469 currentGroup->name = new char [strlen(groupString)+1]; 470 strcpy(currentGroup->name, groupString); 471 } 472 ++groupCount; 348 473 349 474 } … … 356 481 bool Object::readVertex (char* vertexString) 357 482 { 358 readingVertices = true; 359 char subbuffer1[20]; 360 char subbuffer2[20]; 361 char subbuffer3[20]; 362 sscanf (vertexString, "%s %s %s", subbuffer1, subbuffer2, subbuffer3); 483 float subbuffer1; 484 float subbuffer2; 485 float subbuffer3; 486 sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3); 363 487 if (verbose >= 3) 364 printf ("reading in a vertex: % s %s %s\n", subbuffer1, subbuffer2,subbuffer3);365 currentGroup->vertices->addEntry(atof(subbuffer1)*scaleFactor, atof(subbuffer2)*scaleFactor, atof(subbuffer3)*scaleFactor);488 printf ("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3); 489 vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor); 366 490 return true; 367 491 } … … 375 499 bool Object::readFace (char* faceString) 376 500 { 377 // finalize the Arrays; 378 if (readingVertices == true) 379 { 380 currentGroup->vertices->finalizeArray(); 381 // glVertexPointer(3, GL_FLOAT, 0, currentGroup->vertices->getArray()); 382 currentGroup->normals->finalizeArray(); 383 // glNormalPointer(GL_FLOAT, 0, currentGroup->normals->getArray()); 384 currentGroup->vTexture->finalizeArray(); 385 } 386 387 readingVertices = false; 388 currentGroup->faceCount++; 389 390 int elemCount = 0; 391 392 FaceElement* firstElem = new FaceElement; 393 FaceElement* tmpElem = firstElem; 394 395 501 if (currentGroup->faceCount >0) 502 currentGroup->currentFace = currentGroup->currentFace->next = new Face; 503 initFace (currentGroup->currentFace); 504 505 FaceElement* tmpElem = currentGroup->currentFace->firstElem = new FaceElement; 506 tmpElem->next = NULL; 396 507 while(strcmp (faceString, "\0")) 397 508 { 398 if ( elemCount>0)509 if (currentGroup->currentFace->vertexCount>0) 399 510 tmpElem = tmpElem->next = new FaceElement; 400 511 tmpElem->next = NULL; 401 512 402 403 sscanf (faceString, "%s", tmpElem->value); 404 faceString += strlen(tmpElem->value); 513 char tmpValue [50]; 514 int tmpLen; 515 char* vertex = NULL; 516 char* texture = NULL; 517 char* normal = NULL; 518 519 sscanf (faceString, "%s", tmpValue); 520 tmpLen = strlen(tmpValue); 521 vertex = tmpValue; 522 523 if ((texture = strstr (vertex, "/")) != NULL) 524 { 525 texture[0] = '\0'; 526 texture ++; 527 528 if ((normal = strstr (texture, "/")) !=NULL) 529 { 530 normal[0] = '\0'; 531 normal ++; 532 } 533 } 534 if (vertex) 535 tmpElem->vertexNumber = atoi(vertex)-1; 536 else 537 tmpElem->vertexNumber = -1; 538 if (texture) 539 tmpElem->texCoordNumber = atoi(texture)-1; 540 else 541 tmpElem->texCoordNumber = -1; 542 if (normal) 543 tmpElem->normalNumber = atoi(normal)-1; 544 else 545 tmpElem->normalNumber = -1; 546 547 faceString += tmpLen; 405 548 if (strcmp (faceString, "\0")) 406 549 faceString++; 407 elemCount++; 408 409 410 } 550 currentGroup->currentFace->vertexCount++; 551 } 552 553 currentGroup->faceCount += currentGroup->currentFace->vertexCount -2; 554 } 555 556 /** 557 \brief parses a vertexNormal-String 558 If a vertexNormal line is found this function will inject it into the vertexNormal-Array 559 \param normalString The String that will be parsed. 560 */ 561 bool Object::readVertexNormal (char* normalString) 562 { 563 float subbuffer1; 564 float subbuffer2; 565 float subbuffer3; 566 sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3); 567 if (verbose >=3 ) 568 printf("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3); 569 normals->addEntry(subbuffer1, subbuffer2, subbuffer3); 570 return true; 571 } 572 573 /** 574 \brief parses a vertexTextureCoordinate-String 575 If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array 576 \param vTextureString The String that will be parsed. 577 */ 578 bool Object::readVertexTexture (char* vTextureString) 579 { 580 float subbuffer1; 581 float subbuffer2; 582 sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2); 583 if (verbose >=3 ) 584 printf("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2); 585 vTexture->addEntry(subbuffer1); 586 vTexture->addEntry(subbuffer2); 587 return true; 588 } 589 590 /** 591 \brief Function to read in a mtl File. 592 this Function parses all Lines of an mtl File 593 \param mtlFile The .mtl file to read 594 */ 595 bool Object::readMtlLib (char* mtlFile) 596 { 597 mtlFileName = new char [strlen(mtlFile)+1]; 598 strcpy(mtlFileName, mtlFile); 599 char* fileName = new char [strlen(objPath) + strlen(mtlFileName)+1]; 600 strcpy(fileName, objPath); 601 strcat(fileName, mtlFileName); 411 602 603 604 if (verbose >=2) 605 printf ("Opening mtlFile: %s\n", fileName); 606 607 ifstream* MTL_FILE = new ifstream (fileName); 608 if (MTL_FILE->fail()) 609 { 610 if (verbose >= 1) 611 printf ("unable to open file: %s\n", fileName); 612 delete []fileName; 613 return false; 614 } 615 char Buffer[500]; 616 Material* tmpMat = material; 617 while(!MTL_FILE->eof()) 618 { 619 MTL_FILE->getline(Buffer, 500); 620 if (verbose >= 4) 621 printf("found line in mtlFile: %s\n", Buffer); 622 623 624 // create new Material 625 if (!strncmp(Buffer, "newmtl ", 7)) 626 { 627 tmpMat = tmpMat->addMaterial(Buffer+7); 628 // printf ("%s, %p\n", tmpMat->getName(), tmpMat); 629 } 630 // setting a illumMode 631 else if (!strncmp(Buffer, "illum ", 6)) 632 { 633 tmpMat->setIllum(Buffer+6); 634 635 } 636 // setting Diffuse Color 637 else if (!strncmp(Buffer, "Kd ", 3)) 638 { 639 tmpMat->setDiffuse(Buffer+3); 640 } 641 // setting Ambient Color 642 else if (!strncmp(Buffer, "Ka ", 3)) 643 { 644 tmpMat->setAmbient(Buffer+3); 645 } 646 // setting Specular Color 647 else if (!strncmp(Buffer, "Ks ", 3)) 648 { 649 tmpMat->setSpecular(Buffer+3); 650 } 651 // setting The Specular Shininess 652 else if (!strncmp(Buffer, "Ns ", 3)) 653 { 654 tmpMat->setShininess(Buffer+3); 655 } 656 // setting up transparency 657 else if (!strncmp(Buffer, "d ", 2)) 658 { 659 tmpMat->setTransparency(Buffer+2); 660 } 661 else if (!strncmp(Buffer, "Tf ", 3)) 662 { 663 tmpMat->setTransparency(Buffer+3); 664 } 665 666 else if (!strncmp(Buffer, "map_Kd ", 7)) 667 { 668 tmpMat->setDiffuseMap(Buffer+7); 669 } 670 else if (!strncmp(Buffer, "map_Ka ", 7)) 671 { 672 tmpMat->setAmbientMap(Buffer+7); 673 } 674 else if (!strncmp(Buffer, "map_Ks ", 7)) 675 { 676 tmpMat->setSpecularMap(Buffer+7); 677 } 678 else if (!strncmp(Buffer, "bump ", 5)) 679 { 680 tmpMat->setBump(Buffer+7); 681 } 682 683 684 } 685 delete []fileName; 686 return true; 687 } 688 689 /** 690 \brief Function that selects a material, if changed in the obj file. 691 \param matString the Material that will be set. 692 */ 693 bool Object::readUseMtl (char* matString) 694 { 695 if (!mtlFileName) 696 { 697 if (verbose >= 1) 698 printf ("Not using new defined material, because no mtlFile found yet\n"); 699 return false; 700 } 701 702 if (currentGroup->faceCount >0) 703 currentGroup->currentFace = currentGroup->currentFace->next = new Face; 704 initFace (currentGroup->currentFace); 412 705 413 if (elemCount == 3) 414 { 415 if (currentGroup->faceMode != 3) 416 { 417 if (currentGroup->faceMode != -1) 418 glEnd(); 419 glBegin(GL_TRIANGLES); 420 } 421 422 currentGroup->faceMode = 3; 423 if (verbose >=3) 424 printf ("found triag.\n"); 425 } 706 currentGroup->currentFace->materialString = new char[strlen(matString)+1]; 707 strcpy (currentGroup->currentFace->materialString, matString); 426 708 427 else if (elemCount == 4) 428 { 429 if (currentGroup->faceMode != 4) 430 { 431 if (currentGroup->faceMode != -1) 432 glEnd(); 433 glBegin(GL_QUADS); 434 } 435 currentGroup->faceMode = 4; 436 if (verbose >=3 ) 437 printf ("found quad.\n"); 438 } 439 440 else if (elemCount > 4) 441 { 442 if (currentGroup->faceMode != -1) 443 glEnd(); 444 glBegin(GL_POLYGON); 445 if (verbose >=3) 446 printf ("Polygon with %i faces found.", elemCount); 447 currentGroup->faceMode = elemCount; 448 } 449 450 tmpElem = firstElem; 451 while (tmpElem != NULL) 452 { 453 // printf ("%s\n", tmpElem->value); 454 addGLElement(tmpElem->value); 455 tmpElem = tmpElem->next; 456 } 457 709 if (currentGroup->faceCount == 0) 710 currentGroup->faceCount ++; 711 712 } 713 714 /** 715 \brief reads and includes the Faces/Materials into the openGL state Machine 716 */ 717 bool Object::importToGL (void) 718 { 719 720 // finalize the Arrays 721 vertices->finalizeArray(); 722 vTexture->finalizeArray(); 723 if (normals->getCount() == 0) // vertices-Array must be uilt for this 724 buildVertexNormals(); 725 normals->finalizeArray(); 726 727 currentGroup = firstGroup; 728 729 while (currentGroup != NULL) 730 { 731 732 // creating a glList for the Group 733 if ((currentGroup->listNumber = glGenLists(1)) == 0) 734 { 735 printf ("list could not be created for this Object\n"); 736 return false; 737 } 738 glNewList (currentGroup->listNumber, GL_COMPILE); 739 740 // Putting Faces to GL 741 Face* tmpFace = currentGroup->firstFace; 742 while (tmpFace != NULL) 743 { 744 if (tmpFace->vertexCount == 0 && tmpFace->materialString != NULL) 745 { 746 if (currentGroup->faceMode != -1) 747 glEnd(); 748 currentGroup->faceMode = 0; 749 if (verbose >= 2) 750 printf ("using material %s for coming Faces.\n", tmpFace->materialString); 751 Material* tmpMat; 752 if ((tmpMat = material->search(tmpFace->materialString)) != NULL) 753 tmpMat->select(); 754 755 } 756 757 else if (tmpFace->vertexCount == 3) 758 { 759 if (currentGroup->faceMode != 3) 760 { 761 if (currentGroup->faceMode != -1) 762 glEnd(); 763 glBegin(GL_TRIANGLES); 764 } 765 766 currentGroup->faceMode = 3; 767 if (verbose >=3) 768 printf ("found triag.\n"); 769 } 770 771 else if (tmpFace->vertexCount == 4) 772 { 773 if (currentGroup->faceMode != 4) 774 { 775 if (currentGroup->faceMode != -1) 776 glEnd(); 777 glBegin(GL_QUADS); 778 } 779 currentGroup->faceMode = 4; 780 if (verbose >=3 ) 781 printf ("found quad.\n"); 782 } 783 784 else if (tmpFace->vertexCount > 4) 785 { 786 if (currentGroup->faceMode != -1) 787 glEnd(); 788 glBegin(GL_POLYGON); 789 if (verbose >=3) 790 printf ("Polygon with %i faces found.", tmpFace->vertexCount); 791 currentGroup->faceMode = tmpFace->vertexCount; 792 } 793 794 FaceElement* tmpElem = tmpFace->firstElem; 795 while (tmpElem != NULL) 796 { 797 // printf ("%s\n", tmpElem->value); 798 addGLElement(tmpElem); 799 tmpElem = tmpElem->next; 800 } 801 tmpFace = tmpFace->next; 802 } 803 glEnd(); 804 glEndList(); 805 currentGroup = currentGroup->next; 806 } 458 807 } 459 808 … … 467 816 468 817 */ 469 bool Object::addGLElement ( char* elementString)818 bool Object::addGLElement (FaceElement* elem) 470 819 { 471 820 if (verbose >=3) 472 printf ("importing grafical Element to openGL\n"); 473 char* vertex = elementString; 474 475 char* texture; 476 if ((texture = strstr (vertex, "/")) != NULL) 477 { 478 texture[0] = '\0'; 479 texture ++; 480 if (verbose>=3) 481 printf ("includeing texture #%i, and mapping it to group texture #%i, textureArray has %i entries.\n", atoi(texture), (atoi(texture)-1 - currentGroup->firstVertexTexture)*3, currentGroup->vTexture->getCount()); 482 glTexCoord2fv(currentGroup->vTexture->getArray()+(atoi(texture)-1 - currentGroup->firstVertexTexture)*2); 483 484 char* normal; 485 if ((normal = strstr (texture, "/")) !=NULL) 486 { 487 normal[0] = '\0'; 488 normal ++; 489 //glArrayElement(atoi(vertex)-1); 490 glNormal3fv(currentGroup->normals->getArray() +(atoi(normal)-1 - currentGroup->firstNormal)*3); 491 } 492 } 493 if (verbose>=3) 494 printf ("includeing vertex #%i, and mapping it to group vertex #%i, vertexArray has %i entries.\n", atoi(vertex), (atoi(vertex)-1 - currentGroup->firstVertex)*3, currentGroup->vertices->getCount()); 495 glVertex3fv(currentGroup->vertices->getArray() +(atoi(vertex)-1 - currentGroup->firstVertex)*3); 496 497 } 498 499 /** 500 \brief parses a vertexNormal-String 501 If a vertexNormal line is found this function will inject it into the vertexNormal-Array 502 \param normalString The String that will be parsed. 503 */ 504 bool Object::readVertexNormal (char* normalString) 505 { 506 readingVertices = true; 507 char subbuffer1[20]; 508 char subbuffer2[20]; 509 char subbuffer3[20]; 510 sscanf (normalString, "%s %s %s", subbuffer1, subbuffer2, subbuffer3); 511 if (verbose >=3 ) 512 printf("found vertex-Normal %s, %s, %s\n", subbuffer1,subbuffer2,subbuffer3); 513 currentGroup->normals->addEntry(atof(subbuffer1), atof(subbuffer2), atof(subbuffer3)); 514 return true; 515 } 516 517 /** 518 \brief parses a vertexTextureCoordinate-String 519 If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array 520 \param vTextureString The String that will be parsed. 521 */ 522 bool Object::readVertexTexture (char* vTextureString) 523 { 524 readingVertices = true; 525 char subbuffer1[20]; 526 char subbuffer2[20]; 527 sscanf (vTextureString, "%s %s", subbuffer1, subbuffer2); 528 if (verbose >=3 ) 529 printf("found vertex-Texture %s, %s\n", subbuffer1,subbuffer2); 530 currentGroup->vTexture->addEntry(atof(subbuffer1)); 531 currentGroup->vTexture->addEntry(atof(subbuffer2)); 532 return true; 533 } 534 535 /** 536 \brief parses a group String 537 This function initializes a new Group. 538 With it you should be able to import .obj-files with more than one Objects inside. 539 \param groupString the new Group to create 540 */ 541 bool Object::readGroup (char* groupString) 542 { 543 // setting the group name if not default. 544 if (strcmp(currentGroup->name, "default")) 545 { 546 currentGroup->name = (char*) malloc ( strlen(groupString) * sizeof (char)); 547 strcpy(currentGroup->name, groupString); 548 } 549 if (groupCount != 0 && currentGroup->faceCount>0) 550 { 551 Group* newGroup = new Group; 552 finalizeGroup(currentGroup); 553 currentGroup->nextGroup = newGroup; 554 initGroup(newGroup); 555 cleanupGroup(currentGroup); // deletes the arrays of the group; must be after initGroup. 556 currentGroup = newGroup; // must be after init see initGroup for more info 557 } 558 559 ++groupCount; 560 561 } 562 563 /** 564 \brief Function to read in a mtl File. 565 this Function parses all Lines of an mtl File 566 \param mtlFile The .mtl file to read 567 */ 568 bool Object::readMtlLib (char* mtlFile) 569 { 570 MTL_FILE = new ifstream (mtlFile); 571 if (!MTL_FILE->is_open()) 572 { 573 if (verbose >= 1) 574 printf ("unable to open file: %s\n", mtlFile); 575 return false; 576 } 577 mtlFileName = mtlFile; 821 printf ("importing grafical Element to openGL.\n"); 822 823 if (elem->texCoordNumber != -1) 824 glTexCoord2fv(vTexture->getArray() + elem->texCoordNumber * 2); 825 if (elem->normalNumber != -1) 826 glNormal3fv(normals->getArray() + elem->normalNumber * 3); 827 if (elem->vertexNumber != -1) 828 glVertex3fv(vertices->getArray() + elem->vertexNumber * 3); 829 830 } 831 832 /** 833 \brief A routine that is able to create normals. 834 The algorithm does the following: 835 1. It calculates creates Vectors for each normale, and sets them to zero. 836 2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements 837 3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal. 838 4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array. 839 */ 840 bool Object::buildVertexNormals () 841 { 842 578 843 if (verbose >=2) 579 printf ("Opening mtlFile: %s\n", mtlFileName); 580 char Buffer[500]; 581 Material* tmpMat = material; 582 while(!MTL_FILE->eof()) 583 { 584 MTL_FILE->getline(Buffer, 500); 585 if (verbose >= 4) 586 printf("found line in mtlFile: %s\n", Buffer); 587 588 589 // create new Material 590 if (!strncmp(Buffer, "newmtl ", 2)) 591 { 592 tmpMat = tmpMat->addMaterial(Buffer+7); 593 // printf ("%s, %p\n", tmpMat->getName(), tmpMat); 594 } 595 // setting a illumMode 596 else if (!strncmp(Buffer, "illum", 5)) 597 { 598 tmpMat->setIllum(Buffer+6); 599 600 } 601 // setting Diffuse Color 602 else if (!strncmp(Buffer, "Kd", 2)) 603 { 604 tmpMat->setDiffuse(Buffer+3); 605 } 606 // setting Ambient Color 607 else if (!strncmp(Buffer, "Ka", 2)) 608 { 609 tmpMat->setAmbient(Buffer+3); 610 } 611 // setting Specular Color 612 else if (!strncmp(Buffer, "Ks", 2)) 613 { 614 tmpMat->setSpecular(Buffer+3); 615 } 616 // setting The Specular Shininess 617 else if (!strncmp(Buffer, "Ns", 2)) 618 { 619 tmpMat->setShininess(Buffer+3); 620 } 621 // setting up transparency 622 else if (!strncmp(Buffer, "d", 1)) 623 { 624 tmpMat->setTransparency(Buffer+2); 625 } 626 else if (!strncpy(Buffer, "Tf", 2)) 627 { 628 tmpMat->setTransparency(Buffer+3); 629 } 630 631 } 632 return true; 633 } 634 635 /** 636 \brief Function that selects a material, if changed in the obj file. 637 \param matString the Material that will be set. 638 */ 639 640 bool Object::readUseMtl (char* matString) 641 { 642 if (!strcmp (mtlFileName, "")) 643 { 644 if (verbose >= 1) 645 printf ("Not using new defined material, because no mtlFile found yet\n"); 646 return false; 647 } 648 649 if (currentGroup->faceMode != -1) 650 glEnd(); 651 currentGroup->faceMode = 0; 652 if (verbose >= 2) 653 printf ("using material %s for coming Faces.\n", matString); 654 material->search(matString)->select(); 655 } 844 printf("Normals are being calculated.\n"); 845 846 Vector* normArray = new Vector [vertices->getCount()/3]; 847 for (int i=0; i<vertices->getCount()/3;i++) 848 normArray[i] = Vector(.0,.0,.0); 849 850 int firstTouch; 851 int secondTouch; 852 Vector prevV; 853 Vector nextV; 854 Vector curV; 855 856 Group* tmpGroup = firstGroup; 857 while (tmpGroup) 858 { 859 Face* tmpFace = tmpGroup->firstFace; 860 while (tmpFace) 861 { 862 if (tmpFace->firstElem) 863 { 864 FaceElement* firstElem = tmpFace->firstElem; 865 FaceElement* prevElem; 866 FaceElement* curElem = firstElem; 867 FaceElement* nextElem; 868 FaceElement* lastElem; 869 // find last Element of the Chain. !! IMPORTANT:the last Element of the Chain must point to NULL, or it will resolv into an infinity-loop. 870 while (curElem) 871 { 872 prevElem = curElem; 873 curElem = curElem->next; 874 } 875 lastElem = prevElem; 876 877 curElem = firstElem; 878 for (int j=0; j<tmpFace->vertexCount; j++) 879 { 880 if (!(nextElem = curElem->next)) 881 nextElem = firstElem; 882 curElem->normalNumber = curElem->vertexNumber; 883 884 curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]); 885 prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV; 886 nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV; 887 normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV); 888 889 prevElem = curElem; 890 curElem = curElem->next; 891 } 892 } 893 tmpFace = tmpFace->next; 894 } 895 tmpGroup = tmpGroup->next; 896 } 897 898 for (int i=0; i<vertices->getCount()/3;i++) 899 { 900 normArray[i].normalize(); 901 if (verbose >=3) 902 printf ("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z); 903 904 normals->addEntry(normArray[i].x, normArray[i].y, normArray[i].z); 905 906 } 907 delete []normArray; 908 909 } 910 656 911 657 912 /** … … 669 924 readVertex ("-0.500000 -0.500000 -0.500000"); 670 925 readVertex ("0.500000 -0.500000 -0.500000"); 926 671 927 readVertexTexture ("0.000000 0.000000"); 672 928 readVertexTexture ("1.000000 0.000000"); … … 683 939 readVertexTexture ("-1.000000 0.000000"); 684 940 readVertexTexture ("-1.000000 1.000000"); 685 941 686 942 readVertexNormal ("0.000000 0.000000 1.000000"); 687 943 readVertexNormal ("0.000000 0.000000 1.000000"); … … 709 965 readVertexNormal ("-1.000000 0.000000 0.000000"); 710 966 967 /* normaleLess-testingMode 968 readFace ("1 2 4 3"); 969 readFace ("3 4 6 5"); 970 readFace ("5 6 8 7"); 971 readFace ("7 8 2 1"); 972 readFace ("2 8 6 4"); 973 readFace ("7 1 3 5"); 974 */ 975 711 976 readFace ("1/1/1 2/2/2 4/4/3 3/3/4"); 712 977 readFace ("3/3/5 4/4/6 6/6/7 5/5/8"); … … 715 980 readFace ("2/2/17 8/11/18 6/12/19 4/4/20"); 716 981 readFace ("7/13/21 1/1/22 3/3/23 5/14/24"); 717 } 982 983 } -
orxonox/trunk/src/object.h
r2935 r3185 7 7 #define _OBJECT_H 8 8 9 #include <GL/gl.h> 10 #include <GL/glu.h> 9 #include "stdincl.h" 11 10 12 11 #include "array.h" 13 12 #include "material.h" 13 #include "vector.h" 14 14 #include <fstream> 15 15 16 16 using namespace std; 17 17 18 extern int verbose; //!< fill be removed and added again as a verbose-class18 extern int verbose; //!< Will be removed and added again as a verbose-class. 19 19 20 20 21 struct FaceElement22 {23 char value[20];24 FaceElement* next;25 };26 21 27 22 //! Class that handles 3D-Objects. it can also read them in and display them. … … 34 29 ~Object (); 35 30 36 bool importFile (char* fileName); 37 bool initialize (void); 38 bool finalize(void); 39 void draw (void); 40 void draw (int groupNumber); 41 void draw (char* groupName); 42 int getGroupCount(); 31 void draw (void) const; 32 void draw (int groupNumber) const; 33 void draw (char* groupName) const; 34 int getGroupCount() const; 43 35 44 36 private: 37 struct FaceElement 38 { 39 int vertexNumber; 40 int normalNumber; 41 int texCoordNumber; 42 FaceElement* next; 43 }; 44 45 //! Face 46 struct Face 47 { 48 int vertexCount; 49 FaceElement* firstElem; 50 51 char* materialString; 52 53 Face* next; 54 }; 55 45 56 //! Group to handle multiple Objects per obj-file 46 57 struct Group … … 49 60 50 61 GLuint listNumber; 51 Array* vertices; 52 int verticesCount; 53 Array* colors; 54 Array* normals; 55 Array* vTexture; 62 Face* firstFace; 63 Face* currentFace; 56 64 int faceMode; 57 65 int faceCount; 58 66 59 int firstVertex; 60 int firstNormal; 61 int firstVertexTexture; 67 Group* next; 68 }; 62 69 63 Group* nextGroup; 64 }; 70 71 Array* vertices; 72 int verticesCount; 73 Array* colors; 74 Array* normals; 75 Array* vTexture; 76 65 77 66 78 Group* firstGroup; //!< the first of all groups. … … 68 80 int groupCount; 69 81 70 bool readingVertices; 82 Material* material; 83 float scaleFactor; 71 84 85 char* objPath; 72 86 char* objFileName; 73 87 char* mtlFileName; 74 88 75 Material* material; 76 float scaleFactor; 77 78 ifstream* OBJ_FILE; 79 ifstream* MTL_FILE; 80 89 bool initialize (void); 81 90 bool initGroup(Group* group); 82 bool finalizeGroup (Group* group); 91 bool initFace (Face* face); 92 bool cleanup(void); 83 93 bool cleanupGroup(Group* group); 84 94 bool cleanupFace(Face* face); 95 bool cleanupFaceElement(FaceElement* faceElem); 85 96 86 97 ///// readin /// 87 bool readFromObjFile (char* fileName); 98 bool importFile (char* fileName); 99 bool readFromObjFile (void); 88 100 101 bool readGroup (char* groupString); 89 102 bool readVertex (char* vertexString); 90 103 bool readFace (char* faceString); 91 bool readVT (char* vtString);92 104 bool readVertexNormal (char* normalString); 93 105 bool readVertexTexture (char* vTextureString); 94 bool readGroup (char* groupString);95 106 bool readMtlLib (char* matFile); 96 107 bool readUseMtl (char* mtlString); 97 108 98 bool addGLElement (char* elementString); 109 bool importToGL (void); 110 bool addGLElement (FaceElement* elem); 111 112 bool buildVertexNormals (); 99 113 100 114 void BoxObject (void);
Note: See TracChangeset
for help on using the changeset viewer.