Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/images: libPNG included, and also a routine to read it, but this one is not the best i Could find.

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