Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3087 was 3087, checked in by bensch, 20 years ago

orxonox/branches/images: check for different File-types

File size: 13.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
16#include "material.h"
17
18/**
19   \brief creates a default Material with no Name
20   normally you call this to create a material List (for an obj-file) and then append with addMaterial()
21*/
22Material::Material()
23{
24  init();
25 
26  setName ("");
27}
28
29/**
30   \brief creates a Material.
31   \param mtlName Name of the Material to be added to the Material List
32*/
33Material::Material (char* mtlName)
34{
35  init();
36 
37  setName (mtlName);
38}
39
40/**
41    \brief deletes a Material
42*/
43Material::~Material()
44{
45  if (name)
46    delete []name;
47  if (verbose >= 2)
48    printf ("delete Material %s.\n", name);
49  if (nextMat != NULL)
50    delete nextMat;
51}
52
53/**
54   \brief adds a new Material to the List.
55   this Function will append a new Material to the end of a Material List.
56   \param mtlName The name of the Material to be added.
57*/
58Material* Material::addMaterial(char* mtlName)
59{
60  if (verbose >=2)
61    printf ("adding Material %s.\n", mtlName);
62  Material* newMat = new Material(mtlName);
63  Material* tmpMat = this;
64  while (tmpMat->nextMat != NULL)
65    {
66      tmpMat = tmpMat->nextMat;
67    }
68  tmpMat->nextMat = newMat;
69  return newMat;
70 
71}
72
73/**
74   \brief initializes a new Material with its default Values
75*/
76void Material::init(void)
77{
78  if (verbose >= 3)
79    printf ("initializing new Material.\n");
80  nextMat = NULL;
81
82  setIllum(1);
83  setDiffuse(0,0,0);
84  setAmbient(0,0,0);
85  setSpecular(0,0,0);
86  setShininess(2.0);
87  setTransparency(0.0);
88
89  diffuseTextureSet = false;
90  ambientTextureSet = false;
91  specularTextureSet = false;
92
93 
94}
95
96/**
97   \brief Search for a Material called mtlName
98   \param mtlName the Name of the Material to search for
99   \returns Material named mtlName if it is found. NULL otherwise.
100*/
101Material* Material::search (char* mtlName)
102{
103  if (verbose >=3)
104    printf ("Searching for material %s", mtlName);
105  Material* searcher = this;
106  while (searcher != NULL)
107    {
108      if (verbose >= 3)
109        printf (".");
110      if (!strcmp (searcher->getName(), mtlName))
111        {
112          if (verbose >= 3)
113            printf ("found.\n");
114          return searcher;
115        }
116      searcher = searcher->nextMat;
117    }
118  if (verbose >=3)
119    printf ("not found\n");
120  return NULL;
121}
122
123/**
124   \brief sets the material with which the following Faces will be painted
125*/
126bool Material::select (void)
127{
128  // setting diffuse color
129  //  glColor3f (diffuse[0], diffuse[1], diffuse[2]);
130  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
131
132  // setting ambient color
133  glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
134
135  // setting up Sprecular
136  glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
137
138  // setting up Shininess
139  glMaterialf(GL_FRONT, GL_SHININESS, shininess);
140 
141  // setting illumination Model
142  if (illumModel == 1)
143    glShadeModel(GL_FLAT);
144  else if (illumModel >= 2)
145    glShadeModel(GL_SMOOTH);
146
147  if (diffuseTextureSet)
148    glBindTexture(GL_TEXTURE_2D, diffuseTexture);
149 
150}
151
152
153/**
154   \brief Set the Name of the Material. (Important for searching)
155   \param mtlName the Name of the Material to be set.
156*/ 
157void Material::setName (char* mtlName)
158{
159  if (verbose >= 3)
160    printf("setting Material Name to %s.\n", mtlName);
161  name = new char [strlen(mtlName)];
162  strcpy(name, mtlName);
163  //  printf ("adding new Material: %s, %p\n", this->getName(), this);
164
165}
166/**
167   \returns The Name of The Material
168*/
169char* Material::getName (void)
170{
171  return name;
172}
173
174/**
175   \brief Sets the Material Illumination Model.
176   \brief illu illumination Model in int form
177*/
178void Material::setIllum (int illum)
179{
180  if (verbose >= 3)
181    printf("setting illumModel of Material %s to %i", name, illum);
182  illumModel = illum;
183  //  printf ("setting illumModel to: %i\n", illumModel);
184}
185/**
186   \brief Sets the Material Illumination Model.
187   \brief illu illumination Model in char* form
188*/void Material::setIllum (char* illum)
189{
190  setIllum (atoi(illum));
191}
192
193/**
194   \brief Sets the Material Diffuse Color.
195   \param r Red Color Channel.
196   \param g Green Color Channel.
197   \param b Blue Color Channel.
198*/
199void Material::setDiffuse (float r, float g, float b)
200{
201  if (verbose >= 3)
202    printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
203  diffuse[0] = r;
204  diffuse[1] = g;
205  diffuse[2] = b; 
206  diffuse[3] = 1.0;
207
208}
209/**
210   \brief Sets the Material Diffuse Color.
211   \param rgb The red, green, blue channel in char format (with spaces between them)
212*/
213void Material::setDiffuse (char* rgb)
214{
215  char r[20],g[20],b[20];
216  sscanf (rgb, "%s %s %s", r, g, b);
217  setDiffuse (atof(r), atof(g), atof(b));
218}
219
220/**
221   \brief Sets the Material Ambient Color.
222   \param r Red Color Channel.
223   \param g Green Color Channel.
224   \param b Blue Color Channel.
225*/
226void Material::setAmbient (float r, float g, float b)
227{
228  if (verbose >=3)
229    printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
230  ambient[0] = r;
231  ambient[1] = g;
232  ambient[2] = b;
233  ambient[3] = 1.0;
234}
235/**
236   \brief Sets the Material Ambient Color.
237   \param rgb The red, green, blue channel in char format (with spaces between them)
238*/
239void Material::setAmbient (char* rgb)
240{
241  char r[20],g[20],b[20];
242  sscanf (rgb, "%s %s %s", r, g, b);
243  setAmbient (atof(r), atof(g), atof(b));
244}
245
246/**
247   \brief Sets the Material Specular Color.
248   \param r Red Color Channel.
249   \param g Green Color Channel.
250   \param b Blue Color Channel.
251*/
252void Material::setSpecular (float r, float g, float b)
253{
254  if (verbose >= 3)
255    printf ("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
256  specular[0] = r;
257  specular[1] = g;
258  specular[2] = b;
259  specular[3] = 1.0;
260 }
261/**
262   \brief Sets the Material Specular Color.
263   \param rgb The red, green, blue channel in char format (with spaces between them)
264*/
265void Material::setSpecular (char* rgb)
266{
267  char r[20],g[20],b[20];
268  sscanf (rgb, "%s %s %s", r, g, b);
269  setSpecular (atof(r), atof(g), atof(b));
270}
271
272/**
273   \brief Sets the Material Shininess.
274   \param shini stes the Shininess from float.
275*/
276void Material::setShininess (float shini)
277{
278  shininess = shini;
279}
280/**
281   \brief Sets the Material Shininess.
282   \param shini stes the Shininess from char*.
283*/
284void Material::setShininess (char* shini)
285{
286  setShininess (atof(shini));
287}
288
289/**
290   \brief Sets the Material Transparency.
291   \param trans stes the Transparency from int.
292*/
293void Material::setTransparency (float trans)
294{
295  if (verbose >= 3)
296    printf ("setting Transparency of Material %s to %f.\n", name, trans);
297  transparency = trans;
298}
299/**
300   \brief Sets the Material Transparency.
301   \param trans stes the Transparency from char*.
302*/
303void Material::setTransparency (char* trans)
304{
305  char tr[20];
306  sscanf (trans, "%s", tr);
307  setTransparency (atof(tr));
308}
309
310// MAPPING //
311
312/**
313   \brief Sets the Materials Diffuse Map
314   \param dMap the Name of the Image to Use
315*/
316void Material::setDiffuseMap(char* dMap)
317{
318  if (verbose>=2)
319    printf ("setting Diffuse Map %s\n", dMap);
320
321  //  diffuseTextureSet = loadBMP(dMap, &diffuseTexture);
322  diffuseTextureSet = loadImage(dMap, &diffuseTexture);
323
324}
325
326/**
327   \brief Sets the Materials Ambient Map
328   \param aMap the Name of the Image to Use
329*/
330void Material::setAmbientMap(char* aMap)
331{
332  SDL_Surface* ambientMap;
333
334}
335
336/**
337   \brief Sets the Materials Specular Map
338   \param sMap the Name of the Image to Use
339*/
340void Material::setSpecularMap(char* sMap)
341{
342  SDL_Surface* specularMap;
343
344}
345
346/**
347   \brief Sets the Materials Bumpiness
348   \param bump the Name of the Image to Use
349*/
350void Material::setBump(char* bump)
351{
352
353}
354
355/**
356   \brief Makes the Programm ready to Read-in a texture-File
357   1. Checks what type of Image should be imported
358   2. ToDO: Checks where to find the Image
359*/
360bool Material::loadImage(char* imageName, GLuint* texture)
361{
362  if (!strncmp(imageName+strlen(imageName)-4, ".bmp", 4))
363    {
364      if (verbose >=2)
365        printf ("Requested bmp-image. Trying to Import.\n");
366      return loadBMP(imageName, texture);
367    }
368
369  else if (!strncmp(imageName+strlen(imageName)-4, ".jpg", 4) || !strncmp(imageName+strlen(imageName)-5, ".jpg", 5))
370    {
371      if (verbose >=2)
372        printf ("Requested jpeg-image. Trying to Import\n");
373      return loadJPG(imageName, texture);
374    }
375  else
376    {
377      if (verbose >=1)
378        printf ("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imageName);
379      return false;
380    }
381
382}
383
384/**
385   \brief reads in a Windows BMP-file, and imports it to openGL.
386   \param bmpName The name of the Image to load.
387   \param texture A pointer to the Texture which should be read to.
388*/
389bool Material::loadBMP (char* bmpName, GLuint* texture)
390{
391  SDL_Surface* map;
392  if (map = SDL_LoadBMP(bmpName))
393    {
394
395      glGenTextures( 1, texture );
396      /* Typical Texture Generation Using Data From The Bitmap */
397      glBindTexture( GL_TEXTURE_2D, *texture );
398     
399      /* Generate The Texture */
400      glTexImage2D( GL_TEXTURE_2D, 0, 3, map->w,
401                    map->h, 0, GL_BGR,
402                    GL_UNSIGNED_BYTE, map->pixels );
403     
404      /* Linear Filtering */
405      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
406      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
407      if ( map )
408        SDL_FreeSurface( map );
409
410      return true;
411    }
412  else
413    return false;
414}
415
416bool Material::loadJPG (char* jpgName, GLuint* texture)
417{
418  struct jpeg_decompress_struct cinfo;
419  tImageJPG *pImage = NULL;
420  FILE *pFile;
421 
422  // Open a file pointer to the jpeg file and check if it was found and opened
423  if((pFile = fopen(jpgName, "rb")) == NULL) 
424    {
425      // Display an error message saying the file was not found, then return NULL
426      printf("Unable to load JPG File %s.\n", jpgName);
427      return false;
428    }
429 
430  // Create an error handler
431  jpeg_error_mgr jerr;
432 
433  // Have our compression info object point to the error handler address
434  cinfo.err = jpeg_std_error(&jerr);
435 
436  // Initialize the decompression object
437  jpeg_create_decompress(&cinfo);
438 
439  // Specify the data source (Our file pointer)
440  jpeg_stdio_src(&cinfo, pFile);
441 
442  // Allocate the structure that will hold our eventual jpeg data (must free it!)
443  pImage = (tImageJPG*)malloc(sizeof(tImageJPG));
444 
445  // Decode the jpeg file and fill in the image data structure to pass back
446  decodeJPG(&cinfo, pImage);
447 
448  // This releases all the stored memory for reading and decoding the jpeg
449  jpeg_destroy_decompress(&cinfo);
450 
451  // Close the file pointer that opened the file
452  fclose(pFile);
453 
454
455  if(pImage == NULL)                                                                    // If we can't load the file, quit!
456    exit(0);
457
458  // Generate a texture with the associative texture ID stored in the array
459  glGenTextures(1, texture);
460 
461  // Bind the texture to the texture arrays index and init the texture
462  glBindTexture(GL_TEXTURE_2D, *texture);
463 
464  // Build Mipmaps (builds different versions of the picture for distances - looks better)
465  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->sizeX, pImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
466 
467  // Lastly, we need to tell OpenGL the quality of our texture map.  GL_LINEAR_MIPMAP_LINEAR
468  // is the smoothest.  GL_LINEAR_MIPMAP_NEAREST is faster than GL_LINEAR_MIPMAP_LINEAR,
469  // but looks blochy and pixilated.  Good for slower computers though.
470 
471  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
472  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); 
473 
474
475  // Now we need to free the image data that we loaded since OpenGL stored it as a texture
476 
477  if (pImage)                                                                           // If we loaded the image
478    {
479      if (pImage->data)                                                 // If there is texture data
480        {
481          free(pImage->data);                                           // Free the texture data, we don't need it anymore
482        }
483     
484      free(pImage);                                                             // Free the image structure
485    }
486
487}
488
489void Material::decodeJPG(jpeg_decompress_struct* cinfo, tImageJPG *pImageData)
490{
491  // Read in the header of the jpeg file
492  jpeg_read_header(cinfo, TRUE);
493 
494  // Start to decompress the jpeg file with our compression info
495  jpeg_start_decompress(cinfo);
496 
497  // Get the image dimensions and row span to read in the pixel data
498  pImageData->rowSpan = cinfo->image_width * cinfo->num_components;
499  pImageData->sizeX   = cinfo->image_width;
500  pImageData->sizeY   = cinfo->image_height;
501 
502  // Allocate memory for the pixel buffer
503  pImageData->data = new unsigned char[pImageData->rowSpan * pImageData->sizeY];
504 
505  // Here we use the library's state variable cinfo.output_scanline as the
506  // loop counter, so that we don't have to keep track ourselves.
507 
508  // Create an array of row pointers
509  unsigned char** rowPtr = new unsigned char*[pImageData->sizeY];
510  for (int i = 0; i < pImageData->sizeY; i++)
511    rowPtr[i] = &(pImageData->data[i*pImageData->rowSpan]);
512 
513  // Now comes the juice of our work, here we extract all the pixel data
514  int rowsRead = 0;
515  while (cinfo->output_scanline < cinfo->output_height) 
516    {
517      // Read in the current row of pixels and increase the rowsRead count
518      rowsRead += jpeg_read_scanlines(cinfo, &rowPtr[rowsRead], cinfo->output_height - rowsRead);
519    }
520 
521  // Delete the temporary row pointers
522  delete [] rowPtr;
523 
524  // Finish decompressing the data
525  jpeg_finish_decompress(cinfo);
526}
527
Note: See TracBrowser for help on using the repository browser.