Index: /orxonox/trunk/src/array.cc
===================================================================
--- /orxonox/trunk/src/array.cc	(revision 3184)
+++ /orxonox/trunk/src/array.cc	(revision 3185)
@@ -33,13 +33,13 @@
     printf("deleting array\n");
   Entry* walker = firstEntry;
-  Entry* last;
-  while (walker != NULL)
+  Entry* previous;
+  while (walker)
     {
-      last = walker;
+      previous = walker;
       walker = walker->next;
-      delete last;
+      delete previous;
     }
   if (finalized)
-    delete [] array;
+    delete []array;
 }
 
@@ -67,5 +67,5 @@
 {
   if (verbose >= 3)
-    printf ("Finalizing array.\n");  
+    printf ("Finalizing array. Length: %i\n", entryCount);  
   if ((array = (GLfloat*)malloc( entryCount* sizeof(GLfloat))) == NULL)
   //  if ((array = new GLfloat [entryCount]) == NULL)
Index: /orxonox/trunk/src/array.h
===================================================================
--- /orxonox/trunk/src/array.h	(revision 3184)
+++ /orxonox/trunk/src/array.h	(revision 3185)
@@ -11,6 +11,5 @@
 extern int verbose; //!< will be obsolete soon
 
-#include <GL/gl.h>
-#include <GL/glu.h>
+#include "stdincl.h"
 #include <fstream>
 
Index: /orxonox/trunk/src/material.cc
===================================================================
--- /orxonox/trunk/src/material.cc	(revision 3184)
+++ /orxonox/trunk/src/material.cc	(revision 3185)
@@ -12,7 +12,78 @@
    main-programmer: Benjamin Grauer
    co-programmer: ...
+
+   TGA-code: borrowed from nehe-Tutorials
+
+   ToDo: 
+   - free SDL-surface when deleting Material.
+   - delete imgNameWithPath after use creation.
 */
 
 #include "material.h"
+
+// headers only for PathList
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <fstream>
+
+using namespace std;
+
+
+PathList::PathList()
+{
+  pathName = NULL;
+  next = NULL;
+}
+PathList::PathList(char* pName)
+{
+  pathName = new char [strlen(pName)+1];
+  strcpy (pathName, pName);
+  next = NULL;
+}
+
+PathList::~PathList()
+{
+  if (pathName)
+    delete []pathName;
+  if (next)
+    delete next;
+}
+
+void PathList::addPath (char* pName)
+{
+  if (pName[0] == '\0')
+    {
+      if (verbose >=3)
+	printf("not Adding empty Path to the List.\n");
+      return;
+    }
+  char* tmpPName = new char[strlen(pName)];
+  strncpy(tmpPName, pName, strlen(pName)-1);
+  tmpPName[strlen(pName)-1] = '\0';
+  printf ("%s\n",tmpPName);
+  if (access (tmpPName, F_OK) == 0)
+    {
+      struct stat status;
+      stat(tmpPName, &status);
+      if (status.st_mode & S_IFDIR)
+	{
+	  if (verbose >=2)
+	    printf ("Adding Path %s to the PathList.\n", pName);
+	  PathList* tmpPathList = this;
+	  while (tmpPathList->next)
+	    tmpPathList = tmpPathList->next;
+	  tmpPathList->next = new PathList(pName);
+	}
+      else
+	if (verbose >=1)
+	  printf ("You tried to add non-folder %s to a PathList.\n", tmpPName);
+    }
+  else
+    if (verbose >=1)
+      printf ("You tried to add non-existing folder %s to a PathList.\n", tmpPName);
+  delete []tmpPName;
+}
 
 /**
@@ -44,6 +115,10 @@
 {
   if (verbose >= 2)
-    printf ("delete Material %s\n", name);
-  if (nextMat != NULL)
+    printf ("delete Material %s.\n", name);
+  if (name)
+    delete []name;
+  if (diffuseTextureSet)
+    glDeleteTextures (1, &diffuseTexture);
+  if (nextMat)
     delete nextMat;
 }
@@ -57,13 +132,12 @@
 {
   if (verbose >=2)
-    printf ("adding Material %s\n", mtlName);
-  Material* newMat = new Material(mtlName);
-  Material* tmpMat = this;
+    printf ("adding Material %s.\n", mtlName);
+   Material* tmpMat = this;
   while (tmpMat->nextMat != NULL)
     {
       tmpMat = tmpMat->nextMat;
     }
-      tmpMat->nextMat = newMat;
-      return newMat;
+  tmpMat->nextMat = new Material(mtlName);
+  return tmpMat->nextMat;
   
 }
@@ -75,15 +149,85 @@
 {
   if (verbose >= 3)
-    printf ("initializing new Material\n");
+    printf ("initializing new Material.\n");
   nextMat = NULL;
-
+  name ="";
   setIllum(1);
   setDiffuse(0,0,0);
   setAmbient(0,0,0);
-  setSpecular(0,0,0);
+  setSpecular(.5,.5,.5);
   setShininess(2.0);
   setTransparency(0.0);
-  
-}
+
+  if (!pathList)
+    pathList = new PathList("");
+
+
+  diffuseTextureSet = false;
+  ambientTextureSet = false;
+  specularTextureSet = false;
+
+  
+}
+
+PathList *Material::pathList = NULL;
+
+/**
+   \brief Search for a Material called mtlName
+   \param mtlName the Name of the Material to search for
+   \returns Material named mtlName if it is found. NULL otherwise.
+*/
+Material* Material::search (char* mtlName)
+{
+  if (verbose >=3)
+    printf ("Searching for material %s", mtlName);
+  Material* searcher = this;
+  while (searcher != NULL)
+    {
+      if (verbose >= 3)
+	printf (".");
+      if (!strcmp (searcher->getName(), mtlName))
+	{
+	  if (verbose >= 3)
+	    printf ("found.\n");
+	  return searcher;
+	}
+      searcher = searcher->nextMat;
+    }
+  if (verbose >=3)
+    printf ("not found\n");
+  return NULL;
+}
+
+/**
+   \brief sets the material with which the following Faces will be painted
+*/
+bool Material::select (void)
+{
+  // setting diffuse color
+  //  glColor3f (diffuse[0], diffuse[1], diffuse[2]);
+  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
+
+  // setting ambient color
+  glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
+
+  // setting up Sprecular
+  glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
+
+  // setting up Shininess
+  glMaterialf(GL_FRONT, GL_SHININESS, shininess);
+  
+  // setting illumination Model 
+  if (illumModel == 1)
+    glShadeModel(GL_FLAT);
+  else if (illumModel >= 2)
+    glShadeModel(GL_SMOOTH);
+
+  if (diffuseTextureSet)
+    glBindTexture(GL_TEXTURE_2D, diffuseTexture);
+  else
+    glBindTexture(GL_TEXTURE_2D, 0);
+  
+}
+
 
 /**
@@ -93,7 +237,9 @@
 void Material::setName (char* mtlName)
 {
+  name = new char [strlen(mtlName)+1];
+  strcpy(name, mtlName);
   if (verbose >= 3)
-    printf("setting Material Name to %s", mtlName);
-  strcpy(name, mtlName);
+    printf("setting Material Name to %s.\n", name);
+
   //  printf ("adding new Material: %s, %p\n", this->getName(), this);
 
@@ -114,5 +260,5 @@
 {
   if (verbose >= 3)
-    printf("setting illumModel of Material %s to %i", name, illum);
+    printf("setting illumModel of Material %s to %i\n", name, illum);
   illumModel = illum;
   //  printf ("setting illumModel to: %i\n", illumModel);
@@ -135,5 +281,5 @@
 {
   if (verbose >= 3)
-    printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f\n", name, r, g, b);
+    printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
   diffuse[0] = r;
   diffuse[1] = g;
@@ -148,7 +294,7 @@
 void Material::setDiffuse (char* rgb)
 {
-  char r[20],g[20],b[20];
-  sscanf (rgb, "%s %s %s", r, g, b);
-  setDiffuse (atof(r), atof(g), atof(b));
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  setDiffuse (r, g, b);
 }
 
@@ -162,5 +308,5 @@
 {
   if (verbose >=3)
-    printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f\n", name, r, g, b);
+    printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
   ambient[0] = r;
   ambient[1] = g;
@@ -174,7 +320,7 @@
 void Material::setAmbient (char* rgb)
 {
-  char r[20],g[20],b[20];
-  sscanf (rgb, "%s %s %s", r, g, b);
-  setAmbient (atof(r), atof(g), atof(b));
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  setAmbient (r, g, b);
 }
 
@@ -188,5 +334,5 @@
 {
   if (verbose >= 3)
-    printf ("setting Specular Color of Material %s to r=%f g=%f b=%f\n", name, r, g, b);
+    printf ("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
   specular[0] = r;
   specular[1] = g;
@@ -200,7 +346,7 @@
 void Material::setSpecular (char* rgb)
 {
-  char r[20],g[20],b[20];
-  sscanf (rgb, "%s %s %s", r, g, b);
-  setSpecular (atof(r), atof(g), atof(b));
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  setSpecular (r, g, b);
 }
 
@@ -229,5 +375,5 @@
 {
   if (verbose >= 3)
-    printf ("setting Transparency of Material %s to %f\n", name, trans);
+    printf ("setting Transparency of Material %s to %f.\n", name, trans);
   transparency = trans;
 }
@@ -238,56 +384,871 @@
 void Material::setTransparency (char* trans)
 {
-  char tr[20];
-  sscanf (trans, "%s", tr);
-  setTransparency (atof(tr));
-}
-
-/**
-   \brief Search for a Material called mtlName
-   \param mtlName the Name of the Material to search for
-   \returns Material named mtlName if it is found. NULL otherwise.
-*/
-Material* Material::search (char* mtlName)
+  setTransparency (atof(trans));
+}
+
+/**
+   \brief Adds a Texture Path to the List of already existing Paths
+   \param pathName The Path to add.
+*/
+void Material::addTexturePath(char* pathName)
+{
+  pathList->addPath (pathName);
+}
+
+/**
+   \brief Searches for a Texture inside one of the defined Paths
+   \param texName The name of the texture o search for.
+   \returns pathName+texName if texName was found in the pathList. NULL if the Texture is not found.
+*/
+char* Material::searchTextureInPaths(char* texName) const
+{
+  char* tmpName = NULL;
+  PathList* pList = pathList;
+  while (pList)
+    {
+      if (pList->pathName)
+	{
+	  tmpName = new char [strlen(pList->pathName)+strlen(texName)+1];
+	  strcpy(tmpName, pList->pathName);
+	}
+      else
+	{
+	  tmpName = new char [strlen(texName)+1];
+	  tmpName[0]='\0';
+	}
+      strcat(tmpName, texName);
+      printf("%s\n", tmpName);
+      if (access (tmpName, F_OK) == 0)
+	return tmpName;
+      
+      if (tmpName)
+	delete []tmpName;
+      tmpName = NULL;
+      pList = pList->next;
+    }
+  return NULL;
+}
+
+
+// MAPPING //
+
+/**
+   \brief Sets the Materials Diffuse Map
+   \param dMap the Name of the Image to Use
+*/
+void Material::setDiffuseMap(char* dMap)
+{
+  if (verbose>=2)
+    printf ("setting Diffuse Map %s\n", dMap);
+
+  //  diffuseTextureSet = loadBMP(dMap, &diffuseTexture);
+  diffuseTextureSet = loadImage(dMap, &diffuseTexture);
+
+}
+
+/**
+   \brief Sets the Materials Ambient Map
+   \param aMap the Name of the Image to Use
+*/
+void Material::setAmbientMap(char* aMap)
+{
+  SDL_Surface* ambientMap;
+
+}
+
+/**
+   \brief Sets the Materials Specular Map
+   \param sMap the Name of the Image to Use
+*/
+void Material::setSpecularMap(char* sMap)
+{
+  SDL_Surface* specularMap;
+
+}
+
+/**
+   \brief Sets the Materials Bumpiness
+   \param bump the Name of the Image to Use
+*/
+void Material::setBump(char* bump)
+{
+
+}
+
+bool Material::loadTexToGL (Image* pImage, GLuint* texture)
 {
   if (verbose >=3)
-    printf ("Searching for material %s", mtlName);
-  Material* searcher = this;
-  while (searcher != NULL)
-    {
-      if (verbose >= 3)
-	printf (".");
-      if (!strcmp (searcher->getName(), mtlName))
-	{
-	  if (verbose >= 3)
-	    printf ("found.\n");
-	  return searcher;
-	}
-      searcher = searcher->nextMat;
-    }
-  return NULL;
-}
-
-/**
-   \brief sets the material with which the following Faces will be painted
-*/
-bool Material::select (void)
-{
-  // setting diffuse color
-  //  glColor3f (diffuse[0], diffuse[1], diffuse[2]);
-  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
-
-  // setting ambient color
-  glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
-
-  // setting up Sprecular
-  glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
-
-  // setting up Shininess
-  glMaterialf(GL_FRONT, GL_SHININESS, shininess);
-  
-  // setting illumination Model 
-  if (illumModel == 1)
-    glShadeModel(GL_FLAT);
-  else if (illumModel >= 2)
-    glShadeModel(GL_SMOOTH);
-}
+    printf ("Loading texture to OpenGL-Environment.\n");
+  glGenTextures(1, texture);
+  glBindTexture(GL_TEXTURE_2D, *texture);
+  /* not Working, and not needed. 
+  glTexImage2D( GL_TEXTURE_2D, 0, 3, width,
+		height, 0, GL_BGR,
+		GL_UNSIGNED_BYTE, map->pixels );
+  */ 
+  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->width, pImage->height, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
+  
+  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);	
+}
+
+
+#ifdef HAVE_SDL_SDL_IMAGE_H
+bool Material::loadImage(char* imageName, GLuint* texture)
+{
+  char* imgNameWithPath = searchTextureInPaths(imageName);
+  if (imgNameWithPath)
+    {
+      SDL_Surface* map;
+      Image* pImage = new Image;
+      map=IMG_Load(imgNameWithPath);
+      if(!map)
+	{
+	  printf("IMG_Load: %s\n", IMG_GetError());
+	  return false;
+	}
+      pImage->height = map->h;
+      pImage->width  = map->w;
+      pImage->data   = (GLubyte*)map->pixels;
+      if( !IMG_isPNG(SDL_RWFromFile(imgNameWithPath, "rb")) && !IMG_isJPG(SDL_RWFromFile(imgNameWithPath, "rb")))
+	for (int i=0;i<map->h * map->w *3;i+=3)
+	  { 
+	    GLuint temp = pImage->data[i];
+	    pImage->data[i] = pImage->data[i+2];
+	    pImage->data[i+2] = temp;
+	  }
+      loadTexToGL (pImage, texture);
+    }
+  else
+    {
+      if (verbose >=1)
+	printf ("Image not Found: %s\n", imgNameWithPath);
+      return false;
+    }
+}
+
+
+#else /* HAVE_SDL_SDL_IMAGE_H */
+/**
+   \brief Makes the Programm ready to Read-in a texture-File
+   1. Checks what type of Image should be imported
+   2. ToDO: Checks where to find the Image
+*/
+bool Material::loadImage(char* imageName, GLuint* texture)
+{
+  char* imgNameWithPath = searchTextureInPaths(imageName);
+  if (imgNameWithPath)
+    {
+      if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".bmp", 4))
+	{
+	  if (verbose >=2)
+	    printf ("Requested bmp-image. Trying to Import.\n");
+	  return loadBMP(imgNameWithPath, texture);
+	}
+      
+      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".jpg", 4) || !strncmp(imgNameWithPath+strlen(imgNameWithPath)-5, ".jpg", 5))
+	{
+	  if (verbose >=2)
+	    printf ("Requested jpeg-image. Trying to Import\n");
+	  return loadJPG(imgNameWithPath, texture);
+	}
+      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".tga", 4))
+	{
+	  if (verbose >=2)
+	    printf ("Requested tga-image. Trying to Import\n");
+	  return loadTGA(imgNameWithPath, texture);
+	}
+      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".png", 4))
+	{
+	  if (verbose >=2)
+	    printf ("Requested png-image. Trying to Import\n");
+	  return loadPNG(imgNameWithPath, texture);
+	}
+      else
+	{
+	  if (verbose >=1)
+	    printf ("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imgNameWithPath);
+	  return false;
+	}
+    }
+  else
+    {
+      if (verbose >=1)
+	printf ("Image not Found: %s\n", imgNameWithPath);
+      return false;
+    }
+}
+
+/**
+   \brief reads in a Windows BMP-file, and imports it to openGL.
+   \param bmpName The name of the Image to load.
+   \param texture A pointer to the Texture which should be read to.
+*/
+bool Material::loadBMP (char* bmpName, GLuint* texture)
+{
+  Image* pImage = new Image;
+  FILE *file;
+  unsigned long size;                 // size of the image in bytes.
+  unsigned long i;                    // standard counter.
+  unsigned short int planes;          // number of planes in image (must be 1) 
+  unsigned short int bpp;             // number of bits per pixel (must be 24)
+  GLuint temp;                          // temporary color storage for bgr-rgb conversion.
+
+  // make sure the file is there.
+  if ((file = fopen(bmpName, "rb"))==NULL)
+    {
+      if (verbose >=1)
+	printf("File Not Found : %s\n",bmpName);
+      return false;
+    }
+  // seek through the bmp header, up to the width/height:
+  fseek(file, 18, SEEK_CUR);
+  
+  // read the width
+  if ((i = fread(&pImage->width, 4, 1, file)) != 1) 
+    {
+      if (verbose >=1)
+	printf("Error reading width from %s.\n", bmpName);
+      return false;
+    }
+  // read the height 
+  if ((i = fread(&pImage->height, 4, 1, file)) != 1) 
+    {
+      if (verbose>=1)
+	printf("Error reading height from %s.\n", bmpName);
+      return false;
+    }
+  
+  // calculate the size (assuming 24 bits or 3 bytes per pixel).
+  size = pImage->width * pImage->height * 3;
+  
+  // read the planes
+  if ((fread(&planes, 2, 1, file)) != 1) 
+    {
+      if (verbose>=1)
+	printf("Error reading planes from %s.\n", bmpName);
+      return false;
+    }
+  if (planes != 1) 
+    {
+      if (verbose>=1)
+	printf("Planes from %s is not 1: %u\n", bmpName, planes);
+      return false;
+    }
+  
+  // read the bpp
+  if ((i = fread(&bpp, 2, 1, file)) != 1) 
+    {
+      if (verbose>=1)
+	printf("Error reading bpp from %s.\n", bmpName);
+      return false;
+    }
+  if (bpp != 24) 
+    {
+      if (verbose>=1)
+	printf("Bpp from %s is not 24: %u\n", bmpName, bpp);
+      return false;
+    }
+  
+  // seek past the rest of the bitmap header.
+  fseek(file, 24, SEEK_CUR);
+  
+  // read the data. 
+  pImage->data = (GLubyte *) malloc(size);
+  if (pImage->data == NULL) 
+    {
+      if (verbose>=1)
+	printf("Error allocating memory for color-corrected image data");
+      return false;	
+    }
+  
+  if ((i = fread(pImage->data, size, 1, file)) != 1) 
+    {
+      if (verbose>=1)
+	printf("Error reading image data from %s.\n", bmpName);
+      return false;
+    }
+  fclose(file);
+
+  // reverse all of the colors. (bgr -> rgb)
+  for (i=0;i<size;i+=3) 
+    { 
+      temp = pImage->data[i];
+      pImage->data[i] = pImage->data[i+2];
+      pImage->data[i+2] = temp;
+    }
+  loadTexToGL (pImage, texture);
+  
+  return true;
+
+  if (pImage)
+    {
+      if (pImage->data)
+	{
+	  free(pImage->data);
+	}
+      
+      free(pImage);
+    }
+
+}
+
+/**
+   \brief reads in a jpg-file
+   \param jpgName the Name of the Image to load
+   \param texture a reference to the Texture to write the image to
+*/
+bool Material::loadJPG (char* jpgName, GLuint* texture)
+{
+#ifdef HAVE_JPEGLIB_H
+  struct jpeg_decompress_struct cinfo;
+  Image *pImage = NULL;
+  FILE *pFile;
+  
+  // Open a file pointer to the jpeg file and check if it was found and opened 
+  if((pFile = fopen(jpgName, "rb")) == NULL) 
+    {
+      // Display an error message saying the file was not found, then return NULL
+      printf("Unable to load JPG File %s.\n", jpgName);
+      return false;
+    }
+  
+  // Create an error handler
+  jpeg_error_mgr jerr;
+  
+  // Have our compression info object point to the error handler address
+  cinfo.err = jpeg_std_error(&jerr);
+  
+  // Initialize the decompression object
+  jpeg_create_decompress(&cinfo);
+  
+  // Specify the data source (Our file pointer)	
+  jpeg_stdio_src(&cinfo, pFile);
+  
+  // Allocate the structure that will hold our eventual jpeg data (must free it!)
+  pImage = (Image*)malloc(sizeof(Image));
+  
+  // DECOFING
+  // Read in the header of the jpeg file
+  jpeg_read_header(&cinfo, TRUE);
+  
+  // Start to decompress the jpeg file with our compression info
+  jpeg_start_decompress(&cinfo);
+  
+  // Get the image dimensions and row span to read in the pixel data
+  pImage->rowSpan = cinfo.image_width * cinfo.num_components;
+  pImage->width   = cinfo.image_width;
+  pImage->height   = cinfo.image_height;
+  
+  // Allocate memory for the pixel buffer
+  pImage->data = new unsigned char[pImage->rowSpan * pImage->height];
+  
+  // Here we use the library's state variable cinfo.output_scanline as the
+  // loop counter, so that we don't have to keep track ourselves.
+  
+  // Create an array of row pointers
+  unsigned char** rowPtr = new unsigned char*[pImage->height];
+  for (int i = 0; i < pImage->height; i++)
+    rowPtr[i] = &(pImage->data[i*pImage->rowSpan]);
+  
+  // Now comes the juice of our work, here we extract all the pixel data
+  int rowsRead = 0;
+  while (cinfo.output_scanline < cinfo.output_height) 
+    {
+      // Read in the current row of pixels and increase the rowsRead count
+      rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead);
+    }
+  
+  // Delete the temporary row pointers
+  delete [] rowPtr;
+  
+  // Finish decompressing the data
+  jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage);
+  
+  // This releases all the stored memory for reading and decoding the jpeg
+  jpeg_destroy_decompress(&cinfo);
+  
+  // Close the file pointer that opened the file
+  fclose(pFile);
+  
+
+  if(pImage == NULL)
+    exit(0);
+  
+  loadTexToGL (pImage, texture);
+  if (pImage)
+    {
+      if (pImage->data)
+	{
+	  free(pImage->data);
+	}
+      
+      free(pImage);
+    }
+  return true;
+#else /* HAVE_JPEGLIB_H */
+  if (verbose >=1)
+    printf ("sorry, but you did not compile with jpeg-support.\nEither install SDL_image or jpeglib, and recompile to see the image\n");
+  return false;
+#endif /* HAVE_JPEGLIB_H */
+
+}
+
+/**
+   \brief reads in a tga-file
+   \param tgaName the Name of the Image to load
+   \param texture a reference to the Texture to write the image to
+*/
+bool Material::loadTGA(const char * tgaName, GLuint* texture)
+{
+  typedef struct
+  {
+    GLubyte Header[12];
+  } TGAHeader;
+  TGAHeader tgaHeader;			
+  
+  GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0};	// Uncompressed TGA Header 
+  GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};	// Compressed TGA Header 
+  FILE * fTGA;
+  fTGA = fopen(tgaName, "rb");
+
+  if(fTGA == NULL)
+    {
+      printf("Error could not open texture file: %s\n", tgaName);
+      return false;
+    }
+  
+  if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0)
+    {
+      printf("Error could not read file header of %s\n", tgaName);
+      if(fTGA != NULL)
+	{
+	  fclose(fTGA);
+	}
+      return false;
+    }
+  
+  if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
+    {
+      loadUncompressedTGA(tgaName, fTGA, texture);
+      if (fTGA)
+	fclose (fTGA);
+    }
+  else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
+    {
+      loadCompressedTGA(tgaName, fTGA, texture);
+	if (fTGA)
+	  fclose (fTGA);
+    }
+  else
+    {
+      printf("Error TGA file be type 2 or type 10\n");
+      if (fTGA)
+	fclose(fTGA);
+      return false;
+    }
+  return true;
+}
+
+/**
+   \brief reads in an uncompressed tga-file
+   \param filename the Name of the Image to load
+   \param fTGA a Pointer to a File, that should be read
+   \param texture a reference to the Texture to write the image to
+*/
+bool Material::loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
+{
+  GLubyte header[6];      // First 6 Useful Bytes From The Header 
+  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File 
+  GLuint  imageSize;	  // Used To Store The Image Size When Setting Aside Ram 
+  GLuint  temp;		  // Temporary Variable
+  GLuint  type;
+  GLuint  Height;	  // Height of Image 
+  GLuint  Width;	  // Width of Image 
+  GLuint  Bpp;		  // Bits Per Pixel 
+
+  Image* pImage = new Image;
+  GLuint cswap;
+  if(fread(header, sizeof(header), 1, fTGA) == 0)
+    {
+      printf("Error could not read info header\n");
+      return false;
+    }
+  
+  Width = pImage->width  = header[1] * 256 + header[0];
+  Height =  pImage->height = header[3] * 256 + header[2];
+  Bpp = pImage->bpp = header[4];
+  // Make sure all information is valid
+  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
+    {
+      printf("Error invalid texture information\n");
+      return false;
+    }
+  
+  if(pImage->bpp == 24)	
+    {
+      pImage->type = GL_RGB;
+    }
+  else
+    {
+      pImage->type = GL_RGBA;
+    }
+  
+  bytesPerPixel	= (Bpp / 8);
+  imageSize = (bytesPerPixel * Width * Height);
+  pImage->data = (GLubyte*) malloc(imageSize);
+  
+  if(pImage->data == NULL)
+    {
+      printf("Error could not allocate memory for image\n");
+      return false;
+    }
+  
+  if(fread(pImage->data, 1, imageSize, fTGA) != imageSize)
+    {
+      printf("Error could not read image data\n");
+      if(pImage->data != NULL)
+	{
+	  free(pImage->data);
+	}
+      return false;
+    }
+  
+  for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel)
+    {
+      pImage->data[cswap] ^= pImage->data[cswap+2] ^=
+	pImage->data[cswap] ^= pImage->data[cswap+2];
+    }
+  
+  loadTexToGL (pImage, texture);
+
+  return true;
+}
+
+/**
+   \brief reads in a compressed tga-file
+   \param filename the Name of the Image to load
+   \param fTGA a Pointer to a File, that should be read
+   \param texture a reference to the Texture to write the image to
+*/
+bool Material::loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
+{
+  GLubyte header[6];      // First 6 Useful Bytes From The Header 
+  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File 
+  GLuint  imageSize;	  // Used To Store The Image Size When Setting Aside Ram 
+  GLuint  temp;		  // Temporary Variable
+  GLuint  type;
+  GLuint  Height;	  // Height of Image 
+  GLuint  Width;	  // Width of Image 
+  GLuint  Bpp;		  // Bits Per Pixel 
+
+  Image* pImage = new Image;
+
+  
+  if(fread(header, sizeof(header), 1, fTGA) == 0)
+    {
+      printf("Error could not read info header\n");
+      return false;
+    }
+  
+  Width = pImage->width  = header[1] * 256 + header[0];
+  Height = pImage->height = header[3] * 256 + header[2];
+  Bpp = pImage->bpp	= header[4];
+
+  GLuint pixelcount	= Height * Width;
+  GLuint currentpixel	= 0;
+  GLuint currentbyte	= 0;
+  GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel);
+
+  //Make sure all pImage info is ok 
+  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
+    {
+      printf("Error Invalid pImage information\n");
+      return false;
+    }
+  
+  bytesPerPixel	= (Bpp / 8);
+  imageSize		= (bytesPerPixel * Width * Height);
+  pImage->data	= (GLubyte*) malloc(imageSize);
+  
+  if(pImage->data == NULL)
+    {
+      printf("Error could not allocate memory for image\n");
+      return false;
+    }
+  
+  do
+    {
+      GLubyte chunkheader = 0;
+      
+      if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
+	{
+	  printf("Error could not read RLE header\n");
+	  if(pImage->data != NULL)
+	    {
+	      free(pImage->data);
+	    }
+	  return false;
+	}
+      // If the ehader is < 128, it means the that is the number of RAW color packets minus 1 
+      if(chunkheader < 128)
+	{
+	  short counter;
+	  chunkheader++;
+	  // Read RAW color values
+	  for(counter = 0; counter < chunkheader; counter++)
+	    { 
+	      // Try to read 1 pixel 
+	      if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel)
+		{
+		  printf("Error could not read image data\n");
+		  if(colorbuffer != NULL)
+		    {
+		      free(colorbuffer);
+		    }
+		  
+		  if(pImage->data != NULL)
+		    {
+		      free(pImage->data);
+		    }
+		  
+		  return false;	
+		}
+	      // write to memory 
+	      // Flip R and B vcolor values around in the process 
+	      pImage->data[currentbyte	  ] = colorbuffer[2];				    
+	      pImage->data[currentbyte + 1] = colorbuffer[1];
+	      pImage->data[currentbyte + 2] = colorbuffer[0];
+	      
+	      if(bytesPerPixel == 4) // if its a 32 bpp image 
+		{
+		  pImage->data[currentbyte + 3] = colorbuffer[3];// copy the 4th byte 
+		}
+	      
+	      currentbyte += bytesPerPixel;
+	      currentpixel++;
+
+	      // Make sure we haven't read too many pixels 
+	      if(currentpixel > pixelcount)	
+		{
+		  printf("Error too many pixels read\n");
+		  if(colorbuffer != NULL)
+		    {
+		      free(colorbuffer);
+		    }
+		  
+		  if(pImage->data != NULL)
+		    {
+		      free(pImage->data);
+		    }
+		  
+		  return false;
+		}
+	    }
+	}
+      // chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times
+      else
+	{
+	  short counter;
+	  chunkheader -= 127;	// Subteact 127 to get rid of the ID bit 
+	  if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) // Attempt to read following color values 
+	    {
+	      printf("Error could not read from file");
+	      if(colorbuffer != NULL)
+		{
+		  free(colorbuffer);
+		}
+	      
+	      if(pImage->data != NULL)
+		{
+		  free(pImage->data);
+		}
+	      
+	      return false;
+	    }
+	  
+	  for(counter = 0; counter < chunkheader; counter++) //copy the color into the image data as many times as dictated
+	    {							
+	      // switch R and B bytes areound while copying
+	      pImage->data[currentbyte	  ] = colorbuffer[2];
+	      pImage->data[currentbyte + 1] = colorbuffer[1];
+	      pImage->data[currentbyte + 2] = colorbuffer[0];
+	      
+	      if(bytesPerPixel == 4)
+		{
+		  pImage->data[currentbyte + 3] = colorbuffer[3];
+		}
+	      
+	      currentbyte += bytesPerPixel;
+	      currentpixel++;
+	      
+	      if(currentpixel > pixelcount)
+		{
+		  printf("Error too many pixels read\n");
+		  if(colorbuffer != NULL)
+		    {
+		      free(colorbuffer);
+		    }
+		  
+		  if(pImage->data != NULL)
+		    {
+		      free(pImage->data);
+		    }
+		  
+		  return false;
+		}
+	    }
+	}
+    }
+  
+  while(currentpixel < pixelcount);	// Loop while there are still pixels left
+
+  loadTexToGL (pImage, texture);
+
+  return true;
+}
+
+
+/*
+static int ST_is_power_of_two(unsigned int number)
+{
+  return (number & (number - 1)) == 0;
+}
+*/
+
+/**
+   \brief reads in a png-file
+   \param pngName the Name of the Image to load
+   \param texture a reference to the Texture to write the image to
+*/
+bool Material::loadPNG(const char* pngName, GLuint* texture)
+{
+#ifdef HAVE_PNG_H
+  Image* pImage = new Image;
+
+  FILE *PNG_file = fopen(pngName, "rb");
+  if (PNG_file == NULL)
+    {
+      return 0;
+    }
+  
+  GLubyte PNG_header[8];
+  
+  fread(PNG_header, 1, 8, PNG_file);
+  if (png_sig_cmp(PNG_header, 0, 8) != 0)
+    {
+      if (verbose >=2)
+	printf ("Not Recognized as a pngFile\n");
+      fclose (PNG_file);
+      return 0;
+    }
+  
+  png_structp PNG_reader = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+  if (PNG_reader == NULL)
+    {
+      fclose(PNG_file);
+      return 0;
+    }
+  
+  png_infop PNG_info = png_create_info_struct(PNG_reader);
+  if (PNG_info == NULL)
+    {
+      png_destroy_read_struct(&PNG_reader, NULL, NULL);
+      fclose(PNG_file);
+      return 0;
+    }
+  
+  png_infop PNG_end_info = png_create_info_struct(PNG_reader);
+  if (PNG_end_info == NULL)
+    {
+      png_destroy_read_struct(&PNG_reader, &PNG_info, NULL);
+      fclose(PNG_file);
+      return 0;
+    }
+  
+  if (setjmp(png_jmpbuf(PNG_reader)))
+    {
+      png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
+      fclose(PNG_file);
+      return (0);
+    }
+  
+  png_init_io(PNG_reader, PNG_file);
+  png_set_sig_bytes(PNG_reader, 8);
+  
+  png_read_info(PNG_reader, PNG_info);
+  
+  pImage->width = png_get_image_width(PNG_reader, PNG_info);
+  pImage->height = png_get_image_height(PNG_reader, PNG_info);
+  
+  png_uint_32 bit_depth, color_type;
+  bit_depth = png_get_bit_depth(PNG_reader, PNG_info);
+  color_type = png_get_color_type(PNG_reader, PNG_info);
+  
+  if (color_type == PNG_COLOR_TYPE_PALETTE)
+    {
+      png_set_palette_to_rgb(PNG_reader);
+    }
+  
+  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+    {
+      png_set_gray_1_2_4_to_8(PNG_reader);
+    }
+  
+  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+    {
+      png_set_gray_to_rgb(PNG_reader);
+    }
+  
+  if (png_get_valid(PNG_reader, PNG_info, PNG_INFO_tRNS))
+    {
+      png_set_tRNS_to_alpha(PNG_reader);
+    }
+  else
+    {
+      png_set_filler(PNG_reader, 0xff, PNG_FILLER_AFTER);
+    }
+  
+  if (bit_depth == 16)
+    {
+      png_set_strip_16(PNG_reader);
+    }
+  
+  png_read_update_info(PNG_reader, PNG_info);
+  
+  pImage->data = (png_byte*)malloc(4 * pImage->width * pImage->height);
+  png_byte** PNG_rows = (png_byte**)malloc(pImage->height * sizeof(png_byte*));
+  
+  unsigned int row;
+  for (row = 0; row < pImage->height; ++row)
+    {
+      PNG_rows[pImage->height - 1 - row] = pImage->data + (row * 4 * pImage->width);
+    }
+  
+  png_read_image(PNG_reader, PNG_rows);
+  
+  free(PNG_rows);
+  
+  png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
+  fclose(PNG_file);
+  
+  /*  if (!ST_is_power_of_two(pImage->width) || !ST_is_power_of_two(pImage->height))
+    {
+      free(pImage->data);
+      return 0;
+    }
+  */
+  loadTexToGL (pImage, texture);  
+  
+  free(pImage->data);
+  
+  return true;
+#else /* HAVE_PNG_H */
+  if (verbose >=1)
+    printf ("sorry, but you did not compile with png-support.\nEither install SDL_image or libpng, and recompile to see the image\n");
+  return false;
+#endif /* HAVE_PNG_H */
+
+}
+
+#endif /* HAVE_SDL_SDL_IMAGE_H */
Index: /orxonox/trunk/src/material.h
===================================================================
--- /orxonox/trunk/src/material.h	(revision 3184)
+++ /orxonox/trunk/src/material.h	(revision 3185)
@@ -9,8 +9,36 @@
 extern int verbose; //!< will be obsolete soon.
 
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <stdlib.h>
-#include <fstream>
+#include "stdincl.h"
+
+#if HAVE_CONFIG_H 
+#include <config.h> 
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_SDL_SDL_IMAGE_H
+#include <SDL/SDL_image.h>
+#else
+// IMAGE LIBS //
+#ifdef HAVE_JPEGLIB_H
+extern "C"{         // This has to be done, because not a c++ lib
+#include <jpeglib.h>
+}
+#endif /* HAVE_JPEGLIB_H */
+#ifdef HAVE_PNG_H
+#include <png.h>
+#endif /* HAVE_PNG_H */
+#endif /* HAVE_SDL_SDL_IMAGE_H */
+
+class PathList
+{
+ public:
+  PathList();
+  PathList(char* pName);
+
+  ~PathList();
+  void addPath (char* pName);
+  char* pathName;
+  PathList* next;
+};
+
 
 //! Class to handle Materials.
