00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "core/cosas/medio.h"
00023 #include "lista.cc"
00024 #include <ctype.h>
00025 #include <string.h>
00026
00027
00028
00029
00030
00031 #define ESPERO(tipo, msg) \
00032 if ( tipo_token != (tipo) ) { \
00033 fprintf(stderr, "<MEDIO> ERROR: Esperaba %s y recibi [%s].\n", \
00034 (msg), cad); fflush(stderr); return FALSE; \
00035 }
00036
00037 #define VERIFICAR(c) \
00038 if ( !(c) ) {\
00039 fprintf(stderr, \
00040 "<MEDIO> ERROR: No se pudo crear un objeto dinamico!\n");\
00041 fflush(stderr);\
00042 exit(1);\
00043 }
00044
00045
00046
00047
00048
00049 MEDIO::MEDIO()
00050 {
00051
00052 tengo_niebla = TRUE;
00053 densidad_niebla = 0.02;
00054 color_niebla.r = 1;
00055 color_niebla.g = 1;
00056 color_niebla.b = 1;
00057
00058
00059 patron_caustics = NULL;
00060 num_caustics = 0;
00061 caustic_actual = 0;
00062
00063
00064 Lluvia = NULL;
00065
00066
00067 preprocesada = FALSE;
00068
00069 }
00070
00071 MEDIO::~MEDIO()
00072 {
00073 ;
00074 }
00075
00076 void
00077 MEDIO::set_densidad_niebla(double d)
00078 {
00079 densidad_niebla = d;
00080 preprocesada = FALSE;
00081 }
00082
00083 void
00084 MEDIO::set_niebla_activa(BOOLEAN f)
00085 {
00086 tengo_niebla = f;
00087 }
00088
00089 BOOLEAN
00090 MEDIO::leer(TOKENIZADOR *Sabiondo)
00091 {
00092 char cad[1000];
00093 int i;
00094 int tipo_token = TK_DESCONOCIDO, pos;
00095
00096
00097 pos = 2;
00098 while ( tipo_token != TK_CERRAR) {
00099 tipo_token = Sabiondo->siguiente_token(cad);
00100 switch ( pos ) {
00101 case 2: ESPERO(TK_ABRIR, "\"{\""); pos++; break;
00102 default:
00103 if ( tipo_token == TK_CERRAR ) break;
00104 ESPERO(TK_IDENTIFICADOR, "un identificador (3)");
00105 if ( strcmp(cad, "color_niebla") == 0 ) {
00106 tipo_token = Sabiondo->siguiente_token(cad);
00107 ESPERO(TK_VECTOR_INICIO, "el inicio de un COLOR");
00108 color_niebla.r = (float)atof(&cad[1]);
00109 tipo_token = Sabiondo->siguiente_token(cad);
00110 ESPERO(TK_NUMERO, "un numero (dato 2 de un COLOR)");
00111 color_niebla.g = (float)atof(cad);
00112 tipo_token = Sabiondo->siguiente_token(cad);
00113 ESPERO(TK_VECTOR_FIN, "el final de un COLOR");
00114 cad[strlen(cad) - 1] = '\0';
00115 color_niebla.b = (float)atof(cad);
00116 }
00117 else if ( strcmp(cad, "niebla") == 0 ) {
00118 tipo_token = Sabiondo->siguiente_token(cad);
00119 ESPERO(TK_IDENTIFICADOR, "un identificador (4)");
00120 for ( i = 0; cad[i]; i++ ) cad[i] = (char)toupper(cad[i]);
00121 if ( strstr(cad, "TRUE") || strstr(cad, "SI") ) {
00122 tengo_niebla = TRUE;
00123 }
00124 else {
00125 tengo_niebla = FALSE;
00126 }
00127 }
00128 else if ( strcmp(cad, "densidad_niebla") == 0 ) {
00129 tipo_token = Sabiondo->siguiente_token(cad);
00130 ESPERO(TK_NUMERO, "un numero");
00131 densidad_niebla = atof(cad);
00132 if ( densidad_niebla > 1 ) densidad_niebla = 1;
00133 if ( densidad_niebla < 0 ) densidad_niebla = 0;
00134 }
00135 else if ( strcmp(cad, "lluvia") == 0 ) {
00136 VECTOR mmin(-7, -7, -0), mmax(7, 7, 8);
00137
00138 Lluvia = new SISTEMA_DE_PARTICULAS(5000, 0.1, mmin, mmax);
00139 if ( !Lluvia || !Lluvia->leer(Sabiondo) ) {
00140 fprintf(stderr, "<MEDIO> - Error leyendo la lluvia!\n");
00141 fflush(stderr);
00142 return FALSE;
00143 }
00144 }
00145 else if ( strcmp(cad, "caustics") == 0 ) {
00146 tipo_token = Sabiondo->siguiente_token(cad);
00147 ESPERO(TK_CADENA, "una cadena (patron de archivos)");
00148 des_comille(cad);
00149 patron_caustics = new char[strlen(cad)+1];
00150 VERIFICAR(patron_caustics);
00151 strcpy(patron_caustics, cad);
00152 }
00153 else if ( strcmp(cad, "num_caustics") == 0 ) {
00154 tipo_token = Sabiondo->siguiente_token(cad);
00155 ESPERO(TK_NUMERO, "un numero");
00156 num_caustics = atoi(cad);
00157 }
00158 ;
00159 break;
00160 }
00161 }
00162
00163
00164 IMAGEN_PAL *Imagen;
00165 FILE *fd;
00166
00167 if ( patron_caustics ) {
00168 printf("<MEDIO> Cargando %d caustics:\n[", num_caustics);
00169 fflush(stdout);
00170 for ( i = 0; i < num_caustics; i++ ) {
00171 sprintf(cad, "%s%02d.bw", patron_caustics, i);
00172 fd = fopen(cad, "rb");
00173 Imagen = new IMAGEN_PAL();
00174 if ( !fd || !Imagen || !Imagen->importar_sgibw(fd) ) {
00175 fprintf(stderr,
00176 "<MEDIO> ERROR FATAL: No se pudo crear la imagen!\n");
00177 fflush(stderr);
00178 if ( fd ) fclose(fd);
00179 else fprintf(stderr,"Fallo de archivo.\n"); fflush(stderr);
00180 if ( Imagen ) delete Imagen;
00181 else fprintf(stderr,"Fallo de imagen.\n"); fflush(stderr);
00182 return FALSE;
00183 }
00184 fclose(fd);
00185 Imagen->set_modo_luminancia(TRUE);
00186 lista_caustics.anx(Imagen);
00187 printf("."); fflush(stdout);
00188 }
00189 printf("]\n"); fflush(stdout);
00190 if ( !num_caustics ) {
00191 delete patron_caustics;
00192 patron_caustics = NULL;
00193 }
00194 }
00195 return TRUE;
00196 }
00197
00198 void
00199 MEDIO::init(void)
00200 {
00201
00202 #ifdef GL_ENABLED
00203 GLfloat fogcolor[4]={color_niebla.r, color_niebla.g, color_niebla.b, 1.0};
00204
00205
00206
00207
00208
00209 glFogi(GL_FOG_MODE, GL_EXP);
00210 glFogfv(GL_FOG_COLOR, fogcolor);
00211 glFogf(GL_FOG_DENSITY, (float)densidad_niebla);
00212
00213
00214 #endif
00215
00216 preprocesada = TRUE;
00217 }
00218
00219 #ifdef GL_ENABLED
00220
00221 void
00222 MEDIO::activar_gl(CALIDAD_VISUAL * , CAMARA * )
00223 {
00224 init();
00225 if ( tengo_niebla ) {
00226
00227 glEnable(GL_FOG);
00228 }
00229 else {
00230
00231 glDisable(GL_FOG);
00232 }
00233 }
00234
00235 BOOLEAN
00236 MEDIO::pre_pintar_gl(CALIDAD_VISUAL *Calidad, MATERIAL *Material)
00237 {
00238 if ( !patron_caustics ) return FALSE;
00239
00240
00241
00242
00243 GLfloat sPlane[4] = { 0.05f, 0.03f, 0.0f, 0.0f };
00244 GLfloat tPlane[4] = { 0.0f, 0.03f, 0.05f, 0.0f };
00245 GLfloat causticScale = 1.0;
00246
00247
00248 sPlane[0] = 0.05f * causticScale;
00249 sPlane[1] = 0.03f * causticScale;
00250 tPlane[1] = 0.03f * causticScale;
00251 tPlane[2] = 0.05f * causticScale;
00252
00253 COLOR color_del_fluido(1, 1, 1);
00254
00255 Material->set_difusa(color_del_fluido);
00256 Calidad->con_caras = TRUE;
00257 Calidad->con_bordes = FALSE;
00258 Calidad->con_textura = TRUE;
00259 Calidad->con_caustics = TRUE;
00260 Calidad->con_entorno = FALSE;
00261 Calidad->con_cajas = FALSE;
00262 Calidad->con_normales = FALSE;
00263 Calidad->calidad_caras = CVC_CONSTANTE;
00264
00265 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00266 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00267 glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane);
00268 glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane);
00269 glEnable(GL_TEXTURE_GEN_S);
00270 glEnable(GL_TEXTURE_GEN_T);
00271
00272 glTexParameteri(GL_TEXTURE_2D,
00273 GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00275 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00276
00277 lista_caustics[caustic_actual]->activar_gl();
00278
00279 return TRUE;
00280 }
00281
00282 void
00283 MEDIO::post_pintar_gl(CALIDAD_VISUAL * , CAMARA *Camara)
00284 {
00285 if ( Lluvia ) {
00286 Lluvia->pintar_gl(Camara);
00287 }
00288 }
00289
00290 #endif
00291
00292 void
00293 MEDIO::actualizar(double dt)
00294 {
00295 if ( patron_caustics ) {
00296 caustic_actual++;
00297 if ( caustic_actual >= lista_caustics.tam() ) caustic_actual = 0;
00298 }
00299 if ( Lluvia ) {
00300 Lluvia->actualizar(dt);
00301 }
00302 }
00303
00304
00305
00306
00307