Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/images: moved things to where they belong

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