Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/images: passing struct instead of all its values by themselves.

File size: 14.6 KB
RevLine 
[2823]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
[2776]16#include "material.h"
17
[2842]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*/
[2776]22Material::Material()
23{
24  init();
[2778]25 
26  setName ("");
[2776]27}
28
[2842]29/**
30   \brief creates a Material.
31   \param mtlName Name of the Material to be added to the Material List
32*/
[2776]33Material::Material (char* mtlName)
34{
35  init();
36 
37  setName (mtlName);
38}
39
[2847]40/**
41    \brief deletes a Material
42*/
43Material::~Material()
44{
[3080]45  if (name)
46    delete []name;
[2847]47  if (verbose >= 2)
[3069]48    printf ("delete Material %s.\n", name);
[2847]49  if (nextMat != NULL)
50    delete nextMat;
51}
52
[2842]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*/
[2778]58Material* Material::addMaterial(char* mtlName)
59{
[2804]60  if (verbose >=2)
[3069]61    printf ("adding Material %s.\n", mtlName);
[2778]62  Material* newMat = new Material(mtlName);
63  Material* tmpMat = this;
64  while (tmpMat->nextMat != NULL)
65    {
66      tmpMat = tmpMat->nextMat;
67    }
[3069]68  tmpMat->nextMat = newMat;
69  return newMat;
[2778]70 
71}
72
[2842]73/**
74   \brief initializes a new Material with its default Values
75*/
[2776]76void Material::init(void)
77{
[2804]78  if (verbose >= 3)
[3069]79    printf ("initializing new Material.\n");
[2776]80  nextMat = NULL;
[2778]81
82  setIllum(1);
83  setDiffuse(0,0,0);
84  setAmbient(0,0,0);
[3088]85  setSpecular(.5,.5,.5);
[2850]86  setShininess(2.0);
[2778]87  setTransparency(0.0);
[3070]88
89  diffuseTextureSet = false;
90  ambientTextureSet = false;
91  specularTextureSet = false;
92
[2836]93 
[2776]94}
95
[2842]96/**
[3085]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);
[3088]149  else
150    glBindTexture(GL_TEXTURE_2D, 0);
[3085]151 
152}
153
154
155/**
[2842]156   \brief Set the Name of the Material. (Important for searching)
157   \param mtlName the Name of the Material to be set.
158*/ 
[2776]159void Material::setName (char* mtlName)
160{
[3087]161  if (verbose >= 3)
[3069]162    printf("setting Material Name to %s.\n", mtlName);
163  name = new char [strlen(mtlName)];
[2778]164  strcpy(name, mtlName);
165  //  printf ("adding new Material: %s, %p\n", this->getName(), this);
[2776]166
167}
[2842]168/**
169   \returns The Name of The Material
170*/
[2778]171char* Material::getName (void)
172{
173  return name;
174}
[2776]175
[2842]176/**
177   \brief Sets the Material Illumination Model.
178   \brief illu illumination Model in int form
179*/
[2776]180void Material::setIllum (int illum)
181{
[2804]182  if (verbose >= 3)
183    printf("setting illumModel of Material %s to %i", name, illum);
[2776]184  illumModel = illum;
185  //  printf ("setting illumModel to: %i\n", illumModel);
186}
[2842]187/**
188   \brief Sets the Material Illumination Model.
189   \brief illu illumination Model in char* form
190*/void Material::setIllum (char* illum)
[2776]191{
192  setIllum (atoi(illum));
193}
194
[2842]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*/
[2776]201void Material::setDiffuse (float r, float g, float b)
202{
[2804]203  if (verbose >= 3)
[3069]204    printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
[2776]205  diffuse[0] = r;
206  diffuse[1] = g;
[2780]207  diffuse[2] = b; 
208  diffuse[3] = 1.0;
209
[2776]210}
[2842]211/**
212   \brief Sets the Material Diffuse Color.
213   \param rgb The red, green, blue channel in char format (with spaces between them)
214*/
[2776]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
[2842]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*/
[2776]228void Material::setAmbient (float r, float g, float b)
229{
[2804]230  if (verbose >=3)
[3069]231    printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
[2776]232  ambient[0] = r;
233  ambient[1] = g;
234  ambient[2] = b;
[2780]235  ambient[3] = 1.0;
[2776]236}
[2842]237/**
238   \brief Sets the Material Ambient Color.
239   \param rgb The red, green, blue channel in char format (with spaces between them)
240*/
[2776]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
[2842]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*/
[2776]254void Material::setSpecular (float r, float g, float b)
255{
[2804]256  if (verbose >= 3)
[3069]257    printf ("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
[2776]258  specular[0] = r;
259  specular[1] = g;
260  specular[2] = b;
[2780]261  specular[3] = 1.0;
[2804]262 }
[2842]263/**
264   \brief Sets the Material Specular Color.
265   \param rgb The red, green, blue channel in char format (with spaces between them)
266*/
[2776]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
[2842]274/**
275   \brief Sets the Material Shininess.
276   \param shini stes the Shininess from float.
277*/
[2836]278void Material::setShininess (float shini)
279{
280  shininess = shini;
281}
[2842]282/**
283   \brief Sets the Material Shininess.
284   \param shini stes the Shininess from char*.
285*/
[2836]286void Material::setShininess (char* shini)
287{
288  setShininess (atof(shini));
289}
[2776]290
[2842]291/**
292   \brief Sets the Material Transparency.
293   \param trans stes the Transparency from int.
294*/
[2776]295void Material::setTransparency (float trans)
296{
[2804]297  if (verbose >= 3)
[3069]298    printf ("setting Transparency of Material %s to %f.\n", name, trans);
[2776]299  transparency = trans;
300}
[2842]301/**
302   \brief Sets the Material Transparency.
303   \param trans stes the Transparency from char*.
304*/
[2776]305void Material::setTransparency (char* trans)
306{
307  char tr[20];
308  sscanf (trans, "%s", tr);
309  setTransparency (atof(tr));
310}
[2778]311
[3070]312// MAPPING //
313
[2842]314/**
[3070]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
[3086]323  //  diffuseTextureSet = loadBMP(dMap, &diffuseTexture);
[3087]324  diffuseTextureSet = loadImage(dMap, &diffuseTexture);
[3070]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/**
[3087]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/**
[3070]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{
[3090]393  Image* pImage = new Image;
394  FILE *file;
395  unsigned long size;                 // size of the image in bytes.
396  unsigned long i;                    // standard counter.
397  unsigned short int planes;          // number of planes in image (must be 1)
398  unsigned short int bpp;             // number of bits per pixel (must be 24)
399  GLuint temp;                          // temporary color storage for bgr-rgb conversion.
400
401  // make sure the file is there.
402  if ((file = fopen(bmpName, "rb"))==NULL)
[3070]403    {
[3090]404      if (verbose >=1)
405        printf("File Not Found : %s\n",bmpName);
406      return false;
407    }
408  // seek through the bmp header, up to the width/height:
409  fseek(file, 18, SEEK_CUR);
410 
411  // read the width
412  if ((i = fread(&pImage->sizeX, 4, 1, file)) != 1) 
413    {
414      if (verbose >=1)
415        printf("Error reading width from %s.\n", bmpName);
416      return false;
417    }
418  // read the height
419  if ((i = fread(&pImage->sizeY, 4, 1, file)) != 1) 
420    {
421      if (verbose>=1)
422        printf("Error reading height from %s.\n", bmpName);
423      return false;
424    }
425 
426  // calculate the size (assuming 24 bits or 3 bytes per pixel).
427  size = pImage->sizeX * pImage->sizeY * 3;
428 
429  // read the planes
430  if ((fread(&planes, 2, 1, file)) != 1) 
431    {
432      if (verbose>=1)
433        printf("Error reading planes from %s.\n", bmpName);
434      return false;
435    }
436  if (planes != 1) 
437    {
438      if (verbose>=1)
439        printf("Planes from %s is not 1: %u\n", bmpName, planes);
440      return false;
441    }
442 
443  // read the bpp
444  if ((i = fread(&bpp, 2, 1, file)) != 1) 
445    {
446      if (verbose>=1)
447        printf("Error reading bpp from %s.\n", bmpName);
448      return false;
449    }
450  if (bpp != 24) 
451    {
452      if (verbose>=1)
453        printf("Bpp from %s is not 24: %u\n", bmpName, bpp);
454      return false;
455    }
456 
457  // seek past the rest of the bitmap header.
458  fseek(file, 24, SEEK_CUR);
459 
460  // read the data.
461  pImage->data = (GLubyte *) malloc(size);
462  if (pImage->data == NULL) 
463    {
464      if (verbose>=1)
465        printf("Error allocating memory for color-corrected image data");
466      return false;     
467    }
468 
469  if ((i = fread(pImage->data, size, 1, file)) != 1) 
470    {
471      if (verbose>=1)
472        printf("Error reading image data from %s.\n", bmpName);
473      return false;
474    }
475  // reverse all of the colors. (bgr -> rgb)
476  for (i=0;i<size;i+=3) 
477    { 
478      temp = pImage->data[i];
479      pImage->data[i] = pImage->data[i+2];
480      pImage->data[i+2] = temp;
481    }
[3091]482  loadTexToGL (pImage, texture);
[3090]483 
484  return true;
[3070]485
[3090]486  if (pImage)
487    {
488      if (pImage->data)
489        {
490          free(pImage->data);
491        }
492     
493      free(pImage);
[3070]494    }
[3090]495
[3070]496}
497
[3086]498bool Material::loadJPG (char* jpgName, GLuint* texture)
499{
500  struct jpeg_decompress_struct cinfo;
[3090]501  Image *pImage = NULL;
[3086]502  FILE *pFile;
503 
504  // Open a file pointer to the jpeg file and check if it was found and opened
505  if((pFile = fopen(jpgName, "rb")) == NULL) 
506    {
507      // Display an error message saying the file was not found, then return NULL
508      printf("Unable to load JPG File %s.\n", jpgName);
509      return false;
510    }
511 
512  // Create an error handler
513  jpeg_error_mgr jerr;
514 
515  // Have our compression info object point to the error handler address
516  cinfo.err = jpeg_std_error(&jerr);
517 
518  // Initialize the decompression object
519  jpeg_create_decompress(&cinfo);
520 
521  // Specify the data source (Our file pointer)
522  jpeg_stdio_src(&cinfo, pFile);
523 
524  // Allocate the structure that will hold our eventual jpeg data (must free it!)
[3090]525  pImage = (Image*)malloc(sizeof(Image));
[3086]526 
527  // Decode the jpeg file and fill in the image data structure to pass back
528  decodeJPG(&cinfo, pImage);
529 
530  // This releases all the stored memory for reading and decoding the jpeg
531  jpeg_destroy_decompress(&cinfo);
532 
533  // Close the file pointer that opened the file
534  fclose(pFile);
535 
[3070]536
[3089]537  if(pImage == NULL)
[3086]538    exit(0);
539 
[3091]540  loadTexToGL (pImage, texture);
[3089]541  if (pImage)
[3086]542    {
[3089]543      if (pImage->data)
[3086]544        {
[3089]545          free(pImage->data);
[3086]546        }
547     
[3089]548      free(pImage);
[3086]549    }
[3088]550  return true;
[3086]551}
552
[3090]553void Material::decodeJPG(jpeg_decompress_struct* cinfo, Image* pImageData)
[3086]554{
555  // Read in the header of the jpeg file
556  jpeg_read_header(cinfo, TRUE);
557 
558  // Start to decompress the jpeg file with our compression info
559  jpeg_start_decompress(cinfo);
560 
561  // Get the image dimensions and row span to read in the pixel data
562  pImageData->rowSpan = cinfo->image_width * cinfo->num_components;
563  pImageData->sizeX   = cinfo->image_width;
564  pImageData->sizeY   = cinfo->image_height;
565 
566  // Allocate memory for the pixel buffer
567  pImageData->data = new unsigned char[pImageData->rowSpan * pImageData->sizeY];
568 
569  // Here we use the library's state variable cinfo.output_scanline as the
570  // loop counter, so that we don't have to keep track ourselves.
571 
572  // Create an array of row pointers
573  unsigned char** rowPtr = new unsigned char*[pImageData->sizeY];
574  for (int i = 0; i < pImageData->sizeY; i++)
575    rowPtr[i] = &(pImageData->data[i*pImageData->rowSpan]);
576 
577  // Now comes the juice of our work, here we extract all the pixel data
578  int rowsRead = 0;
579  while (cinfo->output_scanline < cinfo->output_height) 
580    {
581      // Read in the current row of pixels and increase the rowsRead count
582      rowsRead += jpeg_read_scanlines(cinfo, &rowPtr[rowsRead], cinfo->output_height - rowsRead);
583    }
584 
585  // Delete the temporary row pointers
586  delete [] rowPtr;
587 
588  // Finish decompressing the data
589  jpeg_finish_decompress(cinfo);
590}
591
[3091]592bool Material::loadTexToGL (Image* pImage, GLuint* texture)
[3089]593{
594  glGenTextures(1, texture);
595  glBindTexture(GL_TEXTURE_2D, *texture);
596  /* not Working, and not needed.
597  glTexImage2D( GL_TEXTURE_2D, 0, 3, width,
598                height, 0, GL_BGR,
599                GL_UNSIGNED_BYTE, map->pixels );
600  */ 
[3091]601  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->sizeX, pImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
[3089]602 
603  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
604  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); 
605 
606
607}
Note: See TracBrowser for help on using the repository browser.