Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/images/importer/material.cc @ 3097

Last change on this file since 3097 was 3097, checked in by bensch, 21 years ago

orxonox/branches/images: doxygen-tags, comments, etc.

File size: 22.8 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14
15   TGA-code: borrowed from nehe-Tutorials
16*/
17
18#include "material.h"
19
20/**
21   \brief creates a default Material with no Name
22   normally you call this to create a material List (for an obj-file) and then append with addMaterial()
23*/
24Material::Material()
25{
26  init();
27 
28  setName ("");
29}
30
31/**
32   \brief creates a Material.
33   \param mtlName Name of the Material to be added to the Material List
34*/
35Material::Material (char* mtlName)
36{
37  init();
38 
39  setName (mtlName);
40}
41
42/**
43    \brief deletes a Material
44*/
45Material::~Material()
46{
47  if (name)
48    delete []name;
49  if (diffuseTextureSet)
50    glDeleteTextures (1, &diffuseTexture);
51  if (verbose >= 2)
52    printf ("delete Material %s.\n", name);
53  if (nextMat != NULL)
54    delete nextMat;
55}
56
57/**
58   \brief adds a new Material to the List.
59   this Function will append a new Material to the end of a Material List.
60   \param mtlName The name of the Material to be added.
61*/
62Material* Material::addMaterial(char* mtlName)
63{
64  if (verbose >=2)
65    printf ("adding Material %s.\n", mtlName);
66  Material* newMat = new Material(mtlName);
67  Material* tmpMat = this;
68  while (tmpMat->nextMat != NULL)
69    {
70      tmpMat = tmpMat->nextMat;
71    }
72  tmpMat->nextMat = newMat;
73  return newMat;
74 
75}
76
77/**
78   \brief initializes a new Material with its default Values
79*/
80void Material::init(void)
81{
82  if (verbose >= 3)
83    printf ("initializing new Material.\n");
84  nextMat = NULL;
85
86  setIllum(1);
87  setDiffuse(0,0,0);
88  setAmbient(0,0,0);
89  setSpecular(.5,.5,.5);
90  setShininess(2.0);
91  setTransparency(0.0);
92
93  diffuseTextureSet = false;
94  ambientTextureSet = false;
95  specularTextureSet = false;
96
97 
98}
99
100/**
101   \brief Search for a Material called mtlName
102   \param mtlName the Name of the Material to search for
103   \returns Material named mtlName if it is found. NULL otherwise.
104*/
105Material* Material::search (char* mtlName)
106{
107  if (verbose >=3)
108    printf ("Searching for material %s", mtlName);
109  Material* searcher = this;
110  while (searcher != NULL)
111    {
112      if (verbose >= 3)
113        printf (".");
114      if (!strcmp (searcher->getName(), mtlName))
115        {
116          if (verbose >= 3)
117            printf ("found.\n");
118          return searcher;
119        }
120      searcher = searcher->nextMat;
121    }
122  if (verbose >=3)
123    printf ("not found\n");
124  return NULL;
125}
126
127/**
128   \brief sets the material with which the following Faces will be painted
129*/
130bool Material::select (void)
131{
132  // setting diffuse color
133  //  glColor3f (diffuse[0], diffuse[1], diffuse[2]);
134  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
135
136  // setting ambient color
137  glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
138
139  // setting up Sprecular
140  glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
141
142  // setting up Shininess
143  glMaterialf(GL_FRONT, GL_SHININESS, shininess);
144 
145  // setting illumination Model
146  if (illumModel == 1)
147    glShadeModel(GL_FLAT);
148  else if (illumModel >= 2)
149    glShadeModel(GL_SMOOTH);
150
151  if (diffuseTextureSet)
152    glBindTexture(GL_TEXTURE_2D, diffuseTexture);
153  else
154    glBindTexture(GL_TEXTURE_2D, 0);
155 
156}
157
158
159/**
160   \brief Set the Name of the Material. (Important for searching)
161   \param mtlName the Name of the Material to be set.
162*/ 
163void Material::setName (char* mtlName)
164{
165  if (verbose >= 3)
166    printf("setting Material Name to %s.\n", mtlName);
167  name = new char [strlen(mtlName)];
168  strcpy(name, mtlName);
169  //  printf ("adding new Material: %s, %p\n", this->getName(), this);
170
171}
172/**
173   \returns The Name of The Material
174*/
175char* Material::getName (void)
176{
177  return name;
178}
179
180/**
181   \brief Sets the Material Illumination Model.
182   \brief illu illumination Model in int form
183*/
184void Material::setIllum (int illum)
185{
186  if (verbose >= 3)
187    printf("setting illumModel of Material %s to %i", name, illum);
188  illumModel = illum;
189  //  printf ("setting illumModel to: %i\n", illumModel);
190}
191/**
192   \brief Sets the Material Illumination Model.
193   \brief illu illumination Model in char* form
194*/void Material::setIllum (char* illum)
195{
196  setIllum (atoi(illum));
197}
198
199/**
200   \brief Sets the Material Diffuse Color.
201   \param r Red Color Channel.
202   \param g Green Color Channel.
203   \param b Blue Color Channel.
204*/
205void Material::setDiffuse (float r, float g, float b)
206{
207  if (verbose >= 3)
208    printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
209  diffuse[0] = r;
210  diffuse[1] = g;
211  diffuse[2] = b; 
212  diffuse[3] = 1.0;
213
214}
215/**
216   \brief Sets the Material Diffuse Color.
217   \param rgb The red, green, blue channel in char format (with spaces between them)
218*/
219void Material::setDiffuse (char* rgb)
220{
221  char r[20],g[20],b[20];
222  sscanf (rgb, "%s %s %s", r, g, b);
223  setDiffuse (atof(r), atof(g), atof(b));
224}
225
226/**
227   \brief Sets the Material Ambient Color.
228   \param r Red Color Channel.
229   \param g Green Color Channel.
230   \param b Blue Color Channel.
231*/
232void Material::setAmbient (float r, float g, float b)
233{
234  if (verbose >=3)
235    printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
236  ambient[0] = r;
237  ambient[1] = g;
238  ambient[2] = b;
239  ambient[3] = 1.0;
240}
241/**
242   \brief Sets the Material Ambient Color.
243   \param rgb The red, green, blue channel in char format (with spaces between them)
244*/
245void Material::setAmbient (char* rgb)
246{
247  char r[20],g[20],b[20];
248  sscanf (rgb, "%s %s %s", r, g, b);
249  setAmbient (atof(r), atof(g), atof(b));
250}
251
252/**
253   \brief Sets the Material Specular Color.
254   \param r Red Color Channel.
255   \param g Green Color Channel.
256   \param b Blue Color Channel.
257*/
258void Material::setSpecular (float r, float g, float b)
259{
260  if (verbose >= 3)
261    printf ("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
262  specular[0] = r;
263  specular[1] = g;
264  specular[2] = b;
265  specular[3] = 1.0;
266 }
267/**
268   \brief Sets the Material Specular Color.
269   \param rgb The red, green, blue channel in char format (with spaces between them)
270*/
271void Material::setSpecular (char* rgb)
272{
273  char r[20],g[20],b[20];
274  sscanf (rgb, "%s %s %s", r, g, b);
275  setSpecular (atof(r), atof(g), atof(b));
276}
277
278/**
279   \brief Sets the Material Shininess.
280   \param shini stes the Shininess from float.
281*/
282void Material::setShininess (float shini)
283{
284  shininess = shini;
285}
286/**
287   \brief Sets the Material Shininess.
288   \param shini stes the Shininess from char*.
289*/
290void Material::setShininess (char* shini)
291{
292  setShininess (atof(shini));
293}
294
295/**
296   \brief Sets the Material Transparency.
297   \param trans stes the Transparency from int.
298*/
299void Material::setTransparency (float trans)
300{
301  if (verbose >= 3)
302    printf ("setting Transparency of Material %s to %f.\n", name, trans);
303  transparency = trans;
304}
305/**
306   \brief Sets the Material Transparency.
307   \param trans stes the Transparency from char*.
308*/
309void Material::setTransparency (char* trans)
310{
311  char tr[20];
312  sscanf (trans, "%s", tr);
313  setTransparency (atof(tr));
314}
315
316// MAPPING //
317
318/**
319   \brief Sets the Materials Diffuse Map
320   \param dMap the Name of the Image to Use
321*/
322void Material::setDiffuseMap(char* dMap)
323{
324  if (verbose>=2)
325    printf ("setting Diffuse Map %s\n", dMap);
326
327  //  diffuseTextureSet = loadBMP(dMap, &diffuseTexture);
328  diffuseTextureSet = loadImage(dMap, &diffuseTexture);
329
330}
331
332/**
333   \brief Sets the Materials Ambient Map
334   \param aMap the Name of the Image to Use
335*/
336void Material::setAmbientMap(char* aMap)
337{
338  SDL_Surface* ambientMap;
339
340}
341
342/**
343   \brief Sets the Materials Specular Map
344   \param sMap the Name of the Image to Use
345*/
346void Material::setSpecularMap(char* sMap)
347{
348  SDL_Surface* specularMap;
349
350}
351
352/**
353   \brief Sets the Materials Bumpiness
354   \param bump the Name of the Image to Use
355*/
356void Material::setBump(char* bump)
357{
358
359}
360
361bool Material::loadTexToGL (Image* pImage, GLuint* texture)
362{
363  glGenTextures(1, texture);
364  glBindTexture(GL_TEXTURE_2D, *texture);
365  /* not Working, and not needed.
366  glTexImage2D( GL_TEXTURE_2D, 0, 3, width,
367                height, 0, GL_BGR,
368                GL_UNSIGNED_BYTE, map->pixels );
369  */ 
370  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->width, pImage->height, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
371 
372  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
373  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); 
374}
375
376
377
378/**
379   \brief Makes the Programm ready to Read-in a texture-File
380   1. Checks what type of Image should be imported
381   2. ToDO: Checks where to find the Image
382*/
383bool Material::loadImage(char* imageName, GLuint* texture)
384{
385  if (!strncmp(imageName+strlen(imageName)-4, ".bmp", 4))
386    {
387      if (verbose >=2)
388        printf ("Requested bmp-image. Trying to Import.\n");
389      return loadBMP(imageName, texture);
390    }
391
392  else if (!strncmp(imageName+strlen(imageName)-4, ".jpg", 4) || !strncmp(imageName+strlen(imageName)-5, ".jpg", 5))
393    {
394      if (verbose >=2)
395        printf ("Requested jpeg-image. Trying to Import\n");
396      return loadJPG(imageName, texture);
397    }
398  else if (!strncmp(imageName+strlen(imageName)-4, ".tga", 4))
399    {
400      if (verbose >=2)
401        printf ("Requested tga-image. Trying to Import\n");
402      return loadTGA(imageName, texture);
403    }
404  else
405    {
406      if (verbose >=1)
407        printf ("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imageName);
408      return false;
409    }
410
411}
412
413/**
414   \brief reads in a Windows BMP-file, and imports it to openGL.
415   \param bmpName The name of the Image to load.
416   \param texture A pointer to the Texture which should be read to.
417*/
418bool Material::loadBMP (char* bmpName, GLuint* texture)
419{
420  Image* pImage = new Image;
421  FILE *file;
422  unsigned long size;                 // size of the image in bytes.
423  unsigned long i;                    // standard counter.
424  unsigned short int planes;          // number of planes in image (must be 1)
425  unsigned short int bpp;             // number of bits per pixel (must be 24)
426  GLuint temp;                          // temporary color storage for bgr-rgb conversion.
427
428  // make sure the file is there.
429  if ((file = fopen(bmpName, "rb"))==NULL)
430    {
431      if (verbose >=1)
432        printf("File Not Found : %s\n",bmpName);
433      return false;
434    }
435  // seek through the bmp header, up to the width/height:
436  fseek(file, 18, SEEK_CUR);
437 
438  // read the width
439  if ((i = fread(&pImage->width, 4, 1, file)) != 1) 
440    {
441      if (verbose >=1)
442        printf("Error reading width from %s.\n", bmpName);
443      return false;
444    }
445  // read the height
446  if ((i = fread(&pImage->height, 4, 1, file)) != 1) 
447    {
448      if (verbose>=1)
449        printf("Error reading height from %s.\n", bmpName);
450      return false;
451    }
452 
453  // calculate the size (assuming 24 bits or 3 bytes per pixel).
454  size = pImage->width * pImage->height * 3;
455 
456  // read the planes
457  if ((fread(&planes, 2, 1, file)) != 1) 
458    {
459      if (verbose>=1)
460        printf("Error reading planes from %s.\n", bmpName);
461      return false;
462    }
463  if (planes != 1) 
464    {
465      if (verbose>=1)
466        printf("Planes from %s is not 1: %u\n", bmpName, planes);
467      return false;
468    }
469 
470  // read the bpp
471  if ((i = fread(&bpp, 2, 1, file)) != 1) 
472    {
473      if (verbose>=1)
474        printf("Error reading bpp from %s.\n", bmpName);
475      return false;
476    }
477  if (bpp != 24) 
478    {
479      if (verbose>=1)
480        printf("Bpp from %s is not 24: %u\n", bmpName, bpp);
481      return false;
482    }
483 
484  // seek past the rest of the bitmap header.
485  fseek(file, 24, SEEK_CUR);
486 
487  // read the data.
488  pImage->data = (GLubyte *) malloc(size);
489  if (pImage->data == NULL) 
490    {
491      if (verbose>=1)
492        printf("Error allocating memory for color-corrected image data");
493      return false;     
494    }
495 
496  if ((i = fread(pImage->data, size, 1, file)) != 1) 
497    {
498      if (verbose>=1)
499        printf("Error reading image data from %s.\n", bmpName);
500      return false;
501    }
502  fclose(file);
503
504  // reverse all of the colors. (bgr -> rgb)
505  for (i=0;i<size;i+=3) 
506    { 
507      temp = pImage->data[i];
508      pImage->data[i] = pImage->data[i+2];
509      pImage->data[i+2] = temp;
510    }
511  loadTexToGL (pImage, texture);
512 
513  return true;
514
515  if (pImage)
516    {
517      if (pImage->data)
518        {
519          free(pImage->data);
520        }
521     
522      free(pImage);
523    }
524
525}
526
527/**
528   \brief reads in a jpg-file
529   \param jpgName the Name of the Image to load
530   \param texture a reference to the Texture to write the image to
531*/
532bool Material::loadJPG (char* jpgName, GLuint* texture)
533{
534  struct jpeg_decompress_struct cinfo;
535  Image *pImage = NULL;
536  FILE *pFile;
537 
538  // Open a file pointer to the jpeg file and check if it was found and opened
539  if((pFile = fopen(jpgName, "rb")) == NULL) 
540    {
541      // Display an error message saying the file was not found, then return NULL
542      printf("Unable to load JPG File %s.\n", jpgName);
543      return false;
544    }
545 
546  // Create an error handler
547  jpeg_error_mgr jerr;
548 
549  // Have our compression info object point to the error handler address
550  cinfo.err = jpeg_std_error(&jerr);
551 
552  // Initialize the decompression object
553  jpeg_create_decompress(&cinfo);
554 
555  // Specify the data source (Our file pointer)
556  jpeg_stdio_src(&cinfo, pFile);
557 
558  // Allocate the structure that will hold our eventual jpeg data (must free it!)
559  pImage = (Image*)malloc(sizeof(Image));
560 
561  // DECOFING
562  // Read in the header of the jpeg file
563  jpeg_read_header(&cinfo, TRUE);
564 
565  // Start to decompress the jpeg file with our compression info
566  jpeg_start_decompress(&cinfo);
567 
568  // Get the image dimensions and row span to read in the pixel data
569  pImage->rowSpan = cinfo.image_width * cinfo.num_components;
570  pImage->width   = cinfo.image_width;
571  pImage->height   = cinfo.image_height;
572 
573  // Allocate memory for the pixel buffer
574  pImage->data = new unsigned char[pImage->rowSpan * pImage->height];
575 
576  // Here we use the library's state variable cinfo.output_scanline as the
577  // loop counter, so that we don't have to keep track ourselves.
578 
579  // Create an array of row pointers
580  unsigned char** rowPtr = new unsigned char*[pImage->height];
581  for (int i = 0; i < pImage->height; i++)
582    rowPtr[i] = &(pImage->data[i*pImage->rowSpan]);
583 
584  // Now comes the juice of our work, here we extract all the pixel data
585  int rowsRead = 0;
586  while (cinfo.output_scanline < cinfo.output_height) 
587    {
588      // Read in the current row of pixels and increase the rowsRead count
589      rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead);
590    }
591 
592  // Delete the temporary row pointers
593  delete [] rowPtr;
594 
595  // Finish decompressing the data
596  jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage);
597 
598  // This releases all the stored memory for reading and decoding the jpeg
599  jpeg_destroy_decompress(&cinfo);
600 
601  // Close the file pointer that opened the file
602  fclose(pFile);
603 
604
605  if(pImage == NULL)
606    exit(0);
607 
608  loadTexToGL (pImage, texture);
609  if (pImage)
610    {
611      if (pImage->data)
612        {
613          free(pImage->data);
614        }
615     
616      free(pImage);
617    }
618  return true;
619}
620
621/**
622   \brief reads in a tga-file
623   \param tgaName the Name of the Image to load
624   \param texture a reference to the Texture to write the image to
625*/
626bool Material::loadTGA(const char * tgaName, GLuint* texture)
627{
628  typedef struct
629  {
630    GLubyte Header[12];
631  } TGAHeader;
632  TGAHeader tgaHeader;                 
633 
634  GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
635  GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; // Compressed TGA Header
636  FILE * fTGA;
637  fTGA = fopen(tgaName, "rb");
638
639  if(fTGA == NULL)
640    {
641      printf("Error could not open texture file: %s\n", tgaName);
642      return false;
643    }
644 
645  if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0)
646    {
647      printf("Error could not read file header of %s\n", tgaName);
648      if(fTGA != NULL)
649        {
650          fclose(fTGA);
651        }
652      return false;
653    }
654 
655  if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
656    {
657      loadUncompressedTGA(tgaName, fTGA, texture);
658      if (fTGA)
659        fclose (fTGA);
660    }
661  else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
662    {
663      loadCompressedTGA(tgaName, fTGA, texture);
664        if (fTGA)
665          fclose (fTGA);
666    }
667  else
668    {
669      printf("Error TGA file be type 2 or type 10\n");
670      if (fTGA)
671        fclose(fTGA);
672      return false;
673    }
674  return true;
675}
676
677/**
678   \brief reads in an uncompressed tga-file
679   \param filename the Name of the Image to load
680   \param fTGA a Pointer to a File, that should be read
681   \param texture a reference to the Texture to write the image to
682*/
683bool Material::loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
684{
685  GLubyte header[6];      // First 6 Useful Bytes From The Header
686  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File
687  GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram
688  GLuint  temp;           // Temporary Variable
689  GLuint  type;
690  GLuint  Height;         // Height of Image
691  GLuint  Width;          // Width of Image
692  GLuint  Bpp;            // Bits Per Pixel
693
694  Image* pImage = new Image;
695  GLuint cswap;
696  if(fread(header, sizeof(header), 1, fTGA) == 0)
697    {
698      printf("Error could not read info header\n");
699      return false;
700    }
701 
702  Width = pImage->width  = header[1] * 256 + header[0];
703  Height =  pImage->height = header[3] * 256 + header[2];
704  Bpp = pImage->bpp = header[4];
705  // Make sure all information is valid
706  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
707    {
708      printf("Error invalid texture information\n");
709      return false;
710    }
711 
712  if(pImage->bpp == 24) 
713    {
714      pImage->type = GL_RGB;
715    }
716  else
717    {
718      pImage->type = GL_RGBA;
719    }
720 
721  bytesPerPixel = (Bpp / 8);
722  imageSize = (bytesPerPixel * Width * Height);
723  pImage->data = (GLubyte*) malloc(imageSize);
724 
725  if(pImage->data == NULL)
726    {
727      printf("Error could not allocate memory for image\n");
728      return false;
729    }
730 
731  if(fread(pImage->data, 1, imageSize, fTGA) != imageSize)
732    {
733      printf("Error could not read image data\n");
734      if(pImage->data != NULL)
735        {
736          free(pImage->data);
737        }
738      return false;
739    }
740 
741  for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel)
742    {
743      pImage->data[cswap] ^= pImage->data[cswap+2] ^=
744        pImage->data[cswap] ^= pImage->data[cswap+2];
745    }
746 
747  loadTexToGL (pImage, texture);
748
749  return true;
750}
751
752/**
753   \brief reads in a compressed tga-file
754   \param filename the Name of the Image to load
755   \param fTGA a Pointer to a File, that should be read
756   \param texture a reference to the Texture to write the image to
757*/
758bool Material::loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
759{
760  GLubyte header[6];      // First 6 Useful Bytes From The Header
761  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File
762  GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram
763  GLuint  temp;           // Temporary Variable
764  GLuint  type;
765  GLuint  Height;         // Height of Image
766  GLuint  Width;          // Width of Image
767  GLuint  Bpp;            // Bits Per Pixel
768
769  Image* pImage = new Image;
770
771 
772  if(fread(header, sizeof(header), 1, fTGA) == 0)
773    {
774      printf("Error could not read info header\n");
775      return false;
776    }
777 
778  Width = pImage->width  = header[1] * 256 + header[0];
779  Height = pImage->height = header[3] * 256 + header[2];
780  Bpp = pImage->bpp     = header[4];
781
782  GLuint pixelcount     = Height * Width;
783  GLuint currentpixel   = 0;
784  GLuint currentbyte    = 0;
785  GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel);
786
787  //Make sure all pImage info is ok
788  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
789    {
790      printf("Error Invalid pImage information\n");
791      return false;
792    }
793 
794  bytesPerPixel = (Bpp / 8);
795  imageSize             = (bytesPerPixel * Width * Height);
796  pImage->data  = (GLubyte*) malloc(imageSize);
797 
798  if(pImage->data == NULL)
799    {
800      printf("Error could not allocate memory for image\n");
801      return false;
802    }
803 
804  do
805    {
806      GLubyte chunkheader = 0;
807     
808      if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
809        {
810          printf("Error could not read RLE header\n");
811          if(pImage->data != NULL)
812            {
813              free(pImage->data);
814            }
815          return false;
816        }
817      // If the ehader is < 128, it means the that is the number of RAW color packets minus 1
818      if(chunkheader < 128)
819        {
820          short counter;
821          chunkheader++;
822          // Read RAW color values
823          for(counter = 0; counter < chunkheader; counter++)
824            { 
825              // Try to read 1 pixel
826              if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel)
827                {
828                  printf("Error could not read image data\n");
829                  if(colorbuffer != NULL)
830                    {
831                      free(colorbuffer);
832                    }
833                 
834                  if(pImage->data != NULL)
835                    {
836                      free(pImage->data);
837                    }
838                 
839                  return false; 
840                }
841              // write to memory
842              // Flip R and B vcolor values around in the process
843              pImage->data[currentbyte    ] = colorbuffer[2];                               
844              pImage->data[currentbyte + 1] = colorbuffer[1];
845              pImage->data[currentbyte + 2] = colorbuffer[0];
846             
847              if(bytesPerPixel == 4) // if its a 32 bpp image
848                {
849                  pImage->data[currentbyte + 3] = colorbuffer[3];// copy the 4th byte
850                }
851             
852              currentbyte += bytesPerPixel;
853              currentpixel++;
854
855              // Make sure we haven't read too many pixels
856              if(currentpixel > pixelcount)     
857                {
858                  printf("Error too many pixels read\n");
859                  if(colorbuffer != NULL)
860                    {
861                      free(colorbuffer);
862                    }
863                 
864                  if(pImage->data != NULL)
865                    {
866                      free(pImage->data);
867                    }
868                 
869                  return false;
870                }
871            }
872        }
873      // chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times
874      else
875        {
876          short counter;
877          chunkheader -= 127;   // Subteact 127 to get rid of the ID bit
878          if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) // Attempt to read following color values
879            {
880              printf("Error could not read from file");
881              if(colorbuffer != NULL)
882                {
883                  free(colorbuffer);
884                }
885             
886              if(pImage->data != NULL)
887                {
888                  free(pImage->data);
889                }
890             
891              return false;
892            }
893         
894          for(counter = 0; counter < chunkheader; counter++) //copy the color into the image data as many times as dictated
895            {                                                   
896              // switch R and B bytes areound while copying
897              pImage->data[currentbyte    ] = colorbuffer[2];
898              pImage->data[currentbyte + 1] = colorbuffer[1];
899              pImage->data[currentbyte + 2] = colorbuffer[0];
900             
901              if(bytesPerPixel == 4)
902                {
903                  pImage->data[currentbyte + 3] = colorbuffer[3];
904                }
905             
906              currentbyte += bytesPerPixel;
907              currentpixel++;
908             
909              if(currentpixel > pixelcount)
910                {
911                  printf("Error too many pixels read\n");
912                  if(colorbuffer != NULL)
913                    {
914                      free(colorbuffer);
915                    }
916                 
917                  if(pImage->data != NULL)
918                    {
919                      free(pImage->data);
920                    }
921                 
922                  return false;
923                }
924            }
925        }
926    }
927 
928  while(currentpixel < pixelcount);     // Loop while there are still pixels left
929
930  loadTexToGL (pImage, texture);
931
932  return true;
933}
934
Note: See TracBrowser for help on using the repository browser.