Página principal | Jerarquía de la clase | Lista alfabética | Lista de componentes | Lista de archivos | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

material.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= material.h                                   Julio - septiembre de 1998 =
00003 //=-------------------------------------------------------------------------=
00004 //= Definiciones de la clase MATERIAL                                       =
00005 //=-------------------------------------------------------------------------=
00006 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00007 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00008 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00009 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00010 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00011 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00012 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00013 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00014 //=-------------------------------------------------------------------------=
00015 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00016 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00017 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00018 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00019 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00020 //===========================================================================
00021 
00022 #include <string.h>
00023 #include <stdlib.h>
00024 
00025 #include "toolkits/entorno/material.h"
00026 #include "lista.cc"
00027 
00028 #if PLATAFORMA != ANSI
00029     #include "jed_gl.h"
00030 #endif
00031 
00032 #define ESPERO(tipo, msg) \
00033     if ( tipo_token != (tipo) ) { \
00034         fprintf(stderr, "<MATERIAL> ERROR: Esperaba %s y recibi [%s].\n", \
00035           (msg), cad); fflush(stderr);  return FALSE; \
00036     }
00037 
00038 //===========================================================================
00039 //= Variables y funciones globales                                          =
00040 //===========================================================================
00041 
00042 #if PLATAFORMA == SGI
00043 extern // OJO: En la SGI no se permiten templates dentro de librerias
00044 #endif
00045 LISTA <MATERIAL *> LOS_materiales;
00046 
00047 BOOLEAN
00048 leer_materiales(char *archivo)
00052 {
00053     PARSERO preprocesador;
00054     LISTA<char *> *Bloque_de_datos;
00055     TOKENIZADOR sabiondo;
00056     char cad[1000];
00057     int status, tipo_token, i;
00058     MATERIAL *Material;
00059 
00060     if ( !preprocesador.init(archivo) ) {
00061         fprintf(stderr, "<UNIVERSO> ERROR: No puedo cargarme!\n");
00062         fflush(stdout);
00063         return FALSE;
00064     }
00065 
00066     //- Inserta de primeras el material por defecto -
00067     if ( LOS_materiales.tam() < 1 ) {
00068         Material = new MATERIAL;
00069         if ( !Material ) { return FALSE; }
00070         LOS_materiales.anx(Material);
00071     }
00072 
00073     do {
00074         //- Llamar al preprocesador y tener en cuenta su estado -------------
00075         status = preprocesador.siguiente_segmento(&Bloque_de_datos);
00076         if ( status < 0 ) {
00077             fprintf(stderr, "ERROR DE SINTAXIS!\n");  fflush(stderr);
00078             break;
00079         }
00080         if ( status == 0 ) break;
00081 
00082         //- Extraer informacion de las lineas preprocesadas -----------------
00083         sabiondo.cambiar_lista(Bloque_de_datos);
00084         tipo_token = TK_DESCONOCIDO;
00085         while ( Bloque_de_datos->tam() > 0 && tipo_token != TK_FIN ) {
00086             tipo_token = sabiondo.siguiente_token(cad);
00087             switch( tipo_token ) {
00088             //- Lea un elemento del UNIVERSO --------------------------------
00089               case TK_IDENTIFICADOR:
00090                 if ( strcmp(cad, "MATERIAL") == 0 ) { 
00091                     Material = new MATERIAL;
00092                     if ( !Material || !Material->leer(&sabiondo)) {
00093                         return FALSE;
00094                     }
00095                     LOS_materiales.anx(Material);
00096                   }
00097                   else {
00098                     fprintf(stderr,  "<MATERIAL> ERROR, solo se permiten "
00099                         "grupos de tipo MATERIAL en el archivo de\n"
00100                         "especificacion de materiales \"%s\".", archivo);
00101                     fflush(stderr);
00102                 }
00103                 break;
00104             //---------------------------------------------------------------
00105               case TK_DESCONOCIDO: break;
00106             //---------------------------------------------------------------
00107               default:
00108                 fprintf(stderr, "<MATERIAL> ERROR DE SINTAXIS LEYENDO "
00109                     "\"%s\".\n"
00110                     "Se esperaba un identificador de tipo de objeto, y "
00111                     "se encontro \"%s\" que es de tipo %d.\n",
00112                     "el archivo de universo", cad, tipo_token);
00113                 fflush(stderr);
00114                 return FALSE;
00115             }
00116         } 
00117 
00118         //- Borrar la estructura temporal -----------------------------------
00119         // OJO: NO OLVIDAR ESTE PASO!
00120         for ( i = 0; i < Bloque_de_datos->tam(); i++ ) {
00121             delete (*Bloque_de_datos)[i];
00122         }
00123         delete Bloque_de_datos;
00124         Bloque_de_datos = NULL;        
00125     } while( status != 0 );
00126 
00127     return TRUE;
00128 }
00129 
00130 //===========================================================================
00131 //= Clase MATERIAL                                                          =
00132 //===========================================================================
00133 
00134 MATERIAL::MATERIAL()
00138 {
00139     _codigo = 0;
00140     strcpy(_nombre, "[default]");
00141     _ambiente.r = _ambiente.g = _ambiente.b = 0.2f;
00142     _difusa.r = _difusa.g = _difusa.b = 1.0f;
00143     _emision.r = _emision.g = _emision.b = 0;
00144     _especular.r = _especular.g = _especular.b = 1.0f;
00145     _phong_exp = 90;
00146     _phong_coef = 1;
00147     _coeficiente_de_reflexion = 0;
00148     _transparencia = 1.0;
00149     _doble_cara = FALSE;
00150 }
00151 
00152 double
00153 MATERIAL::reflexion(void)
00154 {
00155     return _coeficiente_de_reflexion;
00156 }
00157 
00158 void
00159 MATERIAL::set_reflexion(double r)
00160 {
00161     if ( r < 0 ) {
00162     fprintf(stderr, "<MATERIAL> WARNING: la reflexion debe ser mayor o igual a 0.0\n");
00163     fflush(stderr);
00164         _coeficiente_de_reflexion = 0;
00165     }
00166     else if ( r > 1 ) {
00167     fprintf(stderr, "<MATERIAL> WARNING: la reflexion debe ser menor o igual a 1.0\n");
00168     fflush(stderr);
00169         _coeficiente_de_reflexion = 1;
00170     }
00171     else {
00172         _coeficiente_de_reflexion = r;
00173     }
00174 }
00175 
00176 void
00177 MATERIAL::set_nombre(char *n)
00178 {
00179     if ( strlen(n) < MAX_CAD ) {
00180         strcpy(_nombre, n);
00181       }
00182       else {
00183         memcpy(_nombre, n, MAX_CAD - 1);
00184         _nombre[MAX_CAD-1] = '\0';
00185     }
00186 }
00187 
00188 BOOLEAN MATERIAL::doble_cara(void) { return _doble_cara; }
00189 char * MATERIAL::nombre(void)          {    return _nombre; }
00190 COLOR MATERIAL::ambiente(void)         {    return _ambiente; }
00191 COLOR MATERIAL::difusa(void)           {    return _difusa; }
00192 COLOR MATERIAL::emision(void)          {    return _emision; }
00193 COLOR MATERIAL::especular(void)        {    return _especular; }
00194 double MATERIAL::phong_exp(void)        {    return _phong_exp; }
00195 double MATERIAL::phong_coef(void)       {    return _phong_coef; }
00196 void MATERIAL::set_doble_cara(BOOLEAN c) {
00197 // OJO: Aqui debe desactivarse la listaGL
00198  _doble_cara = c; 
00199 }
00200 void MATERIAL::set_ambiente(COLOR a)   {    _ambiente = a; }
00201 void MATERIAL::set_difusa(COLOR d)     {    _difusa = d; }
00202 void MATERIAL::set_emision(COLOR e)    {    _emision = e; }
00203 void MATERIAL::set_especular(COLOR e)  {    _especular = e; }
00204 void MATERIAL::set_phong_exp(double e)  {    _phong_exp = e; }
00205 void MATERIAL::set_phong_coef(double c) {    _phong_coef = c; }
00206 void MATERIAL::set_transparencia(double t) { _transparencia = t; }
00207 
00208 BOOLEAN
00209 MATERIAL::leer(TOKENIZADOR *Sabiondo)
00210 {
00211     char cad[1000];
00212     int tipo_token = TK_DESCONOCIDO, pos;
00213 
00214     pos = 1;
00215     while ( tipo_token != TK_CERRAR) {
00216         tipo_token = Sabiondo->siguiente_token(cad);
00217         switch ( pos ) {
00218             case 1:
00219               ESPERO(TK_CADENA, "una cadena");
00220               des_comille(cad);
00221               if ( strlen(cad) > MAX_CAD-1 ) cad[MAX_CAD-1] = '\0'; 
00222               set_nombre(cad);
00223               pos++;
00224               break;
00225             case 2:  ESPERO(TK_ABRIR, "\"{\"");  pos++; break;
00226             default:
00227               if ( tipo_token == TK_CERRAR ) break;
00228               ESPERO(TK_IDENTIFICADOR, "un identificador");
00229               if ( strcmp(cad, "codigo") == 0 ) {
00230                   tipo_token = Sabiondo->siguiente_token(cad);
00231                   ESPERO(TK_NUMERO, "un numero");
00232                   _codigo = atoi(cad);
00233                 }
00234                 else if ( strcmp(cad, "phong") == 0 ) {
00235                   tipo_token = Sabiondo->siguiente_token(cad);
00236                   ESPERO(TK_NUMERO, "un numero");
00237                   _phong_coef = atof(cad);
00238                 }
00239                 else if ( strcmp(cad, "phong_size") == 0 ) {
00240                   tipo_token = Sabiondo->siguiente_token(cad);
00241                   ESPERO(TK_NUMERO, "un numero");
00242                   _phong_exp = atof(cad);
00243                 }
00244                 else if ( strcmp(cad, "reflection") == 0 ) {
00245                   tipo_token = Sabiondo->siguiente_token(cad);
00246                   ESPERO(TK_NUMERO, "un numero");
00247                   _coeficiente_de_reflexion = atof(cad);
00248                 }
00249                 else if ( strcmp(cad, "transparencia") == 0 ) {
00250                   tipo_token = Sabiondo->siguiente_token(cad);
00251                   ESPERO(TK_NUMERO, "un numero");
00252                   _transparencia = atof(cad);
00253                 }
00254                 else if ( strstr(cad, "ambient") ) {
00255                   tipo_token = Sabiondo->siguiente_token(cad);
00256                   ESPERO(TK_VECTOR_INICIO, "el inicio de un COLOR");
00257                   _ambiente.r = (float)atof(&cad[1]);
00258                   tipo_token = Sabiondo->siguiente_token(cad);
00259                   ESPERO(TK_NUMERO, "un numero (dato 2 de un COLOR)");
00260                   _ambiente.g = (float)atof(cad);
00261                   tipo_token = Sabiondo->siguiente_token(cad);
00262                   ESPERO(TK_VECTOR_FIN, "el final de un COLOR");
00263                   cad[strlen(cad) - 1] = '\0';
00264                   _ambiente.b = (float)atof(cad);
00265                 }
00266                 else if ( strcmp(cad, "diffuse") == 0 ) {
00267                   tipo_token = Sabiondo->siguiente_token(cad);
00268                   ESPERO(TK_VECTOR_INICIO, "el inicio de un COLOR");
00269                   _difusa.r = (float)atof(&cad[1]);
00270                   tipo_token = Sabiondo->siguiente_token(cad);
00271                   ESPERO(TK_NUMERO, "un numero (dato 2 de un COLOR)");
00272                   _difusa.g = (float)atof(cad);
00273                   tipo_token = Sabiondo->siguiente_token(cad);
00274                   ESPERO(TK_VECTOR_FIN, "el final de un COLOR");
00275                   cad[strlen(cad) - 1] = '\0';
00276                   _difusa.b = (float)atof(cad);
00277                 }
00278                 else if ( strcmp(cad, "specular") == 0 ) {
00279                   tipo_token = Sabiondo->siguiente_token(cad);
00280                   ESPERO(TK_VECTOR_INICIO, "el inicio de un COLOR");
00281                   _especular.r = (float)atof(&cad[1]);
00282                   tipo_token = Sabiondo->siguiente_token(cad);
00283                   ESPERO(TK_NUMERO, "un numero (dato 2 de un COLOR)");
00284                   _especular.g = (float)atof(cad);
00285                   tipo_token = Sabiondo->siguiente_token(cad);
00286                   ESPERO(TK_VECTOR_FIN, "el final de un COLOR");
00287                   cad[strlen(cad) - 1] = '\0';
00288                   _especular.b = (float)atof(cad);
00289                 }
00290                 else if ( strcmp(cad, "emision") == 0 ) {
00291                   tipo_token = Sabiondo->siguiente_token(cad);
00292                   ESPERO(TK_VECTOR_INICIO, "el inicio de un COLOR");
00293                   _emision.r = (float)atof(&cad[1]);
00294                   tipo_token = Sabiondo->siguiente_token(cad);
00295                   ESPERO(TK_NUMERO, "un numero (dato 2 de un COLOR)");
00296                   _emision.g = (float)atof(cad);
00297                   tipo_token = Sabiondo->siguiente_token(cad);
00298                   ESPERO(TK_VECTOR_FIN, "el final de un COLOR");
00299                   cad[strlen(cad) - 1] = '\0';
00300                   _emision.b = (float)atof(cad);
00301                 }
00302               ;
00303               break;
00304         }
00305     }
00306 
00307     return TRUE;
00308 }
00309 
00310 #ifdef GL_ENABLED
00311 void
00312 MATERIAL::activar_gl(void)
00313 {
00314     //----------------------------------------------------------------------
00315     //_transparencia = 1.0; // OJO!
00316 
00317     if ( _transparencia > 1.0 ) _transparencia = 1.0;
00318     if ( _transparencia < 0 ) _transparencia = 0;
00319     if ( _transparencia < 1.0 - EPSILON ) {
00320         glEnable(GL_BLEND);
00321         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00322       }
00323       else {
00324         glDisable(GL_BLEND);
00325     }
00326 
00327 
00328     //----------------------------------------------------------------------
00329     static GLfloat front_mat_shininess;
00330     static GLfloat front_mat_ambient[4];
00331     static GLfloat front_mat_diffuse[4];
00332     static GLfloat front_mat_specular[4];// Deberia ser el de la fuente de luz?
00333 
00334     front_mat_shininess = (float)_phong_exp;
00335     front_mat_ambient[0] = _ambiente.r;
00336     front_mat_ambient[1] = _ambiente.g;
00337     front_mat_ambient[2] = _ambiente.b;
00338     front_mat_ambient[3] = (float)_transparencia;
00339     front_mat_diffuse[0] = _difusa.r;
00340     front_mat_diffuse[1] = _difusa.g;
00341     front_mat_diffuse[2] = _difusa.b;
00342     front_mat_diffuse[3] = (float)_transparencia;
00343     front_mat_specular[0] = _especular.r;
00344     front_mat_specular[1] = _especular.g;
00345     front_mat_specular[2] = _especular.b;
00346     front_mat_specular[3] = (float)_transparencia;
00347 
00348     // OJO: Esto ayudaria mucho estando dentro de una lista!
00349     if ( _doble_cara ) {
00350         glDisable(GL_CULL_FACE);
00351         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, front_mat_ambient);
00352         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
00353         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
00354         glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
00355       }
00356       else {
00357         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
00358         //glDisable(GL_CULL_FACE);
00359         glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
00360         glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
00361         glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
00362         glMaterialf(GL_FRONT, GL_SHININESS, front_mat_shininess);
00363     }
00364 
00365     //----------------------------------------------------------------------
00366     static GLfloat back_mat_shininess = 32;
00367     static GLfloat back_mat_ambient[4] = {0, 0, 0, 1};
00368     static GLfloat back_mat_diffuse[4] = {0.3f, 0.6f, 0.3f, 1};
00369     static GLfloat back_mat_specular[4] = {0.7f, 0.6f, 0.6f, 1};
00370 
00371     if ( !_doble_cara ) {
00372         glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
00373         glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
00374         glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
00375         glMaterialf(GL_BACK, GL_SHININESS, back_mat_shininess);
00376     }
00377 /*
00378     printf("- MATERIAL ---------------------------------------------------\n");
00379     printf("Ambiente: <%.2f, %.2f, %.2f>/%.2f\n",
00380         front_mat_ambient[0], front_mat_ambient[1],
00381         front_mat_ambient[2], front_mat_ambient[3]);
00382     printf("Difusa: <%.2f, %.2f, %.2f>/%.2f\n",
00383         front_mat_diffuse[0], front_mat_diffuse[1],
00384         front_mat_diffuse[2], front_mat_diffuse[3]);
00385     printf("Especular: <%.2f, %.2f, %.2f>/%.2f\n",
00386         front_mat_specular[0], front_mat_specular[1],
00387         front_mat_specular[2], front_mat_specular[3]);
00388     printf("Brillo: %.2f\n", front_mat_shininess);
00389     fflush(stdout);
00390 */
00391 }
00392 #endif
00393 
00394 void
00395 MATERIAL::activar_povray(FILE *fd)
00396 {
00397     fprintf(fd, "    texture {\n");
00398     if ( _transparencia < 1.0 - EPSILON ) {
00399         fprintf(fd,"        pigment { color rgbf <%f, %f, %f, %f> }\n",
00400             _difusa.r, _difusa.g, _difusa.b, _transparencia);
00401       }
00402       else {
00403         fprintf(fd,"        pigment { color rgb <%f, %f, %f> }\n",
00404             _difusa.r, _difusa.g, _difusa.b);
00405     }
00406     fprintf(fd,
00407         "        finish {\n"
00408         "            ambient rgb <%f, %f, %f>\n"
00409         "            phong %f phong_size %f \n"
00410         "            reflection %f\n"
00411         "        } \n"
00412         "    }\n",
00413         _ambiente.r, _ambiente.g, _ambiente.b,
00414         _phong_coef, _phong_exp, _coeficiente_de_reflexion
00415     );
00416 }
00417 
00418 void
00419 MATERIAL::activar_vrml(FILE *fd)
00420 {
00421     fprintf(fd,
00422         "        appearance Appearance {\n"
00423         "            material Material { diffuseColor %f %f %f }\n"
00424         "        }\n",
00425         _difusa.r, _difusa.g, _difusa.b
00426     );
00427 }
00428 
00429 //===========================================================================
00430 //= EOF                                                                     =
00431 //===========================================================================
00432 

Este archivo HTML ha sido generado automáticamente a partir del código fuente AQUYNZA. NO LO EDITE. Para mayor información contacte al autor.