@@ -21,8 +49,9 @@
   Material (char* mtlName);
   Material* addMaterial(char* mtlName);
+  ~Material ();
+  void init(void);
 
-  void init(void);
-  ~Material ();
-
+  Material* search (char* mtlName);
+  bool select (void);
 
   void setName (char* mtlName);
@@ -41,12 +70,27 @@
   void setTransparency (char* trans);
 
-  Material* search (char* mtlName);
 
-  bool select (void);
-
-  Material* nextMat; //!< pointer to the Next Material of the List. NULL if no next exists.
+ 
+  void addTexturePath(char* pathName);
+  char* searchTextureInPaths(char* texName) const;
+ // MAPPING //
+  void setDiffuseMap(char* dMap);
+  void setAmbientMap(char* aMap);
+  void setSpecularMap(char* sMap);
+  void setBump(char* bump);
 
  private:
-  char name [50];
+  struct Image
+  {
+    int rowSpan;
+    GLuint width;
+    GLuint height;
+    GLuint bpp;
+    GLuint type;
+    GLubyte *data;
+  };
+
+
+  char* name;
   int illumModel;
   float diffuse [4];
@@ -56,4 +100,34 @@
   float transparency;
 
+  static PathList* pathList;
+  
+  GLuint diffuseTexture;
+  GLuint ambientTexture;
+  GLuint specularTexture;
+  
+  bool diffuseTextureSet;
+  bool ambientTextureSet;
+  bool specularTextureSet;
+
+  Material* nextMat; //!< pointer to the Next Material of the List. NULL if no next exists.
+
+  // TEXTURING
+  bool loadTexToGL (Image* pImage, GLuint* texture);
+
+  bool loadImage(char* imageName, GLuint* texture);
+#ifndef HAVE_SDL_SDL_IMAGE_H
+
+  bool loadBMP (char* bmpName, GLuint* texture);
+
+  bool loadJPG (char* jpgName, GLuint* texture);
+
+  /// TGA ///
+
+  bool loadTGA(const char * tgaName, GLuint* texture);
+  bool loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture);
+  bool loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture);
+
+  bool loadPNG(const char* pngName, GLuint* texture);
+#endif
 };
 #endif
