00001 /* 00002 * SolImage.cpp 00003 * 00004 * Part of Fly! Legacy project 00005 * 00006 * The design and implementation of these classes is based heavily on the 00007 * sky model of SimGear 0.3.3, by Curtis Olson. Integration into the 00008 * Fly! Legacy project necessitated a rewrite of the actual classes, 00009 * but I am indebteded to Curt and other contributors to the SimGear and 00010 * FlightGear teams for their prior work in this area. 00011 * 00012 * Copyright 2003 Chris Wallace 00013 * 00014 * Fly! Legacy is free software; you can redistribute it and/or modify 00015 * it under the terms of the GNU General Public License as published by 00016 * the Free Software Foundation; either version 2 of the License, or 00017 * (at your option) any later version. 00018 * 00019 * Fly! Legacy is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU General Public License 00025 * along with Fly! Legacy; if not, write to the Free Software 00026 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00027 * 00028 */ 00029 00036 #include "../Include/Sky.h" 00037 #include "../Include/Utility.h" 00038 00039 00040 // 00041 // Pre-draw callback for Sol orb 00042 // 00043 static int sol_orb_predraw (ssgEntity *e) 00044 { 00045 ssgLeaf *f = (ssgLeaf*) e; 00046 if (f->hasState()) f->getState()->apply (); 00047 00048 glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_FOG_BIT); 00049 glDisable (GL_DEPTH_TEST); 00050 glDisable (GL_FOG); 00051 00052 return true; 00053 } 00054 00055 00056 // 00057 // Post-draw callback for Sol orb 00058 // 00059 static int sol_orb_postdraw (ssgEntity *e) 00060 { 00061 glPopAttrib (); 00062 return true; 00063 } 00064 00065 00066 // 00067 // Pre-draw callback for Sol halo 00068 // 00069 static int sol_halo_predraw (ssgEntity *e) 00070 { 00071 ssgLeaf *f = (ssgLeaf*) e; 00072 if (f->hasState()) f->getState()->apply (); 00073 00074 glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_FOG_BIT); 00075 glDisable (GL_DEPTH_TEST); 00076 glDisable (GL_FOG); 00077 00078 return true; 00079 } 00080 00081 00082 // 00083 // Post-draw callback for Sol halo 00084 // 00085 static int sol_halo_postdraw (ssgEntity *e) 00086 { 00087 glPopAttrib (); 00088 return true; 00089 } 00090 00091 00092 // 00093 // Sun layering parameters 00094 // 00095 // In Fly! II, this data was represented by the file Data\sun.txt 00096 // Since there was never any customization done as far as I know, 00097 // there's no real need to support this file, so to save time the 00098 // implementation is just hard-coded to match the contents of the 00099 // default sun.txt shipped with Fly! II 00100 // 00101 00102 typedef struct { 00103 char filename[64]; // Texture filename 00104 int w; // Dimension (width) 00105 float offset; // Layer y-offset 00106 float radius; // Radius in pseudo-feet 00107 float u1, v1, u2, v2; // Texture coordinates 00108 } SSunLayer; 00109 00110 00111 const int nSunLayers = 10; 00112 SSunLayer sunLayers[] = 00113 { 00114 {"sun06", 64, 0.500000, 43.000000, 8, 8, 248, 248}, 00115 {"suncram", 256, 0.30000, 143.000000, 130, 130, 254, 254}, 00116 {"sun07", 64, 0.100000, 11.000000, 8, 8, 248, 248}, 00117 {"sun07", 64, -0.271000, 27.000000, 8, 8, 248, 248}, 00118 {"sun09", 64, -0.416000, 80.000000, 8, 8, 248, 248}, 00119 {"sun11", 64, -0.475000, 41.000000, 8, 8, 248, 248}, 00120 {"sun12", 64, -0.643000, 61.000000, 8, 8, 248, 248}, 00121 {"sun13", 64, -0.674000, 60.000000, 8, 8, 248, 248}, 00122 {"suncram", 256, -1.000000, 213.000000, 130, 2, 254, 126}, 00123 {"suncram", 256, -1.333000, 410.000000, 2, 130, 126, 254} 00124 }; 00125 00126 00127 class CSunTextureCache { 00128 public: 00129 CSunTextureCache (void); 00130 ~CSunTextureCache (void); 00131 00132 public: 00133 char filename[64]; 00134 CSunRawImage *raw; 00135 GLuint tex; 00136 }; 00137 00138 CSunTextureCache::CSunTextureCache (void) 00139 { 00140 strcpy (filename, ""); 00141 raw = NULL; 00142 tex = 0; 00143 } 00144 00145 CSunTextureCache::~CSunTextureCache(void) 00146 { 00147 if (tex != 0) glDeleteTextures (1, &tex); 00148 if (raw != NULL) delete raw; 00149 } 00150 00151 00152 GLuint CSolImage::GetSunTexture (const char* filename, int w) 00153 { 00154 GLuint rc = 0; 00155 /* 00156 // Search if texture is already loaded 00157 int nTextures = textures.getNumEntities (); 00158 for (int i=0; i<nTextures; i++) { 00159 CSunTextureCache *cache = (CSunTextureCache *)textures.getEntity (i); 00160 00161 if (stricmp (filename, cache->filename) == 0) { 00162 // Found a match 00163 rc = cache->tex; 00164 break; 00165 } 00166 } 00167 00168 // Return code will be set if a match was found 00169 if (rc == 0) { 00170 // Create a new cache entry 00171 CSunTextureCache *cache = new CSunTextureCache; 00172 strcpy (cache->filename, filename); 00173 textures.addEntity (cache); 00174 00175 // Load the RAW image 00176 char raw[64]; 00177 sprintf (raw, "ART\\%s.RAW", filename); 00178 char act[64]; 00179 sprintf (act, "ART\\%s.ACT", filename); 00180 cache->raw = new CSunRawImage (w, w, raw, act); 00181 00182 rc = cache->tex = cache->raw->GetTexture (false); 00183 } 00184 */ 00185 return rc; 00186 } 00187 00188 // 00189 // Instantiate the sun image SSG object. 00190 // 00191 CSolImage::CSolImage (double size) 00192 { 00193 // Instantiate SSG entities 00194 top = new ssgTransform; 00195 top->setName ("Sol"); 00196 00197 /* 00198 * Sun orb commented out 2005-Mar-6. 00199 * 00200 00201 // 00202 // Create sun orb as a simple coloured sphere 00203 // 00204 ssgSimpleState *state = new ssgSimpleState (); 00205 state->setShadeModel (GL_SMOOTH); 00206 state->disable (GL_LIGHTING); 00207 state->disable (GL_CULL_FACE); 00208 state->disable (GL_TEXTURE_2D); 00209 state->enable (GL_COLOR_MATERIAL); 00210 state->setColourMaterial (GL_AMBIENT_AND_DIFFUSE); 00211 state->setMaterial (GL_EMISSION, 0, 0, 0, 1); 00212 state->setMaterial (GL_SPECULAR, 0, 0, 0, 1); 00213 state->disable (GL_BLEND); 00214 state->disable (GL_ALPHA_TEST); 00215 00216 // Initialize colour array 00217 rgba = new ssgColourArray (1); 00218 sgVec4 default_colour; 00219 sgSetVec4 (default_colour, 1.0, 1.0, 1.0, 1.0); 00220 rgba->add (default_colour); 00221 00222 ssgBranch *orb = ssgMakeSphere (state, rgba, size, 10, 10, 00223 sol_orb_predraw, sol_orb_postdraw); 00224 orb->setName ("Orb"); 00225 top->addKid (orb); 00226 00227 * 00228 */ 00229 00230 /* 00231 * Sun halo - need to fix texturing and shading before adding to scene 00232 00233 // Create state for halo 00234 state = new ssgSimpleState (); 00235 state->enable (GL_TEXTURE_2D); 00236 // state->disable (GL_TEXTURE_2D); 00237 state->disable (GL_LIGHTING); 00238 state->setShadeModel (GL_SMOOTH); 00239 state->disable (GL_CULL_FACE); 00240 state->enable (GL_COLOR_MATERIAL); 00241 state->setColourMaterial (GL_AMBIENT_AND_DIFFUSE); 00242 state->setMaterial (GL_EMISSION, 0, 0, 0, 1); 00243 state->setMaterial (GL_SPECULAR, 0, 0, 0, 1); 00244 state->enable (GL_ALPHA_TEST); 00245 state->setAlphaClamp (0.01); 00246 state->enable (GL_BLEND); 00247 00248 // GLint tex = GetSunTexture ("halo", 256); 00249 00250 CRawImage *rawHalo = new CRawImage (256, 256, "Art\\Halo.RAW", "Art\\Halo.ACT"); 00251 GLuint tex = rawHalo->GetTexture(false); 00252 state->setTexture (tex); 00253 delete rawHalo; 00254 00255 // Create vertex array 00256 double halo_size = size * 10; 00257 ssgVertexArray *va = new ssgVertexArray (4); 00258 sgVec3 v; 00259 // sgSetVec3 (v, -halo_size, 0.0, -halo_size); 00260 sgSetVec3 (v, -halo_size, -halo_size, 0.0); 00261 va->add (v); 00262 // sgSetVec3 (v, -halo_size, 0.0, halo_size); 00263 sgSetVec3 (v, -halo_size, halo_size, 0.0); 00264 va->add (v); 00265 // sgSetVec3 (v, halo_size, 0.0, halo_size); 00266 sgSetVec3 (v, halo_size, halo_size, 0.0); 00267 va->add (v); 00268 // sgSetVec3 (v, halo_size, 0.0, -halo_size); 00269 sgSetVec3 (v, halo_size, -halo_size, 0.0); 00270 va->add (v); 00271 00272 // Create texture array 00273 ssgTexCoordArray *ta = new ssgTexCoordArray (4); 00274 float u1 = (float)0.0; 00275 float u2 = (float)1.0; 00276 float v1 = (float)0.0; 00277 float v2 = (float)1.0; 00278 sgVec2 t; 00279 sgSetVec2 (t, u1, v1); 00280 ta->add (t); 00281 sgSetVec2 (t, u1, v2); 00282 ta->add (t); 00283 sgSetVec2 (t, u2, v2); 00284 ta->add (t); 00285 sgSetVec2 (t, u2, v1); 00286 ta->add (t); 00287 00288 // Create vertex table object for the halo 00289 ssgVtxTable *vt = new ssgVtxTable (GL_POLYGON, va, NULL, ta, rgba); 00290 vt->setName ("Halo"); 00291 vt->setState (state); 00292 vt->setCallback (SSG_CALLBACK_PREDRAW, sol_halo_predraw); 00293 vt->setCallback (SSG_CALLBACK_POSTDRAW, sol_halo_postdraw); 00294 00296 // top->addKid (vt); 00297 delete vt; 00298 */ 00299 00300 /* 00301 // Create cutout for layered sun 00302 orb_cutout = new ssgCutout (true); 00303 orb_cutout->setName ("Orb cutout"); 00304 00305 // Add various texturing layers to sun orb object 00306 for (int i=0; i<nSunLayers; i++) { 00307 // for (int i=2; i<3; i++) { 00308 SSunLayer *s = &sunLayers[i]; 00309 00310 // Create state for this layer 00311 ssgSimpleState *state = new ssgSimpleState (); 00312 state->setShadeModel (GL_SMOOTH); 00313 state->disable (GL_LIGHTING); 00314 state->disable (GL_CULL_FACE); 00315 state->enable (GL_TEXTURE_2D); 00316 state->enable (GL_COLOR_MATERIAL); 00317 state->enable (GL_BLEND); 00318 state->enable (GL_ALPHA_TEST); 00319 state->setColourMaterial (GL_AMBIENT_AND_DIFFUSE); 00320 state->setMaterial (GL_EMISSION, 0, 0, 0, 1); 00321 state->setMaterial (GL_SPECULAR, 0, 0, 0, 1); 00322 state->setAlphaClamp (0.01); 00323 00324 GLint tex = GetSunTexture (s->filename, s->w); 00325 state->setTexture (tex); 00326 00327 // Allocate arrays 00328 ssgColourArray *rgba = new ssgColourArray (1); 00329 ssgVertexArray *va = new ssgVertexArray (4); 00330 ssgNormalArray *na = new ssgNormalArray (4); 00331 ssgTexCoordArray *ta = new ssgTexCoordArray (4); 00332 00333 // Initialize colour array 00334 sgVec4 default_colour; 00335 sgSetVec4 (default_colour, 1.0, 1.0, 1.0, 1.0); 00336 rgba->add (default_colour); 00337 00338 // Initialize vertex array based on layer radius 00339 float r = (float)s->radius * 100; 00340 sgVec3 v; 00341 sgSetVec3 (v, -r, s->offset, -r); 00342 va->add (v); 00343 sgSetVec3 (v, -r, s->offset, r); 00344 va->add (v); 00345 sgSetVec3 (v, r, s->offset, r); 00346 va->add (v); 00347 sgSetVec3 (v, r, s->offset, -r); 00348 va->add (v); 00349 00350 // Initialize normal array 00351 sgVec3 n; 00352 sgSetVec3 (n, 0.0, -1.0, 0.0); 00353 na->add (n); 00354 na->add (n); 00355 na->add (n); 00356 na->add (n); 00357 00358 // Initialize texture array 00359 float u1 = (float)s->u1 / 256; 00360 float u2 = (float)s->u2 / 256; 00361 float v1 = (float)s->v1 / 256; 00362 float v2 = (float)s->v2 / 256; 00363 sgVec2 t; 00364 sgSetVec2 (t, u1, v1); 00365 ta->add (t); 00366 sgSetVec2 (t, u1, v2); 00367 ta->add (t); 00368 sgSetVec2 (t, u2, v2); 00369 ta->add (t); 00370 sgSetVec2 (t, u2, v1); 00371 ta->add (t); 00372 00373 // Create vertex table object for this layer 00374 ssgVtxTable *vt = new ssgVtxTable (GL_TRIANGLE_STRIP, va, NULL, ta, rgba); 00375 char name[64]; 00376 sprintf (name, "Layer %d", i); 00377 vt->setName (name); 00378 vt->setState (state); 00379 vt->setCallback (SSG_CALLBACK_PREDRAW, sol_orb_predraw); 00380 vt->setCallback (SSG_CALLBACK_POSTDRAW, sol_orb_postdraw); 00381 orb_cutout->addKid (vt); 00382 } 00383 */ 00384 // top->addKid (orb_cutout); 00385 00386 // Apply scaling transform to top-level 00387 // sgMat4 T; 00388 // sgMakeIdentMat4 (T); 00389 // sgScaleMat4 (T, T, size); 00390 // top->setTransform (T); 00391 00392 Repaint (0); 00393 00394 // FILE* f = fopen ("solimage.txt", "w"); 00395 // top->print (f); 00396 // fclose (f); 00397 } 00398 00399 CSolImage::~CSolImage (void) 00400 { 00401 // int i, n; 00402 /* 00403 n = textures.getNumEntities(); 00404 for (i=0; i<n; i++) { 00405 CSunTextureCache *cache = (CSunTextureCache *)textures.getEntity (i); 00406 delete cache; 00407 } 00408 textures.removeAllEntities(); 00409 */ 00410 } 00411 00412 00413 ssgEntity* CSolImage::GetSSGEntity (void) 00414 { 00415 return top; 00416 } 00417 00418 00419 void CSolImage::Repaint (double angle) 00420 { 00421 static float prev_angle = 9999.0f; 00422 00423 if (angle != prev_angle) { 00424 prev_angle = angle; 00425 00426 // Compute power factor, clamped to [-1, +1] 00427 float factor = 4 * cos(angle); 00428 if (factor > 1.0f) factor = 1.0f; 00429 if (factor < -1.0f) factor = -1.0f; 00430 00431 // Compute RGB colours for sun orb 00432 sgVec4 colour; 00433 colour[0] = pow (factor, 0.25); // Red 00434 colour[1] = pow (factor, 0.50); // Green 00435 colour[2] = pow (factor, 4.0); // Blue 00436 colour[3] = 1.0; // Alpha (opaque) 00437 00438 // DEBUG 00439 // sgSetVec4 (colour, 1.0, 1.0, 1.0, 1.0); 00440 00441 // Set orb colour 00443 float *p = rgba->get (0); 00444 sgCopyVec4 (p, colour); 00445 } 00446 } 00447 00448 // 00449 // Reposition the image of the sun in the sky 00450 // 00451 // Arguments: 00452 // pos 3D position of the eye (cartesian coordinates??) 00453 // lst Local Sidereal Time, in degrees 00454 // ra Right Ascension, in radians 00455 // dec Declination, in radians 00456 // distance Distance from the eye in world units 00457 // 00458 void CSolImage::Reposition (sgVec3 pos, double lst, double lat, double ra, double dec, double distance) 00459 { 00460 sgMat4 LST, LAT, RA, DEC, D; 00461 sgVec3 axis; 00462 sgVec3 v; 00463 00464 // Rotation matrix for latitude 00465 sgSetVec3 (axis, -1, 0, 0); 00466 sgMakeRotMat4 (LAT, 90-lat, axis); 00467 00468 // Rotation matrix for local sidereal time, converted from h to deg 00469 sgSetVec3 (axis, 0, 0, -1); 00470 sgMakeRotMat4 (LST, (lst * 15), axis); 00471 00472 // Rotation matrix for right ascension 00473 sgSetVec3 (axis, 0, 0, 1); 00474 sgMakeRotMat4 (RA, RadToDeg (ra), axis); 00475 00476 // Rotation matrix for declination 00477 sgSetVec3 (axis, 1, 0, 0); 00478 sgMakeRotMat4 (DEC, 90 - RadToDeg (dec), axis); 00479 00480 // Translate sun distance 00481 sgSetVec3 (v, 0, 0, distance); 00482 sgMakeTransMat4 (D, v); 00483 00484 // Combine all transforms 00485 sgMat4 T; 00486 sgMakeIdentMat4 (T); 00487 sgPreMultMat4 (T, LAT); 00488 sgPreMultMat4 (T, LST); 00489 sgPreMultMat4 (T, RA); 00490 sgPreMultMat4 (T, DEC); 00491 sgPreMultMat4 (T, D); 00492 00493 sgCoord skypos; 00494 sgSetCoord (&skypos, T); 00495 00496 // Set up the sun light position 00497 sgVec3 sunlight; 00498 sgSetVec3 (sunlight, -skypos.xyz[0], -skypos.xyz[1], skypos.xyz[2]); 00499 ssgGetLight (0)->setPosition (sunlight); 00500 00501 top->setTransform (T); 00502 } 00503 00504
|
|
Documentation generated by
|