glCullFace(GL_BACK);
glDisable(GL_DEPTH_TEST);
sgVec4 panel_color;
- sgCopyVec4( panel_color, cur_light_params.scene_diffuse );
+
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
+ sgCopyVec4( panel_color, l->scene_diffuse());
if ( fgGetDouble("/systems/electrical/outputs/instrument-lights") > 1.0 ) {
if ( panel_color[0] < 0.7 ) panel_color[0] = 0.7;
if ( panel_color[1] < 0.2 ) panel_color[1] = 0.2;
// From Curt: turn on the panel
// lights after sundown.
sgVec4 panel_color;
- sgCopyVec4( panel_color, cur_light_params.scene_diffuse );
+
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
+ sgCopyVec4( panel_color, l->scene_diffuse());
if ( fgGetDouble("/systems/electrical/outputs/instrument-lights") > 1.0 ) {
if ( panel_color[0] < 0.7 ) panel_color[0] = 0.7;
if ( panel_color[1] < 0.2 ) panel_color[1] = 0.2;
fgReInitSubsystems();
globals->get_tile_mgr()->update( fgGetDouble("/environment/visibility-m") );
-
- cur_light_params.Update();
fgReshape( xsize, ysize );
}
-/**
- * Update the lighting manually.
- */
-static bool
-do_lighting_update (const SGPropertyNode * arg)
-{
- fgUpdateSkyAndLightingParams();
- return true;
-}
-
-
/**
* Update the lighting manually.
*/
cur_time_override->getLongValue(),
globals->get_warp() );
- fgUpdateSkyAndLightingParams();
-
return true;
}
{ "view-cycle", do_view_cycle },
{ "screen-capture", do_screen_capture },
{ "tile-cache-reload", do_tile_cache_reload },
- { "lighting-update", do_lighting_update },
{ "timeofday", do_timeofday },
{ "property-toggle", do_property_toggle },
{ "property-assign", do_property_assign },
SG_LOG( SG_GENERAL, SG_INFO, "After fgInitTimeOffset(): warp = "
<< globals->get_warp() );
-
- fgUpdateSkyAndLightingParams();
}
// This is the top level init routine which calls all the other
// static const SGPropertyNode *altitude
// = fgGetNode("/sim/presets/altitude-ft");
- fgLIGHT *l = &cur_light_params;
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
SG_LOG( SG_GENERAL, SG_INFO, "Initialize Subsystems");
SG_LOG( SG_GENERAL, SG_INFO, "========== ==========");
// Initialize the lighting subsystem.
////////////////////////////////////////////////////////////////////
- // fgUpdateSunPos() needs a few position and view parameters set
- // so it can calculate local relative sun angle and a few other
- // things for correctly orienting the sky.
- fgUpdateSunPos();
- fgUpdateMoonPos();
- global_events.Register( "fgUpdateSunPos()", &fgUpdateSunPos,
- 60000);
- global_events.Register( "fgUpdateMoonPos()", &fgUpdateMoonPos,
- 60000);
-
- // Initialize Lighting interpolation tables
- l->Init();
-
- // force one lighting update to make it right to start with...
- l->Update();
- // update the lighting parameters (based on sun angle)
- global_events.Register( "fgLight::Update()",
- &cur_light_params, &fgLIGHT::Update,
- 30000 );
-
+ globals->add_subsystem("lighting", new FGLight);
////////////////////////////////////////////////////////////////////
// Create and register the logger.
globals->get_controls()->reset_all();
globals->get_autopilot()->reset();
- fgUpdateSunPos();
- fgUpdateMoonPos();
- cur_light_params.Update();
fgUpdateLocalTime();
if ( !freeze ) {
double lat = current_aircraft.fdm_state->get_Latitude();
globals->set_warp(warp);
st->update(lon, lat, cur_time_override->getLongValue(), warp);
- fgUpdateSkyAndLightingParams();
}
/**
channel_options_list( NULL ),
scenery( NULL ),
tile_mgr( NULL ),
- io( new FGIO )
+ io( new FGIO ),
+ cur_light_params( NULL )
{
}
class FGAutopilot;
class FGControls;
class FGIO;
+class FGLight;
class FGModelMgr;
class FGScenery;
#ifdef FG_MPLAYER_AS
// Tile manager
FGTileMgr *tile_mgr;
- FGIO* io;
+ // Input/Ouput subsystem
+ FGIO *io;
+
+ // light parameters
+ FGLight *cur_light_params;
#ifdef FG_MPLAYER_AS
//Mulitplayer managers
inline FGTileMgr * get_tile_mgr () const { return tile_mgr; }
inline void set_tile_mgr ( FGTileMgr *t ) { tile_mgr = t; }
- FGIO* get_io() const { return io; }
-
+ inline FGIO* get_io() const { return io; }
/**
* Save the current state as the initial state.
// fgInitVisuals() -- Initialize various GL/view parameters
void fgInitVisuals( void ) {
- fgLIGHT *l;
- l = &cur_light_params;
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
#ifndef GLUT_WRONG_VERSION
// Go full screen if requested ...
// glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec ); // done later with ssg
sgVec3 sunpos;
- sgSetVec3( sunpos, l->sun_vec[0], l->sun_vec[1], l->sun_vec[2] );
+ sgSetVec3( sunpos, l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2] );
ssgGetLight( 0 ) -> setPosition( sunpos );
glFogi (GL_FOG_MODE, GL_EXP2);
static GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
static GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
- fgLIGHT *l = &cur_light_params;
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
- glClearColor(l->adj_fog_color[0], l->adj_fog_color[1],
- l->adj_fog_color[2], l->adj_fog_color[3]);
+ glClearColor(l->adj_fog_color()[0], l->adj_fog_color()[1],
+ l->adj_fog_color()[2], l->adj_fog_color()[3]);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable( GL_FOG );
glFogf ( GL_FOG_DENSITY, fog_exp2_density);
glFogi ( GL_FOG_MODE, GL_EXP2 );
- glFogfv ( GL_FOG_COLOR, l->adj_fog_color );
+ glFogfv ( GL_FOG_COLOR, l->adj_fog_color() );
// GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
// we only update GL_AMBIENT for our lights we will never get
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE );
- ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient );
+ ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient() );
// texture parameters
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
// draw the ssg scene
// return to the desired diffuse color
- ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse );
+ ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
glEnable( GL_DEPTH_TEST );
ssgSetNearFar( scene_nearplane, scene_farplane );
ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
FGViewer *current__view = globals->get_current_view();
- fgLIGHT *l = &cur_light_params;
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
static double last_visibility = -9999;
// update fog params
if ( skyblend ) {
if ( fgGetBool("/sim/rendering/textures") ) {
// glClearColor(black[0], black[1], black[2], black[3]);
- glClearColor(l->adj_fog_color[0], l->adj_fog_color[1],
- l->adj_fog_color[2], l->adj_fog_color[3]);
+ glClearColor(l->adj_fog_color()[0], l->adj_fog_color()[1],
+ l->adj_fog_color()[2], l->adj_fog_color()[3]);
clear_mask |= GL_COLOR_BUFFER_BIT;
}
} else {
- glClearColor(l->sky_color[0], l->sky_color[1],
- l->sky_color[2], l->sky_color[3]);
+ glClearColor(l->sky_color()[0], l->sky_color()[1],
+ l->sky_color()[2], l->sky_color()[3]);
clear_mask |= GL_COLOR_BUFFER_BIT;
}
glClear( clear_mask );
*/
static SGSkyColor scolor;
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
- scolor.sky_color = cur_light_params.sky_color;
- scolor.fog_color = cur_light_params.adj_fog_color;
- scolor.cloud_color = cur_light_params.cloud_color;
- scolor.sun_angle = cur_light_params.sun_angle;
- scolor.moon_angle = cur_light_params.moon_angle;
+ scolor.sky_color = l->sky_color();
+ scolor.fog_color = l->adj_fog_color();
+ scolor.cloud_color = l->cloud_color();
+ scolor.sun_angle = l->get_sun_angle();
+ scolor.moon_angle = l->get_moon_angle();
scolor.nplanets = globals->get_ephem()->getNumPlanets();
scolor.nstars = globals->get_ephem()->getNumStars();
scolor.planet_data = globals->get_ephem()->getPlanets();
// Sun distance: 150,000,000 kilometers
double sun_horiz_eff, moon_horiz_eff;
if (fgGetBool("/sim/rendering/horizon-effect")) {
- sun_horiz_eff = 0.67+pow(0.5+cos(cur_light_params.sun_angle*2)/2,0.33)/3;
- moon_horiz_eff = 0.67+pow(0.5+cos(cur_light_params.moon_angle*2)/2,0.33)/3;
+ sun_horiz_eff = 0.67+pow(0.5+cos(l->get_sun_angle())*2/2, 0.33)/3;
+ moon_horiz_eff = 0.67+pow(0.5+cos(l->get_moon_angle())*2/2, 0.33)/3;
} else {
sun_horiz_eff = moon_horiz_eff = 1.0;
}
* SGD_DEGREES_TO_RADIANS;
sstate.alt = current__view->getAltitudeASL_ft()
* SG_FEET_TO_METER;
- sstate.spin = cur_light_params.sun_rotation;
+ sstate.spin = l->get_sun_rotation();
sstate.gst = globals->get_time_params()->getGst();
sstate.sun_ra = globals->get_ephem()->getSunRightAscension();
sstate.sun_dec = globals->get_ephem()->getSunDeclination();
if ( strcmp(fgGetString("/sim/rendering/fog"), "disabled") ) {
glEnable( GL_FOG );
glFogi( GL_FOG_MODE, GL_EXP2 );
- glFogfv( GL_FOG_COLOR, l->adj_fog_color );
+ glFogfv( GL_FOG_COLOR, l->adj_fog_color() );
}
// set sun/lighting parameters
- ssgGetLight( 0 ) -> setPosition( l->sun_vec );
+ ssgGetLight( 0 ) -> setPosition( l->sun_vec() );
// GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
// we only update GL_AMBIENT for our lights we will never get
// explicitely to black.
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
- ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient );
- ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse );
- ssgGetLight( 0 ) -> setColour( GL_SPECULAR, l->scene_specular );
+ ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient() );
+ ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
+ ssgGetLight( 0 ) -> setColour( GL_SPECULAR, l->scene_specular() );
// texture parameters
// glEnable( GL_TEXTURE_2D );
thesky->preDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
// return to the desired diffuse color
- ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse );
+ ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
// FIXME: This should not be needed, but at this time (08/15/2003)
// certain NVidia drivers don't seem to implement
//SG_LOG(SG_FLIGHT,SG_INFO, "Updating time dep calcs()");
- fgLIGHT *l = &cur_light_params;
-
// Initialize the FDM here if it hasn't been and if we have a
// scenery elevation hit.
// update the view angle
globals->get_viewmgr()->update(delta_time_sec);
- l->UpdateAdjFog();
-
// Update solar system
globals->get_ephem()->update( globals->get_time_params()->getMjd(),
globals->get_time_params()->getLst(),
SGTime *t = globals->get_time_params();
sglog().setLogLevels( SG_ALL, (sgDebugPriority)fgGetInt("/sim/log-level") );
- sglog().setLogLevels( SG_ALL, SG_INFO );
SGLocation * acmodel_location = 0;
if(cur_fdm_state->getACModel() != 0) {
cur_time_override->getLongValue(),
globals->get_warp() );
- if ( globals->get_warp_delta() != 0 ) {
- fgUpdateSkyAndLightingParams();
- }
-
// update magvar model
globals->get_mag()->update( longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
fgReshape( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
- fgUpdateSkyAndLightingParams();
}
if ( idle_state == 1000 ) {
// temporary hack for deck lights - ultimately should move to PLib (when ??)
if (m == 1) {
if (lightpoints_transform) {
- lightpoints_transform->setTransform( &shippos );
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
- if ( sun_angle > 89 ) {
- lightpoints_brightness->select(0x01);
- } else {
- lightpoints_brightness->select(0x00);
- }
+ lightpoints_transform->setTransform( &shippos );
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
+ float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
+ if ( sun_angle > 89 ) {
+ lightpoints_brightness->select(0x01);
+ } else {
+ lightpoints_brightness->select(0x00);
+ }
}
float elev;
sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() );
terra_transform->setTransform( sgTrans );
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
if ( gnd_lights_transform ) {
// we need to lift the lights above the terrain to avoid
// z-buffer fighting. We do this based on our altitude and
gnd_lights_transform->setTransform( lt_trans );
// select which set of lights based on sun angle
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
+ float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
if ( sun_angle > 95 ) {
gnd_lights_brightness->select(0x04);
} else if ( sun_angle > 92 ) {
rwy_lights_transform->setTransform( lt_trans );
// turn runway lights on/off based on sun angle and visibility
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
+ float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
if ( sun_angle > 85 ||
(fgGetDouble("/environment/visibility-m") < 5000.0) ) {
rwy_lights_selector->select(0x01);
taxi_lights_transform->setTransform( lt_trans );
// turn taxi lights on/off based on sun angle and visibility
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
+ float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
if ( sun_angle > 85 ||
(fgGetDouble("/environment/visibility-m") < 5000.0) ) {
taxi_lights_selector->select(0x01);
#include "light.hxx"
#include "sunpos.hxx"
-fgLIGHT cur_light_params;
-
// Constructor
-fgLIGHT::fgLIGHT( void ) {
+FGLight::FGLight ()
+ : _prev_sun_angle(-9999.0),
+ _dt_total( 0.0 )
+{
+}
+
+// Destructor
+FGLight::~FGLight ()
+{
}
// initialize lighting tables
-void fgLIGHT::Init( void ) {
+void FGLight::init () {
SG_LOG( SG_EVENT, SG_INFO,
"Initializing Lighting interpolation tables." );
- // build the path name to the ambient lookup table
+ // build the path names of the lookup tables
SGPath path( globals->get_fg_root() );
- SGPath ambient = path;
- ambient.append( "Lighting/ambient" );
- SGPath diffuse = path;
- diffuse.append( "Lighting/diffuse" );
- SGPath specular = path;
- specular.append( "Lighting/specular" );
- SGPath sky = path;
- sky.append( "Lighting/sky" );
-
- // initialize ambient table
- ambient_tbl = new SGInterpTable( ambient.str() );
-
- // initialize diffuse table
- diffuse_tbl = new SGInterpTable( diffuse.str() );
-
- // initialize diffuse table
- specular_tbl = new SGInterpTable( specular.str() );
+
+ // initialize ambient, diffuse and specular tables
+ SGPath ambient_path = path;
+ ambient_path.append( "Lighting/ambient" );
+ _ambient_tbl = new SGInterpTable( ambient_path.str() );
+
+ SGPath diffuse_path = path;
+ diffuse_path.append( "Lighting/diffuse" );
+ _diffuse_tbl = new SGInterpTable( diffuse_path.str() );
+
+ SGPath specular_path = path;
+ specular_path.append( "Lighting/specular" );
+ _specular_tbl = new SGInterpTable( specular_path.str() );
// initialize sky table
- sky_tbl = new SGInterpTable( sky.str() );
+ SGPath sky_path = path;
+ sky_path.append( "Lighting/sky" );
+ _sky_tbl = new SGInterpTable( sky_path.str() );
+}
+
+
+void FGLight::reinit () {
+ _prev_sun_angle = -9999.0;
+ _dt_total = 0;
+
+ fgUpdateSunPos();
+ fgUpdateMoonPos();
+
+ update_sky_color();
+ update_adj_fog_color();
+}
+
+void FGLight::bind () {
+}
+
+void FGLight::unbind () {
}
// update lighting parameters based on current sun position
-void fgLIGHT::Update( void ) {
+void FGLight::update( double dt ) {
+
+ update_adj_fog_color();
+
+ _dt_total += dt;
+ if (_dt_total > 0.5) {
+ _dt_total -= 0.5;
+ fgUpdateSunPos();
+ fgUpdateMoonPos();
+ }
+
+ if (_prev_sun_angle != _sun_angle) {
+ update_sky_color();
+ _prev_sun_angle = _sun_angle;
+ }
+}
+
+void FGLight::update_sky_color () {
// if the 4th field is 0.0, this specifies a direction ...
- const GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
- // base sky color
+ const GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
const GLfloat base_sky_color[4] = { 0.39, 0.50, 0.74, 1.0 };
- // base fog color
- const GLfloat base_fog_color[4] = { 0.84, 0.87, 1.0, 1.0 };
- float deg, ambient, diffuse, specular, sky_brightness;
+ const GLfloat base_fog_color[4] = { 0.84, 0.87, 1.0, 1.0 };
SG_LOG( SG_EVENT, SG_INFO, "Updating light parameters." );
// calculate lighting parameters based on sun's relative angle to
// local up
- deg = sun_angle * SGD_RADIANS_TO_DEGREES;
+ float deg = _sun_angle * SGD_RADIANS_TO_DEGREES;
SG_LOG( SG_EVENT, SG_INFO, " Sun angle = " << deg );
- ambient = ambient_tbl->interpolate( deg );
- diffuse = diffuse_tbl->interpolate( deg );
- specular = specular_tbl->interpolate( deg );
- sky_brightness = sky_tbl->interpolate( deg );
+ float ambient = _ambient_tbl->interpolate( deg );
+ float diffuse = _diffuse_tbl->interpolate( deg );
+ float specular = _specular_tbl->interpolate( deg );
+ float sky_brightness = _sky_tbl->interpolate( deg );
SG_LOG( SG_EVENT, SG_INFO,
" ambient = " << ambient << " diffuse = " << diffuse
// if ( sky_brightness < 0.1 ) { sky_brightness = 0.1; }
// set sky color
- sky_color[0] = base_sky_color[0] * sky_brightness;
- sky_color[1] = base_sky_color[1] * sky_brightness;
- sky_color[2] = base_sky_color[2] * sky_brightness;
- sky_color[3] = base_sky_color[3];
- gamma_correct_rgb( sky_color );
+ _sky_color[0] = base_sky_color[0] * sky_brightness;
+ _sky_color[1] = base_sky_color[1] * sky_brightness;
+ _sky_color[2] = base_sky_color[2] * sky_brightness;
+ _sky_color[3] = base_sky_color[3];
+ gamma_correct_rgb( _sky_color );
// set cloud and fog color
- cloud_color[0] = fog_color[0] = base_fog_color[0] * sky_brightness;
- cloud_color[1] = fog_color[1] = base_fog_color[1] * sky_brightness;
- cloud_color[2] = fog_color[2] = base_fog_color[2] * sky_brightness;
- cloud_color[3] = fog_color[3] = base_fog_color[3];
- gamma_correct_rgb( fog_color );
+ _cloud_color[0] = _fog_color[0] = base_fog_color[0] * sky_brightness;
+ _cloud_color[1] = _fog_color[1] = base_fog_color[1] * sky_brightness;
+ _cloud_color[2] = _fog_color[2] = base_fog_color[2] * sky_brightness;
+ _cloud_color[3] = _fog_color[3] = base_fog_color[3];
+ gamma_correct_rgb( _fog_color );
// adjust the cloud colors for sunrise/sunset effects (darken them)
- if (sun_angle > 1.0) {
- float sun2 = sqrt(sun_angle);
- cloud_color[0] /= sun2;
- cloud_color[1] /= sun2;
- cloud_color[2] /= sun2;
+ if (_sun_angle > 1.0) {
+ float sun2 = sqrt(_sun_angle);
+ _cloud_color[0] /= sun2;
+ _cloud_color[1] /= sun2;
+ _cloud_color[2] /= sun2;
}
- gamma_correct_rgb( cloud_color );
+ gamma_correct_rgb( _cloud_color );
float *sun_color = thesky->get_sun_color();
- scene_ambient[0] = ((sun_color[0]*0.25 + cloud_color[0]*0.75) + ambient) / 2;
- scene_ambient[1] = ((sun_color[1]*0.25 + cloud_color[1]*0.75) + ambient) / 2;
- scene_ambient[2] = ((sun_color[2]*0.25 + cloud_color[2]*0.75) + ambient) / 2;
- scene_ambient[3] = 1.0;
+ _scene_ambient[0] = ((sun_color[0]*0.25 + _cloud_color[0]*0.75) + ambient) / 2;
+ _scene_ambient[1] = ((sun_color[1]*0.25 + _cloud_color[1]*0.75) + ambient) / 2;
+ _scene_ambient[2] = ((sun_color[2]*0.25 + _cloud_color[2]*0.75) + ambient) / 2;
+ _scene_ambient[3] = 1.0;
- scene_diffuse[0] = (sun_color[0]*0.25 + fog_color[0]*0.75) * diffuse;
- scene_diffuse[1] = (sun_color[1]*0.25 + fog_color[1]*0.75) * diffuse;
- scene_diffuse[2] = (sun_color[2]*0.25 + fog_color[2]*0.75) * diffuse;
- scene_diffuse[3] = 1.0;
+ _scene_diffuse[0] = (sun_color[0]*0.25 + _fog_color[0]*0.75) * diffuse;
+ _scene_diffuse[1] = (sun_color[1]*0.25 + _fog_color[1]*0.75) * diffuse;
+ _scene_diffuse[2] = (sun_color[2]*0.25 + _fog_color[2]*0.75) * diffuse;
+ _scene_diffuse[3] = 1.0;
- scene_specular[0] = sun_color[0] * specular;
- scene_specular[1] = sun_color[1] * specular;
- scene_specular[2] = sun_color[2] * specular;
- scene_specular[3] = 1.0;
+ _scene_specular[0] = sun_color[0] * specular;
+ _scene_specular[1] = sun_color[1] * specular;
+ _scene_specular[2] = sun_color[2] * specular;
+ _scene_specular[3] = 1.0;
}
// calculate fog color adjusted for sunrise/sunset effects
-void fgLIGHT::UpdateAdjFog( void ) {
+void FGLight::update_adj_fog_color () {
double heading = globals->get_current_view()->getHeading_deg()
* SGD_DEGREES_TO_RADIANS;
// direction we are looking
// Do some sanity checking ...
- if ( sun_rotation < -2.0 * SGD_2PI || sun_rotation > 2.0 * SGD_2PI ) {
- SG_LOG( SG_EVENT, SG_ALERT, "Sun rotation bad = " << sun_rotation );
+ if ( _sun_rotation < -2.0 * SGD_2PI || _sun_rotation > 2.0 * SGD_2PI ) {
+ SG_LOG( SG_EVENT, SG_ALERT, "Sun rotation bad = " << _sun_rotation );
exit(-1);
}
// first determine the difference between our view angle and local
// direction to the sun
- rotation = -(sun_rotation + SGD_PI) - heading + heading_offset;
+ rotation = -(_sun_rotation + SGD_PI) - heading + heading_offset;
while ( rotation < 0 ) {
rotation += SGD_2PI;
}
//
float *sun_color = thesky->get_sun_color();
- gamma_restore_rgb( fog_color );
+ gamma_restore_rgb( _fog_color );
// Calculate the fog color in the direction of the sun for
// sunrise/sunset effects.
//
- float s_red = (fog_color[0] + 2 * sun_color[0]*sun_color[0]) / 3;
- float s_green = (fog_color[1] + 2 * sun_color[1]*sun_color[1]) / 3;
- float s_blue = (fog_color[2] + 2 * sun_color[2]) / 3;
+ float s_red = (_fog_color[0] + 2 * sun_color[0]*sun_color[0]) / 3;
+ float s_green = (_fog_color[1] + 2 * sun_color[1]*sun_color[1]) / 3;
+ float s_blue = (_fog_color[2] + 2 * sun_color[2]) / 3;
// interpolate beween the sunrise/sunset color and the color
// at the opposite direction of this effect. Take in account
av = 45000;
float avf = 0.87 - (45000 - av) / 83333.33;
- float sif = 0.5 - cos(sun_angle*2)/2;
+ float sif = 0.5 - cos(_sun_angle*2)/2;
float rf1 = fabs((rotation - SGD_PI) / SGD_PI); // 0.0 .. 1.0
float rf2 = avf * pow(rf1 * rf1, 1/sif);
float rf3 = 0.94 - rf2;
- adj_fog_color[0] = rf3 * fog_color[0] + rf2 * s_red;
- adj_fog_color[1] = rf3 * fog_color[1] + rf2 * s_green;
- adj_fog_color[2] = rf3 * fog_color[2] + rf2 * s_blue;
- gamma_correct_rgb( adj_fog_color );
+ _adj_fog_color[0] = rf3 * _fog_color[0] + rf2 * s_red;
+ _adj_fog_color[1] = rf3 * _fog_color[1] + rf2 * s_green;
+ _adj_fog_color[2] = rf3 * _fog_color[2] + rf2 * s_blue;
+ gamma_correct_rgb( _adj_fog_color );
// make sure the colors have their original value before they are being
// used by the rest of the program.
//
- gamma_correct_rgb( fog_color );
+ gamma_correct_rgb( _fog_color );
}
-
-// Destructor
-fgLIGHT::~fgLIGHT( void ) {
-}
-
-
# include <windows.h>
#endif
-#include FG_GLUT_H
+#include <GL/gl.h>
#include <plib/sg.h> // plib include
// Define a structure containing the global lighting parameters
-class fgLIGHT {
+class FGLight : public FGSubsystem
+{
- // Lighting look up tables (based on sun angle with local horizon)
- SGInterpTable *ambient_tbl;
- SGInterpTable *diffuse_tbl;
- SGInterpTable *specular_tbl;
- SGInterpTable *sky_tbl;
+private:
-public:
+ /*
+ * Lighting look up tables (based on sun angle with local horizon)
+ */
+ SGInterpTable *_ambient_tbl, *_diffuse_tbl, *_specular_tbl;
+ SGInterpTable *_sky_tbl;
- ///////////////////////////////////////////////////////////
- // position of the sun in various forms
+ /**
+ * position of the sun and moon in various forms
+ */
// in geocentric coordinates
- double sun_lon, sun_gc_lat;
+ double _sun_lon, _sun_gc_lat;
+ double _moon_lon, _moon_gc_lat;
// in cartesian coordiantes
- Point3D fg_sunpos;
+ Point3D _sunpos, _moonpos;
// (in view coordinates)
- sgVec4 sun_vec;
+ sgVec4 _sun_vec, _moon_vec;
// inverse (in view coordinates)
- sgVec4 sun_vec_inv;
+ sgVec4 _sun_vec_inv, _moon_vec_inv;
- // the angle between the sun and the local horizontal (in radians)
- double sun_angle;
+ // the angle between the celestial object and the local horizontal
+ // (in radians)
+ double _sun_angle, _moon_angle;
+ double _prev_sun_angle;
// the rotation around our vertical axis of the sun (relative to
// due south with positive numbers going in the counter clockwise
// direction.) This is the direction we'd need to face if we
- // wanted to travel towards the sun.
- double sun_rotation;
+ // wanted to travel towards celestial object.
+ double _sun_rotation, _moon_rotation;
- ///////////////////////////////////////////////////////////
- // Have the same for the moon. Useful for having some light at night
- // and stuff. I (Durk) also want to use this for adding similar
- // coloring effects to the moon as I did to the sun.
- ///////////////////////////////////////////////////////////
- // position of the moon in various forms
+ /**
+ * Derived lighting values
+ */
- // in geocentric coordinates
- double moon_lon, moon_gc_lat;
+ // ambient, diffuse and specular component
+ GLfloat _scene_ambient[4];
+ GLfloat _scene_diffuse[4];
+ GLfloat _scene_specular[4];
- // in cartesian coordiantes
- Point3D fg_moonpos;
+ // clear sky, fog and cloud color
+ GLfloat _sky_color[4];
+ GLfloat _fog_color[4];
+ GLfloat _cloud_color[4];
- // (in view coordinates)
- GLfloat moon_vec[4];
+ // clear sky and fog color adjusted for sunset effects
+ GLfloat _adj_fog_color[4];
+ GLfloat _adj_sky_color[4];
- // inverse (in view coordinates)
- GLfloat moon_vec_inv[4];
+ double _dt_total;
- // the angle between the moon and the local horizontal (in radians)
- double moon_angle;
+ void update_sky_color ();
+ void update_adj_fog_color ();
- // the rotation around our vertical axis of the moon (relative to
- // due south with positive numbers going in the counter clockwise
- // direction.) This is the direction we'd need to face if we
- // wanted to travel towards the sun.
- double moon_rotation;
+public:
- ///////////////////////////////////////////////////////////
- // Derived lighting values
+ FGLight ();
+ virtual ~FGLight ();
- // ambient component
- GLfloat scene_ambient[4];
+ virtual void init ();
+ virtual void reinit ();
+ virtual void bind ();
+ virtual void unbind ();
+ virtual void update ( double dt );
- // diffuse component
- GLfloat scene_diffuse[4];
- // diffuse component
- GLfloat scene_specular[4];
+ // Color related functions
- // fog color
- GLfloat fog_color[4];
+ inline float *scene_ambient () const { return (float *)_scene_ambient; }
+ inline float *scene_diffuse () const { return (float *)_scene_diffuse; }
+ inline float *scene_specular () const { return (float *)_scene_specular; }
- // fog color adjusted for sunset effects
- GLfloat adj_fog_color[4];
+ inline float *sky_color () const { return (float *)_sky_color; }
+ inline float *cloud_color () const { return (float *)_cloud_color; }
+ inline float *adj_fog_color () const { return (float *)_adj_fog_color; }
- // cloud color
- GLfloat cloud_color[4];
- // clear screen color
- GLfloat sky_color[4];
+ // Sun related functions
- // screen color adjusted for sunset effects
- GLfloat adj_sky_color[4];
+ inline double get_sun_angle () const { return _sun_angle; }
+ inline void set_sun_angle (double a) { _sun_angle = a; }
- // Constructor
- fgLIGHT( void );
+ inline double get_sun_rotation () const { return _sun_rotation; }
+ inline void set_sun_rotation (double r) { _sun_rotation = r; }
- // initialize lighting tables
- void Init( void );
+ inline double get_sun_lon () const { return _sun_lon; }
+ inline void set_sun_lon (double l) { _sun_lon = l; }
- // update lighting parameters based on current sun position
- void Update( void);
+ inline double get_sun_gc_lat () const { return _sun_gc_lat; }
+ inline void set_sun_gc_lat (double l) { _sun_gc_lat = l; }
- // calculate fog color adjusted for sunrise/sunset effects
- void UpdateAdjFog( void );
+ inline Point3D get_sunpos () const { return _sunpos; }
+ inline void set_sunpos (Point3D p) { _sunpos = p; }
- // Destructor
- ~fgLIGHT( void );
-};
+ inline float *sun_vec () const { return (float *)_sun_vec; }
+ inline float *sun_vec_inv () const { return (float *)_sun_vec_inv; }
+
+
+ // Moon related functions
+
+ inline double get_moon_angle () const { return _moon_angle; }
+ inline void set_moon_angle (double a) { _moon_angle = a; }
+ inline double get_moon_rotation () const { return _moon_rotation; }
+ inline void set_moon_rotation (double r) { _moon_rotation = r; }
-// Global shared light parameter structure
-extern fgLIGHT cur_light_params;
+ inline double get_moon_lon () const { return _moon_lon; }
+ inline void set_moon_lon (double l) { _moon_lon = l; }
+ inline double get_moon_gc_lat () const { return _moon_gc_lat; }
+ inline void set_moon_gc_lat (double l) { _moon_gc_lat = l; }
+
+ inline Point3D get_moonpos () const { return _moonpos; }
+ inline void set_moonpos (Point3D p) { _moonpos = p; }
+
+ inline float *moon_vec () const { return (float *)_moon_vec; }
+ inline float *moon_vec_inv () const { return (float *)_moon_vec_inv; }
+};
#endif // _LIGHT_HXX
+
// update the cur_time_params structure with the current moon position
void fgUpdateMoonPos( void ) {
- fgLIGHT *l;
- FGViewer *v;
sgVec3 nup, nmoon;
- Point3D p, rel_moonpos;
+ Point3D rel_moonpos;
double dot, east_dot;
double moon_gd_lat, sl_radius;
// surface direction to go to head towards moon
sgVec3 surface_to_moon;
- l = &cur_light_params;
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
SGTime *t = globals->get_time_params();
- v = globals->get_current_view();
+ FGViewer *v = globals->get_current_view();
SG_LOG( SG_EVENT, SG_INFO, " Updating Moon position" );
- // (not sure why there was two)
- // fgMoonPosition(t->cur_time, &l->moon_lon, &moon_gd_lat);
- fgMoonPositionGST(t->getGst(), &l->moon_lon, &moon_gd_lat);
+ double moon_l;
+ fgMoonPositionGST(t->getGst(), &moon_l, &moon_gd_lat);
+ l->set_moon_lon(moon_l);
- sgGeodToGeoc(moon_gd_lat, 0.0, &sl_radius, &l->moon_gc_lat);
+ sgGeodToGeoc(moon_gd_lat, 0.0, &sl_radius, &moon_l);
+ l->set_moon_gc_lat(moon_l);
- p = Point3D( l->moon_lon, l->moon_gc_lat, sl_radius );
- l->fg_moonpos = sgPolarToCart3d(p);
+ Point3D p = Point3D( l->get_moon_lon(), l->get_moon_gc_lat(), sl_radius );
+ l->set_moonpos( sgPolarToCart3d(p) );
SG_LOG( SG_EVENT, SG_INFO, " t->cur_time = " << t->get_cur_time() );
SG_LOG( SG_EVENT, SG_INFO,
" Moon Geodetic lat = " << moon_gd_lat
- << " Geocentric lat = " << l->moon_gc_lat );
+ << " Geocentric lat = " << l->get_moon_gc_lat() );
// update the sun light vector
- sgSetVec4( l->moon_vec,
- l->fg_moonpos.x(), l->fg_moonpos.y(), l->fg_moonpos.z(), 0.0 );
- sgNormalizeVec4( l->moon_vec );
- sgCopyVec4( l->moon_vec_inv, l->moon_vec );
- sgNegateVec4( l->moon_vec_inv );
+ sgSetVec4( l->moon_vec(), l->get_moonpos().x(),
+ l->get_moonpos().y(), l->get_moonpos().z(), 0.0 );
+ sgNormalizeVec4( l->moon_vec() );
+ sgCopyVec4( l->moon_vec_inv(), l->moon_vec() );
+ sgNegateVec4( l->moon_vec_inv() );
// make sure these are directional light sources only
- l->moon_vec[3] = l->moon_vec_inv[3] = 0.0;
+ l->moon_vec()[3] = l->moon_vec_inv()[3] = 0.0;
// cout << " l->moon_vec = " << l->moon_vec[0] << "," << l->moon_vec[1]
// << ","<< l->moon_vec[2] << endl;
// calculate the moon's relative angle to local up
sgCopyVec3( nup, v->get_world_up() );
- sgSetVec3( nmoon, l->fg_moonpos.x(), l->fg_moonpos.y(), l->fg_moonpos.z() );
+ sgSetVec3( nmoon, l->get_moonpos().x(),
+ l->get_moonpos().y(), l->get_moonpos().z() );
sgNormalizeVec3(nup);
sgNormalizeVec3(nmoon);
// cout << "nup = " << nup[0] << "," << nup[1] << ","
// cout << "nmoon = " << nmoon[0] << "," << nmoon[1] << ","
// << nmoon[2] << endl;
- l->moon_angle = acos( sgScalarProductVec3( nup, nmoon ) );
+ l->set_moon_angle( acos( sgScalarProductVec3( nup, nmoon ) ) );
SG_LOG( SG_EVENT, SG_INFO, "moon angle relative to current location = "
- << l->moon_angle );
+ << l->get_moon_angle() );
// calculate vector to moon's position on the earth's surface
Point3D vp( v->get_view_pos()[0],
v->get_view_pos()[1],
v->get_view_pos()[2] );
- rel_moonpos = l->fg_moonpos - ( vp + globals->get_scenery()->get_center() );
+ rel_moonpos = l->get_moonpos()-(vp + globals->get_scenery()->get_center());
sgSetVec3( to_moon, rel_moonpos.x(), rel_moonpos.y(), rel_moonpos.z() );
// printf( "Vector to moon = %.2f %.2f %.2f\n",
// to_moon[0], to_moon[1], to_moon[2]);
// cout << " Dot product = " << dot << endl;
if ( east_dot >= 0 ) {
- l->moon_rotation = acos(dot);
+ l->set_moon_rotation( acos(dot) );
} else {
- l->moon_rotation = -acos(dot);
+ l->set_moon_rotation( -acos(dot) );
}
// cout << " Sky needs to rotate = " << angle << " rads = "
// << angle * SGD_RADIANS_TO_DEGREES << " degrees." << endl;
// update the cur_time_params structure with the current sun position
void fgUpdateSunPos( void ) {
- fgLIGHT *l;
- FGViewer *v;
sgVec3 nup, nsun;
- Point3D p, rel_sunpos;
+ Point3D rel_sunpos;
double dot, east_dot;
double sun_gd_lat, sl_radius;
// surface direction to go to head towards sun
sgVec3 surface_to_sun;
- l = &cur_light_params;
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
SGTime *t = globals->get_time_params();
- v = globals->get_current_view();
+ FGViewer *v = globals->get_current_view();
SG_LOG( SG_EVENT, SG_INFO, " Updating Sun position" );
SG_LOG( SG_EVENT, SG_INFO, " Gst = " << t->getGst() );
- fgSunPositionGST(t->getGst(), &l->sun_lon, &sun_gd_lat);
+ double sun_l;
+ fgSunPositionGST(t->getGst(), &sun_l, &sun_gd_lat);
+ l->set_sun_lon(sun_l);
- sgGeodToGeoc(sun_gd_lat, 0.0, &sl_radius, &l->sun_gc_lat);
+ sgGeodToGeoc(sun_gd_lat, 0.0, &sl_radius, &sun_l);
+ l->set_sun_gc_lat(sun_l);
- p = Point3D( l->sun_lon, l->sun_gc_lat, sl_radius );
- l->fg_sunpos = sgPolarToCart3d(p);
+ Point3D p = Point3D( l->get_sun_lon(), l->get_sun_gc_lat(), sl_radius );
+ l->set_sunpos( sgPolarToCart3d(p) );
SG_LOG( SG_EVENT, SG_INFO, " t->cur_time = " << t->get_cur_time() );
SG_LOG( SG_EVENT, SG_INFO,
" Sun Geodetic lat = " << sun_gd_lat
- << " Geocentric lat = " << l->sun_gc_lat );
+ << " Geocentric lat = " << l->get_sun_gc_lat() );
// update the sun light vector
- sgSetVec4( l->sun_vec,
- l->fg_sunpos.x(), l->fg_sunpos.y(), l->fg_sunpos.z(), 0.0 );
- sgNormalizeVec4( l->sun_vec );
- sgCopyVec4( l->sun_vec_inv, l->sun_vec );
- sgNegateVec4( l->sun_vec_inv );
+ sgSetVec4( l->sun_vec(), l->get_sunpos().x(),
+ l->get_sunpos().y(), l->get_sunpos().z(), 0.0 );
+ sgNormalizeVec4( l->sun_vec() );
+ sgCopyVec4( l->sun_vec_inv(), l->sun_vec() );
+ sgNegateVec4( l->sun_vec_inv() );
// make sure these are directional light sources only
- l->sun_vec[3] = l->sun_vec_inv[3] = 0.0;
+ l->sun_vec()[3] = l->sun_vec_inv()[3] = 0.0;
// cout << " l->sun_vec = " << l->sun_vec[0] << "," << l->sun_vec[1]
// << ","<< l->sun_vec[2] << endl;
// calculate the sun's relative angle to local up
sgCopyVec3( nup, v->get_world_up() );
- sgSetVec3( nsun, l->fg_sunpos.x(), l->fg_sunpos.y(), l->fg_sunpos.z() );
+ sgSetVec3( nsun, l->get_sunpos().x(),
+ l->get_sunpos().y(), l->get_sunpos().z() );
sgNormalizeVec3(nup);
sgNormalizeVec3(nsun);
// cout << "nup = " << nup[0] << "," << nup[1] << ","
// cout << "nsun = " << nsun[0] << "," << nsun[1] << ","
// << nsun[2] << endl;
- l->sun_angle = acos( sgScalarProductVec3 ( nup, nsun ) );
+ l->set_sun_angle( acos( sgScalarProductVec3 ( nup, nsun ) ) );
SG_LOG( SG_EVENT, SG_INFO, "sun angle relative to current location = "
- << l->sun_angle );
+ << l->get_sun_angle() );
// calculate vector to sun's position on the earth's surface
Point3D vp( v->get_view_pos()[0],
v->get_view_pos()[1],
v->get_view_pos()[2] );
- rel_sunpos = l->fg_sunpos - ( vp + globals->get_scenery()->get_center() );
+ rel_sunpos = l->get_sunpos() - (vp + globals->get_scenery()->get_center());
sgSetVec3( to_sun, rel_sunpos.x(), rel_sunpos.y(), rel_sunpos.z() );
// printf( "Vector to sun = %.2f %.2f %.2f\n",
// v->to_sun[0], v->to_sun[1], v->to_sun[2]);
// cout << " Dot product = " << dot << endl;
if ( east_dot >= 0 ) {
- l->sun_rotation = acos(dot);
+ l->set_sun_rotation( acos(dot) );
} else {
- l->sun_rotation = -acos(dot);
+ l->set_sun_rotation( -acos(dot) );
}
// cout << " Sky needs to rotate = " << angle << " rads = "
// << angle * SGD_RADIANS_TO_DEGREES << " degrees." << endl;
zone.str() );
}
-
-// update sky and lighting parameters
-void fgUpdateSkyAndLightingParams() {
- fgUpdateSunPos();
- fgUpdateMoonPos();
- cur_light_params.Update();
-}
// periodic time updater
void fgUpdateLocalTime();
-// update sky and lighting parameters
-void fgUpdateSkyAndLightingParams();
-
#endif // _LIGHT_HXX
+