Index: /orxonox/trunk/src/object.cc
===================================================================
--- /orxonox/trunk/src/object.cc	(revision 3184)
+++ /orxonox/trunk/src/object.cc	(revision 3185)
@@ -17,4 +17,5 @@
 
 #include "object.h"
+using namespace std;
 
 /**
@@ -29,5 +30,7 @@
   BoxObject();
 
-  finalize();
+  importToGL ();
+
+  cleanup();
 }
 
@@ -42,5 +45,7 @@
   importFile (fileName);
 
-  finalize();
+  importToGL ();
+
+  cleanup();
 }
 
@@ -50,5 +55,4 @@
    \param scaling The factor that the object will be scaled with.
 */
-
 Object::Object(char* fileName, float scaling)
 {
@@ -58,5 +62,7 @@
   importFile (fileName);
 
-  finalize();
+  importToGL ();
+
+  cleanup();
 }
 
@@ -67,16 +73,116 @@
 {
   if (verbose >= 2)
-    printf ("Deleting display List.\n");
+    printf ("Deleting display Lists.\n");
   Group* walker = firstGroup;
   while (walker != NULL)
     {
       glDeleteLists (walker->listNumber, 1);
-      Group* lastWalker = walker;
-      walker = walker->nextGroup;
-      delete lastWalker;
-    } 
-}
-
-/** 
+      Group* delWalker = walker;
+      walker = walker->next;
+      delete delWalker;
+    }
+
+  if (objPath)
+    delete []objPath;
+  if (objFileName)
+    delete []objFileName;
+  if (mtlFileName)
+    delete []mtlFileName;
+
+  if (verbose >=2)
+    printf("Deleting Materials.\n");
+  if (material)
+    delete material;
+}
+
+
+/**
+   \brief Draws the Objects of all Groups.
+   It does this by just calling the Lists that must have been created earlier.
+*/
+void Object::draw (void) const
+{
+  if (verbose >=2)
+    printf("drawing the 3D-Objects\n"); 
+  Group* walker = firstGroup;
+  while (walker != NULL)
+    {
+      if (verbose >= 3)
+	printf ("Drawing object %s\n", walker->name);
+      glCallList (walker->listNumber);
+      walker = walker->next;
+    }
+}
+
+/**
+   \brief Draws the Object number groupNumber
+   It does this by just calling the List that must have been created earlier.
+   \param groupNumber The number of the group that will be displayed.
+*/
+void Object::draw (int groupNumber) const 
+{
+  if (groupNumber >= groupCount)
+    {
+      if (verbose>=1)
+	printf ("You requested object number %i, but this File only contains of %i Objects.\n", groupNumber-1, groupCount);
+      return;
+    }
+  if (verbose >=2)
+    printf("drawing the requested 3D-Objects if found.\n"); 
+  Group* walker = firstGroup;
+  int counter = 0;
+  while (walker != NULL)
+    {
+      if (counter == groupNumber)
+	{
+	  if (verbose >= 2)
+	    printf ("Drawing object number %i named %s\n", counter, walker->name);
+	  glCallList (walker->listNumber);
+	  return;
+	}
+      ++counter;
+      walker = walker->next;
+    }
+  if (verbose >= 1)
+    printf("Object number %i in %s not Found.\n", groupNumber, objFileName);
+  return;
+
+}
+
+/**
+   \brief Draws the Object with a specific groupName
+   It does this by just calling the List that must have been created earlier.
+   \param groupName The name of the group that will be displayed.
+*/
+void Object::draw (char* groupName) const
+{
+  if (verbose >=2)
+    printf("drawing the requested 3D-Objects if found.\n"); 
+  Group* walker = firstGroup;
+  while (walker != NULL)
+    {
+      if (!strcmp(walker->name, groupName))
+	{
+	  if (verbose >= 2)
+	    printf ("Drawing object %s\n", walker->name);
+	  glCallList (walker->listNumber);
+	  return;
+	}
+      walker = walker->next;
+    }
+  if (verbose >= 2)
+    printf("Object Named %s in %s not Found.\n", groupName, objFileName);
+  return;
+}
+
+/**
+   \returns Count of the Objects in this File
+*/
+int Object::getGroupCount (void) const
+{
+  return groupCount;
+}
+
+/**
     \brief initializes the Object
     This Function initializes all the needed arrays, Lists and clientStates
@@ -92,129 +198,16 @@
   groupCount = 0;
   
-  initGroup (currentGroup);
-  mtlFileName = "";
+  initGroup (firstGroup);
+  objPath = NULL;
+  objFileName = NULL;
+  mtlFileName = NULL;
   scaleFactor = 1;
   material = new Material();
 
-  glEnableClientState (GL_VERTEX_ARRAY);
-  //  glEnableClientState (GL_NORMAL_ARRAY);
-  //  glEnableClientState (GL_TEXTURE_COORD_ARRAY);
-
+  vertices = new Array();
+  vTexture = new Array();
+  normals = new Array();
 
   return true;
-}
-
-/**
-   \brief Imports a obj file and handles the the relative location
-   \param fileName The file to import
-*/
-bool Object::importFile (char* fileName)
-{
-  if (verbose >=3)
-    printf("preparing to read in file: %s\n", fileName);   
-  objFileName = fileName;
-  this->readFromObjFile (objFileName);
-  return true;
-}
-
-/**
-  \brief finalizes an Object.
-   This funcion is needed, to close the glList and all the other lists.
-*/
-bool Object::finalize(void)
-{
-  //  if (verbose >=3)
-    printf("finalizing the 3D-Object\n"); 
-  finalizeGroup (currentGroup);
-  if (material != NULL)
-    delete material;
-  return true;
-}
-
-/**
-   \brief Draws the Objects of all Groups.
-   It does this by just calling the Lists that must have been created earlier.
-*/
-void Object::draw (void)
-{
-  if (verbose >=2)
-    printf("drawing the 3D-Objects\n"); 
-  Group* walker = firstGroup;
-  while (walker != NULL)
-    {
-      if (verbose >= 3)
-	printf ("Drawing object %s\n", walker->name);
-      glCallList (walker->listNumber);
-      walker = walker->nextGroup;
-    }
-}
-
-/**
-   \brief Draws the Object number groupNumber
-   It does this by just calling the List that must have been created earlier.
-   \param groupNumber The number of the group that will be displayed.
-*/
-void Object::draw (int groupNumber)
-{
-  if (groupNumber >= groupCount)
-    {
-      if (verbose>=2)
-	printf ("You requested object number %i, but this File only contains of %i Objects.\n", groupNumber-1, groupCount);
-      return;
-    }
-  if (verbose >=2)
-    printf("drawing the requested 3D-Objects if found.\n"); 
-  Group* walker = firstGroup;
-  int counter = 0;
-  while (walker != NULL)
-    {
-      if (counter == groupNumber)
-	{
-	  if (verbose >= 2)
-	    printf ("Drawing object number %s named %s\n", counter, walker->name);
-	  glCallList (walker->listNumber);
-	  return;
-	}
-      ++counter;
-      walker = walker->nextGroup;
-    }
-  if (verbose >= 2)
-    printf("Object number %i in %s not Found.\n", groupNumber, objFileName);
-  return;
-
-}
-
-/**
-   \brief Draws the Object with a specific groupname
-   It does this by just calling the List that must have been created earlier.
-   \param groupName The name of the group that will be displayed.
-*/
-void Object::draw (char* groupName)
-{
-  if (verbose >=2)
-    printf("drawing the requested 3D-Objects if found.\n"); 
-  Group* walker = firstGroup;
-  while (walker != NULL)
-    {
-      if (!strcmp(walker->name, groupName))
-	{
-	  if (verbose >= 2)
-	    printf ("Drawing object %s\n", walker->name);
-	  glCallList (walker->listNumber);
-	  return;
-	}
-      walker = walker->nextGroup;
-    }
-  if (verbose >= 2)
-    printf("Object Named %s in %s not Found.\n", groupName, objFileName);
-  return;
-}
-
-/**
-   \returns Count of the Objects in this File
-*/
-int Object::getGroupCount (void)
-{
-  return groupCount;
 }
 
