00001 #include "backdrop.h"
00002
00003 BACKDROP::BACKDROP()
00004 {
00005
00006 error_log.open("logs/backdrop.log");
00007 initdone = false;
00008 sky_tex_img = NULL;
00009 }
00010
00011 extern bool verbose_output;
00012 BACKDROP::~BACKDROP()
00013 {
00014 if (verbose_output)
00015 cout << "backdrop deinit" << endl;
00016
00017 error_log.close();
00018 }
00019
00020 void BACKDROP::DeInit()
00021 {
00022 if (initdone)
00023 {
00024
00025
00026
00027
00028
00029
00030
00031
00032 sun_texture.Unload();
00033 rain_texture.Unload();
00034 cloud_texture.Unload();
00035 moon_texture.Unload();
00036 stars_texture.Unload();
00037 sun_texture_ref.Unload();
00038 sky_texture.Unload();
00039
00040 if (sky_tex_img)
00041 {
00042 SDL_FreeSurface( sky_tex_img );
00043 }
00044
00045 initdone = false;
00046 }
00047 }
00048
00049 void BACKDROP::Init()
00050 {
00051 fogdensity = 0.0005f;
00052
00053
00054 string filepath = "weather/star.png";
00055 sun_texture.Load(filepath, false);
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 filepath = "weather/star_reflection.png";
00091
00092
00093 sun_texture_ref.Load(filepath, false);
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 string tex_size;
00124 settings.Get( "display.texture_size", tex_size );
00125 filepath = settings.GetFullDataPath("textures/" + tex_size + "/weather/clearSky-joe.png");
00126
00127
00128
00129 sky_texture.Load(filepath, false);
00130 sky_tex_img = IMG_Load(filepath.c_str());
00131
00132
00133 filepath = "weather/raindrop.tga";
00134
00135 rain_texture.Load(filepath, false);
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 cloud_texture.Load("weather/clouds.png", true);
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 float fogcolor[4] = { 0.53f, 0.74f, 0.91f, 0.0f };
00214 glFogfv(GL_FOG_COLOR, fogcolor);
00215 glFogf(GL_FOG_START, 100);
00216 glFogf(GL_FOG_END, 1000);
00217 glFogf(GL_FOG_DENSITY, 0.0005f);
00218
00219 glFogi(GL_FOG_MODE, GL_EXP);
00220 glEnable(GL_FOG);
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 sunpos_lng = 0.0f;
00241 sunpos_lat = 0.7f;
00242
00243 moonpos_lng = 0.0f;
00244 moonpos_lat = 0.2f;
00245
00246 moon_texture.Load("weather/moon.png", false);
00247 stars_texture.Load("weather/stars.png", false);
00248 }
00249
00250 void BACKDROP::Draw(VERTEX tersize)
00251 {
00252
00253
00254 glDisable(GL_BLEND);
00255 glDisable( GL_TEXTURE_2D );
00256 glDisable( GL_LIGHTING);
00257
00258
00259 glDisable(GL_DEPTH_TEST);
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 glEnable(GL_FOG);
00294 glEnable(GL_DEPTH_TEST);
00295 glDisable(GL_BLEND);
00296 glColor4f(1.0f,1.0f,1.0f,1.0f);
00297 glEnable( GL_TEXTURE_2D );
00298 glEnable( GL_LIGHTING);
00299 }
00300
00301 void BACKDROP::DrawSky(double daytime, float transparency)
00302 {
00303 daytime_cache = daytime;
00304 sunpos_lat = daytime*3.141593f*2.0f;
00305
00306 moonpos_lat = (daytime+0.4)*3.141593f*2.0f;
00307
00308
00309 glPushAttrib(GL_ALL_ATTRIB_BITS);
00310 glEnable(GL_BLEND);
00311 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00312 glEnable( GL_TEXTURE_2D );
00313 glDisable(GL_LIGHTING);
00314 glDisable(GL_DEPTH_TEST);
00315 glDisable(GL_FOG);
00316
00317 QUATERNION cor, qx, qy, qz, qt;
00318 double temp_radius, temp_long, temp_lat;
00319 GLdouble temp_matrix[16];
00320 temp_radius = sqrt(cam.position.x*cam.position.x+cam.position.z*cam.position.z+(cam.position.y+EARTH_RADIUS)*(cam.position.y+EARTH_RADIUS));
00321 temp_long = atan2((double)(cam.position.y+EARTH_RADIUS),(double)cam.position.x);
00322 temp_lat = acos(cam.position.z/temp_radius);
00323 temp_lat -= 1.570796f;
00324 temp_long -= 1.570796f;
00325 qz.SetAxisAngle(-temp_long, 0, 0, 1);
00326 qx.SetAxisAngle(temp_lat, 1, 0, 0);
00327 qt = qx*qz;
00328 qt.GetMat(temp_matrix);
00329
00330 DrawStars(daytime, transparency, temp_matrix);
00331 DrawMoon(daytime, transparency, temp_matrix);
00332 DrawSkyGradient(daytime, transparency, temp_matrix);
00333
00334
00335
00336 DrawSun(daytime, transparency, temp_matrix);
00337 DrawClouds(daytime, transparency, temp_matrix);
00338
00339 glPopAttrib();
00340 }
00341
00342 void BACKDROP::DrawSkyGradient(double daytime, float transparency, GLdouble *temp_matrix)
00343 {
00344
00345 glPushAttrib(GL_ALL_ATTRIB_BITS);
00346 glEnable(GL_BLEND);
00347
00348 glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR);
00349 glEnable( GL_TEXTURE_2D );
00350 glDisable(GL_LIGHTING);
00351 glDisable(GL_DEPTH_TEST);
00352 glDisable(GL_FOG);
00353
00354
00355 int lng,lat;
00356 int num_longitudes = 12;
00357 int num_lattitudes = 12;
00358 float hem_radius = 10.0f;
00359
00360 float safety_factor = 0.0f;
00361 float hem_height = hem_radius;
00362 float pi = 3.141593f;
00363
00364 int i;
00365
00366 glPushMatrix();
00367 glMultMatrixd(temp_matrix);
00368
00369 float colhoriz[3], colzenith[3];
00370 colhoriz[0] = .53f;
00371 colhoriz[1] = .74f;
00372 colhoriz[2] = .91f;
00373
00374
00375
00376
00377 colzenith[0] = 0.0f;
00378 colzenith[1] = 50.0f/255.0f;
00379 colzenith[2] = 100.0f/255.0f;
00380
00381 VERTEX * oldset;
00382 VERTEX * curset;
00383 oldset = new VERTEX [num_longitudes+1];
00384 curset = new VERTEX [num_longitudes+1];
00385 VERTEX oldrot;
00386
00387 QUATERNION qrot, qtemp;
00388
00389 sky_texture.Activate();
00390
00391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00393
00394 glBegin(GL_QUADS);
00395
00396 int num_repeats = 0;
00397 int old_repeats = 0;
00398
00399 glColor4f(1.0f,1.0f,1.0f,transparency);
00400
00401 int pass;
00402 for (pass = 0; pass < 2; pass++)
00403 {
00404 for (lat = 0; lat <= num_lattitudes; lat++)
00405 {
00406 qrot.SetAxisAngle((pi/2.0f)*((float)lat/(float)num_lattitudes), 0, 0, 1);
00407 VERTEX rotvec;
00408 rotvec.x = hem_radius;
00409 rotvec = qrot.RotateVec(rotvec);
00410
00411 for (lng = 0; lng <= num_longitudes; lng++)
00412 {
00413 VERTEX currot;
00414 float curcol[4];
00415
00416 qtemp.SetAxisAngle(2.0f*pi*((float)lng/(float)num_longitudes), 0, 1, 0);
00417 currot = qtemp.RotateVec(rotvec);
00418
00419
00420 if (lat > 0 && lng > 0)
00421 {
00422
00423 float rheight;
00424
00425 rheight = 1.0f-currot.y/hem_height;
00426
00427
00428 for (i = 0; i < 3; i++)
00429 curcol[i] = colhoriz[i]*(1.0f-rheight)+colzenith[i]*rheight;
00430
00431 glTexCoord2f(daytime,rheight);
00432
00433 glVertex3f(oldrot.x, oldrot.y-safety_factor, oldrot.z);
00434 glVertex3f(currot.x, currot.y-safety_factor, currot.z);
00435
00436 rheight = 1.0f-oldset[lng].y/hem_height;
00437
00438
00439 for (i = 0; i < 3; i++)
00440 curcol[i] = colhoriz[i]*(1.0f-rheight)+colzenith[i]*(rheight);
00441
00442 glTexCoord2f(daytime,rheight);
00443 glVertex3f(oldset[lng].x, oldset[lng].y-safety_factor, oldset[lng].z);
00444 glVertex3f(oldset[lng-1].x, oldset[lng-1].y-safety_factor, oldset[lng-1].z);
00445 }
00446
00447 oldrot = currot;
00448 curset[lng] = currot;
00449 }
00450
00451 VERTEX * tptr = curset;
00452 curset = oldset;
00453 oldset = tptr;
00454 old_repeats = num_repeats;
00455 }
00456
00457 hem_radius = -hem_radius;
00458 hem_height = hem_radius;
00459 }
00460
00461 delete [] curset;
00462 delete [] oldset;
00463
00464 glEnd();
00465 glPopMatrix();
00466 glPopAttrib();
00467 }
00468
00469 void BACKDROP::DrawSun(double daytime, float transparency, GLdouble *temp_matrix)
00470 {
00471 int i;
00472 float hem_radius = 10.0f;
00473 float hem_height = hem_radius;
00474
00475
00476 glPushAttrib(GL_ALL_ATTRIB_BITS);
00477 glEnable(GL_TEXTURE_2D);
00478 glEnable(GL_BLEND);
00479 glClear(GL_DEPTH_BUFFER_BIT);
00480 float sunsize = 2.0f;
00481
00482
00483
00484 float sunsize_x = sunsize;
00485 float sunsize_y = sunsize;
00486
00487 VERTEX sunquad[4];
00488 for (i = 0; i < 4; i++)
00489 {
00490 if (i == 0 || i == 3)
00491 {
00492 sunquad[i].y = -sunsize_y;
00493 }
00494 else
00495 {
00496 sunquad[i].y = sunsize_y;
00497 }
00498 if (i < 2)
00499 sunquad[i].x = -sunsize_x;
00500 else
00501 sunquad[i].x = sunsize_x;
00502 }
00503 QUATERNION sunquat, sunquat2;
00504
00505 float transform_matrix[16];
00506 glPushMatrix();
00507 glMultMatrixd(temp_matrix);
00508
00509
00510 sunquat.SetAxisAngle(sunpos_lng+3.141593/2.0, 0, 0, 1);
00511 sunquat.GetMat(transform_matrix);
00512 glMultMatrixf(transform_matrix);
00513
00514 sunquat2.SetAxisAngle(sunpos_lat, 0, 1, 0);
00515 sunquat2.GetMat(transform_matrix);
00516 glMultMatrixf(transform_matrix);
00517
00518 glTranslatef(hem_height,0,0);
00519
00520
00521 sunquat2.ReturnConjugate().GetMat(transform_matrix);
00522 glMultMatrixf(transform_matrix);
00523
00524
00525
00526
00527 sunquat.ReturnConjugate().GetMat(transform_matrix);
00528 glMultMatrixf(transform_matrix);
00529
00530 cam.dir.ReturnConjugate().GetMat(transform_matrix);
00531 glMultMatrixf(transform_matrix);
00532
00533 glColor4f(1.0f, 1.0f, 1.0f, transparency);
00534
00535 sun_texture_ref.Activate();
00536 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00537
00538 glBegin(GL_QUADS);
00539 for (i = 0; i < 4; i++)
00540 {
00541 switch(i)
00542 {
00543 case 0:
00544 glTexCoord2f(0,0);
00545 break;
00546 case 1:
00547 glTexCoord2f(1,0);
00548 break;
00549 case 2:
00550 glTexCoord2f(1,1);
00551 break;
00552 case 3:
00553 glTexCoord2f(0,1);
00554 break;
00555 }
00556
00557 glVertex3f(sunquad[i].x, sunquad[i].y, sunquad[i].z);
00558 }
00559 glEnd();
00560 glPopMatrix();
00561
00562 glPopAttrib();
00563 }
00564
00565 void BACKDROP::DrawClouds(double daytime, float transparency, GLdouble *temp_matrix)
00566 {
00567
00568 cloudthresh = weathersystem.GetCloudCover();
00569 glPushAttrib(GL_ALL_ATTRIB_BITS);
00570 glPushMatrix();
00571 glEnable(GL_TEXTURE_2D);
00572 glEnable(GL_BLEND);
00573
00574 glEnable(GL_FOG);
00575 float oldfog = fogdensity;
00576 SetFogStrength(fogdensity*300.0f);
00577 RefreshFog();
00578
00579 glClear(GL_DEPTH_BUFFER_BIT);
00580 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00581
00582 float origalpha = transparency;
00583 float fadealpha = 1.0f;
00584 float cloudcolor = sin(sunpos_lat);
00585 float cloudscale = 20000.0f;
00586
00587
00588
00589
00590 float cloudrep = 1.0f;
00591 float cloudoffset_x, cloudoffset_z;
00592 cloudoffset_x = windx;
00593
00594 cloudoffset_z = windz;
00595 cloudcolor += 0.4f;
00596 if (cloudcolor < 0)
00597 cloudcolor *= 10.0f;
00598 if (cloudcolor < 0.1f)
00599 cloudcolor = 0.1f;
00600 if (cloudcolor > 1.0f)
00601 cloudcolor = 1.0f;
00602 glColor4f(cloudcolor, cloudcolor, cloudcolor, origalpha);
00603 glTranslatef(0,-0.4f,0);
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 glMultMatrixd(temp_matrix);
00615
00616 glScalef(1.0,0.1f,1.0f);
00617
00618
00619 int num_repeats = 0;
00620 int old_repeats = 0;
00621 int num_longitudes = 12;
00622 int num_lattitudes = 12;
00623
00624 cloud_texture.Activate();
00625
00626 VERTEX * oldset = new VERTEX [num_longitudes+1];
00627 VERTEX * curset = new VERTEX [num_longitudes+1];
00628 float hem_height = 10.0f;
00629 float hem_radius = 10.0f;
00630 int pass, lat, lng;
00631 QUATERNION qrot, qtemp;
00632 VERTEX oldrot;
00633 float safety_factor = 0.0f;
00634 float pi = 3.141593f;
00635 glBegin(GL_QUADS);
00636 for (pass = 0; pass < 2; pass++)
00637 {
00638 for (lat = 0; lat <= num_lattitudes; lat++)
00639 {
00640 if (pass == 0)
00641 qrot.SetAxisAngle((pi/2.0f)*((float)lat/(float)num_lattitudes), 0, 1, 0);
00642 else
00643 qrot.SetAxisAngle((pi/2.0f)*((float)lat/(float)num_lattitudes), 0, -1, 0);
00644 VERTEX rotvec;
00645 rotvec.z = hem_radius;
00646 rotvec = qrot.RotateVec(rotvec);
00647
00648 for (lng = 0; lng <= num_longitudes; lng++)
00649 {
00650 VERTEX currot;
00651 float curcol[4];
00652
00653 curcol[4] = 1.0f;
00654
00655
00656 qtemp.SetAxisAngle(2.0f*pi*((float)lng/(float)num_longitudes), 1, 0, 0);
00657
00658
00659 currot = qtemp.RotateVec(rotvec);
00660
00661 if (lat > 0 && lng > 0)
00662 {
00663 float rheight;
00664
00665 float vtile = 1.0f;
00666
00667
00668 float texu, texv, cx, cv;
00669
00670 rheight = 1.0f-vtile*currot.x/hem_height;
00671
00672 float fadeterm = 25.0f;
00673 float alphafactor;
00674 alphafactor = oldrot.x*oldrot.x+oldrot.z*oldrot.z;
00675 alphafactor /= (hem_radius*hem_radius-fadeterm);
00676 if (alphafactor > 1)
00677 alphafactor = 1.0f;
00678 alphafactor = 1.0f - alphafactor;
00679 glColor4f(cloudcolor, cloudcolor, cloudcolor,
00680 alphafactor*origalpha+(1.0f-alphafactor)*fadealpha);
00681
00682
00683
00684 cx = oldrot.x;
00685 cv = oldrot.z;
00686 texu = (cx/hem_height+cloudoffset_x)*cloudrep+(-cam.position.x/cloudscale)/cloudrep;
00687 texv = (cv/hem_height+cloudoffset_z)*cloudrep+(-cam.position.z/cloudscale)/cloudrep;
00688 glTexCoord2f(texu, texv);
00689 glVertex3f(oldrot.x, oldrot.y-safety_factor, oldrot.z);
00690
00691 alphafactor = currot.x*currot.x+currot.z*currot.z;
00692 alphafactor /= (hem_radius*hem_radius-fadeterm);
00693 if (alphafactor > 1)
00694 alphafactor = 1.0f;
00695 alphafactor = 1.0f - alphafactor;
00696 glColor4f(cloudcolor, cloudcolor, cloudcolor,
00697 alphafactor*origalpha+(1.0f-alphafactor)*fadealpha);
00698
00699
00700
00701 cx = currot.x;
00702 cv = currot.z;
00703 texu = (cx/hem_height+cloudoffset_x)*cloudrep+(-cam.position.x/cloudscale)/cloudrep;
00704 texv = (cv/hem_height+cloudoffset_z)*cloudrep+(-cam.position.z/cloudscale)/cloudrep;
00705 glTexCoord2f(texu, texv);
00706 glVertex3f(currot.x, currot.y-safety_factor, currot.z);
00707
00708 rheight = 1.0f-vtile*oldset[lng].x/hem_height;
00709
00710 alphafactor = oldset[lng].x*oldset[lng].x+oldset[lng].z*oldset[lng].z;
00711 alphafactor /= (hem_radius*hem_radius-fadeterm);
00712 if (alphafactor > 1)
00713 alphafactor = 1.0f;
00714 alphafactor = 1.0f - alphafactor;
00715 glColor4f(cloudcolor, cloudcolor, cloudcolor,
00716 alphafactor*origalpha+(1.0f-alphafactor)*fadealpha);
00717
00718
00719
00720 cx = oldset[lng].x;
00721 cv = oldset[lng].z;
00722 texu = (cx/hem_height+cloudoffset_x)*cloudrep+(-cam.position.x/cloudscale)/cloudrep;
00723 texv = (cv/hem_height+cloudoffset_z)*cloudrep+(-cam.position.z/cloudscale)/cloudrep;
00724 glTexCoord2f(texu, texv);
00725 glVertex3f(oldset[lng].x, oldset[lng].y-safety_factor, oldset[lng].z);
00726
00727 alphafactor = oldset[lng-1].x*oldset[lng-1].x+oldset[lng-1].z*oldset[lng-1].z;
00728 alphafactor /= (hem_radius*hem_radius-fadeterm);
00729 if (alphafactor > 1)
00730 alphafactor = 1.0f;
00731 alphafactor = 1.0f - alphafactor;
00732 glColor4f(cloudcolor, cloudcolor, cloudcolor,
00733 alphafactor*origalpha+(1.0f-alphafactor)*fadealpha);
00734
00735
00736
00737 cx = oldset[lng-1].x;
00738 cv = oldset[lng-1].z;
00739 texu = (cx/hem_height+cloudoffset_x)*cloudrep+(-cam.position.x/cloudscale)/cloudrep;
00740 texv = (cv/hem_height+cloudoffset_z)*cloudrep+(-cam.position.z/cloudscale)/cloudrep;
00741 glTexCoord2f(texu, texv);
00742 glVertex3f(oldset[lng-1].x, oldset[lng-1].y-safety_factor, oldset[lng-1].z);
00743 }
00744
00745 oldrot = currot;
00746 curset[lng] = currot;
00747 }
00748
00749 VERTEX * tptr = curset;
00750 curset = oldset;
00751 oldset = tptr;
00752 old_repeats = num_repeats;
00753 }
00754
00755
00756
00757 }
00758 delete [] curset;
00759 delete [] oldset;
00760 glEnd();
00761
00762
00763
00764
00765
00766
00767
00768
00769 SetFogStrength(oldfog);
00770 RefreshFog();
00771 glPopAttrib();
00772 glPopMatrix();
00773 }
00774
00775 void BACKDROP::DrawStars(double daytime, float transparency, GLdouble *temp_matrix)
00776 {
00777
00778 glPushAttrib(GL_ALL_ATTRIB_BITS);
00779 glPushMatrix();
00780 glEnable(GL_TEXTURE_2D);
00781 glEnable(GL_BLEND);
00782
00783 glClear(GL_DEPTH_BUFFER_BIT);
00784 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 float fogcolor[4];
00798 GetSkyColor(fogcolor);
00799 glColor4f(1.0,1.0,1.0,1.0-fogcolor[3]);
00800 glTranslatef(0,-0.4f,0);
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 glMultMatrixd(temp_matrix);
00812
00813
00814 glScalef(1.0,1.0f,1.0f);
00815
00816
00817 stars_texture.Activate();
00818 glMatrixMode(GL_TEXTURE);
00819 glLoadIdentity();
00820 glScalef(10.0f,10.0f,10.0f);
00821
00822 glMatrixMode(GL_MODELVIEW);
00823 glRotatef(90,1,0,0);
00824 GLUquadricObj *quadratic;
00825 quadratic=gluNewQuadric();
00826 gluQuadricTexture(quadratic, GL_TRUE);
00827 gluSphere(quadratic,1.0f,32,32);
00828 gluDeleteQuadric(quadratic);
00829
00830 glMatrixMode(GL_TEXTURE);
00831 glLoadIdentity();
00832 glMatrixMode(GL_MODELVIEW);
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 glPopAttrib();
00988 glPopMatrix();
00989 }
00990
00991 void BACKDROP::RefreshFog()
00992 {
00993
00994 float fogcolor[4];
00995 GetHorizonColor(fogcolor);
00996 fogcolor[3] = 0.0f;
00997
00998
00999 float colmean = (fogcolor[0] + fogcolor[1] + fogcolor[2])/3.0f;
01000 float cloudiness;
01001 if (cloudthresh >= 0)
01002 cloudiness = 0.0f;
01003 else
01004 cloudiness = -(cloudthresh/100.0f);
01005
01006
01007
01008 if (cloudiness > 1.0f)
01009 cloudiness = 1.0f;
01010 if (cloudiness < 0.0f)
01011 cloudiness = 0.0f;
01012
01013 int i;
01014 for (i = 0; i < 3; i++)
01015 {
01016 fogcolor[i] = fogcolor[i]*(1.0f-cloudiness) + colmean*cloudiness;
01017 }
01018
01019 glFogfv(GL_FOG_COLOR, fogcolor);
01020 glFogf(GL_FOG_DENSITY, fogdensity);
01021 glFogi(GL_FOG_MODE, GL_EXP);
01022 glEnable(GL_FOG);
01023 }
01024
01025 struct pix24
01026 {
01027 unsigned char r;
01028 unsigned char g;
01029 unsigned char b;
01030 };
01031
01032 struct pix32
01033 {
01034 unsigned char r;
01035 unsigned char g;
01036 unsigned char b;
01037 unsigned char a;
01038 };
01039
01040 void BACKDROP::GetHorizonColor(float * color3)
01041 {
01042
01043
01044
01045
01046 struct pix32 * pix;
01047
01048 pix = (struct pix32 *) sky_tex_img->pixels;
01049
01050 float dx;
01051 int x;
01052 int sky_tex_size = 16;
01053 dx = (daytime_cache*sky_tex_size);
01054 x = (int)dx;
01055 dx = dx - x;
01056 x %= sky_tex_size;
01057 int idx1 = x + 15*sky_tex_size;
01058 x++;
01059 x %= sky_tex_size;
01060 int idx2 = x + 15*sky_tex_size;
01061
01062 color3[0] = (1.0f-dx)*pix[idx1].r/255.0f+dx*pix[idx2].r/255.0f;
01063 color3[1] = (1.0f-dx)*pix[idx1].g/255.0f+dx*pix[idx2].g/255.0f;
01064 color3[2] = (1.0f-dx)*pix[idx1].b/255.0f+dx*pix[idx2].b/255.0f;
01065 color3[3] = (1.0f-dx)*pix[idx1].a/255.0f+dx*pix[idx2].a/255.0f;
01066 }
01067
01068 void BACKDROP::GetSkyColor(float * color3)
01069 {
01070
01071
01072
01073
01074 struct pix32 * pix;
01075
01076 pix = (struct pix32 *) sky_tex_img->pixels;
01077
01078 float dx;
01079 int x;
01080 int sky_tex_size = 16;
01081 dx = (daytime_cache*sky_tex_size);
01082 x = (int)dx;
01083 dx = dx - x;
01084 x %= sky_tex_size;
01085
01086 int idx1 = x;
01087 x++;
01088 x %= sky_tex_size;
01089
01090 int idx2 = x;
01091
01092 color3[0] = (1.0f-dx)*pix[idx1].r/255.0f+dx*pix[idx2].r/255.0f;
01093 color3[1] = (1.0f-dx)*pix[idx1].g/255.0f+dx*pix[idx2].g/255.0f;
01094 color3[2] = (1.0f-dx)*pix[idx1].b/255.0f+dx*pix[idx2].b/255.0f;
01095 color3[3] = (1.0f-dx)*pix[idx1].a/255.0f+dx*pix[idx2].a/255.0f;
01096 }
01097
01098 void BACKDROP::SetFogStrength(float density)
01099 {
01100 fogdensity = density;
01101 glFogf(GL_FOG_DENSITY, fogdensity);
01102 }
01103
01104 void BACKDROP::SetWindoffset(float windoffset_x, float windoffset_z)
01105 {
01106 windx = windoffset_x;
01107 windz = windoffset_z;
01108 }
01109
01110 void BACKDROP::SetCloudCover(int newcloudthresh)
01111 {
01112 cloudthresh = newcloudthresh;
01113 }
01114
01115 void BACKDROP::DrawRain(float day_time)
01116 {
01117 glPushMatrix();
01118 glLoadIdentity();
01119 glPushAttrib(GL_ALL_ATTRIB_BITS);
01120 glDisable(GL_DEPTH_TEST);
01121 glEnable(GL_TEXTURE_2D);
01122 glEnable(GL_BLEND);
01123 glDisable(GL_FOG);
01124 glDisable(GL_LIGHTING);
01125 glTranslatef(0,0,-40.0f);
01126
01127
01128 rain_texture.Activate();
01129 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
01130 glColor4f(1.0f,1.0f,1.0f,1.0f);
01131 glBegin(GL_TRIANGLES);
01132
01133 VERTEX pos;
01134 float alpha;
01135 int numdrops = weathersystem.GetRainDrops();
01136 int i;
01137
01138 VERTEX up, forward, right;
01139 up.y = 1.0f;
01140 up = cam.dir.RotateVec(up);
01141 up.y = sin(up.y);
01142 forward.z = 1.0f;
01143 forward = cam.dir.RotateVec(forward);
01144 if ((forward.y >= 0 && forward.z >= 0) || (forward.y < 0 && forward.z < 0))
01145 forward.y = 1.0f;
01146 else
01147 forward.y = -1.0f;
01148
01149 float randperm;
01150 float lum;
01151
01152 float dayout = day_time;
01153 float daythresh = 0.1f;
01154 if (dayout >= 0.5)
01155 dayout = 0.0f;
01156 if (dayout < 0.5f && dayout > 0.5f - daythresh)
01157 dayout = 0.5-dayout;
01158 dayout /= daythresh;
01159 if (dayout > 1.0f)
01160 dayout = 1.0f;
01161 dayout = dayout*0.75f+0.25f;
01162
01163 for (i = 0; i < numdrops; i++)
01164 {
01165 pos.x = (rand()/(float)RAND_MAX-0.5f)*50.0f;
01166 pos.y = (rand()/(float)RAND_MAX-0.5f)*40.0f;
01167 pos.z = (rand()/(float)RAND_MAX);
01168 alpha = (rand()/(float)RAND_MAX)/4.0f + 0.2f;
01169 lum = (rand()/(float)RAND_MAX)/2.0f + 0.5f;
01170 lum *= dayout;
01171 glColor4f(lum,lum,lum,alpha);
01172 randperm = (rand()/(float)RAND_MAX-0.5f)*1.0f;
01173 DrawDrop(pos, randperm, up.y, forward.y);
01174 }
01175
01176 glEnd();
01177 glPopAttrib();
01178 glPopMatrix();
01179 }
01180
01181 void BACKDROP::DrawDrop(VERTEX pos, float rndperm, float yscale, float zheight)
01182 {
01183 float dropwidth = 0.25f;
01184 bool negy;
01185 if (zheight >= 0)
01186 negy = false;
01187 else
01188 negy = true;
01189
01190 float dropheight = 10.0f*pos.z*yscale;
01191 if (dropheight < 0.5f)
01192 dropheight = 0.5f;
01193 float xoffset;
01194 if (negy)
01195 xoffset = -(1.0f-yscale)*0.2f*pos.x*pos.z;
01196 else
01197 xoffset = (1.0f-yscale)*0.2f*pos.x*pos.z;
01198
01199 glTexCoord2f(0,0);
01200 glVertex3f(pos.x-dropwidth, pos.y+dropheight, 0.0f);
01201 glTexCoord2f(0,1);
01202 glVertex3f(pos.x-dropwidth+rndperm+xoffset, pos.y-dropheight, 0.0f);
01203 glTexCoord2f(1,1);
01204 glVertex3f(pos.x+dropwidth+rndperm+xoffset, pos.y-dropheight, 0.0f);
01205 }
01206
01207 void BACKDROP::DrawMoon(double daytime, float transparency, GLdouble *temp_matrix)
01208 {
01209 int i;
01210 float hem_radius = 10.0f;
01211 float hem_height = hem_radius;
01212
01213
01214 glPushAttrib(GL_ALL_ATTRIB_BITS);
01215 glEnable(GL_TEXTURE_2D);
01216