00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00040
00041
00042 #if PLATAFORMA == SGI
00043 extern
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
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
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
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
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
00119
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
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
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
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];
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
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
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
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
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
00431
00432