1
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5 #include <limits.h>
6 #include <SDL.h>
7 #include "asc.h"
8 #include "sky.h"
9 #include "draw_scene.h"
10 #include "elconfig.h"
11 #include "errors.h"
12 #include "gl_init.h"
13 #include "lights.h"
14 #include "map.h"
15 #include "multiplayer.h"
16 #include "reflection.h"
17 #include "shadows.h"
18 #include "textures.h"
19 #include "vmath.h"
20 #include "weather.h"
21
22 float skybox_clouds[360][4];
23 float skybox_clouds_detail[360][4];
24 float skybox_clouds_sunny[360][4];
25 float skybox_clouds_detail_sunny[360][4];
26 float skybox_clouds_rainy[360][4];
27 float skybox_clouds_detail_rainy[360][4];
28 float skybox_sky1[360][4];
29 float skybox_sky2[360][4];
30 float skybox_sky3[360][4];
31 float skybox_sky4[360][4];
32 float skybox_sky5[360][4];
33 float skybox_sky1_sunny[360][4];
34 float skybox_sky2_sunny[360][4];
35 float skybox_sky3_sunny[360][4];
36 float skybox_sky4_sunny[360][4];
37 float skybox_sky5_sunny[360][4];
38 float skybox_sun[360][4];
39 float skybox_fog[360][4];
40 float skybox_fog_sunny[360][4];
41 float skybox_fog_rainy[360][4];
42 float skybox_light_ambient[360][4];
43 float skybox_light_diffuse[360][4];
44 float skybox_light_ambient_rainy[360][4];
45 float skybox_light_diffuse_rainy[360][4];
46 float skybox_sky_color[4] = {0.0, 0.0, 0.0, 0.0};
47 float skybox_fog_color[4] = {0.0, 0.0, 0.0, 0.0};
48 float skybox_fog_density = 0.0;
49 float skybox_light_ambient_color[4];
50 float skybox_light_diffuse_color[4];
51 int skybox_no_clouds = 1;
52 int skybox_no_sun = 1;
53 int skybox_no_moons = 1;
54 int skybox_no_stars = 1;
55 int skybox_clouds_tex = -1;
56 int skybox_clouds_detail_tex = -1;
57
58 int skybox_show_sky = 1;
59 int skybox_show_clouds = 1;
60 int skybox_show_sun = 1;
61 int skybox_show_moons = 1;
62 int skybox_show_stars = 1;
63 float skybox_sunny_sky_bias = -0.3;
64 float skybox_sunny_clouds_bias = -0.3;
65 float skybox_sunny_fog_bias = -0.3;
66 float skybox_moonlight1_bias = 0.92;
67 float skybox_moonlight2_bias = 0.98;
68
69 float skybox_sun_position[4] = {0.0, 0.0, 0.0, 0.0};
70 float skybox_sun_projection[2] = {0.0, 0.0};
71 double skybox_time_d = 0.0;
72 double skybox_view[16];
73
74 float skybox_z = 0.0;
75
76 typedef struct
77 {
78 int slices_count;
79 int stacks_count;
80 int vertices_count;
81 int faces_count;
82 GLfloat *vertices;
83 GLfloat *normals;
84 GLfloat *colors;
85 GLfloat *tex_coords;
86 GLuint *faces;
87 float radius;
88 float real_radius;
89 float opening;
90 float height;
91 float texture_size;
92 float tex_coords_conversion_factor;
93 float conversion_factor;
94 } sky_dome;
95
96 typedef struct
97 {
98 int vertices_count;
99 int faces_count;
100 GLfloat *vertices;
101 GLfloat *tex_coords;
102 GLuint *faces;
103 } sky_sphere;
104
105 sky_dome dome_sky = {0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
106 sky_dome dome_clouds = {0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
107
108 GLfloat *dome_clouds_detail_colors = NULL;
109 GLfloat *dome_clouds_colors_bis = NULL;
110 GLfloat *dome_clouds_detail_colors_bis = NULL;
111 GLfloat *dome_clouds_tex_coords_bis = NULL;
112
113 sky_sphere moon_mesh = {0, 0, NULL, NULL, NULL};
114
115 GLfloat moon1_direction[3];
116 GLfloat moon2_direction[3];
117 GLfloat moon1_color[3];
118 GLfloat moon2_color[3];
119 GLfloat sun_color[4];
120 double moon_spin = 0.0;
121 float rain_coef = 0.0;
122 float day_alpha = 0.0;
123 skybox_type current_sky = SKYBOX_NONE;
124
125 #define NUM_STARS 3000
126 GLuint sky_lists;
127 int thick_clouds_tex;
128 int thick_clouds_detail_tex;
129 int moon_tex;
130 int sun_tex;
131
create_dome(int slices,int stacks,float radius,float opening,int fake_opening,float first_angle,float texture_size)132 sky_dome create_dome(int slices, int stacks, float radius, float opening, int fake_opening, float first_angle, float texture_size)
133 {
134 sky_dome dome = {0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
135 int i, j;
136 float angle, angle_step;
137 int idx, vtx_idx;
138 float max_sin_angle;
139 float max_cos_angle;
140
141 dome.slices_count = slices;
142 dome.stacks_count = stacks;
143
144 dome.vertices_count = dome.slices_count*(dome.stacks_count+1)+1;
145 dome.faces_count = dome.slices_count*(1+2*dome.stacks_count);
146
147 dome.vertices = (GLfloat*)malloc(3*dome.vertices_count*sizeof(GLfloat));
148 dome.normals = (GLfloat*)malloc(3*dome.vertices_count*sizeof(GLfloat));
149 dome.colors = (GLfloat*)malloc(4*dome.vertices_count*sizeof(GLfloat));
150 dome.tex_coords = (GLfloat*)malloc(2*dome.vertices_count*sizeof(GLfloat));
151 dome.faces = (GLuint*)malloc(3*dome.faces_count*sizeof(GLuint));
152
153 dome.radius = radius;
154 dome.opening = opening;
155
156 angle = dome.opening * M_PI / 180.0;
157 max_sin_angle = sinf(angle);
158 max_cos_angle = cosf(angle);
159
160 dome.real_radius = dome.radius/max_sin_angle;
161 dome.height = dome.real_radius - dome.real_radius*max_cos_angle;
162 dome.texture_size = texture_size;
163 dome.tex_coords_conversion_factor = dome.radius / texture_size;
164
165 texture_size *= dome.radius * max_cos_angle / (max_sin_angle * dome.real_radius);
166
167 dome.conversion_factor = max_cos_angle * dome.radius;
168
169 // we compute the vertices positions and normals
170 i = idx = 0;
171 if (first_angle > 0.0)
172 {
173 float cos_angle = cosf(angle);
174 float sin_angle = sinf(angle);
175 float z_pos = cos_angle * dome.real_radius + dome.height - dome.real_radius;
176 float tmp = texture_size * sin_angle/cos_angle;
177 float fake_angle = angle * fake_opening / opening;
178 float fake_cos_angle = cosf(fake_angle);
179 float fake_sin_angle = sinf(fake_angle);
180 for (j = 0; j < dome.slices_count; ++j)
181 {
182 float teta = j * 2.0 * M_PI / (float)dome.slices_count;
183 float cos_teta = cosf(teta);
184 float sin_teta = sinf(teta);
185 int idx3 = idx*3;
186 dome.vertices[idx3 ] = sin_angle * cos_teta * dome.real_radius;
187 dome.vertices[idx3+1] = sin_angle * sin_teta * dome.real_radius;
188 dome.vertices[idx3+2] = z_pos;
189 dome.normals[idx3 ] = fake_sin_angle * cos_teta;
190 dome.normals[idx3+1] = fake_sin_angle * sin_teta;
191 dome.normals[idx3+2] = fake_cos_angle;
192 dome.tex_coords[idx*2 ] = 0.5 + tmp * cos_teta;
193 dome.tex_coords[idx*2+1] = 0.5 + tmp * sin_teta;
194 ++idx;
195 }
196 angle -= first_angle * M_PI / 180.0;
197 angle_step = angle / (float)dome.stacks_count;
198 ++i;
199 }
200 else
201 {
202 angle_step = angle / (float)(dome.stacks_count+1);
203 }
204 for (; i <= dome.stacks_count; ++i)
205 {
206 float cos_angle = cosf(angle);
207 float sin_angle = sinf(angle);
208 float z_pos = cos_angle * dome.real_radius + dome.height - dome.real_radius;
209 float tmp = texture_size * sin_angle/cos_angle;
210 float fake_angle = angle * fake_opening / opening;
211 float fake_cos_angle = cosf(fake_angle);
212 float fake_sin_angle = sinf(fake_angle);
213 for (j = 0; j < dome.slices_count; ++j)
214 {
215 float teta = j * 2.0 * M_PI / (float)dome.slices_count;
216 float cos_teta = cosf(teta);
217 float sin_teta = sinf(teta);
218 int idx3 = idx*3;
219 dome.vertices[idx3 ] = sin_angle * cos_teta * dome.real_radius;
220 dome.vertices[idx3+1] = sin_angle * sin_teta * dome.real_radius;
221 dome.vertices[idx3+2] = z_pos;
222 dome.normals[idx3 ] = fake_sin_angle * cos_teta;
223 dome.normals[idx3+1] = fake_sin_angle * sin_teta;
224 dome.normals[idx3+2] = fake_cos_angle;
225 dome.tex_coords[idx*2 ] = 0.5 + tmp * cos_teta;
226 dome.tex_coords[idx*2+1] = 0.5 + tmp * sin_teta;
227 ++idx;
228 }
229 angle -= angle_step;
230 }
231
232 // the vertex at the top of the dome
233 dome.vertices[idx*3 ] = 0.0;
234 dome.vertices[idx*3+1] = 0.0;
235 dome.vertices[idx*3+2] = dome.height;
236 dome.normals[idx*3 ] = 0.0;
237 dome.normals[idx*3+1] = 0.0;
238 dome.normals[idx*3+2] = 1.0;
239 dome.tex_coords[idx*2 ] = 0.5;
240 dome.tex_coords[idx*2+1] = 0.5;
241
242 // we build the faces of the dome
243 idx = 0;
244 vtx_idx = 0;
245 for (i = 0; i < dome.stacks_count; ++i)
246 {
247 for (j = 0; j < dome.slices_count; ++j)
248 {
249 int next = (j+1)%dome.slices_count;
250 dome.faces[idx++] = vtx_idx+j;
251 dome.faces[idx++] = vtx_idx+j+dome.slices_count;
252 dome.faces[idx++] = vtx_idx+next;
253 dome.faces[idx++] = vtx_idx+next;
254 dome.faces[idx++] = vtx_idx+j+dome.slices_count;
255 dome.faces[idx++] = vtx_idx+next+dome.slices_count;
256 }
257 vtx_idx += dome.slices_count;
258 }
259
260 // the last stack of faces at the top of the dome
261 for (j = 0; j < dome.slices_count; ++j)
262 {
263 int next = (j+1)%dome.slices_count;
264 dome.faces[idx++] = vtx_idx+j;
265 dome.faces[idx++] = vtx_idx+dome.slices_count;
266 dome.faces[idx++] = vtx_idx+next;
267 }
268
269 return dome;
270 }
271
create_sphere(int slices,int stacks)272 sky_sphere create_sphere(int slices, int stacks)
273 {
274 sky_sphere sphere;
275 int i, j;
276 int idx, vtx_idx;
277
278 sphere.vertices_count = (slices+1)*(stacks+1);
279 sphere.faces_count = slices*stacks*2;
280
281 sphere.vertices = (GLfloat*)malloc(3*sphere.vertices_count*sizeof(GLfloat));
282 sphere.tex_coords = (GLfloat*)malloc(2*sphere.vertices_count*sizeof(GLfloat));
283 sphere.faces = (GLuint*)malloc(3*sphere.faces_count*sizeof(GLuint));
284
285 // we compute the vertices positions and normals
286 idx = 0;
287 for (j = 0; j <= stacks; ++j)
288 {
289 float angle = j * M_PI / (float)stacks;
290 float cos_angle = cosf(angle);
291 float sin_angle = sinf(angle);
292 float tex_j = j / (float)stacks;
293 for (i = 0; i <= slices; ++i)
294 {
295 float teta = i * 2.0 * M_PI / (float)slices;
296 float cos_teta = cosf(teta);
297 float sin_teta = sinf(teta);
298 int idx3 = idx*3;
299 sphere.vertices[idx3 ] = sin_angle * cos_teta;
300 sphere.vertices[idx3+1] = sin_angle * sin_teta;
301 sphere.vertices[idx3+2] = cos_angle;
302 sphere.tex_coords[idx*2 ] = i / (float)slices;
303 sphere.tex_coords[idx*2+1] = tex_j;
304 ++idx;
305 }
306 }
307
308 // we build the faces of the dome
309 idx = 0;
310 vtx_idx = 0;
311 for (j = 0; j < stacks; ++j)
312 {
313 for (i = 0; i < slices; ++i)
314 {
315 sphere.faces[idx++] = vtx_idx + i;
316 sphere.faces[idx++] = vtx_idx + i + slices+1;
317 sphere.faces[idx++] = vtx_idx + i+1;
318 sphere.faces[idx++] = vtx_idx + i+1;
319 sphere.faces[idx++] = vtx_idx + i + slices+1;
320 sphere.faces[idx++] = vtx_idx + i+1 + slices+1;
321 }
322 vtx_idx += slices+1;
323 }
324
325 return sphere;
326 }
327
destroy_dome(sky_dome * dome)328 void destroy_dome(sky_dome *dome)
329 {
330 if (dome->vertices ) { free(dome->vertices ); dome->vertices = NULL; }
331 if (dome->normals ) { free(dome->normals ); dome->normals = NULL; }
332 if (dome->colors ) { free(dome->colors ); dome->colors = NULL; }
333 if (dome->tex_coords) { free(dome->tex_coords); dome->tex_coords = NULL; }
334 if (dome->faces ) { free(dome->faces ); dome->faces = NULL; }
335 }
336
destroy_sphere(sky_sphere * sphere)337 void destroy_sphere(sky_sphere *sphere)
338 {
339 if (sphere->vertices ) { free(sphere->vertices ); sphere->vertices = NULL; }
340 if (sphere->tex_coords) { free(sphere->tex_coords); sphere->tex_coords = NULL; }
341 if (sphere->faces ) { free(sphere->faces ); sphere->faces = NULL; }
342 }
343
draw_sphere(sky_sphere * sphere)344 static __inline__ void draw_sphere(sky_sphere *sphere)
345 {
346 glEnableClientState(GL_VERTEX_ARRAY);
347 glEnableClientState(GL_NORMAL_ARRAY);
348 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
349
350 glVertexPointer(3, GL_FLOAT, 0, sphere->vertices);
351 glNormalPointer(GL_FLOAT, 0, sphere->vertices);
352 glTexCoordPointer(2, GL_FLOAT, 0, sphere->tex_coords);
353
354 glDrawElements(GL_TRIANGLES, sphere->faces_count*3, GL_UNSIGNED_INT, sphere->faces);
355
356 glDisableClientState(GL_VERTEX_ARRAY);
357 glDisableClientState(GL_NORMAL_ARRAY);
358 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
359 }
360
skybox_compute_z_position()361 void skybox_compute_z_position()
362 {
363 if (far_plane < 500.0)
364 {
365 float zl = first_person ? 0.0 : zoom_level;
366 float cos_rx = cosf(-rx*M_PI/180.0);
367 float sin_rx = sinf(-rx*M_PI/180.0);
368 float eye_xy = sin_rx*zl*camera_distance;
369 float eye_z = cos_rx*zl*camera_distance-camera_z;
370 float water_end = sin_rx*far_plane+(far_plane*cos_rx-eye_z)*cos_rx/sin_rx;
371
372 skybox_z = eye_z*(water_end-500.0+eye_xy)/water_end;
373
374 //printf("camera_z=%f rx=%f zoom_level=%f camera_distance=%f eye_xy=%f eye_z=%f water_end=%f skybox_z=%f\n", camera_z, rx, zoom_level, camera_distance, eye_xy, eye_z, water_end, skybox_z);
375 }
376 else
377 skybox_z = 0.0;
378 }
379
skybox_get_z_position()380 float skybox_get_z_position()
381 {
382 return skybox_z;
383 }
384
skybox_vertex_to_ground_coords(sky_dome * dome,int i,float * gx,float * gy)385 static __inline__ void skybox_vertex_to_ground_coords(sky_dome *dome, int i, float *gx, float *gy)
386 {
387 *gx = dome->tex_coords_conversion_factor * (dome->tex_coords[i*2 ] - dome->tex_coords[dome->vertices_count*2-2]);
388 *gy = dome->tex_coords_conversion_factor * (dome->tex_coords[i*2+1] - dome->tex_coords[dome->vertices_count*2-1]);
389 }
390
skybox_direction_to_ground_coords(float dir[3],float * gx,float * gy)391 void skybox_direction_to_ground_coords(float dir[3], float *gx, float *gy)
392 {
393 float sd = sqrtf(dir[0]*dir[0] + dir[1]*dir[1]);
394 float t = sd / (dir[2] - dome_sky.height + dome_sky.real_radius);
395 float gd = t * dome_clouds.conversion_factor;
396
397 *gx = gd * dir[0] / sd;
398 *gy = gd * dir[1] / sd;
399
400 //printf("dir=%f,%f,%f t=%f gx=%f gy=%f\n", dir[0], dir[1], dir[2], t, *gx, *gy);
401 }
402
skybox_coords_from_ground_coords(float sky_coords[3],float gx,float gy)403 void skybox_coords_from_ground_coords(float sky_coords[3], float gx, float gy)
404 {
405 float gd = sqrtf(gx*gx + gy*gy);
406 float t = gd / dome_clouds.conversion_factor;
407 float sd = dome_clouds.real_radius * t / sqrtf(1.0 + t*t);
408
409 sky_coords[0] = sd * gx / gd;
410 sky_coords[1] = sd * gy / gd;
411 sky_coords[2] = sd / t + dome_sky.height - dome_sky.real_radius;
412 }
413
skybox_compute_element_projection(float proj[3],float pos[3])414 void skybox_compute_element_projection(float proj[3], float pos[3])
415 {
416 float coef, a, b, c, delta;
417 float r2 = dome_sky.real_radius*dome_sky.real_radius;
418 float z = dome_sky.height - dome_sky.real_radius;
419
420 c = z*z - r2;
421
422 if (pos[0] != 0.0)
423 {
424 coef = pos[2]/pos[0];
425 a = 1.0 + coef*coef;
426 b = -2.0*coef*z;
427 delta = b*b - 4*a*c;
428 if (delta <= 0.0) fprintf(stderr, "delta=%f\n", delta);
429
430 if (pos[0] < 0.0)
431 proj[0] = (-b - sqrtf(delta)) / (2.0*a);
432 else
433 proj[0] = (-b + sqrtf(delta)) / (2.0*a);
434 }
435 else proj[0] = 0.0;
436
437 if (pos[1] != 0.0)
438 {
439 coef = pos[2]/pos[1];
440 a = 1.0 + coef*coef;
441 b = -2.0*coef*z;
442 delta = b*b - 4*a*c;
443 if (delta <= 0.0) fprintf(stderr, "delta=%f\n", delta);
444
445 if (pos[1] < 0.0)
446 proj[1] = (-b - sqrtf(delta)) / (2.0*a);
447 else
448 proj[1] = (-b + sqrtf(delta)) / (2.0*a);
449 }
450 else proj[1] = 0.0;
451
452 proj[2] = sqrtf(r2 - proj[0]*proj[0] - proj[1]*proj[1]) + z;
453 }
454
skybox_get_height(float x,float y)455 float skybox_get_height(float x, float y)
456 {
457 float d2 = dome_sky.real_radius*dome_sky.real_radius - x*x - y*y;
458 float d = d2 <= 0.0 ? 0.0 : sqrtf(d2);
459 return (d + dome_sky.height - dome_sky.real_radius);
460 }
461
skybox_set_type(skybox_type sky)462 void skybox_set_type(skybox_type sky)
463 {
464 current_sky = sky;
465 }
466
467 void cloudy_sky();
468 void underworld_sky();
469
skybox_display()470 void skybox_display()
471 {
472 glMatrixMode(GL_PROJECTION);
473 glPushMatrix();
474 glLoadMatrixd(skybox_view);
475 glMatrixMode(GL_MODELVIEW);
476 glPushMatrix();
477
478 // we center the sky on the camera, not on the world
479 glTranslatef(-camera_x, -camera_y, 0.0);
480
481 switch (current_sky)
482 {
483 case SKYBOX_CLOUDY:
484 cloudy_sky();
485 break;
486
487 case SKYBOX_UNDERWORLD:
488 underworld_sky();
489 break;
490
491 case SKYBOX_NONE:
492 default:
493 break;
494 }
495
496 glPopMatrix();
497 glMatrixMode(GL_PROJECTION);
498 glPopMatrix();
499 glMatrixMode(GL_MODELVIEW);
500 }
501
502 void update_cloudy_sky_positions();
503
skybox_update_positions()504 void skybox_update_positions()
505 {
506 switch(current_sky)
507 {
508 case SKYBOX_CLOUDY:
509 update_cloudy_sky_positions();
510 break;
511
512 case SKYBOX_UNDERWORLD:
513 case SKYBOX_NONE:
514 default:
515 break;
516 }
517 }
518
519 void update_cloudy_sky_colors();
520 void update_cloudy_sky_local_colors();
521 void update_underworld_sky_colors();
522
skybox_update_colors()523 void skybox_update_colors()
524 {
525 switch(current_sky)
526 {
527 case SKYBOX_CLOUDY:
528 if (skybox_local_weather)
529 update_cloudy_sky_local_colors();
530 else
531 update_cloudy_sky_colors();
532 break;
533
534 case SKYBOX_UNDERWORLD:
535 update_underworld_sky_colors();
536 break;
537
538 case SKYBOX_NONE:
539 skybox_sky_color[0] = 0.0;
540 skybox_sky_color[1] = 0.0;
541 skybox_sky_color[2] = 0.0;
542 skybox_sky_color[3] = 1.0;
543 skybox_fog_color[0] = 0.0;
544 skybox_fog_color[1] = 0.0;
545 skybox_fog_color[2] = 0.0;
546 skybox_fog_color[3] = 1.0;
547 skybox_fog_density = 0.01;
548 default:
549 break;
550 }
551 }
552
update_cloudy_sky_positions()553 void update_cloudy_sky_positions()
554 {
555 float rot1[9], rot2[9], rot3[9];
556 float moon1_vect[3] = {0.0, 0.0, 1.0};
557 float moon2_vect[3] = {0.0, 0.0, 1.0};
558
559 if (is_day)
560 {
561 float dir[3] = {skybox_sun_position[0] * 480.0,
562 skybox_sun_position[1] * 480.0,
563 skybox_sun_position[2] * 480.0};
564 skybox_direction_to_ground_coords(dir, &skybox_sun_projection[0], &skybox_sun_projection[1]);
565 }
566 else
567 {
568 skybox_sun_projection[0] = skybox_sun_projection[1] = 0.0;
569 }
570
571 moon_spin = cur_time % (1296000*1000);
572 moon_spin *= 360.0/(1296000.0/*seconds in large month*/ * 1000.0/*millisecond bump*/);
573 moon_spin += skybox_time_d;
574
575 MAT3_ROT_Y(rot1, -((float)game_minute+(float)game_second/60.0)*M_PI/180.0);
576 MAT3_ROT_Y(rot2, moon_spin*M_PI/180.0);
577 MAT3_MULT(rot3, rot1, rot2);
578 MAT3_VECT3_MULT(moon1_direction, rot3, moon1_vect);
579
580 MAT3_ROT_Z(rot2, M_PI/9.0);
581 MAT3_MULT(rot3, rot1, rot2);
582 MAT3_ROT_Y(rot1, moon_spin*M_PI/18.0);
583 MAT3_MULT(rot2, rot3, rot1);
584 MAT3_VECT3_MULT(moon2_direction, rot2, moon2_vect);
585 }
586
get_sky_sunlight(const GLfloat normal[3])587 static __inline__ float get_sky_sunlight(const GLfloat normal[3])
588 {
589 GLfloat dot = normal[0]*sun_position[0]+normal[1]*sun_position[1]+normal[2]*sun_position[2];
590 if (skybox_show_sun && !skybox_no_sun)
591 return (dot > skybox_sunny_sky_bias ? (dot-skybox_sunny_sky_bias)/(1.0-skybox_sunny_sky_bias) : 0.0);
592 else
593 return 0.0;
594 }
595
get_clouds_sunlight(const GLfloat normal[3])596 static __inline__ float get_clouds_sunlight(const GLfloat normal[3])
597 {
598 GLfloat dot = normal[0]*sun_position[0]+normal[1]*sun_position[1]+normal[2]*sun_position[2];
599 if (skybox_show_sun && !skybox_no_sun)
600 return (dot > skybox_sunny_clouds_bias ? (dot-skybox_sunny_clouds_bias)/(1.0-skybox_sunny_clouds_bias) : 0.0);
601 else
602 return 0.0;
603 }
604
get_fog_sunlight(const GLfloat normal[3])605 static __inline__ float get_fog_sunlight(const GLfloat normal[3])
606 {
607 GLfloat dot = normal[0]*sun_position[0]+normal[1]*sun_position[1]+normal[2]*sun_position[2];
608 if (skybox_show_sun && !skybox_no_sun)
609 return (dot > skybox_sunny_fog_bias ? (dot-skybox_sunny_fog_bias)/(1.0-skybox_sunny_fog_bias) : 0.0);
610 else
611 return 0.0;
612 }
613
get_moonlight1(const GLfloat normal[3])614 static __inline__ float get_moonlight1(const GLfloat normal[3])
615 {
616 GLfloat dot1 = normal[0]*moon1_direction[0]+normal[1]*moon1_direction[1]+normal[2]*moon1_direction[2];
617 GLfloat dot2 = -(sun_position[0]*moon1_direction[0]+sun_position[1]*moon1_direction[1]+sun_position[2]*moon1_direction[2])*0.5+0.5;
618 dot1 = (dot1 > skybox_moonlight1_bias ? (dot1-skybox_moonlight1_bias)/(1.0-skybox_moonlight1_bias) : 0.0);
619 if (skybox_show_moons && !skybox_no_moons)
620 return dot1*dot2;
621 else
622 return 0.0;
623 }
624
get_moonlight2(const GLfloat normal[3])625 static __inline__ float get_moonlight2(const GLfloat normal[3])
626 {
627 GLfloat dot1 = normal[0]*moon2_direction[0]+normal[1]*moon2_direction[1]+normal[2]*moon2_direction[2];
628 GLfloat dot2 = -(sun_position[0]*moon2_direction[0]+sun_position[1]*moon2_direction[1]+sun_position[2]*moon2_direction[2])*0.5+0.5;
629 dot1 = (dot1 > skybox_moonlight2_bias ? (dot1-skybox_moonlight2_bias)/(1.0-skybox_moonlight2_bias) : 0.0);
630 if (skybox_show_moons && !skybox_no_moons)
631 return dot1*dot2;
632 else
633 return 0.0;
634 }
635
update_cloudy_sky_colors()636 void update_cloudy_sky_colors()
637 {
638 int i, idx, end;
639 GLfloat color_sun[4];
640 GLfloat color_sky[4];
641 GLfloat color[4];
642 float abs_light;
643 float *normal, ml1, ml2;
644 float x, y, lg;
645
646 abs_light = light_level;
647 if(light_level > 59)
648 {
649 abs_light = 119 - light_level;
650 }
651 abs_light = 1.0f - abs_light/59.0f;
652
653 rain_coef = weather_get_density();
654
655 // alpha adjustment for objects that should fade in daylight
656 day_alpha = (1.0-abs_light)*(1.0-rain_coef);
657
658 // color of the moons
659 moon1_color[0] = 0.9;
660 moon1_color[1] = 0.9;
661 moon1_color[2] = 0.9;
662 moon2_color[0] = 0.9;
663 moon2_color[1] = 0.8;
664 moon2_color[2] = 0.7;
665
666 // color of the sun
667 skybox_get_current_color(sun_color, skybox_sun);
668 sun_color[0] *= 1.0 - rain_coef;
669 sun_color[1] *= 1.0 - rain_coef;
670 sun_color[2] *= 1.0 - rain_coef;
671 sun_color[3] *= 1.0 - rain_coef;
672
673 // color of the light
674 skybox_blend_current_colors(skybox_light_ambient_color, skybox_light_ambient, skybox_light_ambient_rainy, rain_coef);
675 skybox_blend_current_colors(skybox_light_diffuse_color, skybox_light_diffuse, skybox_light_diffuse_rainy, rain_coef);
676
677 // we compute the color and the density of the fog
678 skybox_blend_current_colors(skybox_fog_color, skybox_fog, skybox_fog_rainy, rain_coef);
679 if (rain_coef > 0.0)
680 {
681 float fog_density;
682 blend_colors(&fog_density, &skybox_fog[game_minute][3], &skybox_fog[(game_minute+1)%360][3], (float)game_second/60.0, 1);
683 skybox_fog_color[0] *= (1.0-rain_coef) + rain_coef*weather_color[0];
684 skybox_fog_color[1] *= (1.0-rain_coef) + rain_coef*weather_color[1];
685 skybox_fog_color[2] *= (1.0-rain_coef) + rain_coef*weather_color[2];
686 skybox_fog_color[3] = (1.0-rain_coef)*fog_density + rain_coef*skybox_fog_color[3];
687 }
688 skybox_fog_density = skybox_fog_color[3];
689 skybox_fog_color[3] = 1.0;
690
691 i = idx = 0;
692
693 // clouds color
694 skybox_blend_current_colors(color_sky, skybox_clouds, skybox_clouds_rainy, rain_coef);
695 skybox_blend_current_colors(color_sun, skybox_clouds_sunny, skybox_clouds_rainy, rain_coef);
696 while (i < dome_clouds.slices_count * 2)
697 {
698 normal = &dome_clouds.normals[i*3];
699 ml1 = get_moonlight1(normal)*0.3*day_alpha;
700 ml2 = get_moonlight2(normal)*0.2*day_alpha;
701
702 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
703
704 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
705 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
706 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
707
708 if (lightning_falling) {
709 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
710 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
711 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
712 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
713 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
714 }
715
716 dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
717 dome_clouds_colors_bis[idx++] = color[0];
718 dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
719 dome_clouds_colors_bis[idx++] = color[1];
720 dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
721 dome_clouds_colors_bis[idx++] = color[2];
722 dome_clouds.colors[idx] = 0.0;
723 dome_clouds_colors_bis[idx++] = 0.0;
724 ++i;
725 }
726 while (i < dome_clouds.vertices_count)
727 {
728 normal = &dome_clouds.normals[i*3];
729 ml1 = get_moonlight1(normal)*0.3*day_alpha;
730 ml2 = get_moonlight2(normal)*0.2*day_alpha;
731
732 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
733
734 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
735 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
736 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
737
738 if (lightning_falling) {
739 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
740 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
741 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
742 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
743 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
744 }
745
746 dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
747 dome_clouds_colors_bis[idx++] = color[0];
748 dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
749 dome_clouds_colors_bis[idx++] = color[1];
750 dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
751 dome_clouds_colors_bis[idx++] = color[2];
752 dome_clouds.colors[idx] = 1.0;
753 dome_clouds_colors_bis[idx++] = rain_coef;
754 ++i;
755 }
756
757 i = idx = 0;
758
759 // clouds detail color
760 skybox_blend_current_colors(color_sky, skybox_clouds_detail, skybox_clouds_detail_rainy, rain_coef);
761 skybox_blend_current_colors(color_sun, skybox_clouds_detail_sunny, skybox_clouds_detail_rainy, rain_coef);
762 while (i < dome_clouds.slices_count * 2)
763 {
764 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
765
766 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
767 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
768 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
769
770 if (lightning_falling) {
771 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
772 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
773 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
774 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
775 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
776 }
777
778 dome_clouds_detail_colors[idx] = color[0];
779 dome_clouds_detail_colors_bis[idx++] = color[0];
780 dome_clouds_detail_colors[idx] = color[1];
781 dome_clouds_detail_colors_bis[idx++] = color[1];
782 dome_clouds_detail_colors[idx] = color[2];
783 dome_clouds_detail_colors_bis[idx++] = color[2];
784 dome_clouds_detail_colors[idx] = 0.0;
785 dome_clouds_detail_colors_bis[idx++] = 0.0;
786 ++i;
787 }
788 while (i < dome_clouds.vertices_count)
789 {
790 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
791
792 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
793 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
794 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
795
796 if (lightning_falling) {
797 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
798 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
799 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
800 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
801 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
802 }
803
804 dome_clouds_detail_colors[idx] = color[0];
805 dome_clouds_detail_colors_bis[idx++] = color[0];
806 dome_clouds_detail_colors[idx] = color[1];
807 dome_clouds_detail_colors_bis[idx++] = color[1];
808 dome_clouds_detail_colors[idx] = color[2];
809 dome_clouds_detail_colors_bis[idx++] = color[2];
810 dome_clouds_detail_colors[idx] = 1.0;
811 dome_clouds_detail_colors_bis[idx++] = rain_coef;
812 ++i;
813 }
814
815 i = idx = 0;
816
817 // sky color
818 skybox_blend_current_colors(color_sky, skybox_sky1, skybox_fog_rainy, rain_coef);
819 skybox_blend_current_colors(color_sun, skybox_sky1_sunny, skybox_fog_rainy, rain_coef);
820 end = dome_sky.slices_count;
821 while (i < end)
822 {
823 normal = &dome_sky.normals[i*3];
824 ml1 = get_moonlight1(normal)*0.15*day_alpha;
825 ml2 = get_moonlight2(normal)*0.1*day_alpha;
826
827 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
828
829 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
830 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
831 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
832
833 if (lightning_falling) {
834 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
835 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
836 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
837 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
838 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
839 }
840
841 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
842 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
843 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
844 dome_sky.colors[idx++] = 1.0;
845 ++i;
846 }
847
848 skybox_blend_current_colors(color_sky, skybox_sky2, skybox_fog_rainy, rain_coef);
849 skybox_blend_current_colors(color_sun, skybox_sky2_sunny, skybox_fog_rainy, rain_coef);
850 end += dome_sky.slices_count;
851 while (i < end)
852 {
853 normal = &dome_sky.normals[i*3];
854 ml1 = get_moonlight1(normal)*0.15*day_alpha;
855 ml2 = get_moonlight2(normal)*0.1*day_alpha;
856
857 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
858
859 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
860 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
861 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
862
863 if (lightning_falling) {
864 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
865 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
866 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
867 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
868 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
869 }
870
871 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
872 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
873 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
874 dome_sky.colors[idx++] = 1.0;
875 ++i;
876 }
877
878 skybox_blend_current_colors(color_sky, skybox_sky3, skybox_fog_rainy, rain_coef);
879 skybox_blend_current_colors(color_sun, skybox_sky3_sunny, skybox_fog_rainy, rain_coef);
880 end += dome_sky.slices_count;
881 while (i < end)
882 {
883 normal = &dome_sky.normals[i*3];
884 ml1 = get_moonlight1(normal)*0.15*day_alpha;
885 ml2 = get_moonlight2(normal)*0.1*day_alpha;
886
887 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
888
889 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
890 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
891 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
892
893 if (lightning_falling) {
894 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
895 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
896 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
897 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
898 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
899 }
900
901 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
902 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
903 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
904 dome_sky.colors[idx++] = 1.0;
905 ++i;
906 }
907
908 skybox_blend_current_colors(color_sky, skybox_sky4, skybox_fog_rainy, rain_coef);
909 skybox_blend_current_colors(color_sun, skybox_sky4_sunny, skybox_fog_rainy, rain_coef);
910 end += dome_sky.slices_count;
911 while (i < end)
912 {
913 normal = &dome_sky.normals[i*3];
914 ml1 = get_moonlight1(normal)*0.15*day_alpha;
915 ml2 = get_moonlight2(normal)*0.1*day_alpha;
916
917 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
918
919 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
920 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
921 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
922
923 if (lightning_falling) {
924 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
925 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
926 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
927 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
928 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
929 }
930
931 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
932 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
933 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
934 dome_sky.colors[idx++] = 1.0;
935 ++i;
936 }
937
938 skybox_blend_current_colors(color_sky, skybox_sky5, skybox_fog_rainy, rain_coef);
939 skybox_blend_current_colors(color_sun, skybox_sky5_sunny, skybox_fog_rainy, rain_coef);
940 while (i < dome_sky.vertices_count)
941 {
942 normal = &dome_sky.normals[i*3];
943 ml1 = get_moonlight1(normal)*0.15*day_alpha;
944 ml2 = get_moonlight2(normal)*0.1*day_alpha;
945
946 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
947
948 color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
949 color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
950 color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
951
952 if (lightning_falling) {
953 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
954 lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
955 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
956 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
957 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
958 }
959
960 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
961 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
962 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
963 dome_sky.colors[idx++] = 1.0;
964 ++i;
965 }
966
967 memcpy(skybox_sky_color, color_sun, 4*sizeof(float));
968
969 // color of the moons update
970 moon1_color[0] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
971 moon1_color[1] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
972 moon1_color[2] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
973 moon2_color[0] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
974 moon2_color[1] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
975 moon2_color[2] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
976 }
977
update_cloudy_sky_local_colors()978 void update_cloudy_sky_local_colors()
979 {
980 int i, idx, end;
981 GLfloat color_sun[4];
982 GLfloat color_sky[4];
983 GLfloat color[4];
984 GLfloat local_color[4];
985 float abs_light;
986 float ratios[MAX_WEATHER_TYPES];
987 float *normal, ml1, ml2, x, y, lg;
988
989 abs_light = light_level;
990 if(light_level > 59)
991 {
992 abs_light = 119 - light_level;
993 }
994 abs_light = 1.0f - abs_light/59.0f;
995
996 // alpha adjustment for objects that should fade in daylight
997 day_alpha = (1.0-abs_light);
998
999 // color of the moons
1000 moon1_color[0] = 0.9;
1001 moon1_color[1] = 0.9;
1002 moon1_color[2] = 0.9;
1003 moon2_color[0] = 0.9;
1004 moon2_color[1] = 0.8;
1005 moon2_color[2] = 0.7;
1006
1007 // color of the sun
1008 skybox_get_current_color(sun_color, skybox_sun);
1009 weather_compute_ratios(ratios, skybox_sun_projection[0]-camera_x, skybox_sun_projection[1]-camera_y);
1010 rain_coef = weather_get_density_from_ratios(ratios);
1011 sun_color[0] *= 1.0 - rain_coef;
1012 sun_color[1] *= 1.0 - rain_coef;
1013 sun_color[2] *= 1.0 - rain_coef;
1014 sun_color[3] *= 1.0 - rain_coef;
1015
1016 // color of the light
1017 skybox_blend_current_colors(skybox_light_ambient_color, skybox_light_ambient, skybox_light_ambient_rainy, rain_coef);
1018 skybox_blend_current_colors(skybox_light_diffuse_color, skybox_light_diffuse, skybox_light_diffuse_rainy, rain_coef);
1019
1020 // we compute the color and the density of the fog
1021 rain_coef = weather_get_intensity();
1022 skybox_blend_current_colors(skybox_fog_color, skybox_fog, skybox_fog_rainy, rain_coef);
1023 if (rain_coef > 0.0)
1024 {
1025 float fog_density;
1026 rain_coef = weather_get_density();
1027 blend_colors(&fog_density, &skybox_fog[game_minute][3], &skybox_fog[(game_minute+1)%360][3], (float)game_second/60.0, 1);
1028 skybox_fog_color[0] *= (1.0-rain_coef) + rain_coef*weather_color[0];
1029 skybox_fog_color[1] *= (1.0-rain_coef) + rain_coef*weather_color[1];
1030 skybox_fog_color[2] *= (1.0-rain_coef) + rain_coef*weather_color[2];
1031 skybox_fog_color[3] = (1.0-rain_coef)*fog_density + rain_coef*skybox_fog_color[3];
1032 }
1033 skybox_fog_density = skybox_fog_color[3];
1034 skybox_fog_color[3] = 1.0;
1035
1036 i = idx = 0;
1037
1038 // clouds color
1039 while (i < dome_clouds.slices_count * 2)
1040 {
1041 normal = &dome_clouds.normals[i*3];
1042 ml1 = get_moonlight1(normal)*0.3*day_alpha;
1043 ml2 = get_moonlight2(normal)*0.2*day_alpha;
1044
1045 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1046 x -= camera_x;
1047 y -= camera_y;
1048 lg = weather_get_lightning_intensity(x, y);
1049 weather_compute_ratios(ratios, x, y);
1050 rain_coef = weather_get_density_from_ratios(ratios);
1051 weather_get_color_from_ratios(local_color, ratios);
1052
1053 ml1 *= 1.0 - rain_coef;
1054 ml2 *= 1.0 - rain_coef;
1055
1056 skybox_blend_current_colors(color_sky, skybox_clouds, skybox_clouds_rainy, rain_coef);
1057 skybox_blend_current_colors(color_sun, skybox_clouds_sunny, skybox_clouds_rainy, rain_coef);
1058
1059 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
1060
1061 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1062 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1063 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1064
1065 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1066 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1067 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1068
1069 dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1070 dome_clouds_colors_bis[idx++] = color[0];
1071 dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1072 dome_clouds_colors_bis[idx++] = color[1];
1073 dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1074 dome_clouds_colors_bis[idx++] = color[2];
1075 dome_clouds.colors[idx] = 0.0;
1076 dome_clouds_colors_bis[idx++] = rain_coef;
1077 ++i;
1078 }
1079 while (i < dome_clouds.vertices_count)
1080 {
1081 normal = &dome_clouds.normals[i*3];
1082 ml1 = get_moonlight1(normal)*0.3*day_alpha;
1083 ml2 = get_moonlight2(normal)*0.2*day_alpha;
1084
1085 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1086 x -= camera_x;
1087 y -= camera_y;
1088 lg = weather_get_lightning_intensity(x, y);
1089 weather_compute_ratios(ratios, x, y);
1090 rain_coef = weather_get_density_from_ratios(ratios);
1091 weather_get_color_from_ratios(local_color, ratios);
1092
1093 ml1 *= 1.0 - rain_coef;
1094 ml2 *= 1.0 - rain_coef;
1095
1096 skybox_blend_current_colors(color_sky, skybox_clouds, skybox_clouds_rainy, rain_coef);
1097 skybox_blend_current_colors(color_sun, skybox_clouds_sunny, skybox_clouds_rainy, rain_coef);
1098
1099 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
1100
1101 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1102 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1103 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1104
1105 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1106 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1107 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1108
1109 dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1110 dome_clouds_colors_bis[idx++] = color[0];
1111 dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1112 dome_clouds_colors_bis[idx++] = color[1];
1113 dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1114 dome_clouds_colors_bis[idx++] = color[2];
1115 dome_clouds.colors[idx] = 1.0;
1116 dome_clouds_colors_bis[idx++] = rain_coef;
1117 ++i;
1118 }
1119
1120 i = idx = 0;
1121
1122 // clouds detail color
1123 while (i < dome_clouds.slices_count * 2)
1124 {
1125 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1126 x -= camera_x;
1127 y -= camera_y;
1128 weather_compute_ratios(ratios, x, y);
1129 rain_coef = weather_get_density_from_ratios(ratios);
1130 weather_get_color_from_ratios(local_color, ratios);
1131
1132 skybox_blend_current_colors(color_sky, skybox_clouds_detail, skybox_clouds_detail_rainy, rain_coef);
1133 skybox_blend_current_colors(color_sun, skybox_clouds_detail_sunny, skybox_clouds_detail_rainy, rain_coef);
1134
1135 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
1136
1137 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1138 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1139 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1140
1141 dome_clouds_detail_colors[idx] = color[0];
1142 dome_clouds_detail_colors_bis[idx++] = color[0];
1143 dome_clouds_detail_colors[idx] = color[1];
1144 dome_clouds_detail_colors_bis[idx++] = color[1];
1145 dome_clouds_detail_colors[idx] = color[2];
1146 dome_clouds_detail_colors_bis[idx++] = color[2];
1147 dome_clouds_detail_colors[idx] = 0.0;
1148 dome_clouds_detail_colors_bis[idx++] = 0.0;
1149 ++i;
1150 }
1151 while (i < dome_clouds.vertices_count)
1152 {
1153 skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1154 x -= camera_x;
1155 y -= camera_y;
1156 weather_compute_ratios(ratios, x, y);
1157 rain_coef = weather_get_density_from_ratios(ratios);
1158 weather_get_color_from_ratios(local_color, ratios);
1159
1160 skybox_blend_current_colors(color_sky, skybox_clouds_detail, skybox_clouds_detail_rainy, rain_coef);
1161 skybox_blend_current_colors(color_sun, skybox_clouds_detail_sunny, skybox_clouds_detail_rainy, rain_coef);
1162
1163 blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
1164
1165 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1166 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1167 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1168
1169 dome_clouds_detail_colors[idx] = color[0];
1170 dome_clouds_detail_colors_bis[idx++] = color[0];
1171 dome_clouds_detail_colors[idx] = color[1];
1172 dome_clouds_detail_colors_bis[idx++] = color[1];
1173 dome_clouds_detail_colors[idx] = color[2];
1174 dome_clouds_detail_colors_bis[idx++] = color[2];
1175 dome_clouds_detail_colors[idx] = 1.0;
1176 dome_clouds_detail_colors_bis[idx++] = rain_coef;
1177 ++i;
1178 }
1179
1180 i = idx = 0;
1181
1182 // sky color
1183 end = dome_sky.slices_count;
1184 while (i < end)
1185 {
1186 normal = &dome_sky.normals[i*3];
1187 ml1 = get_moonlight1(normal)*0.15*day_alpha;
1188 ml2 = get_moonlight2(normal)*0.1*day_alpha;
1189
1190 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1191 x -= camera_x;
1192 y -= camera_y;
1193 lg = weather_get_lightning_intensity(x, y);
1194 weather_compute_ratios(ratios, x, y);
1195 rain_coef = weather_get_density_from_ratios(ratios);
1196 weather_get_color_from_ratios(local_color, ratios);
1197
1198 ml1 *= 1.0 - rain_coef;
1199 ml2 *= 1.0 - rain_coef;
1200
1201 skybox_blend_current_colors(color_sky, skybox_sky1, skybox_fog_rainy, rain_coef);
1202 skybox_blend_current_colors(color_sun, skybox_sky1_sunny, skybox_fog_rainy, rain_coef);
1203
1204 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1205
1206 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1207 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1208 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1209
1210 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1211 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1212 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1213
1214 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1215 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1216 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1217 dome_sky.colors[idx++] = 1.0;
1218 ++i;
1219 }
1220
1221 end += dome_sky.slices_count;
1222 while (i < end)
1223 {
1224 normal = &dome_sky.normals[i*3];
1225 ml1 = get_moonlight1(normal)*0.15*day_alpha;
1226 ml2 = get_moonlight2(normal)*0.1*day_alpha;
1227
1228 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1229 x -= camera_x;
1230 y -= camera_y;
1231 lg = weather_get_lightning_intensity(x, y);
1232 weather_compute_ratios(ratios, x, y);
1233 rain_coef = weather_get_density_from_ratios(ratios);
1234 weather_get_color_from_ratios(local_color, ratios);
1235
1236 ml1 *= 1.0 - rain_coef;
1237 ml2 *= 1.0 - rain_coef;
1238
1239 skybox_blend_current_colors(color_sky, skybox_sky2, skybox_fog_rainy, rain_coef);
1240 skybox_blend_current_colors(color_sun, skybox_sky2_sunny, skybox_fog_rainy, rain_coef);
1241
1242 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1243
1244 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1245 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1246 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1247
1248 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1249 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1250 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1251
1252 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1253 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1254 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1255 dome_sky.colors[idx++] = 1.0;
1256 ++i;
1257 }
1258
1259 end += dome_sky.slices_count;
1260 while (i < end)
1261 {
1262 normal = &dome_sky.normals[i*3];
1263 ml1 = get_moonlight1(normal)*0.15*day_alpha;
1264 ml2 = get_moonlight2(normal)*0.1*day_alpha;
1265
1266 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1267 x -= camera_x;
1268 y -= camera_y;
1269 lg = weather_get_lightning_intensity(x, y);
1270 weather_compute_ratios(ratios, x, y);
1271 rain_coef = weather_get_density_from_ratios(ratios);
1272 weather_get_color_from_ratios(local_color, ratios);
1273
1274 ml1 *= 1.0 - rain_coef;
1275 ml2 *= 1.0 - rain_coef;
1276
1277 skybox_blend_current_colors(color_sky, skybox_sky3, skybox_fog_rainy, rain_coef);
1278 skybox_blend_current_colors(color_sun, skybox_sky3_sunny, skybox_fog_rainy, rain_coef);
1279
1280 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1281
1282 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1283 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1284 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1285
1286 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1287 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1288 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1289
1290 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1291 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1292 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1293 dome_sky.colors[idx++] = 1.0;
1294 ++i;
1295 }
1296
1297 end += dome_sky.slices_count;
1298 while (i < end)
1299 {
1300 normal = &dome_sky.normals[i*3];
1301 ml1 = get_moonlight1(normal)*0.15*day_alpha;
1302 ml2 = get_moonlight2(normal)*0.1*day_alpha;
1303
1304 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1305 x -= camera_x;
1306 y -= camera_y;
1307 lg = weather_get_lightning_intensity(x, y);
1308 weather_compute_ratios(ratios, x, y);
1309 rain_coef = weather_get_density_from_ratios(ratios);
1310 weather_get_color_from_ratios(local_color, ratios);
1311
1312 ml1 *= 1.0 - rain_coef;
1313 ml2 *= 1.0 - rain_coef;
1314
1315 skybox_blend_current_colors(color_sky, skybox_sky4, skybox_fog_rainy, rain_coef);
1316 skybox_blend_current_colors(color_sun, skybox_sky4_sunny, skybox_fog_rainy, rain_coef);
1317
1318 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1319
1320 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1321 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1322 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1323
1324 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1325 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1326 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1327
1328 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1329 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1330 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1331 dome_sky.colors[idx++] = 1.0;
1332 ++i;
1333 }
1334
1335 while (i < dome_sky.vertices_count)
1336 {
1337 normal = &dome_sky.normals[i*3];
1338 ml1 = get_moonlight1(normal)*0.15*day_alpha;
1339 ml2 = get_moonlight2(normal)*0.1*day_alpha;
1340
1341 skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1342 x -= camera_x;
1343 y -= camera_y;
1344 lg = weather_get_lightning_intensity(x, y);
1345 weather_compute_ratios(ratios, x, y);
1346 rain_coef = weather_get_density_from_ratios(ratios);
1347 weather_get_color_from_ratios(local_color, ratios);
1348
1349 ml1 *= 1.0 - rain_coef;
1350 ml2 *= 1.0 - rain_coef;
1351
1352 skybox_blend_current_colors(color_sky, skybox_sky5, skybox_fog_rainy, rain_coef);
1353 skybox_blend_current_colors(color_sun, skybox_sky5_sunny, skybox_fog_rainy, rain_coef);
1354
1355 blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1356
1357 color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1358 color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1359 color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1360
1361 color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1362 color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1363 color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1364
1365 dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1366 dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1367 dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1368 dome_sky.colors[idx++] = 1.0;
1369 ++i;
1370 }
1371
1372 skybox_blend_current_colors(skybox_sky_color, skybox_sky5_sunny, skybox_fog_rainy, weather_get_density());
1373
1374 // color of the moons update
1375 moon1_color[0] *= (0.5 + 0.5*day_alpha);
1376 moon1_color[1] *= (0.5 + 0.5*day_alpha);
1377 moon1_color[2] *= (0.5 + 0.5*day_alpha);
1378 moon2_color[0] *= (0.5 + 0.5*day_alpha);
1379 moon2_color[1] *= (0.5 + 0.5*day_alpha);
1380 moon2_color[2] *= (0.5 + 0.5*day_alpha);
1381 }
1382
update_underworld_sky_colors()1383 void update_underworld_sky_colors()
1384 {
1385 int i, idx, end;
1386
1387 i = idx = 0;
1388
1389 end = dome_sky.slices_count;
1390 while (i < end)
1391 {
1392 dome_sky.colors[idx++] = 230/255.0;
1393 dome_sky.colors[idx++] = 104/255.0;
1394 dome_sky.colors[idx++] = 11/255.0;
1395 dome_sky.colors[idx++] = 1.0;
1396 ++i;
1397 }
1398
1399 end += dome_sky.slices_count;
1400 while (i < end)
1401 {
1402 dome_sky.colors[idx++] = 230/255.0;
1403 dome_sky.colors[idx++] = 104/255.0;
1404 dome_sky.colors[idx++] = 11/255.0;
1405 dome_sky.colors[idx++] = 1.0;
1406 ++i;
1407 }
1408
1409 end += dome_sky.slices_count;
1410 while (i < end)
1411 {
1412 dome_sky.colors[idx++] = 201/255.0;
1413 dome_sky.colors[idx++] = 58/255.0;
1414 dome_sky.colors[idx++] = 13/255.0;
1415 dome_sky.colors[idx++] = 0.8;
1416 ++i;
1417 }
1418
1419 end += dome_sky.slices_count;
1420 while (i < end)
1421 {
1422 dome_sky.colors[idx++] = 83/255.0;
1423 dome_sky.colors[idx++] = 31/255.0;
1424 dome_sky.colors[idx++] = 23/255.0;
1425 dome_sky.colors[idx++] = 0.6;
1426 ++i;
1427 }
1428
1429 while (i < dome_sky.vertices_count)
1430 {
1431 dome_sky.colors[idx++] = 33/255.0;
1432 dome_sky.colors[idx++] = 6/255.0;
1433 dome_sky.colors[idx++] = 16/255.0;
1434 dome_sky.colors[idx++] = 0.0;
1435 ++i;
1436 }
1437
1438 memcpy(skybox_fog_color, &dome_sky.colors[(dome_sky.vertices_count-1)*4], 3*sizeof(float));
1439 skybox_fog_color[3] = 1.0;
1440 skybox_fog_density = 0.01;
1441 memcpy(skybox_sky_color, skybox_fog_color, 4*sizeof(float));
1442 }
1443
cloudy_sky()1444 void cloudy_sky()
1445 {
1446 static Uint32 last_cloud_time = 0;
1447 int i;
1448 GLfloat black_color[] = {0.0, 0.0, 0.0, 0.0};
1449
1450 // disable lights not used for sky just in case
1451 switch(show_lights)
1452 {
1453 case 6:
1454 glDisable(GL_LIGHT6);
1455 // fall-through - suppress the compile warning with this comment
1456 case 5:
1457 glDisable(GL_LIGHT5);
1458 // fall-through
1459 case 4:
1460 glDisable(GL_LIGHT4);
1461 // fall-through
1462 case 3:
1463 glDisable(GL_LIGHT3);
1464 // fall-through
1465 case 2:
1466 glDisable(GL_LIGHT2);
1467 // fall-through
1468 case 1:
1469 glDisable(GL_LIGHT1);
1470 // fall-through
1471 default:
1472 glDisable(GL_LIGHT0);
1473 break;
1474 }
1475
1476 glPushAttrib(GL_TEXTURE_BIT|GL_ENABLE_BIT);
1477
1478 glEnable(GL_CULL_FACE);
1479 glDisable(GL_LIGHTING);
1480 glDisable(GL_FOG);
1481 glDisable(GL_BLEND);
1482 glDisable(GL_TEXTURE_2D);
1483 glDisable(GL_ALPHA_TEST);
1484 glEnable(GL_COLOR_MATERIAL);
1485
1486 glDisable(GL_DEPTH_TEST);
1487
1488 // we draw a ring to continue the sky a bit under the horizon
1489 glBegin(GL_QUAD_STRIP);
1490 for (i = 0; i < dome_sky.slices_count; ++i)
1491 {
1492 const GLfloat *vtx = &dome_sky.vertices[i*3];
1493 glColor3fv(&dome_sky.colors[i*4]);
1494 glVertex3f(vtx[0]*0.9, vtx[1]*0.9, -dome_sky.height*0.1);
1495 glVertex3fv(vtx);
1496 }
1497 glColor3fv(&dome_sky.colors[0]);
1498 glVertex3f(dome_sky.vertices[0]*0.9, dome_sky.vertices[1]*0.9, -dome_sky.height*0.1);
1499 glVertex3fv(&dome_sky.vertices[0]);
1500 glEnd();
1501
1502 // we draw the sky background
1503 glEnableClientState(GL_VERTEX_ARRAY);
1504 glEnableClientState(GL_COLOR_ARRAY);
1505
1506 glVertexPointer(3, GL_FLOAT, 0, dome_sky.vertices);
1507 glColorPointer(4, GL_FLOAT, 0, dome_sky.colors);
1508
1509 glDrawElements(GL_TRIANGLES, dome_sky.faces_count*3, GL_UNSIGNED_INT, dome_sky.faces);
1510
1511 glDisableClientState(GL_VERTEX_ARRAY);
1512 glDisableClientState(GL_COLOR_ARRAY);
1513
1514 glEnable(GL_BLEND);
1515
1516 glEnable(GL_DEPTH_TEST); // we need it to draw moons and stars
1517 glClear(GL_DEPTH_BUFFER_BIT);
1518 glEnable(GL_TEXTURE_2D);
1519 glBlendFunc(GL_SRC_COLOR, GL_ONE);
1520
1521 // we draw the moons
1522 if(skybox_show_moons && !skybox_no_moons)
1523 {
1524 // the current light color is black so we change it to light the moons
1525 GLfloat light_color[] = {0.8, 0.8, 0.8, 1.0};
1526 glLightfv(GL_LIGHT7, GL_DIFFUSE, light_color);
1527
1528 glPushMatrix();
1529 glRotatef((float)game_minute+(float)game_second/60.0, 0.0, -1.0, 0.0);
1530
1531 glEnable(GL_LIGHTING);
1532 glDisable(GL_COLOR_MATERIAL);
1533 bind_texture(moon_tex);
1534 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black_color);
1535
1536 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, moon1_color);
1537
1538 glPushMatrix();
1539 glRotatef(moon_spin, 0.0, 1.0, 0.0);
1540 glTranslatef(0.0, 0.0, 450.0);
1541 glRotatef(90.0, 1.0, 0.0, 0.0);
1542 glRotatef(moon_spin, 0.0, 0.0, 1.0);
1543 glScalef(20.0, 20.0, 20.0);
1544 //glCallList(sky_lists+3);
1545 draw_sphere(&moon_mesh);
1546 glPopMatrix();
1547
1548 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, moon2_color);
1549
1550 glPushMatrix();
1551 glRotatef(20.0, 0.0, 0.0, 1.0);
1552 glRotatef(10.0*moon_spin, 0.0, 1.0, 0.0);
1553 glTranslatef(0.0, 0.0, 480.0);
1554 glRotatef(90.0, 1.0, 0.0, 0.0);
1555 glRotatef(10.0*moon_spin, 0.0, 0.0, 1.0);
1556 glScalef(12.0, 12.0, 12.0);
1557 //glCallList(sky_lists+3);
1558 draw_sphere(&moon_mesh);
1559 glPopMatrix();
1560
1561 glPopMatrix();
1562 glLightfv(GL_LIGHT7, GL_DIFFUSE, diffuse_light); // we restore the light color
1563 glEnable(GL_COLOR_MATERIAL);
1564 glDisable(GL_LIGHTING);
1565 }
1566
1567 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1568 glDepthMask(GL_FALSE); // we don't want the stars to update the depth buffer
1569 glDisable(GL_TEXTURE_2D);
1570
1571 // we draw the stars
1572 if (skybox_show_stars && !skybox_no_stars && day_alpha > 0.0)
1573 {
1574 glPushMatrix();
1575 glPointSize(1.0);
1576 glRotatef((float)game_minute+(float)game_second/60.0, 0.0, -1.0, 0.0);
1577 glColor4f(1.0, 1.0, 1.0, day_alpha);
1578 glCallList(sky_lists);
1579 glColor4f(1.0, 1.0, 1.0, day_alpha*0.5);
1580 glCallList(sky_lists+1);
1581 glColor4f(1.0, 1.0, 1.0, day_alpha*0.25);
1582 glCallList(sky_lists+2);
1583 glPopMatrix();
1584 }
1585
1586 glDepthMask(GL_TRUE);
1587 glDisable(GL_DEPTH_TEST);
1588 glEnable(GL_TEXTURE_2D);
1589
1590 // we draw the clouds
1591 if (skybox_show_clouds && !skybox_no_clouds)
1592 {
1593 float clouds_step = (cur_time - last_cloud_time)*2E-6;
1594
1595 // we update the tex coords for the first clouds layer
1596 if (dome_clouds.tex_coords[0] <= 1.0)
1597 {
1598 for (i = dome_clouds.vertices_count; i--; )
1599 dome_clouds.tex_coords[i*2] += clouds_step;
1600 }
1601 else
1602 {
1603 for (i = dome_clouds.vertices_count; i--; )
1604 dome_clouds.tex_coords[i*2] += clouds_step - 1.0;
1605 }
1606
1607 // we update the tex coords for the second clouds layer
1608 if (dome_clouds_tex_coords_bis[0] <= 1.0)
1609 {
1610 for (i = dome_clouds.vertices_count; i--; )
1611 dome_clouds_tex_coords_bis[i*2] += clouds_step*2.0;
1612 }
1613 else
1614 {
1615 for (i = dome_clouds.vertices_count; i--; )
1616 dome_clouds_tex_coords_bis[i*2] += clouds_step*2.0 - 1.0;
1617 }
1618
1619 glEnableClientState(GL_VERTEX_ARRAY);
1620 glEnableClientState(GL_COLOR_ARRAY);
1621 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1622
1623 glVertexPointer(3, GL_FLOAT, 0, dome_clouds.vertices);
1624 glColorPointer(4, GL_FLOAT, 0, dome_clouds.colors);
1625 glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds.tex_coords);
1626
1627 bind_texture(skybox_clouds_tex);
1628
1629 glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1630
1631 {
1632 // we draw the second clouds layer
1633 bind_texture(thick_clouds_tex);
1634 glColorPointer(4, GL_FLOAT, 0, dome_clouds_colors_bis);
1635 glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds_tex_coords_bis);
1636 glPushMatrix();
1637 glScalef(1.0, 1.0, 0.95);
1638 glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1639 glPopMatrix();
1640 }
1641
1642 glDisableClientState(GL_VERTEX_ARRAY);
1643 glDisableClientState(GL_COLOR_ARRAY);
1644 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1645 }
1646
1647 glBlendFunc(GL_SRC_COLOR, GL_ONE);
1648
1649 // draw the sun
1650 if (skybox_show_sun && !skybox_no_sun &&
1651 (skybox_sun_position[0] != 0.0 ||
1652 skybox_sun_position[1] != 0.0 ||
1653 skybox_sun_position[2] != 0.0))
1654 {
1655 glColor4fv(sun_color);
1656 bind_texture(sun_tex);
1657 glPushMatrix();
1658 glScalef(480.0, 480.0, 480.0);
1659 glBegin(GL_QUADS);
1660 {
1661 //two cross products. Dangerous to use these functions. Float type essential.
1662 //Better to robustly produce two vectors in perpendicular plane elsewhere.
1663 VECTOR3 perp1, perp2, someVec = {0.0, 1.0, 0.0};
1664 VCross(perp1, someVec, skybox_sun_position);
1665 VCross(perp2, perp1, skybox_sun_position);
1666 glTexCoord2f(0,0);
1667 glVertex3f(skybox_sun_position[0]+.08*(perp1[0]+perp2[0]),
1668 skybox_sun_position[1]+.08*(perp1[1]+perp2[1]),
1669 skybox_sun_position[2]+.08*(perp1[2]+perp2[2]));
1670 glTexCoord2f(1,0);
1671 glVertex3f(skybox_sun_position[0]+.08*(-perp1[0]+perp2[0]),
1672 skybox_sun_position[1]+.08*(-perp1[1]+perp2[1]),
1673 skybox_sun_position[2]+.08*(-perp1[2]+perp2[2]));
1674 glTexCoord2f(1,1);
1675 glVertex3f(skybox_sun_position[0]+.08*(-perp1[0]-perp2[0]),
1676 skybox_sun_position[1]+.08*(-perp1[1]-perp2[1]),
1677 skybox_sun_position[2]+.08*(-perp1[2]-perp2[2]));
1678 glTexCoord2f(0,1);
1679 glVertex3f(skybox_sun_position[0]+.08*(perp1[0]-perp2[0]),
1680 skybox_sun_position[1]+.08*(perp1[1]-perp2[1]),
1681 skybox_sun_position[2]+.08*(perp1[2]-perp2[2]));
1682 }
1683 glEnd();
1684 glPopMatrix();
1685 }
1686
1687 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1688
1689 // we draw the clouds detail
1690 if (skybox_show_clouds && !skybox_no_clouds)
1691 {
1692 glEnableClientState(GL_VERTEX_ARRAY);
1693 glEnableClientState(GL_COLOR_ARRAY);
1694 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1695
1696 bind_texture(skybox_clouds_detail_tex);
1697 glVertexPointer(3, GL_FLOAT, 0, dome_clouds.vertices);
1698 glColorPointer(4, GL_FLOAT, 0, dome_clouds_detail_colors);
1699 glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds.tex_coords);
1700
1701 glPushMatrix();
1702 glScalef(1.0, 1.0, 0.98);
1703 glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1704 glPopMatrix();
1705
1706 {
1707 bind_texture(thick_clouds_detail_tex);
1708 glColorPointer(4, GL_FLOAT, 0, dome_clouds_detail_colors_bis);
1709 glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds_tex_coords_bis);
1710 glPushMatrix();
1711 glScalef(1.0, 1.0, 0.93);
1712 glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1713 glPopMatrix();
1714 }
1715
1716 glDisableClientState(GL_VERTEX_ARRAY);
1717 glDisableClientState(GL_COLOR_ARRAY);
1718 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1719 }
1720
1721 glDisable(GL_TEXTURE_2D);
1722
1723 // we fade the sky that is under the horizon
1724 glBegin(GL_QUAD_STRIP);
1725 for (i = 0; i < dome_sky.slices_count; ++i)
1726 {
1727 const GLfloat *vtx = &dome_sky.vertices[i*3];
1728 glColor4fv(skybox_fog_color);
1729 glVertex3f(vtx[0]*0.9, vtx[1]*0.9, -dome_sky.height*0.1);
1730 glColor4f(skybox_fog_color[0], skybox_fog_color[1], skybox_fog_color[2], 0.0);
1731 glVertex3fv(vtx);
1732 }
1733 glColor4fv(skybox_fog_color);
1734 glVertex3f(dome_sky.vertices[0]*0.9, dome_sky.vertices[1]*0.9, -dome_sky.height*0.1);
1735 glColor4f(skybox_fog_color[0], skybox_fog_color[1], skybox_fog_color[2], 0.0);
1736 glVertex3fv(&dome_sky.vertices[0]);
1737 glEnd();
1738
1739 // we mask all the elements that are under the horizon with the fog color
1740 glBegin(GL_TRIANGLE_FAN);
1741 glColor3fv(skybox_fog_color);
1742 glVertex3f(0.0, 0.0, -dome_sky.height);
1743 for (i = 0; i < dome_sky.slices_count; ++i)
1744 {
1745 const GLfloat *vtx = &dome_sky.vertices[i*3];
1746 glVertex3f(vtx[0]*0.9, vtx[1]*0.9, -dome_sky.height*0.1);
1747 }
1748 glVertex3f(dome_sky.vertices[0]*0.9, dome_sky.vertices[1]*0.9, -dome_sky.height*0.1);
1749 glEnd();
1750
1751 glPopAttrib();
1752 reset_material();
1753 last_texture = -1;
1754
1755 // we restore the lights
1756 if(!is_day||dungeon)
1757 {
1758 switch(show_lights)
1759 {
1760 case 6:
1761 glEnable(GL_LIGHT6);
1762 // fall-through - suppress the compile warning with this comment
1763 case 5:
1764 glEnable(GL_LIGHT5);
1765 // fall-through
1766 case 4:
1767 glEnable(GL_LIGHT4);
1768 // fall-through
1769 case 3:
1770 glEnable(GL_LIGHT3);
1771 // fall-through
1772 case 2:
1773 glEnable(GL_LIGHT2);
1774 // fall-through
1775 case 1:
1776 glEnable(GL_LIGHT1);
1777 // fall-through
1778 default:
1779 glEnable(GL_LIGHT0);
1780 break;
1781 }
1782 }
1783
1784 last_cloud_time = cur_time;
1785 }
1786
underworld_sky()1787 void underworld_sky()
1788 {
1789 static Uint32 last_cloud_time = 0;
1790 int i;
1791
1792 glTranslatef(0.0, 0.0, -40.0);
1793
1794 glPushAttrib(GL_TEXTURE_BIT|GL_ENABLE_BIT);
1795 glClear(GL_DEPTH_BUFFER_BIT);
1796
1797 /* if(use_shadow_mapping) */
1798 /* { */
1799 /* glDisable(GL_TEXTURE_2D); */
1800 /* ELglActiveTextureARB(shadow_unit); */
1801 /* glDisable(depth_texture_target); */
1802 /* disable_texgen(); */
1803 /* ELglActiveTextureARB(GL_TEXTURE0); */
1804 /* glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */
1805 /* } */
1806
1807 glDisable(GL_LIGHTING);
1808 glDisable(GL_FOG);
1809 glEnable(GL_COLOR_MATERIAL);
1810 glDisable(GL_TEXTURE_2D);
1811 glDisable(GL_DEPTH_TEST);
1812 glEnable(GL_BLEND);
1813
1814 if (skybox_show_clouds)
1815 {
1816 float clouds_step = (cur_time - last_cloud_time)*1E-5;
1817
1818 // we update the tex coords for the first clouds layer
1819 if (dome_clouds.tex_coords[0] <= 1.0)
1820 {
1821 for (i = dome_clouds.vertices_count; i--; )
1822 dome_clouds.tex_coords[i*2] += clouds_step*2.0;
1823 }
1824 else
1825 {
1826 for (i = dome_clouds.vertices_count; i--; )
1827 dome_clouds.tex_coords[i*2] += clouds_step*2.0 - 1.0;
1828 }
1829
1830 // we update the tex coords for the second clouds layer
1831 if (dome_clouds_tex_coords_bis[0] <= 1.0)
1832 {
1833 for (i = dome_clouds.vertices_count; i--; )
1834 dome_clouds_tex_coords_bis[i*2] += clouds_step;
1835 }
1836 else
1837 {
1838 for (i = dome_clouds.vertices_count; i--; )
1839 dome_clouds_tex_coords_bis[i*2] += clouds_step - 1.0;
1840 }
1841
1842 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1843 glEnable(GL_TEXTURE_2D);
1844 bind_texture(thick_clouds_detail_tex);
1845
1846 glEnableClientState(GL_VERTEX_ARRAY);
1847 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1848
1849 glVertexPointer(3, GL_FLOAT, 0, dome_clouds.vertices);
1850
1851 glColor3f(0.8, 0.0, 0.0);
1852 glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds_tex_coords_bis);
1853 glPushMatrix();
1854 glRotatef(90.0, 0.0, 0.0, 1.0);
1855 glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1856 glPopMatrix();
1857
1858 glColor3f(0.8, 0.2, 0.0);
1859 glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds.tex_coords);
1860 glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1861
1862 glDisableClientState(GL_VERTEX_ARRAY);
1863 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1864 glDisable(GL_TEXTURE_2D);
1865 }
1866
1867 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1868 glEnableClientState(GL_VERTEX_ARRAY);
1869 glEnableClientState(GL_COLOR_ARRAY);
1870
1871 glVertexPointer(3, GL_FLOAT, 0, dome_sky.vertices);
1872 glColorPointer(4, GL_FLOAT, 0, dome_sky.colors);
1873
1874 glDrawElements(GL_TRIANGLES, dome_sky.faces_count*3, GL_UNSIGNED_INT, dome_sky.faces);
1875
1876 glDisableClientState(GL_VERTEX_ARRAY);
1877 glDisableClientState(GL_COLOR_ARRAY);
1878
1879 glBegin(GL_QUAD_STRIP);
1880 for (i = 0; i < dome_sky.slices_count; ++i)
1881 {
1882 const GLfloat *vtx = &dome_sky.vertices[i*3];
1883 glColor3fv(&dome_sky.colors[i*4]);
1884 glVertex4f(vtx[0], vtx[1], vtx[2], 500.0);
1885 glVertex3fv(vtx);
1886 }
1887 glColor3fv(&dome_sky.colors[0]);
1888 glVertex4f(dome_sky.vertices[0], dome_sky.vertices[1], dome_sky.vertices[2], 500.0);
1889 glVertex3fv(&dome_sky.vertices[0]);
1890 glEnd();
1891
1892 glPopAttrib();
1893 reset_material();
1894 last_texture = -1;
1895
1896 last_cloud_time = cur_time;
1897 }
1898
1899 #define XML_BOOL(s) (!xmlStrcasecmp((s), (xmlChar*)"yes") ||\
1900 !xmlStrcasecmp((s), (xmlChar*)"true") ||\
1901 !xmlStrcasecmp((s), (xmlChar*)"1"))
1902
skybox_parse_color_properties(xmlNode * node,float container[360][4])1903 int skybox_parse_color_properties(xmlNode *node, float container[360][4])
1904 {
1905 xmlAttr *attr;
1906 int t = -1;
1907 float r = 0.0, g = 0.0, b = 0.0, a = 1.0;
1908 int ok = 1;
1909
1910 for (attr = node->properties; attr; attr = attr->next)
1911 {
1912 if (attr->type == XML_ATTRIBUTE_NODE)
1913 {
1914 if (xmlStrcasecmp (attr->name, (xmlChar*)"t") == 0)
1915 t = atoi((char*)attr->children->content);
1916 else if (xmlStrcasecmp (attr->name, (xmlChar*)"r") == 0)
1917 r = atof((char*)attr->children->content);
1918 else if (xmlStrcasecmp (attr->name, (xmlChar*)"g") == 0)
1919 g = atof((char*)attr->children->content);
1920 else if (xmlStrcasecmp (attr->name, (xmlChar*)"b") == 0)
1921 b = atof((char*)attr->children->content);
1922 else if (xmlStrcasecmp (attr->name, (xmlChar*)"a") == 0)
1923 a = atof((char*)attr->children->content);
1924 else {
1925 LOG_ERROR("unknown attribute for color: %s", (char*)attr->name);
1926 ok = 0;
1927 }
1928 }
1929 }
1930
1931 if (t >= 0 && t < 360)
1932 {
1933 container[t][0] = r <= 1.0 ? r : r / 255.0;
1934 container[t][1] = g <= 1.0 ? g : g / 255.0;
1935 container[t][2] = b <= 1.0 ? b : b / 255.0;
1936 container[t][3] = a <= 1.0 ? a : a / 255.0;
1937 }
1938 else
1939 {
1940 LOG_ERROR("the time attribute of the color doesn't exist or is wrong!");
1941 ok = 0;
1942 }
1943
1944 return ok;
1945 }
1946
skybox_parse_colors(xmlNode * node,float container[360][4])1947 int skybox_parse_colors(xmlNode *node, float container[360][4])
1948 {
1949 xmlNode *item;
1950 xmlAttr *attr;
1951 int ok = 1;
1952 int i, t;
1953 int reset = 0;
1954
1955 if(node == NULL || node->children == NULL) return 0;
1956
1957 for (attr = node->properties; attr; attr = attr->next) {
1958 if (attr->type == XML_ATTRIBUTE_NODE &&
1959 (!xmlStrcasecmp(attr->name, (xmlChar*)"reset") ||
1960 !xmlStrcasecmp(attr->name, (xmlChar*)"overwrite"))) {
1961 reset = XML_BOOL(attr->children->content);
1962 }
1963 else {
1964 LOG_ERROR("unknown attribute for element: %s", (char*)attr->name);
1965 ok = 0;
1966 }
1967 }
1968
1969 if (reset)
1970 {
1971 // we erase the previous color keys
1972 for (t = 360; t--; )
1973 {
1974 for (i = 3; i--; )
1975 {
1976 container[t][i] = 0.0;
1977 }
1978 container[t][3] = -1.0;
1979 }
1980 }
1981
1982 for(item = node->children; item; item = item->next) {
1983 if(item->type == XML_ELEMENT_NODE) {
1984 if(xmlStrcasecmp(item->name, (xmlChar*)"color") == 0) {
1985 ok &= skybox_parse_color_properties(item, container);
1986 }
1987 else {
1988 LOG_ERROR("unknown node for element: %s", item->name);
1989 ok = 0;
1990 }
1991 }
1992 else if (item->type == XML_ENTITY_REF_NODE) {
1993 ok &= skybox_parse_colors(item->children, container);
1994 }
1995 }
1996
1997 return ok;
1998 }
1999
skybox_parse_properties(xmlNode * node)2000 int skybox_parse_properties(xmlNode *node)
2001 {
2002 xmlNode *item;
2003 xmlAttr *attr;
2004 int ok = 1;
2005
2006 for(item = node->children; item; item = item->next) {
2007 if(item->type == XML_ELEMENT_NODE) {
2008 if(xmlStrcasecmp(item->name, (xmlChar*)"clouds") == 0) {
2009 for (attr = item->properties; attr; attr = attr->next)
2010 {
2011 if (attr->type == XML_ATTRIBUTE_NODE)
2012 {
2013 if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2014 skybox_no_clouds = !XML_BOOL(attr->children->content);
2015 else if (xmlStrcasecmp (attr->name, (xmlChar*)"texture") == 0)
2016 skybox_clouds_tex = load_texture_cached((char*)attr->children->content, tt_mesh);
2017 else if (xmlStrcasecmp (attr->name, (xmlChar*)"texture_detail") == 0)
2018 skybox_clouds_detail_tex = load_texture_cached((char*)attr->children->content, tt_mesh);
2019 else {
2020 LOG_ERROR("unknown attribute for clouds: %s", (char*)attr->name);
2021 ok = 0;
2022 }
2023 }
2024 }
2025 }
2026 else if(xmlStrcasecmp(item->name, (xmlChar*)"sun") == 0) {
2027 for (attr = item->properties; attr; attr = attr->next)
2028 if (attr->type == XML_ATTRIBUTE_NODE) {
2029 if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2030 skybox_no_sun = !XML_BOOL(attr->children->content);
2031 else {
2032 LOG_ERROR("unknown attribute for sun: %s", (char*)attr->name);
2033 ok = 0;
2034 }
2035 }
2036 }
2037 else if(xmlStrcasecmp(item->name, (xmlChar*)"moons") == 0) {
2038 for (attr = item->properties; attr; attr = attr->next)
2039 if (attr->type == XML_ATTRIBUTE_NODE) {
2040 if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2041 skybox_no_moons = !XML_BOOL(attr->children->content);
2042 else {
2043 LOG_ERROR("unknown attribute for moons: %s", (char*)attr->name);
2044 ok = 0;
2045 }
2046 }
2047 }
2048 else if(xmlStrcasecmp(item->name, (xmlChar*)"stars") == 0) {
2049 for (attr = item->properties; attr; attr = attr->next)
2050 if (attr->type == XML_ATTRIBUTE_NODE) {
2051 if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2052 skybox_no_stars = !XML_BOOL(attr->children->content);
2053 else {
2054 LOG_ERROR("unknown attribute for stars: %s", (char*)attr->name);
2055 ok = 0;
2056 }
2057 }
2058 }
2059 else if(xmlStrcasecmp(item->name, (xmlChar*)"freeze_time") == 0) {
2060 int value = get_int_value(item);
2061 if (value >= 0 && value <= 359) {
2062 freeze_time = 1;
2063 game_minute = value;
2064 game_second = 0;
2065 }
2066 else {
2067 freeze_time = 0;
2068 game_minute = real_game_minute;
2069 game_second = real_game_second;
2070 }
2071 }
2072 else {
2073 LOG_ERROR("unknown node for properties: %s", item->name);
2074 ok = 0;
2075 }
2076 }
2077 else if (item->type == XML_ENTITY_REF_NODE) {
2078 ok &= skybox_parse_properties(item->children);
2079 }
2080 }
2081
2082 return ok;
2083 }
2084
skybox_parse_defs(xmlNode * node,const char * map_name)2085 int skybox_parse_defs(xmlNode *node, const char *map_name)
2086 {
2087 xmlNode *def;
2088 int ok = 1;
2089
2090 for (def = node->children; def; def = def->next) {
2091 if (def->type == XML_ELEMENT_NODE)
2092 {
2093 if (xmlStrcasecmp(def->name, (xmlChar*)"properties") == 0) {
2094 ok &= skybox_parse_properties(def);
2095 }
2096 else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds") == 0) {
2097 ok &= skybox_parse_colors(def, skybox_clouds);
2098 }
2099 else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_detail") == 0) {
2100 ok &= skybox_parse_colors(def, skybox_clouds_detail);
2101 }
2102 else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_sunny") == 0) {
2103 ok &= skybox_parse_colors(def, skybox_clouds_sunny);
2104 }
2105 else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_detail_sunny") == 0) {
2106 ok &= skybox_parse_colors(def, skybox_clouds_detail_sunny);
2107 }
2108 else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_rainy") == 0) {
2109 ok &= skybox_parse_colors(def, skybox_clouds_rainy);
2110 }
2111 else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_detail_rainy") == 0) {
2112 ok &= skybox_parse_colors(def, skybox_clouds_detail_rainy);
2113 }
2114 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky1") == 0) {
2115 ok &= skybox_parse_colors(def, skybox_sky1);
2116 }
2117 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky2") == 0) {
2118 ok &= skybox_parse_colors(def, skybox_sky2);
2119 }
2120 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky3") == 0) {
2121 ok &= skybox_parse_colors(def, skybox_sky3);
2122 }
2123 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky4") == 0) {
2124 ok &= skybox_parse_colors(def, skybox_sky4);
2125 }
2126 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky5") == 0) {
2127 ok &= skybox_parse_colors(def, skybox_sky5);
2128 }
2129 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky1_sunny") == 0) {
2130 ok &= skybox_parse_colors(def, skybox_sky1_sunny);
2131 }
2132 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky2_sunny") == 0) {
2133 ok &= skybox_parse_colors(def, skybox_sky2_sunny);
2134 }
2135 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky3_sunny") == 0) {
2136 ok &= skybox_parse_colors(def, skybox_sky3_sunny);
2137 }
2138 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky4_sunny") == 0) {
2139 ok &= skybox_parse_colors(def, skybox_sky4_sunny);
2140 }
2141 else if (xmlStrcasecmp(def->name, (xmlChar*)"sky5_sunny") == 0) {
2142 ok &= skybox_parse_colors(def, skybox_sky5_sunny);
2143 }
2144 else if (xmlStrcasecmp(def->name, (xmlChar*)"sun") == 0) {
2145 ok &= skybox_parse_colors(def, skybox_sun);
2146 }
2147 else if (xmlStrcasecmp(def->name, (xmlChar*)"fog") == 0) {
2148 ok &= skybox_parse_colors(def, skybox_fog);
2149 }
2150 else if (xmlStrcasecmp(def->name, (xmlChar*)"fog_sunny") == 0) {
2151 ok &= skybox_parse_colors(def, skybox_fog_sunny);
2152 }
2153 else if (xmlStrcasecmp(def->name, (xmlChar*)"fog_rainy") == 0) {
2154 ok &= skybox_parse_colors(def, skybox_fog_rainy);
2155 }
2156 else if (xmlStrcasecmp(def->name, (xmlChar*)"light_ambient") == 0) {
2157 ok &= skybox_parse_colors(def, skybox_light_ambient);
2158 }
2159 else if (xmlStrcasecmp(def->name, (xmlChar*)"light_diffuse") == 0) {
2160 ok &= skybox_parse_colors(def, skybox_light_diffuse);
2161 }
2162 else if (xmlStrcasecmp(def->name, (xmlChar*)"light_ambient_rainy") == 0) {
2163 ok &= skybox_parse_colors(def, skybox_light_ambient_rainy);
2164 }
2165 else if (xmlStrcasecmp(def->name, (xmlChar*)"light_diffuse_rainy") == 0) {
2166 ok &= skybox_parse_colors(def, skybox_light_diffuse_rainy);
2167 }
2168 else if (xmlStrcasecmp(def->name, (xmlChar*)"map") == 0) {
2169 const char *name = get_string_property(def, "name");
2170 if (!strcasecmp(name, map_name)) {
2171 //printf("Found custom sky defs for the current map!\n");
2172 ok &= skybox_parse_defs(def, "");
2173 }
2174 }
2175 else {
2176 LOG_ERROR("unknown element for skybox: %s", def->name);
2177 ok = 0;
2178 }
2179 }
2180 else if (def->type == XML_ENTITY_REF_NODE) {
2181 ok &= skybox_parse_defs(def->children, map_name);
2182 }
2183 }
2184
2185 return ok;
2186 }
2187
skybox_read_defs(const char * file_name,const char * map_name)2188 int skybox_read_defs(const char *file_name, const char *map_name)
2189 {
2190 xmlNode *root;
2191 xmlDoc *doc;
2192 int ok = 1;
2193
2194 doc = xmlReadFile(file_name, NULL, XML_PARSE_NOENT);
2195 if (doc == NULL) {
2196 LOG_ERROR("Unable to read skybox definition file %s", file_name);
2197 return 0;
2198 }
2199
2200 root = xmlDocGetRootElement(doc);
2201 if (root == NULL) {
2202 LOG_ERROR("Unable to parse skybox definition file %s", file_name);
2203 ok = 0;
2204 } else if (xmlStrcasecmp(root->name, (xmlChar*)"skybox") != 0) {
2205 LOG_ERROR("Unknown key \"%s\" (\"skybox\" expected).", root->name);
2206 ok = 0;
2207 } else {
2208 ok = skybox_parse_defs(root, map_name);
2209 }
2210
2211 xmlFreeDoc(doc);
2212 return ok;
2213 }
2214
skybox_build_gradients(float container[360][4])2215 int skybox_build_gradients(float container[360][4])
2216 {
2217 int t;
2218 int first = 0;
2219 int prev, next, diff;
2220
2221 while (first < 360 && container[first][3] < 0.0) ++first;
2222
2223 if (first >= 360) return 0;
2224
2225 prev = first;
2226 do
2227 {
2228 next = (prev+1)%360;
2229 while (container[next][3] < 0.0) next = (next+1)%360;
2230 diff = (next-prev+360)%360;
2231 if (diff) // prev != next
2232 {
2233 for (t = prev+1; t != next; t = (t+1)%360)
2234 blend_colors(container[t], container[prev], container[next],
2235 (float)((t-prev+360)%360)/(float)diff, 4);
2236 }
2237 else // prev == next
2238 {
2239 for (t = prev+1; t != next; t = (t+1)%360)
2240 memcpy(container[t], container[prev], 4*sizeof(float));
2241 }
2242 prev = next;
2243 }
2244 while (prev != first);
2245
2246 return 1;
2247 }
2248
skybox_init_defs(const char * map_name)2249 void skybox_init_defs(const char *map_name)
2250 {
2251 static char last_map[256] = "\0";
2252 int t;
2253 int i;
2254
2255 for (t = 360; t--; )
2256 {
2257 for (i = 3; i--; )
2258 {
2259 skybox_clouds[t][i] = 0.0;
2260 skybox_clouds_detail[t][i] = 0.0;
2261 skybox_clouds_sunny[t][i] = 0.0;
2262 skybox_clouds_detail_sunny[t][i] = 0.0;
2263 skybox_clouds_rainy[t][i] = 0.0;
2264 skybox_clouds_detail_rainy[t][i] = 0.0;
2265 skybox_sky1[t][i] = 0.0;
2266 skybox_sky2[t][i] = 0.0;
2267 skybox_sky3[t][i] = 0.0;
2268 skybox_sky4[t][i] = 0.0;
2269 skybox_sky5[t][i] = 0.0;
2270 skybox_sky1_sunny[t][i] = 0.0;
2271 skybox_sky2_sunny[t][i] = 0.0;
2272 skybox_sky3_sunny[t][i] = 0.0;
2273 skybox_sky4_sunny[t][i] = 0.0;
2274 skybox_sky5_sunny[t][i] = 0.0;
2275 skybox_sun[t][i] = 0.0;
2276 skybox_fog[t][i] = 0.0;
2277 skybox_fog_sunny[t][i] = 0.0;
2278 skybox_fog_rainy[t][i] = 0.0;
2279 skybox_light_ambient[t][i] = 0.0;
2280 skybox_light_diffuse[t][i] = 0.0;
2281 skybox_light_ambient_rainy[t][i] = 0.0;
2282 skybox_light_diffuse_rainy[t][i] = 0.0;
2283 }
2284 skybox_clouds[t][3] = -1.0;
2285 skybox_clouds_detail[t][3] = -1.0;
2286 skybox_clouds_sunny[t][3] = -1.0;
2287 skybox_clouds_detail_sunny[t][3] = -1.0;
2288 skybox_clouds_rainy[t][3] = -1.0;
2289 skybox_clouds_detail_rainy[t][3] = -1.0;
2290 skybox_sky1[t][3] = -1.0;
2291 skybox_sky2[t][3] = -1.0;
2292 skybox_sky3[t][3] = -1.0;
2293 skybox_sky4[t][3] = -1.0;
2294 skybox_sky5[t][3] = -1.0;
2295 skybox_sky1_sunny[t][3] = -1.0;
2296 skybox_sky2_sunny[t][3] = -1.0;
2297 skybox_sky3_sunny[t][3] = -1.0;
2298 skybox_sky4_sunny[t][3] = -1.0;
2299 skybox_sky5_sunny[t][3] = -1.0;
2300 skybox_sun[t][3] = -1.0;
2301 skybox_fog[t][3] = -1.0;
2302 skybox_fog_sunny[t][3] = -1.0;
2303 skybox_fog_rainy[t][3] = -1.0;
2304 skybox_light_ambient[t][3] = -1.0;
2305 skybox_light_diffuse[t][3] = -1.0;
2306 skybox_light_ambient_rainy[t][3] = -1.0;
2307 skybox_light_diffuse_rainy[t][3] = -1.0;
2308 }
2309
2310 skybox_no_clouds = 1;
2311 skybox_no_sun = 1;
2312 skybox_no_moons = 1;
2313 skybox_no_stars = 1;
2314 skybox_clouds_tex = -1;
2315 skybox_clouds_detail_tex = -1;
2316 freeze_time = 0;
2317 game_minute = real_game_minute;
2318 game_second = real_game_second;
2319
2320 if (map_name) {
2321 int pos = strlen(map_name)-1;
2322 while (pos >= 0 && map_name[pos] != '/') --pos;
2323 strcpy(last_map, map_name+pos+1);
2324 }
2325
2326 //printf("Loading sky defs for map '%s'\n", last_map);
2327 if (!skybox_read_defs("skybox/skybox_defs.xml", last_map))
2328 LOG_ERROR("Error while loading the skybox definitions.");
2329
2330 if (!skybox_build_gradients(skybox_clouds))
2331 LOG_ERROR("no color key defined for 'clouds' element!");
2332 if (!skybox_build_gradients(skybox_clouds_detail))
2333 LOG_ERROR("no color key defined for 'clouds_detail' element!");
2334 if (!skybox_build_gradients(skybox_clouds_sunny))
2335 LOG_ERROR("no color key defined for 'clouds_sunny' element!");
2336 if (!skybox_build_gradients(skybox_clouds_detail_sunny))
2337 LOG_ERROR("no color key defined for 'clouds_detail_sunny' element!");
2338 if (!skybox_build_gradients(skybox_clouds_rainy))
2339 LOG_ERROR("no color key defined for 'clouds_rainy' element!");
2340 if (!skybox_build_gradients(skybox_clouds_detail_rainy))
2341 LOG_ERROR("no color key defined for 'clouds_detail_rainy' element!");
2342 if (!skybox_build_gradients(skybox_sky1))
2343 LOG_ERROR("no color key defined for 'sky1' element!");
2344 if (!skybox_build_gradients(skybox_sky2))
2345 LOG_ERROR("no color key defined for 'sky2' element!");
2346 if (!skybox_build_gradients(skybox_sky3))
2347 LOG_ERROR("no color key defined for 'sky3' element!");
2348 if (!skybox_build_gradients(skybox_sky4))
2349 LOG_ERROR("no color key defined for 'sky4' element!");
2350 if (!skybox_build_gradients(skybox_sky5))
2351 LOG_ERROR("no color key defined for 'sky5' element!");
2352 if (!skybox_build_gradients(skybox_sky1_sunny))
2353 LOG_ERROR("no color key defined for 'sky1_sunny' element!");
2354 if (!skybox_build_gradients(skybox_sky2_sunny))
2355 LOG_ERROR("no color key defined for 'sky2_sunny' element!");
2356 if (!skybox_build_gradients(skybox_sky3_sunny))
2357 LOG_ERROR("no color key defined for 'sky3_sunny' element!");
2358 if (!skybox_build_gradients(skybox_sky4_sunny))
2359 LOG_ERROR("no color key defined for 'sky4_sunny' element!");
2360 if (!skybox_build_gradients(skybox_sky5_sunny))
2361 LOG_ERROR("no color key defined for 'sky5_sunny' element!");
2362 if (!skybox_build_gradients(skybox_sun))
2363 LOG_ERROR("no color key defined for 'sun' element!");
2364 if (!skybox_build_gradients(skybox_fog))
2365 LOG_ERROR("no color key defined for 'fog' element!");
2366 if (!skybox_build_gradients(skybox_fog_sunny))
2367 LOG_ERROR("no color key defined for 'fog_sunny' element!");
2368 if (!skybox_build_gradients(skybox_fog_rainy))
2369 LOG_ERROR("no color key defined for 'fog_rainy' element!");
2370 if (!skybox_build_gradients(skybox_light_ambient))
2371 LOG_ERROR("no color key defined for 'light_ambient' element!");
2372 if (!skybox_build_gradients(skybox_light_diffuse))
2373 LOG_ERROR("no color key defined for 'light_diffuse' element!");
2374 if (!skybox_build_gradients(skybox_light_ambient_rainy))
2375 LOG_ERROR("no color key defined for 'light_ambient_rainy' element!");
2376 if (!skybox_build_gradients(skybox_light_diffuse_rainy))
2377 LOG_ERROR("no color key defined for 'light_diffuse_rainy' element!");
2378
2379 skybox_update_positions();
2380 skybox_update_colors();
2381 }
2382
skybox_init_gl()2383 void skybox_init_gl()
2384 {
2385 /* GLUquadricObj *qobj; */
2386 GLfloat randx,randy,randz;
2387 int i;
2388 float maxr;
2389 float strs[NUM_STARS][3];
2390
2391 thick_clouds_tex = load_texture_cached("textures/thick_clouds", tt_mesh);
2392 thick_clouds_detail_tex = load_texture_cached("textures/thick_clouds_detail", tt_mesh);
2393 moon_tex = load_texture_cached("textures/moonmap", tt_mesh);
2394 sun_tex = load_texture_cached("textures/BrightSun", tt_mesh);
2395
2396 sky_lists = glGenLists(3);
2397
2398 /* qobj = gluNewQuadric(); */
2399 /* gluQuadricOrientation(qobj, GLU_OUTSIDE); */
2400 /* gluQuadricNormals(qobj, GLU_SMOOTH); */
2401 /* gluQuadricTexture(qobj, GL_TRUE); */
2402 /* glNewList(sky_lists, GL_COMPILE); */
2403 /* gluSphere(qobj, 1.0, 32, 16); */
2404 /* glEndList(); */
2405 /* gluDeleteQuadric(qobj); */
2406
2407 srand(0);
2408 maxr = 1.0/RAND_MAX;
2409 for (i = 0; i < NUM_STARS; i++)
2410 {
2411 float norm;
2412 do
2413 {
2414 randx = rand()*(float)(maxr)-0.5f;
2415 randy = rand()*(float)(maxr)-0.5f;
2416 randz = rand()*(float)(maxr)-0.5f;
2417 norm = sqrt(randx*randx + randy*randy + randz*randz);
2418 } while (norm > 0.5f);
2419
2420 strs[i][0] = 500 * randx / norm;
2421 strs[i][1] = 500 * randy / norm;
2422 strs[i][2] = 500 * randz / norm;
2423 }
2424 glNewList(sky_lists,GL_COMPILE);
2425 glBegin(GL_POINTS);
2426 for (i = 0; i < NUM_STARS/3; i++)
2427 {
2428 glVertex3fv(strs[i]);
2429 }
2430 glEnd();
2431 glEndList();
2432 glNewList(sky_lists+1,GL_COMPILE);
2433 glBegin(GL_POINTS);
2434 for (i = 1*NUM_STARS/3; i < 2*NUM_STARS/3; i++)
2435 {
2436 glVertex3fv(strs[i]);
2437 }
2438 glEnd();
2439 glEndList();
2440 glNewList(sky_lists+2,GL_COMPILE);
2441 glBegin(GL_POINTS);
2442 for (i = 2*NUM_STARS/3; i < NUM_STARS; i++)
2443 {
2444 glVertex3fv(strs[i]);
2445 }
2446 glEnd();
2447 glEndList();
2448
2449 destroy_dome(&dome_sky);
2450 destroy_dome(&dome_clouds);
2451 destroy_sphere(&moon_mesh);
2452 if (dome_clouds_detail_colors) free(dome_clouds_detail_colors);
2453 if (dome_clouds_colors_bis) free(dome_clouds_colors_bis);
2454 if (dome_clouds_detail_colors_bis) free(dome_clouds_detail_colors_bis);
2455 if (dome_clouds_tex_coords_bis) free(dome_clouds_tex_coords_bis);
2456
2457 dome_sky = create_dome(24, 12, 500.0, 80.0, 90.0, 3.5, 1.0);
2458 dome_clouds = create_dome(24, 12, 500.0, 80.0, 90.0, 2.0, 1.0);
2459 moon_mesh = create_sphere(24, 12);
2460 dome_clouds_detail_colors = (GLfloat*)malloc(4*dome_clouds.vertices_count*sizeof(GLfloat));
2461 dome_clouds_colors_bis = (GLfloat*)malloc(4*dome_clouds.vertices_count*sizeof(GLfloat));
2462 dome_clouds_detail_colors_bis = (GLfloat*)malloc(4*dome_clouds.vertices_count*sizeof(GLfloat));
2463 dome_clouds_tex_coords_bis = (GLfloat*)malloc(2*dome_clouds.vertices_count*sizeof(GLfloat));
2464
2465 for (i = dome_clouds.vertices_count; i--; )
2466 {
2467 int idx = i*2;
2468 dome_clouds_tex_coords_bis[idx] = dome_clouds.tex_coords[idx];
2469 dome_clouds_tex_coords_bis[idx+1] = dome_clouds.tex_coords[idx+1]+0.5;
2470 }
2471 }
2472
free_skybox()2473 void free_skybox()
2474 {
2475 destroy_dome(&dome_sky);
2476 destroy_dome(&dome_clouds);
2477 destroy_sphere(&moon_mesh);
2478 if (dome_clouds_detail_colors) free(dome_clouds_detail_colors);
2479 if (dome_clouds_colors_bis) free(dome_clouds_colors_bis);
2480 if (dome_clouds_detail_colors_bis) free(dome_clouds_detail_colors_bis);
2481 if (dome_clouds_tex_coords_bis) free(dome_clouds_tex_coords_bis);
2482 }
2483
2484