Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/images: ability to readIn jpg-files

File size: 12.4 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 = loadJPG(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 reads in a Windows BMP-file, and imports it to openGL.
357   \param bmpName The name of the Image to load.
358   \param texture A pointer to the Texture which should be read to.
359*/
360bool Material::loadBMP (char* bmpName, GLuint* texture)
361{
362  SDL_Surface* map;
363  if (map = SDL_LoadBMP(bmpName))
364    {
365
366      glGenTextures( 1, texture );
367      /* Typical Texture Generation Using Data From The Bitmap */
368      glBindTexture( GL_TEXTURE_2D, *texture );
369     
370      /* Generate The Texture */
371      glTexImage2D( GL_TEXTURE_2D, 0, 3, map->w,
372                    map->h, 0, GL_BGR,
373                    GL_UNSIGNED_BYTE, map->pixels );
374     
375      /* Linear Filtering */
376      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
377      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
378      if ( map )
379        SDL_FreeSurface( map );
380
381      return true;
382    }
383  else
384    return false;
385}
386
387bool Material::loadJPG (char* jpgName, GLuint* texture)
388{
389  struct jpeg_decompress_struct cinfo;
390  tImageJPG *pImage = NULL;
391  FILE *pFile;
392 
393  // Open a file pointer to the jpeg file and check if it was found and opened
394  if((pFile = fopen(jpgName, "rb")) == NULL) 
395    {
396      // Display an error message saying the file was not found, then return NULL
397      printf("Unable to load JPG File %s.\n", jpgName);
398      return false;
399    }
400 
401  // Create an error handler
402  jpeg_error_mgr jerr;
403 
404  // Have our compression info object point to the error handler address
405  cinfo.err = jpeg_std_error(&jerr);
406 
407  // Initialize the decompression object
408  jpeg_create_decompress(&cinfo);
409 
410  // Specify the data source (Our file pointer)
411  jpeg_stdio_src(&cinfo, pFile);
412 
413  // Allocate the structure that will hold our eventual jpeg data (must free it!)
414  pImage = (tImageJPG*)malloc(sizeof(tImageJPG));
415 
416  // Decode the jpeg file and fill in the image data structure to pass back
417  decodeJPG(&cinfo, pImage);
418 
419  // This releases all the stored memory for reading and decoding the jpeg
420  jpeg_destroy_decompress(&cinfo);
421 
422  // Close the file pointer that opened the file
423  fclose(pFile);
424 
425
426  if(pImage == NULL)                                                                    // If we can't load the file, quit!
427    exit(0);
428
429  // Generate a texture with the associative texture ID stored in the array
430  glGenTextures(1, texture);
431 
432  // Bind the texture to the texture arrays index and init the texture
433  glBindTexture(GL_TEXTURE_2D, *texture);
434 
435  // Build Mipmaps (builds different versions of the picture for distances - looks better)
436  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->sizeX, pImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
437 
438  // Lastly, we need to tell OpenGL the quality of our texture map.  GL_LINEAR_MIPMAP_LINEAR
439  // is the smoothest.  GL_LINEAR_MIPMAP_NEAREST is faster than GL_LINEAR_MIPMAP_LINEAR,
440  // but looks blochy and pixilated.  Good for slower computers though.
441 
442  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
443  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); 
444 
445
446  // Now we need to free the image data that we loaded since OpenGL stored it as a texture
447 
448  if (pImage)                                                                           // If we loaded the image
449    {
450      if (pImage->data)                                                 // If there is texture data
451        {
452          free(pImage->data);                                           // Free the texture data, we don't need it anymore
453        }
454     
455      free(pImage);                                                             // Free the image structure
456    }
457
458}
459
460void Material::decodeJPG(jpeg_decompress_struct* cinfo, tImageJPG *pImageData)
461{
462  // Read in the header of the jpeg file
463  jpeg_read_header(cinfo, TRUE);
464 
465  // Start to decompress the jpeg file with our compression info
466  jpeg_start_decompress(cinfo);
467 
468  // Get the image dimensions and row span to read in the pixel data
469  pImageData->rowSpan = cinfo->image_width * cinfo->num_components;
470  pImageData->sizeX   = cinfo->image_width;
471  pImageData->sizeY   = cinfo->image_height;
472 
473  // Allocate memory for the pixel buffer
474  pImageData->data = new unsigned char[pImageData->rowSpan * pImageData->sizeY];
475 
476  // Here we use the library's state variable cinfo.output_scanline as the
477  // loop counter, so that we don't have to keep track ourselves.
478 
479  // Create an array of row pointers
480  unsigned char** rowPtr = new unsigned char*[pImageData->sizeY];
481  for (int i = 0; i < pImageData->sizeY; i++)
482    rowPtr[i] = &(pImageData->data[i*pImageData->rowSpan]);
483 
484  // Now comes the juice of our work, here we extract all the pixel data
485  int rowsRead = 0;
486  while (cinfo->output_scanline < cinfo->output_height) 
487    {
488      // Read in the current row of pixels and increase the rowsRead count
489      rowsRead += jpeg_read_scanlines(cinfo, &rowPtr[rowsRead], cinfo->output_height - rowsRead);
490    }
491 
492  // Delete the temporary row pointers
493  delete [] rowPtr;
494 
495  // Finish decompressing the data
496  jpeg_finish_decompress(cinfo);
497}
498
Note: See TracBrowser for help on using the repository browser.