@@ -228,55 +221,148 @@
   group->name = "";
   group->faceMode = -1;
-  group->faceCount =0;  
-  if ((group->listNumber = glGenLists(1)) == 0 )
-    {
-      printf ("list could not be created for this Object\n");
-      return false;
-    }
+  group->faceCount = 0;  
+  group->next = NULL;
+
+  group->firstFace = new Face;
+  initFace (group->firstFace);
+  group->currentFace = group->firstFace;
+}
+
+/**
+   \brief initializes a new Face. (sets default Values)
+*/
+bool Object::initFace (Face* face)
+{
+  face->vertexCount = 0;
+
+  face->firstElem = NULL;
   
-  if (groupCount == 0)
-    {
-      group->firstVertex = 0;
-      group->firstNormal = 0;
-      group->firstNormal = 0;
-    }
-  else
-    {
-      group->firstVertex = currentGroup->firstVertex + currentGroup->vertices->getCount()/3;
-      group->firstNormal = currentGroup->firstNormal + currentGroup->normals->getCount()/3;
-      group->firstVertexTexture = currentGroup->firstVertexTexture + currentGroup->vTexture->getCount()/2;
-    }
+  face->materialString = NULL;
+  
+  face->next = NULL;
+
+  return true;
+}
+
+/**
+   \brief finalizes an Object.
+   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.
+*/
+bool Object::cleanup(void)
+{
   if (verbose >=2)
-    printf ("Creating new Arrays, with starting points v:%i, vt:%i, vn:%i .\n", group->firstVertex, group->firstVertexTexture, group->firstNormal);
-  group->vertices = new Array();
-  group->normals = new Array();
-  group->vTexture = new Array();
-
-  glNewList (group->listNumber, GL_COMPILE);
-}
-
-/**
-   \brief finalizes a Group.
-   \param group the group to finalize.
-*/
-bool Object::finalizeGroup(Group* group)
-{
+    printf("cleaning up the 3D-Object to save Memory.\n");
+
+  if (vertices != NULL)
+    delete vertices;
+  if (vTexture != NULL)
+    delete vTexture;
+  if (normals != NULL)
+    delete normals;
+
+  cleanupGroup(firstGroup);
+  return true; 
+}
+
+/**
+   \brief Cleans up all groups starting from group.
+   \param group the first Group to clean
+*/
+bool Object::cleanupGroup (Group* group)
+{
+  if (verbose>=4)
+    printf ("Cleaning up group\n");
+  if (group->firstFace != NULL)
+    {
+      cleanupFace (group->firstFace);
+      delete group->firstFace;
+    }
+
+  if (group->next !=NULL)
+    cleanupGroup (group->next);
+  return true;
+}
+
+/**
+   \brief Cleans up all Faces starting from face.
+   \param face the first face to clean
+*/
+bool Object::cleanupFace (Face* face)
+{
+  if (verbose>=4)
+    printf ("Cleaning up Face\n");
+
+  if (face->materialString != NULL)
+      delete []face->materialString;
+  if (face->firstElem != NULL)
+    {
+      cleanupFaceElement(face->firstElem);
+      delete face->firstElem;
+    }
+      
+  if (face->next != NULL)
+    {
+      cleanupFace (face->next);
+      delete face->next;
+    }
+      
+}
+
+
+/**
+   \brief Cleans up all FaceElements starting from faceElem.
+   \param faceElem the first FaceElement to clean.
+*/
+bool Object::cleanupFaceElement(FaceElement* faceElem)
+{
+  if (faceElem->next != NULL)
+    {
+      cleanupFaceElement (faceElem->next);
+      delete faceElem->next;
+    }
+}
+
+/**
+   \brief Imports a obj file and handles the the relative location
+   \param fileName The file to import
+*/
+bool Object::importFile (char* fileName)
+{
+  if (verbose >=3)
+    printf("preparing to read in file: %s\n", fileName);
+
+
+#ifdef __WIN32__
+  // win32 path reading
+  char pathSplitter= '\\';
+#else /* __WIN32__ */
+  // unix path reading
+  char pathSplitter='/';
+#endif /* __WIN32__ */
+  char* tmpName = fileName;
+  if (tmpName[0] == pathSplitter)
+    tmpName++;
+  char* name = tmpName;
+  while (( tmpName = strchr (tmpName+1, pathSplitter)))
+    {
+      name = tmpName+1;
+    }
+  objPath = new char[name-fileName];
+  strncpy(objPath, fileName, name-fileName);
+  objPath[name-fileName] = '\0';
   if (verbose >=2)
-    printf ("Finalize group %s.\n", group->name);
-  glEnd();
-  glEndList();
-}
-/**
-   \brief deletes the Arrays of the Group to save space.
-   \param group the group to delete the arrays from.
-*/
-bool Object::cleanupGroup(Group* group)
-{
-  if (verbose >=2)
-    printf ("cleaning up group %s.\n", group->name);
+    if (strlen(objPath)> 0)
+      {
+	printf("Resolved file %s to folder: %s.\n", name, objPath);
+      }
+    else
+      printf("Resolved file %s.\n", name);
   
-  delete group->vertices;
-  delete group->normals;
-  delete group->vTexture;
+  if (material)
+    material->addTexturePath(objPath);
+  objFileName = new char[strlen(name)+1];
+  strcpy (objFileName, name);
+  this->readFromObjFile ();
+  return true;
 }
 
