Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 3185 in orxonox.OLD


Ignore:
Timestamp:
Dec 15, 2004, 6:24:28 PM (19 years ago)
Author:
bensch
Message:

orxonox/trunk/src: merged trunk/importer into trunk/src again.
All conflicts resolved in favor of trunk/src.

Location:
orxonox/trunk/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • orxonox/trunk/src/array.cc

    r2866 r3185  
    3333    printf("deleting array\n");
    3434  Entry* walker = firstEntry;
    35   Entry* last;
    36   while (walker != NULL)
     35  Entry* previous;
     36  while (walker)
    3737    {
    38       last = walker;
     38      previous = walker;
    3939      walker = walker->next;
    40       delete last;
     40      delete previous;
    4141    }
    4242  if (finalized)
    43     delete [] array;
     43    delete []array;
    4444}
    4545
     
    6767{
    6868  if (verbose >= 3)
    69     printf ("Finalizing array.\n"); 
     69    printf ("Finalizing array. Length: %i\n", entryCount); 
    7070  if ((array = (GLfloat*)malloc( entryCount* sizeof(GLfloat))) == NULL)
    7171  //  if ((array = new GLfloat [entryCount]) == NULL)
  • orxonox/trunk/src/array.h

    r2853 r3185  
    1111extern int verbose; //!< will be obsolete soon
    1212
    13 #include <GL/gl.h>
    14 #include <GL/glu.h>
     13#include "stdincl.h"
    1514#include <fstream>
    1615
  • orxonox/trunk/src/material.cc

    r2853 r3185  
    1212   main-programmer: Benjamin Grauer
    1313   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.
    1420*/
    1521
    1622#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
     31using namespace std;
     32
     33
     34PathList::PathList()
     35{
     36  pathName = NULL;
     37  next = NULL;
     38}
     39PathList::PathList(char* pName)
     40{
     41  pathName = new char [strlen(pName)+1];
     42  strcpy (pathName, pName);
     43  next = NULL;
     44}
     45
     46PathList::~PathList()
     47{
     48  if (pathName)
     49    delete []pathName;
     50  if (next)
     51    delete next;
     52}
     53
     54void 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}
    1788
    1889/**
     
    44115{
    45116  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)
    48123    delete nextMat;
    49124}
     
    57132{
    58133  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;
    62136  while (tmpMat->nextMat != NULL)
    63137    {
    64138      tmpMat = tmpMat->nextMat;
    65139    }
    66       tmpMat->nextMat = newMat;
    67       return newMat;
     140  tmpMat->nextMat = new Material(mtlName);
     141  return tmpMat->nextMat;
    68142 
    69143}
     
    75149{
    76150  if (verbose >= 3)
    77     printf ("initializing new Material\n");
     151    printf ("initializing new Material.\n");
    78152  nextMat = NULL;
    79 
     153  name ="";
    80154  setIllum(1);
    81155  setDiffuse(0,0,0);
    82156  setAmbient(0,0,0);
    83   setSpecular(0,0,0);
     157  setSpecular(.5,.5,.5);
    84158  setShininess(2.0);
    85159  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
     172PathList *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*/
     179Material* 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*/
     204bool 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
    88232
    89233/**
     
    93237void Material::setName (char* mtlName)
    94238{
     239  name = new char [strlen(mtlName)+1];
     240  strcpy(name, mtlName);
    95241  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
    98244  //  printf ("adding new Material: %s, %p\n", this->getName(), this);
    99245
     
    114260{
    115261  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);
    117263  illumModel = illum;
    118264  //  printf ("setting illumModel to: %i\n", illumModel);
     
    135281{
    136282  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);
    138284  diffuse[0] = r;
    139285  diffuse[1] = g;
     
    148294void Material::setDiffuse (char* rgb)
    149295{
    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);
    153299}
    154300
     
    162308{
    163309  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);
    165311  ambient[0] = r;
    166312  ambient[1] = g;
     
    174320void Material::setAmbient (char* rgb)
    175321{
    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);
    179325}
    180326
     
    188334{
    189335  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);
    191337  specular[0] = r;
    192338  specular[1] = g;
     
    200346void Material::setSpecular (char* rgb)
    201347{
    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);
    205351}
    206352
     
    229375{
    230376  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);
    232378  transparency = trans;
    233379}
     
    238384void Material::setTransparency (char* trans)
    239385{
    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*/
     393void 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*/
     403char* 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*/
     439void 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*/
     453void 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*/
     463void 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*/
     473void Material::setBump(char* bump)
     474{
     475
     476}
     477
     478bool Material::loadTexToGL (Image* pImage, GLuint* texture)
    251479{
    252480  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
     497bool 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*/
     537bool 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*/
     587bool 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*/
     701bool 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*/
     802bool 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*/
     859bool 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*/
     934bool 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/*
     1113static 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*/
     1124bool 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  
    99extern int verbose; //!< will be obsolete soon.
    1010
    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
     22extern "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
     31class 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
    1543
    1644//! Class to handle Materials.
     
    2149  Material (char* mtlName);
    2250  Material* addMaterial(char* mtlName);
     51  ~Material ();
     52  void init(void);
    2353
    24   void init(void);
    25   ~Material ();
    26 
     54  Material* search (char* mtlName);
     55  bool select (void);
    2756
    2857  void setName (char* mtlName);
     
    4170  void setTransparency (char* trans);
    4271
    43   Material* search (char* mtlName);
    4472
    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);
    4881
    4982 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;
    5195  int illumModel;
    5296  float diffuse [4];
     
    56100  float transparency;
    57101
     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
    58132};
    59133#endif
  • orxonox/trunk/src/object.cc

    r2935 r3185  
    1717
    1818#include "object.h"
     19using namespace std;
    1920
    2021/**
     
    2930  BoxObject();
    3031
    31   finalize();
     32  importToGL ();
     33
     34  cleanup();
    3235}
    3336
     
    4245  importFile (fileName);
    4346
    44   finalize();
     47  importToGL ();
     48
     49  cleanup();
    4550}
    4651
     
    5055   \param scaling The factor that the object will be scaled with.
    5156*/
    52 
    5357Object::Object(char* fileName, float scaling)
    5458{
     
    5862  importFile (fileName);
    5963
    60   finalize();
     64  importToGL ();
     65
     66  cleanup();
    6167}
    6268
     
    6773{
    6874  if (verbose >= 2)
    69     printf ("Deleting display List.\n");
     75    printf ("Deleting display Lists.\n");
    7076  Group* walker = firstGroup;
    7177  while (walker != NULL)
    7278    {
    7379      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*/
     103void 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*/
     122void 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*/
     157void 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*/
     181int Object::getGroupCount (void) const
     182{
     183  return groupCount;
     184}
     185
     186/**
    81187    \brief initializes the Object
    82188    This Function initializes all the needed arrays, Lists and clientStates
     
    92198  groupCount = 0;
    93199 
    94   initGroup (currentGroup);
    95   mtlFileName = "";
     200  initGroup (firstGroup);
     201  objPath = NULL;
     202  objFileName = NULL;
     203  mtlFileName = NULL;
    96204  scaleFactor = 1;
    97205  material = new Material();
    98206
    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();
    103210
    104211  return true;
    105 }
    106 
    107 /**
    108    \brief Imports a obj file and handles the the relative location
    109    \param fileName The file to import
    110 */
    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 groupNumber
    154    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 groupname
    189    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 File
    215 */
    216 int Object::getGroupCount (void)
    217 {
    218   return groupCount;
    219212}
    220213
     
    228221  group->name = "";
    229222  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*/
     234bool Object::initFace (Face* face)
     235{
     236  face->vertexCount = 0;
     237
     238  face->firstElem = NULL;
    236239 
    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*/
     251bool Object::cleanup(void)
     252{
    249253  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*/
     271bool 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*/
     290bool 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*/
     316bool 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*/
     329bool 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';
    264353  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);
    277360 
    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;
    281367}
    282368
     
    284370   \brief Reads in the .obj File and sets all the Values.
    285371   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*/
     373bool 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())
    292383    {
    293384      if (verbose >=1)
    294385        printf ("unable to open .OBJ file: %s\n Loading Box Object instead.\n", fileName);
    295386      BoxObject();
     387      delete []fileName;
    296388      return false;
    297389    }
    298   objFileName = fileName;
     390  if (verbose >=2)
     391    printf ("Reading from opened file %s\n", fileName);
    299392  char Buffer[10000];
    300393  while(!OBJ_FILE->eof())
     
    317410        }
    318411     
    319       else if (!strncmp(Buffer, "mtllib", 6))
     412      else if (!strncmp(Buffer, "mtllib ", 7))
    320413        {
    321414          readMtlLib (Buffer+7);
    322415        }
    323416
    324       else if (!strncmp(Buffer, "usemtl", 6))
     417      else if (!strncmp(Buffer, "usemtl ", 7))
    325418        {
    326419          readUseMtl (Buffer+7);
     
    328421
    329422      // case VertexNormal
    330       else if (!strncmp(Buffer, "vn ", 2))
     423      else if (!strncmp(Buffer, "vn ", 3))
    331424      {
    332425        readVertexNormal(Buffer+3);
     
    334427
    335428      // case VertexTextureCoordinate
    336       else if (!strncmp(Buffer, "vt ", 2))
     429      else if (!strncmp(Buffer, "vt ", 3))
    337430      {
    338431        readVertexTexture(Buffer+3);
    339432      }
    340433      // case group
    341       else if (!strncmp(Buffer, "g", 1))
     434      else if (!strncmp(Buffer, "g ", 2))
    342435        {
    343436          readGroup (Buffer+2);
    344437        }
     438      else if (!strncmp(Buffer, "s ", 2))
     439        {
     440          if (verbose >= 2)
     441            printf("smoothing groups not supportet yet. line: %s\n", Buffer);
     442        }
    345443    }
    346444  OBJ_FILE->close();
     445  delete []fileName;
    347446  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*/
     456bool 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;
    348473
    349474}
     
    356481bool Object::readVertex (char* vertexString)
    357482{
    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);
    363487  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);
    366490  return true;
    367491}
     
    375499bool Object::readFace (char* faceString)
    376500{
    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;
    396507  while(strcmp (faceString, "\0"))
    397508    {
    398       if (elemCount>0)
     509      if (currentGroup->currentFace->vertexCount>0)
    399510          tmpElem = tmpElem->next = new FaceElement;
    400511      tmpElem->next = NULL;
    401512
    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;
    405548      if (strcmp (faceString, "\0"))
    406549        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*/
     561bool 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*/
     578bool 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*/
     595bool 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);
    411602 
     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*/
     693bool 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);
    412705 
    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);
    426708 
    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*/
     717bool 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    }
    458807}
    459808
     
    467816
    468817*/
    469 bool Object::addGLElement (char* elementString)
     818bool Object::addGLElement (FaceElement* elem)
    470819{
    471820  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*/
     840bool Object::buildVertexNormals ()
     841{
     842 
    578843  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
    656911
    657912/**
     
    669924  readVertex ("-0.500000 -0.500000 -0.500000");
    670925  readVertex ("0.500000 -0.500000 -0.500000");
     926
    671927  readVertexTexture ("0.000000 0.000000");
    672928  readVertexTexture ("1.000000 0.000000");
     
    683939  readVertexTexture ("-1.000000 0.000000");
    684940  readVertexTexture ("-1.000000 1.000000");
    685  
     941
    686942  readVertexNormal ("0.000000 0.000000 1.000000");
    687943  readVertexNormal ("0.000000 0.000000 1.000000");
     
    709965  readVertexNormal ("-1.000000 0.000000 0.000000");
    710966
     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
    711976  readFace ("1/1/1 2/2/2 4/4/3 3/3/4");
    712977  readFace ("3/3/5 4/4/6 6/6/7 5/5/8");
     
    715980  readFace ("2/2/17 8/11/18 6/12/19 4/4/20");
    716981  readFace ("7/13/21 1/1/22 3/3/23 5/14/24");
    717 }
     982
     983}
  • orxonox/trunk/src/object.h

    r2935 r3185  
    77#define _OBJECT_H
    88
    9 #include <GL/gl.h>
    10 #include <GL/glu.h>
     9#include "stdincl.h"
    1110
    1211#include "array.h"
    1312#include "material.h"
     13#include "vector.h"
    1414#include <fstream>
    1515
    1616using namespace std;
    1717
    18 extern int verbose; //!< fill be removed and added again as a verbose-class
     18extern int verbose; //!< Will be removed and added again as a verbose-class.
    1919
    2020
    21 struct FaceElement
    22 {
    23   char value[20];
    24   FaceElement* next;
    25 };
    2621
    2722//! Class that handles 3D-Objects. it can also read them in and display them.
     
    3429  ~Object ();
    3530 
    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;
    4335
    4436 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
    4556  //! Group to handle multiple Objects per obj-file
    4657  struct Group
     
    4960
    5061    GLuint listNumber;
    51     Array* vertices;
    52     int verticesCount;
    53     Array* colors;
    54     Array* normals;
    55     Array* vTexture;
     62    Face* firstFace;
     63    Face* currentFace;
    5664    int faceMode;
    5765    int faceCount;
    5866
    59     int firstVertex;
    60     int firstNormal;
    61     int firstVertexTexture;
     67    Group* next;
     68  };
    6269
    63     Group* nextGroup;
    64   };
     70
     71  Array* vertices;
     72  int verticesCount;
     73  Array* colors;
     74  Array* normals;
     75  Array* vTexture;
     76
    6577 
    6678  Group* firstGroup; //!< the first of all groups.
     
    6880  int groupCount;
    6981
    70   bool readingVertices;
     82  Material* material;
     83  float scaleFactor;
    7184
     85  char* objPath;
    7286  char* objFileName;
    7387  char* mtlFileName;
    7488
    75   Material* material;
    76   float scaleFactor;
    77 
    78   ifstream* OBJ_FILE;
    79   ifstream* MTL_FILE;
    80 
     89  bool initialize (void);
    8190  bool initGroup(Group* group);
    82   bool finalizeGroup (Group* group);
     91  bool initFace (Face* face);
     92  bool cleanup(void);
    8393  bool cleanupGroup(Group* group);
    84 
     94  bool cleanupFace(Face* face);
     95  bool cleanupFaceElement(FaceElement* faceElem);
    8596
    8697  ///// readin ///
    87   bool readFromObjFile (char* fileName);
     98  bool importFile (char* fileName);
     99  bool readFromObjFile (void);
    88100 
     101  bool readGroup (char* groupString);
    89102  bool readVertex (char* vertexString);
    90103  bool readFace (char* faceString);
    91   bool readVT (char* vtString);
    92104  bool readVertexNormal (char* normalString);
    93105  bool readVertexTexture (char* vTextureString);
    94   bool readGroup (char* groupString);
    95106  bool readMtlLib (char* matFile);
    96107  bool readUseMtl (char* mtlString);
    97108
    98   bool addGLElement (char* elementString);
     109  bool importToGL (void);
     110  bool addGLElement (FaceElement* elem);
     111
     112  bool buildVertexNormals ();
    99113
    100114  void BoxObject (void);
Note: See TracChangeset for help on using the changeset viewer.