Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3096 was 3096, checked in by bensch, 19 years ago

orxonox/branches/images: compressed TGA work to

File size: 22.2 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
527bool Material::loadJPG (char* jpgName, GLuint* texture)
528{
529  struct jpeg_decompress_struct cinfo;
530  Image *pImage = NULL;
531  FILE *pFile;
532 
533  // Open a file pointer to the jpeg file and check if it was found and opened
534  if((pFile = fopen(jpgName, "rb")) == NULL) 
535    {
536      // Display an error message saying the file was not found, then return NULL
537      printf("Unable to load JPG File %s.\n", jpgName);
538      return false;
539    }
540 
541  // Create an error handler
542  jpeg_error_mgr jerr;
543 
544  // Have our compression info object point to the error handler address
545  cinfo.err = jpeg_std_error(&jerr);
546 
547  // Initialize the decompression object
548  jpeg_create_decompress(&cinfo);
549 
550  // Specify the data source (Our file pointer)
551  jpeg_stdio_src(&cinfo, pFile);
552 
553  // Allocate the structure that will hold our eventual jpeg data (must free it!)
554  pImage = (Image*)malloc(sizeof(Image));
555 
556  // DECOFING
557  // Read in the header of the jpeg file
558  jpeg_read_header(&cinfo, TRUE);
559 
560  // Start to decompress the jpeg file with our compression info
561  jpeg_start_decompress(&cinfo);
562 
563  // Get the image dimensions and row span to read in the pixel data
564  pImage->rowSpan = cinfo.image_width * cinfo.num_components;
565  pImage->width   = cinfo.image_width;
566  pImage->height   = cinfo.image_height;
567 
568  // Allocate memory for the pixel buffer
569  pImage->data = new unsigned char[pImage->rowSpan * pImage->height];
570 
571  // Here we use the library's state variable cinfo.output_scanline as the
572  // loop counter, so that we don't have to keep track ourselves.
573 
574  // Create an array of row pointers
575  unsigned char** rowPtr = new unsigned char*[pImage->height];
576  for (int i = 0; i < pImage->height; i++)
577    rowPtr[i] = &(pImage->data[i*pImage->rowSpan]);
578 
579  // Now comes the juice of our work, here we extract all the pixel data
580  int rowsRead = 0;
581  while (cinfo.output_scanline < cinfo.output_height) 
582    {
583      // Read in the current row of pixels and increase the rowsRead count
584      rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead);
585    }
586 
587  // Delete the temporary row pointers
588  delete [] rowPtr;
589 
590  // Finish decompressing the data
591  jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage);
592 
593  // This releases all the stored memory for reading and decoding the jpeg
594  jpeg_destroy_decompress(&cinfo);
595 
596  // Close the file pointer that opened the file
597  fclose(pFile);
598 
599
600  if(pImage == NULL)
601    exit(0);
602 
603  loadTexToGL (pImage, texture);
604  if (pImage)
605    {
606      if (pImage->data)
607        {
608          free(pImage->data);
609        }
610     
611      free(pImage);
612    }
613  return true;
614}
615
616bool Material::loadTGA(const char * tgaName, GLuint* texture)
617{
618  typedef struct
619  {
620    GLubyte Header[12];                                                                 /* TGA File Header */
621  } TGAHeader;
622 TGAHeader tgaHeader;                   
623
624  GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0}; /* Uncompressed TGA Header */
625  GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; /* Compressed TGA Header */
626  FILE * fTGA;
627  fTGA = fopen(tgaName, "rb");
628
629  if(fTGA == NULL)
630    {
631      printf("Error could not open texture file: %s\n", tgaName);
632      return false;
633    }
634 
635  if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0)
636    {
637      printf("Error could not read file header of %s\n", tgaName);
638      if(fTGA != NULL)
639        {
640          fclose(fTGA);
641        }
642      return false;
643    }
644 
645  if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
646    {
647      loadUncompressedTGA(tgaName, fTGA, texture);
648      if (fTGA)
649        fclose (fTGA);
650    }
651  else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
652    {
653      loadCompressedTGA(tgaName, fTGA, texture);
654        if (fTGA)
655          fclose (fTGA);
656    }
657  else
658    {
659      printf("Error TGA file be type 2 or type 10\n");
660      if (fTGA)
661        fclose(fTGA);
662      return false;
663    }
664  return true;
665}
666
667bool Material::loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
668{
669  GLubyte header[6];      // First 6 Useful Bytes From The Header
670  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File
671  GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram
672  GLuint  temp;           // Temporary Variable
673  GLuint  type;
674  GLuint  Height;         // Height of Image
675  GLuint  Width;          // Width of Image
676  GLuint  Bpp;            // Bits Per Pixel
677
678  Image* pImage = new Image;
679  GLuint cswap;
680  if(fread(header, sizeof(header), 1, fTGA) == 0)
681    {
682      printf("Error could not read info header\n");
683      return false;
684    }
685 
686  Width = pImage->width  = header[1] * 256 + header[0];
687  Height =  pImage->height = header[3] * 256 + header[2];
688  Bpp = pImage->bpp = header[4];
689  // Make sure all information is valid
690  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
691    {
692      printf("Error invalid texture information\n");
693      return false;
694    }
695 
696  if(pImage->bpp == 24) 
697    {
698      pImage->type = GL_RGB;
699    }
700  else
701    {
702      pImage->type = GL_RGBA;
703    }
704 
705  bytesPerPixel = (Bpp / 8);
706  imageSize = (bytesPerPixel * Width * Height);
707  pImage->data = (GLubyte*) malloc(imageSize);
708 
709  if(pImage->data == NULL)
710    {
711      printf("Error could not allocate memory for image\n");
712      return false;
713    }
714 
715  if(fread(pImage->data, 1, imageSize, fTGA) != imageSize)
716    {
717      printf("Error could not read image data\n");
718      if(pImage->data != NULL)
719        {
720          free(pImage->data);
721        }
722      return false;
723    }
724 
725  /* Byte Swapping Optimized By Steve Thomas */
726  for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel)
727    {
728      pImage->data[cswap] ^= pImage->data[cswap+2] ^=
729        pImage->data[cswap] ^= pImage->data[cswap+2];
730    }
731 
732  loadTexToGL (pImage, texture);
733
734  return true;
735}
736
737bool Material::loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
738{
739  GLubyte header[6];      // First 6 Useful Bytes From The Header
740  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File
741  GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram
742  GLuint  temp;           // Temporary Variable
743  GLuint  type;
744  GLuint  Height;         // Height of Image
745  GLuint  Width;          // Width of Image
746  GLuint  Bpp;            // Bits Per Pixel
747
748  Image* pImage = new Image;
749
750 
751  if(fread(header, sizeof(header), 1, fTGA) == 0)
752    {
753      printf("Error could not read info header\n");
754      return false;
755    }
756 
757  Width = pImage->width  = header[1] * 256 + header[0];
758  Height = pImage->height = header[3] * 256 + header[2];
759  Bpp = pImage->bpp     = header[4];
760
761  GLuint pixelcount     = Height * Width;
762  GLuint currentpixel   = 0;
763  GLuint currentbyte    = 0;
764  GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel);
765
766  //Make sure all pImage info is ok
767  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
768    {
769      printf("Error Invalid pImage information\n");
770      return false;
771    }
772 
773  bytesPerPixel = (Bpp / 8);
774  imageSize             = (bytesPerPixel * Width * Height);
775  pImage->data  = (GLubyte*) malloc(imageSize);
776 
777  if(pImage->data == NULL)
778    {
779      printf("Error could not allocate memory for image\n");
780      return false;
781    }
782 
783  do
784    {
785      GLubyte chunkheader = 0;
786     
787      if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
788        {
789          printf("Error could not read RLE header\n");
790          if(pImage->data != NULL)
791            {
792              free(pImage->data);
793            }
794          return false;
795        }
796      // If the ehader is < 128, it means the that is the number of RAW color packets minus 1
797      if(chunkheader < 128)
798        {
799          short counter;
800          chunkheader++;
801          // Read RAW color values
802          for(counter = 0; counter < chunkheader; counter++)
803            { 
804              // Try to read 1 pixel
805              if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel)
806                {
807                  printf("Error could not read image data\n");
808                  if(colorbuffer != NULL)
809                    {
810                      free(colorbuffer);
811                    }
812                 
813                  if(pImage->data != NULL)
814                    {
815                      free(pImage->data);
816                    }
817                 
818                  return false; 
819                }
820              // write to memory
821              // Flip R and B vcolor values around in the process
822              pImage->data[currentbyte    ] = colorbuffer[2];                               
823              pImage->data[currentbyte + 1] = colorbuffer[1];
824              pImage->data[currentbyte + 2] = colorbuffer[0];
825             
826              if(bytesPerPixel == 4) // if its a 32 bpp image
827                {
828                  pImage->data[currentbyte + 3] = colorbuffer[3];// copy the 4th byte
829                }
830             
831              currentbyte += bytesPerPixel;
832              currentpixel++;
833
834              // Make sure we haven't read too many pixels
835              if(currentpixel > pixelcount)     
836                {
837                  printf("Error too many pixels read\n");
838                  if(colorbuffer != NULL)
839                    {
840                      free(colorbuffer);
841                    }
842                 
843                  if(pImage->data != NULL)
844                    {
845                      free(pImage->data);
846                    }
847                 
848                  return false;
849                }
850            }
851        }
852      // chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times
853      else
854        {
855          short counter;
856          chunkheader -= 127;   // Subteact 127 to get rid of the ID bit
857          if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) // Attempt to read following color values
858            {
859              printf("Error could not read from file");
860              if(colorbuffer != NULL)
861                {
862                  free(colorbuffer);
863                }
864             
865              if(pImage->data != NULL)
866                {
867                  free(pImage->data);
868                }
869             
870              return false;
871            }
872         
873          for(counter = 0; counter < chunkheader; counter++) //copy the color into the image data as many times as dictated
874            {                                                   
875              // switch R and B bytes areound while copying                                                                                             /* by the header */
876              pImage->data[currentbyte    ] = colorbuffer[2];
877              pImage->data[currentbyte + 1] = colorbuffer[1];
878              pImage->data[currentbyte + 2] = colorbuffer[0];
879             
880              if(bytesPerPixel == 4)
881                {
882                  pImage->data[currentbyte + 3] = colorbuffer[3];
883                }
884             
885              currentbyte += bytesPerPixel;
886              currentpixel++;
887             
888              if(currentpixel > pixelcount)
889                {
890                  printf("Error too many pixels read\n");
891                  if(colorbuffer != NULL)
892                    {
893                      free(colorbuffer);
894                    }
895                 
896                  if(pImage->data != NULL)
897                    {
898                      free(pImage->data);
899                    }
900                 
901                  return false;
902                }
903            }
904        }
905    }
906 
907  while(currentpixel < pixelcount);     /* Loop while there are still pixels left */
908  loadTexToGL (pImage, texture);
909
910  return true;
911}
912
Note: See TracBrowser for help on using the repository browser.