@@ -284,17 +370,24 @@
    \brief Reads in the .obj File and sets all the Values.
    This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
-   \param fileName the File that will be parsed (.obj-file)
-*/
-bool Object::readFromObjFile (char* fileName)
-{
-  OBJ_FILE = new ifstream(fileName);
-  if (!OBJ_FILE->is_open())
+*/
+bool Object::readFromObjFile (void)
+{
+  char* fileName = new char [strlen(objPath)+strlen(objFileName)+1];
+  if (objFileName != NULL && !strcmp(objFileName, ""))
+    return false;
+  strcpy(fileName, objPath);
+  strcat(fileName, objFileName);
+
+  ifstream* OBJ_FILE = new ifstream(fileName);
+  if (OBJ_FILE->fail())
     {
       if (verbose >=1)
 	printf ("unable to open .OBJ file: %s\n Loading Box Object instead.\n", fileName);
       BoxObject();
+      delete []fileName;
       return false;
     }
-  objFileName = fileName;
+  if (verbose >=2)
+    printf ("Reading from opened file %s\n", fileName);
   char Buffer[10000];
   while(!OBJ_FILE->eof())
@@ -317,10 +410,10 @@
 	}
       
-      else if (!strncmp(Buffer, "mtllib", 6))
+      else if (!strncmp(Buffer, "mtllib ", 7))
 	{
 	  readMtlLib (Buffer+7);
 	}
 
-      else if (!strncmp(Buffer, "usemtl", 6))
+      else if (!strncmp(Buffer, "usemtl ", 7))
 	{
 	  readUseMtl (Buffer+7);
@@ -328,5 +421,5 @@
 
       // case VertexNormal
-      else if (!strncmp(Buffer, "vn ", 2))
+      else if (!strncmp(Buffer, "vn ", 3))
       {
 	readVertexNormal(Buffer+3);
@@ -334,16 +427,48 @@
 
       // case VertexTextureCoordinate
-      else if (!strncmp(Buffer, "vt ", 2))
+      else if (!strncmp(Buffer, "vt ", 3))
       {
 	readVertexTexture(Buffer+3);
       }
       // case group
-      else if (!strncmp(Buffer, "g", 1))
+      else if (!strncmp(Buffer, "g ", 2))
 	{
 	  readGroup (Buffer+2);
 	}
+      else if (!strncmp(Buffer, "s ", 2))
+	{
+	  if (verbose >= 2)
+	    printf("smoothing groups not supportet yet. line: %s\n", Buffer);
+	}
     }
   OBJ_FILE->close();
+  delete []fileName;
   return true;
+
+}
+
+/**
+   \brief parses a group String
+   This function initializes a new Group. 
+   With it you should be able to import .obj-files with more than one Objects inside. 
+   \param groupString the new Group to create
+*/
+bool Object::readGroup (char* groupString)
+{
+  if (verbose >=3)
+    printf ("Read Group: %s.\n", groupString);
+  if (groupCount != 0 && currentGroup->faceCount>0)
+    {
+      //      finalizeGroup(currentGroup);
+      currentGroup = currentGroup->next = new Group;
+      initGroup(currentGroup);
+    }
+  // setting the group name if not default.
+  if (strcmp(groupString, "default"))
+    {
+      currentGroup->name = new char [strlen(groupString)+1];
+      strcpy(currentGroup->name, groupString);
+    }
+  ++groupCount;
 
 }
@@ -356,12 +481,11 @@
 bool Object::readVertex (char* vertexString)
 {
-  readingVertices = true;
-  char subbuffer1[20];
-  char subbuffer2[20];
-  char subbuffer3[20];
-  sscanf (vertexString, "%s %s %s", subbuffer1, subbuffer2, subbuffer3);
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
   if (verbose >= 3)
-    printf ("reading in a vertex: %s %s %s\n", subbuffer1, subbuffer2, subbuffer3);
-  currentGroup->vertices->addEntry(atof(subbuffer1)*scaleFactor, atof(subbuffer2)*scaleFactor, atof(subbuffer3)*scaleFactor);
+    printf ("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
+  vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
   return true;
 }
@@ -375,85 +499,310 @@
 bool Object::readFace (char* faceString)
 {
-  // finalize the Arrays;
-  if (readingVertices == true)
-    {
-      currentGroup->vertices->finalizeArray();
-      //      glVertexPointer(3, GL_FLOAT, 0, currentGroup->vertices->getArray());
-      currentGroup->normals->finalizeArray();
-      //      glNormalPointer(GL_FLOAT, 0, currentGroup->normals->getArray());
-      currentGroup->vTexture->finalizeArray();
-    }
-
-  readingVertices = false;
-  currentGroup->faceCount++;
-
-  int elemCount = 0;
-  
-  FaceElement* firstElem = new FaceElement;
-  FaceElement* tmpElem = firstElem;
-
-  
+  if (currentGroup->faceCount >0)
+    currentGroup->currentFace = currentGroup->currentFace->next = new Face;
+  initFace (currentGroup->currentFace);
+
+  FaceElement* tmpElem = currentGroup->currentFace->firstElem = new FaceElement;
+  tmpElem->next = NULL;
   while(strcmp (faceString, "\0"))
     {
-      if (elemCount>0)
+      if (currentGroup->currentFace->vertexCount>0)
 	  tmpElem = tmpElem->next = new FaceElement;
       tmpElem->next = NULL;
 
-
-      sscanf (faceString, "%s", tmpElem->value);
-      faceString += strlen(tmpElem->value);
+      char tmpValue [50];
+      int tmpLen;
+      char* vertex = NULL;
+      char* texture = NULL;
+      char* normal = NULL;
+
+      sscanf (faceString, "%s", tmpValue);
+      tmpLen = strlen(tmpValue);
+      vertex = tmpValue;
+
+      if ((texture = strstr (vertex, "/")) != NULL)
+	{
+	  texture[0] = '\0';
+	  texture ++;
+	  
+	  if ((normal = strstr (texture, "/")) !=NULL)
+	    {
+	      normal[0] = '\0';
+	      normal ++;
+	    }	  
+	}
+      if (vertex)
+	tmpElem->vertexNumber = atoi(vertex)-1;
+      else
+	tmpElem->vertexNumber = -1;
+      if (texture)
+	tmpElem->texCoordNumber = atoi(texture)-1;
+      else
+	tmpElem->texCoordNumber = -1;
+      if (normal)
+	tmpElem->normalNumber = atoi(normal)-1;
+      else
+	tmpElem->normalNumber = -1;
+
+      faceString += tmpLen;
       if (strcmp (faceString, "\0"))
 	faceString++;
-      elemCount++;
-
-
-    }
+      currentGroup->currentFace->vertexCount++;
+    }
+
+  currentGroup->faceCount += currentGroup->currentFace->vertexCount -2;
+}
+
+/**
+   \brief parses a vertexNormal-String
+   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+   \param normalString The String that will be parsed.
+*/
+bool Object::readVertexNormal (char* normalString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  if (verbose >=3 )
+    printf("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
+  normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
+  return true;
+}
+
+/**
+   \brief parses a vertexTextureCoordinate-String
+   If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array
+   \param vTextureString The String that will be parsed.
+*/
+bool Object::readVertexTexture (char* vTextureString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
+  if (verbose >=3 )
+    printf("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
+  vTexture->addEntry(subbuffer1);
+  vTexture->addEntry(subbuffer2);
+  return true;
+}
+
+/** 
+    \brief Function to read in a mtl File.
+    this Function parses all Lines of an mtl File
+    \param mtlFile The .mtl file to read
+*/
+bool Object::readMtlLib (char* mtlFile)
+{
+  mtlFileName = new char [strlen(mtlFile)+1];
+  strcpy(mtlFileName, mtlFile);
+  char* fileName = new char [strlen(objPath) + strlen(mtlFileName)+1];
+  strcpy(fileName, objPath);
+  strcat(fileName, mtlFileName);
   
+
+  if (verbose >=2)
+    printf ("Opening mtlFile: %s\n", fileName);
+
+  ifstream* MTL_FILE = new ifstream (fileName);
+  if (MTL_FILE->fail())
+    {
+      if (verbose >= 1)
+	printf ("unable to open file: %s\n", fileName);
+      delete []fileName;
+      return false;
+    }
+  char Buffer[500];
+  Material* tmpMat = material;
+  while(!MTL_FILE->eof())
+    {
+      MTL_FILE->getline(Buffer, 500);
+      if (verbose >= 4)
+	printf("found line in mtlFile: %s\n", Buffer);
+      
+
+      // create new Material
+      if (!strncmp(Buffer, "newmtl ", 7))
+	{
+	  tmpMat = tmpMat->addMaterial(Buffer+7);
+	  //	  printf ("%s, %p\n", tmpMat->getName(), tmpMat);
+	}
+      // setting a illumMode
+      else if (!strncmp(Buffer, "illum ", 6))
+	{
+	  tmpMat->setIllum(Buffer+6);
+
+	}
+      // setting Diffuse Color
+      else if (!strncmp(Buffer, "Kd ", 3))
+	{
+	  tmpMat->setDiffuse(Buffer+3);
+	}
+      // setting Ambient Color
+      else if (!strncmp(Buffer, "Ka ", 3))
+	{
+	  tmpMat->setAmbient(Buffer+3);
+	}
+      // setting Specular Color
+      else if (!strncmp(Buffer, "Ks ", 3))
+	{
+	  tmpMat->setSpecular(Buffer+3);
+	}
+      // setting The Specular Shininess
+      else if (!strncmp(Buffer, "Ns ", 3))
+	{
+	  tmpMat->setShininess(Buffer+3);
+	}
+      // setting up transparency
+      else if (!strncmp(Buffer, "d ", 2))
+	{
+	  tmpMat->setTransparency(Buffer+2);
+	}
+      else if (!strncmp(Buffer, "Tf ", 3))
+	{
+	  tmpMat->setTransparency(Buffer+3);
+	}
+      
+      else if (!strncmp(Buffer, "map_Kd ", 7))
+	{
+	  tmpMat->setDiffuseMap(Buffer+7);
+	}
+      else if (!strncmp(Buffer, "map_Ka ", 7))
+	{
+	  tmpMat->setAmbientMap(Buffer+7);
+	}
+      else if (!strncmp(Buffer, "map_Ks ", 7))
+	{
+	  tmpMat->setSpecularMap(Buffer+7);
+	}
+      else if (!strncmp(Buffer, "bump ", 5))
+	{
+	  tmpMat->setBump(Buffer+7);
+	}
+     
+
+    }
+  delete []fileName;
+  return true;
+}
+
+/**
+   \brief Function that selects a material, if changed in the obj file.
+   \param matString the Material that will be set.
+*/
+bool Object::readUseMtl (char* matString)
+{
+  if (!mtlFileName)
+    {
+      if (verbose >= 1)
+	printf ("Not using new defined material, because no mtlFile found yet\n");
+      return false;
+    }
+      
+  if (currentGroup->faceCount >0)
+    currentGroup->currentFace = currentGroup->currentFace->next = new Face;
+  initFace (currentGroup->currentFace);
   
-  if (elemCount == 3)
-    {
-      if (currentGroup->faceMode != 3)
-	{
-	  if (currentGroup->faceMode != -1)
-	    glEnd();
-	  glBegin(GL_TRIANGLES);
-	}
-      
-      currentGroup->faceMode = 3;
-      if (verbose >=3)
-	printf ("found triag.\n");
-    }
+  currentGroup->currentFace->materialString = new char[strlen(matString)+1];
+  strcpy (currentGroup->currentFace->materialString, matString);
   
-  else if (elemCount == 4)
-    {
-      if (currentGroup->faceMode != 4)
-	{
-	  if (currentGroup->faceMode != -1)
-	    glEnd();
-	  glBegin(GL_QUADS);
-	}
-      currentGroup->faceMode = 4;
-      if (verbose >=3 )
-	printf ("found quad.\n");
-    }
-  
-  else if (elemCount > 4)
-    {
-      if (currentGroup->faceMode != -1)
-	glEnd();
-      glBegin(GL_POLYGON);
-      if (verbose >=3)
-	printf ("Polygon with %i faces found.", elemCount);
-      currentGroup->faceMode = elemCount;
-    }
-
-  tmpElem = firstElem;
-  while (tmpElem != NULL)
-    {
-      //      printf ("%s\n", tmpElem->value);
-      addGLElement(tmpElem->value);
-      tmpElem = tmpElem->next;
-    }
-
+  if (currentGroup->faceCount == 0)
+    currentGroup->faceCount ++;
+
+}
+
+/**
+   \brief reads and includes the Faces/Materials into the openGL state Machine
+*/
+bool Object::importToGL (void)
+{
+
+  // finalize the Arrays
+  vertices->finalizeArray();
+  vTexture->finalizeArray();
+  if (normals->getCount() == 0) // vertices-Array must be uilt for this
+    buildVertexNormals();
+  normals->finalizeArray();
+
+  currentGroup = firstGroup;
+
+  while (currentGroup != NULL)
+    {
+
+      // creating a glList for the Group
+      if ((currentGroup->listNumber = glGenLists(1)) == 0)
+	{
+	  printf ("list could not be created for this Object\n");
+	  return false;
+	}
+      glNewList (currentGroup->listNumber, GL_COMPILE);
+
+      // Putting Faces to GL
+      Face* tmpFace = currentGroup->firstFace;
+      while (tmpFace != NULL)
+	{
+	  if (tmpFace->vertexCount == 0 && tmpFace->materialString != NULL)
+	    {
+	      if (currentGroup->faceMode != -1)
+		glEnd();
+	      currentGroup->faceMode = 0;
+	      if (verbose >= 2)
+		printf ("using material %s for coming Faces.\n", tmpFace->materialString);
+	      Material* tmpMat;
+	      if ((tmpMat = material->search(tmpFace->materialString)) != NULL)
+		tmpMat->select();
+
+	    }
+
+	  else if (tmpFace->vertexCount == 3)
+	    {
+	      if (currentGroup->faceMode != 3)
+		{
+		  if (currentGroup->faceMode != -1)
+		    glEnd();
+		  glBegin(GL_TRIANGLES);
+		}
+	      
+	      currentGroup->faceMode = 3;
+	      if (verbose >=3)
+		printf ("found triag.\n");
+	    }
+	  
+	  else if (tmpFace->vertexCount == 4)
+	    {
+	      if (currentGroup->faceMode != 4)
+		{
+		  if (currentGroup->faceMode != -1)
+		    glEnd();
+		  glBegin(GL_QUADS);
+		}
+	      currentGroup->faceMode = 4;
+	      if (verbose >=3 )
+		printf ("found quad.\n");
+	    }
+	  
+	  else if (tmpFace->vertexCount > 4)
+	    {
+	      if (currentGroup->faceMode != -1)
+		glEnd();
+	      glBegin(GL_POLYGON);
+	      if (verbose >=3)
+		printf ("Polygon with %i faces found.", tmpFace->vertexCount);
+	      currentGroup->faceMode = tmpFace->vertexCount;
+	    }
+	  
+	  FaceElement* tmpElem = tmpFace->firstElem;
+	  while (tmpElem != NULL)
+	    {
+	      //      printf ("%s\n", tmpElem->value);
+	      addGLElement(tmpElem);
+	      tmpElem = tmpElem->next;
+	    }
+	  tmpFace = tmpFace->next;
+	}
+      glEnd();
+      glEndList();
+      currentGroup = currentGroup->next;
+    } 
 }
 
@@ -467,191 +816,97 @@
 
 */
-bool Object::addGLElement (char* elementString)
+bool Object::addGLElement (FaceElement* elem)
 {
   if (verbose >=3)
-    printf ("importing grafical Element to openGL\n");
-  char* vertex = elementString;
-
-  char* texture;
-  if ((texture = strstr (vertex, "/")) != NULL)
-    {
-      texture[0] = '\0';
-      texture ++;
-      if (verbose>=3)
-	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());
-      glTexCoord2fv(currentGroup->vTexture->getArray()+(atoi(texture)-1 - currentGroup->firstVertexTexture)*2);
-
-      char* normal;
-      if ((normal = strstr (texture, "/")) !=NULL)
-	{
-	  normal[0] = '\0';
-	  normal ++;
-	  //glArrayElement(atoi(vertex)-1);
-	  glNormal3fv(currentGroup->normals->getArray() +(atoi(normal)-1 - currentGroup->firstNormal)*3);
-	}
-    }
-  if (verbose>=3)
-    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());
-  glVertex3fv(currentGroup->vertices->getArray() +(atoi(vertex)-1 - currentGroup->firstVertex)*3);
-
-}
-
-/**
-   \brief parses a vertexNormal-String
-   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
-   \param normalString The String that will be parsed.
-*/
-bool Object::readVertexNormal (char* normalString)
-{
-  readingVertices = true;
-  char subbuffer1[20];
-  char subbuffer2[20];
-  char subbuffer3[20];
-  sscanf (normalString, "%s %s %s", subbuffer1, subbuffer2, subbuffer3);
-  if (verbose >=3 )
-    printf("found vertex-Normal %s, %s, %s\n", subbuffer1,subbuffer2,subbuffer3);
-  currentGroup->normals->addEntry(atof(subbuffer1), atof(subbuffer2), atof(subbuffer3));
-  return true;
-}
-
-/**
-   \brief parses a vertexTextureCoordinate-String
-   If a vertexTextureCoordinate line is found this function will inject it into the vertexTexture-Array
-   \param vTextureString The String that will be parsed.
-*/
-bool Object::readVertexTexture (char* vTextureString)
-{
-  readingVertices = true;
-  char subbuffer1[20];
-  char subbuffer2[20];
-  sscanf (vTextureString, "%s %s", subbuffer1, subbuffer2);
-  if (verbose >=3 )
-    printf("found vertex-Texture %s, %s\n", subbuffer1,subbuffer2);
-  currentGroup->vTexture->addEntry(atof(subbuffer1));
-  currentGroup->vTexture->addEntry(atof(subbuffer2));
-  return true;
-}
-
-/**
-   \brief parses a group String
-   This function initializes a new Group. 
-   With it you should be able to import .obj-files with more than one Objects inside. 
-   \param groupString the new Group to create
-*/
-bool Object::readGroup (char* groupString)
-{
-  // setting the group name if not default.
-  if (strcmp(currentGroup->name, "default"))
-    {
-      currentGroup->name = (char*) malloc ( strlen(groupString) * sizeof (char));
-      strcpy(currentGroup->name, groupString);
-    }
-  if (groupCount != 0 && currentGroup->faceCount>0)
-    {
-      Group* newGroup = new Group;
-      finalizeGroup(currentGroup);
-      currentGroup->nextGroup = newGroup;
-      initGroup(newGroup);
-      cleanupGroup(currentGroup); // deletes the arrays of the group; must be after initGroup.
-      currentGroup = newGroup; // must be after init see initGroup for more info
-    }
-
-  ++groupCount;
-
-}
-
-/** 
-    \brief Function to read in a mtl File.
-    this Function parses all Lines of an mtl File
-    \param mtlFile The .mtl file to read
-*/
-bool Object::readMtlLib (char* mtlFile)
-{
-  MTL_FILE = new ifstream (mtlFile);
-  if (!MTL_FILE->is_open())
-    {
-      if (verbose >= 1)
-	printf ("unable to open file: %s\n", mtlFile);
-      return false;
-    }
-  mtlFileName = mtlFile;
+    printf ("importing grafical Element to openGL.\n");
+
+  if (elem->texCoordNumber != -1)
+    glTexCoord2fv(vTexture->getArray() + elem->texCoordNumber * 2);
+  if (elem->normalNumber != -1)
+    glNormal3fv(normals->getArray() + elem->normalNumber * 3);
+  if (elem->vertexNumber != -1)
+    glVertex3fv(vertices->getArray() + elem->vertexNumber * 3);
+
+}
+
+/**
+   \brief A routine that is able to create normals.
+   The algorithm does the following:
+   1. It calculates creates Vectors for each normale, and sets them to zero.
+   2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
+   3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
+   4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
+*/
+bool Object::buildVertexNormals ()
+{
+  
   if (verbose >=2)
-    printf ("Opening mtlFile: %s\n", mtlFileName);
-  char Buffer[500];
-  Material* tmpMat = material;
-  while(!MTL_FILE->eof())
-    {
-      MTL_FILE->getline(Buffer, 500);
-      if (verbose >= 4)
-	printf("found line in mtlFile: %s\n", Buffer);
-      
-
-      // create new Material
-      if (!strncmp(Buffer, "newmtl ", 2))
-	{
-	  tmpMat = tmpMat->addMaterial(Buffer+7);
-	  //	  printf ("%s, %p\n", tmpMat->getName(), tmpMat);
-	}
-      // setting a illumMode
-      else if (!strncmp(Buffer, "illum", 5))
-	{
-	  tmpMat->setIllum(Buffer+6);
-
-	}
-      // setting Diffuse Color
-      else if (!strncmp(Buffer, "Kd", 2))
-	{
-	  tmpMat->setDiffuse(Buffer+3);
-	}
-      // setting Ambient Color
-      else if (!strncmp(Buffer, "Ka", 2))
-	{
-	  tmpMat->setAmbient(Buffer+3);
-	}
-      // setting Specular Color
-      else if (!strncmp(Buffer, "Ks", 2))
-	{
-	  tmpMat->setSpecular(Buffer+3);
-	}
-      // setting The Specular Shininess
-      else if (!strncmp(Buffer, "Ns", 2))
-	{
-	  tmpMat->setShininess(Buffer+3);
-	}
-      // setting up transparency
-      else if (!strncmp(Buffer, "d", 1))
-	{
-	  tmpMat->setTransparency(Buffer+2);
-	}
-      else if (!strncpy(Buffer, "Tf", 2))
-	{
-	  tmpMat->setTransparency(Buffer+3);
-	}
-
-    }
-  return true;
-}
-
-/**
-   \brief Function that selects a material, if changed in the obj file.
-   \param matString the Material that will be set.
-*/
-
-bool Object::readUseMtl (char* matString)
-{
-  if (!strcmp (mtlFileName, ""))
-    {
-      if (verbose >= 1)
-	printf ("Not using new defined material, because no mtlFile found yet\n");
-      return false;
-    }
-      
-  if (currentGroup->faceMode != -1)
-    glEnd();
-  currentGroup->faceMode = 0;
-  if (verbose >= 2)
-    printf ("using material %s for coming Faces.\n", matString);
-  material->search(matString)->select();
-}
+    printf("Normals are being calculated.\n");
+
+  Vector* normArray = new Vector [vertices->getCount()/3];
+  for (int i=0; i<vertices->getCount()/3;i++)
+    normArray[i] = Vector(.0,.0,.0);
+  
+  int firstTouch;
+  int secondTouch;
+  Vector prevV;
+  Vector nextV;
+  Vector curV;
+
+  Group* tmpGroup = firstGroup;
+  while (tmpGroup)
+    {
+      Face* tmpFace = tmpGroup->firstFace;
+      while (tmpFace)
+	{
+	  if (tmpFace->firstElem)
+	    {
+	      FaceElement* firstElem = tmpFace->firstElem;
+	      FaceElement* prevElem;
+	      FaceElement* curElem = firstElem;
+	      FaceElement* nextElem;
+	      FaceElement* lastElem;
+	      // 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.
+	      while (curElem)
+		{
+		  prevElem = curElem;
+		  curElem = curElem->next;
+		}
+	      lastElem = prevElem;
+	      
+	      curElem = firstElem;
+	      for (int j=0; j<tmpFace->vertexCount; j++)
+		{
+		  if (!(nextElem = curElem->next))
+		    nextElem = firstElem;
+		  curElem->normalNumber = curElem->vertexNumber;
+		  
+		  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
+		  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
+		  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV;
+		  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
+
+		  prevElem = curElem;
+		  curElem = curElem->next;
+		}
+	    }
+	  tmpFace = tmpFace->next;
+	}
+      tmpGroup = tmpGroup->next;
+    }
+
+  for (int i=0; i<vertices->getCount()/3;i++)
+    {
+      normArray[i].normalize();
+      if (verbose >=3)
+	printf ("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
+
+      normals->addEntry(normArray[i].x, normArray[i].y, normArray[i].z);
+
+    }
+  delete []normArray; 
+  
+}
+
 
 /**
@@ -669,4 +924,5 @@
   readVertex ("-0.500000 -0.500000 -0.500000");
   readVertex ("0.500000 -0.500000 -0.500000");
+
   readVertexTexture ("0.000000 0.000000");
   readVertexTexture ("1.000000 0.000000");
@@ -683,5 +939,5 @@
   readVertexTexture ("-1.000000 0.000000");
   readVertexTexture ("-1.000000 1.000000");
-  
+
   readVertexNormal ("0.000000 0.000000 1.000000");
   readVertexNormal ("0.000000 0.000000 1.000000");
@@ -709,4 +965,13 @@
   readVertexNormal ("-1.000000 0.000000 0.000000");
 
+  /* normaleLess-testingMode
+  readFace ("1 2 4 3");
+  readFace ("3 4 6 5");
+  readFace ("5 6 8 7");
+  readFace ("7 8 2 1");
+  readFace ("2 8 6 4");
+  readFace ("7 1 3 5");
+  */
+
   readFace ("1/1/1 2/2/2 4/4/3 3/3/4");
   readFace ("3/3/5 4/4/6 6/6/7 5/5/8");
@@ -715,3 +980,4 @@
   readFace ("2/2/17 8/11/18 6/12/19 4/4/20");
   readFace ("7/13/21 1/1/22 3/3/23 5/14/24");
-}
+
+}
Index: /orxonox/trunk/src/object.h
===================================================================
--- /orxonox/trunk/src/object.h	(revision 3184)
+++ /orxonox/trunk/src/object.h	(revision 3185)
@@ -7,21 +7,16 @@
 #define _OBJECT_H
 
