Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/images: images will now load only to selected regions

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