Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 3185 in orxonox.OLD for orxonox/trunk/src/material.cc


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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 */
Note: See TracChangeset for help on using the changeset viewer.