-#include <GL/gl.h>
-#include <GL/glu.h>
+#include "stdincl.h"
 
 #include "array.h"
 #include "material.h"
+#include "vector.h"
 #include <fstream>
 
 using namespace std;
 
-extern int verbose; //!< fill be removed and added again as a verbose-class
+extern int verbose; //!< Will be removed and added again as a verbose-class.
 
 
-struct FaceElement
-{
-  char value[20];
-  FaceElement* next;
-};
 
 //! Class that handles 3D-Objects. it can also read them in and display them.
@@ -34,13 +29,29 @@
   ~Object ();
   
-  bool importFile (char* fileName);
-  bool initialize (void);
-  bool finalize(void);
-  void draw (void);
-  void draw (int groupNumber);
-  void draw (char* groupName);
-  int getGroupCount();
+  void draw (void) const;
+  void draw (int groupNumber) const;
+  void draw (char* groupName) const;
+  int getGroupCount() const;
 
  private:
+  struct FaceElement
+  {
+    int vertexNumber;
+    int normalNumber;
+    int texCoordNumber;
+    FaceElement* next;
+  };
+
+  //! Face
+  struct Face
+  {
+    int vertexCount;
+    FaceElement* firstElem;
+
+    char* materialString;
+
+    Face* next;
+  };
+
   //! Group to handle multiple Objects per obj-file
   struct Group
