Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

SolImage.cpp

Go to the documentation of this file.
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 
SourceForge.net Logo Documentation generated by doxygen