@@ -49,18 +60,19 @@
 
     GLuint listNumber;
-    Array* vertices;
-    int verticesCount;
-    Array* colors;
-    Array* normals;
-    Array* vTexture;
+    Face* firstFace;
+    Face* currentFace;
     int faceMode;
     int faceCount;
 
-    int firstVertex;
-    int firstNormal;
-    int firstVertexTexture;
+    Group* next;
+  };
 
-    Group* nextGroup;
-  };
+
+  Array* vertices;
+  int verticesCount;
+  Array* colors;
+  Array* normals;
+  Array* vTexture;
+
   
   Group* firstGroup; //!< the first of all groups.
@@ -68,33 +80,35 @@
   int groupCount;
 
-  bool readingVertices;
+  Material* material;
+  float scaleFactor;
 
+  char* objPath;
   char* objFileName;
   char* mtlFileName;
 
-  Material* material;
-  float scaleFactor;
-
-  ifstream* OBJ_FILE;
-  ifstream* MTL_FILE;
-
+  bool initialize (void);
   bool initGroup(Group* group);
-  bool finalizeGroup (Group* group);
+  bool initFace (Face* face);
+  bool cleanup(void);
   bool cleanupGroup(Group* group);
-
+  bool cleanupFace(Face* face);
+  bool cleanupFaceElement(FaceElement* faceElem);
 
   ///// readin ///
-  bool readFromObjFile (char* fileName);
+  bool importFile (char* fileName);
+  bool readFromObjFile (void);
   
+  bool readGroup (char* groupString);
   bool readVertex (char* vertexString);
   bool readFace (char* faceString);
-  bool readVT (char* vtString);
   bool readVertexNormal (char* normalString);
   bool readVertexTexture (char* vTextureString);
-  bool readGroup (char* groupString);
   bool readMtlLib (char* matFile);
   bool readUseMtl (char* mtlString);
 
-  bool addGLElement (char* elementString);
+  bool importToGL (void);
+  bool addGLElement (FaceElement* elem);
+
+  bool buildVertexNormals ();
 
   void BoxObject (void);
