1
0
Fork 0

Convert fgLIGHT to FGLight and make it FGSubsystem compatible. Let the subsystem manager handle it and let FGLight::update() handle the repositioning of the sun and the moon.

This commit is contained in:
ehofman 2003-09-20 09:38:32 +00:00
parent 7807a68fa3
commit a33ad90ed7
15 changed files with 306 additions and 305 deletions

View file

@ -381,7 +381,9 @@ FGPanel::draw()
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;
@ -943,7 +945,9 @@ FGTexturedLayer::draw ()
// 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;

View file

@ -81,8 +81,6 @@ void reInit(puObject *cb)
fgReInitSubsystems();
globals->get_tile_mgr()->update( fgGetDouble("/environment/visibility-m") );
cur_light_params.Update();
fgReshape( xsize, ysize );

View file

@ -468,17 +468,6 @@ do_tile_cache_reload (const SGPropertyNode * arg)
}
/**
* Update the lighting manually.
*/
static bool
do_lighting_update (const SGPropertyNode * arg)
{
fgUpdateSkyAndLightingParams();
return true;
}
/**
* Update the lighting manually.
*/
@ -561,8 +550,6 @@ do_timeofday (const SGPropertyNode * arg)
cur_time_override->getLongValue(),
globals->get_warp() );
fgUpdateSkyAndLightingParams();
return true;
}
@ -994,7 +981,6 @@ static struct {
{ "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 },

View file

@ -1391,8 +1391,6 @@ void fgInitTimeOffset() {
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
@ -1407,7 +1405,7 @@ bool fgInitSubsystems() {
// 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, "========== ==========");
@ -1483,26 +1481,7 @@ bool fgInitSubsystems() {
// 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.
@ -1823,9 +1802,6 @@ void fgReInitSubsystems()
globals->get_controls()->reset_all();
globals->get_autopilot()->reset();
fgUpdateSunPos();
fgUpdateMoonPos();
cur_light_params.Update();
fgUpdateLocalTime();
if ( !freeze ) {

View file

@ -334,7 +334,6 @@ setDateString (const char * date_string)
double lat = current_aircraft.fdm_state->get_Latitude();
globals->set_warp(warp);
st->update(lon, lat, cur_time_override->getLongValue(), warp);
fgUpdateSkyAndLightingParams();
}
/**

View file

@ -73,7 +73,8 @@ FGGlobals::FGGlobals() :
channel_options_list( NULL ),
scenery( NULL ),
tile_mgr( NULL ),
io( new FGIO )
io( new FGIO ),
cur_light_params( NULL )
{
}

View file

@ -68,6 +68,7 @@ class FGAircraftModel;
class FGAutopilot;
class FGControls;
class FGIO;
class FGLight;
class FGModelMgr;
class FGScenery;
#ifdef FG_MPLAYER_AS
@ -181,7 +182,11 @@ private:
// Tile manager
FGTileMgr *tile_mgr;
FGIO* io;
// Input/Ouput subsystem
FGIO *io;
// light parameters
FGLight *cur_light_params;
#ifdef FG_MPLAYER_AS
//Mulitplayer managers
@ -333,8 +338,7 @@ public:
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.

View file

@ -250,9 +250,8 @@ void fgBuildRenderStates( void ) {
// 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 ...
@ -271,7 +270,7 @@ void fgInitVisuals( void ) {
// 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);
@ -311,10 +310,10 @@ void trRenderFrame( void ) {
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 );
@ -324,7 +323,7 @@ void trRenderFrame( void ) {
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
@ -333,7 +332,7 @@ void trRenderFrame( void ) {
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 ) ;
@ -345,7 +344,7 @@ void trRenderFrame( void ) {
// 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() );
@ -392,7 +391,7 @@ void fgRenderFrame() {
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
@ -472,13 +471,13 @@ void fgRenderFrame() {
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 );
@ -526,12 +525,13 @@ void fgRenderFrame() {
*/
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();
@ -565,8 +565,8 @@ void fgRenderFrame() {
// 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;
}
@ -582,7 +582,7 @@ void fgRenderFrame() {
* 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();
@ -598,11 +598,11 @@ void fgRenderFrame() {
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
@ -610,9 +610,9 @@ void fgRenderFrame() {
// 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 );
@ -679,7 +679,7 @@ void fgRenderFrame() {
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
@ -902,8 +902,6 @@ void fgUpdateTimeDepCalcs() {
//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.
@ -950,8 +948,6 @@ void fgUpdateTimeDepCalcs() {
// 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(),
@ -1030,7 +1026,6 @@ static void fgMainLoop( void ) {
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) {
@ -1108,10 +1103,6 @@ static void fgMainLoop( void ) {
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,
@ -1365,7 +1356,6 @@ static void fgIdleFunction ( void ) {
fgReshape( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
fgUpdateSkyAndLightingParams();
}
if ( idle_state == 1000 ) {
@ -2042,13 +2032,14 @@ void fgUpdateDCS (void) {
// 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;

View file

@ -319,6 +319,7 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
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
@ -354,7 +355,7 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
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 ) {
@ -397,7 +398,7 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
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);
@ -437,7 +438,7 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
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);

View file

@ -63,66 +63,102 @@ SG_USING_STD(string);
#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 ambient, diffuse and specular tables
SGPath ambient_path = path;
ambient_path.append( "Lighting/ambient" );
_ambient_tbl = new SGInterpTable( ambient_path.str() );
// initialize diffuse table
diffuse_tbl = new SGInterpTable( diffuse.str() );
// initialize diffuse table
specular_tbl = new SGInterpTable( specular.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
@ -135,49 +171,49 @@ void fgLIGHT::Update( void ) {
// 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;
@ -190,8 +226,8 @@ void fgLIGHT::UpdateAdjFog( void ) {
// 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);
}
@ -209,7 +245,7 @@ void fgLIGHT::UpdateAdjFog( void ) {
// 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;
}
@ -221,14 +257,14 @@ void fgLIGHT::UpdateAdjFog( void ) {
//
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
@ -239,26 +275,20 @@ void fgLIGHT::UpdateAdjFog( void ) {
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 ) {
}

View file

@ -38,7 +38,7 @@
# include <windows.h>
#endif
#include FG_GLUT_H
#include <GL/gl.h>
#include <plib/sg.h> // plib include
@ -47,114 +47,132 @@
// 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; }
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; }
};
// Global shared light parameter structure
extern fgLIGHT cur_light_params;
#endif // _LIGHT_HXX

View file

@ -336,10 +336,8 @@ static void fgMoonPositionGST(double gst, double *lon, double *lat) {
// 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;
@ -350,41 +348,43 @@ void fgUpdateMoonPos( void ) {
// 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] << ","
@ -392,15 +392,15 @@ void fgUpdateMoonPos( void ) {
// 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]);
@ -432,9 +432,9 @@ void fgUpdateMoonPos( void ) {
// 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;

View file

@ -244,10 +244,8 @@ void fgSunPositionGST(double gst, double *lon, double *lat) {
// 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;
@ -258,40 +256,44 @@ void fgUpdateSunPos( void ) {
// 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] << ","
@ -299,15 +301,15 @@ void fgUpdateSunPos( void ) {
// 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]);
@ -340,9 +342,9 @@ void fgUpdateSunPos( void ) {
// 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;

View file

@ -61,10 +61,3 @@ void fgUpdateLocalTime() {
zone.str() );
}
// update sky and lighting parameters
void fgUpdateSkyAndLightingParams() {
fgUpdateSunPos();
fgUpdateMoonPos();
cur_light_params.Update();
}

View file

@ -38,8 +38,6 @@
// periodic time updater
void fgUpdateLocalTime();
// update sky and lighting parameters
void fgUpdateSkyAndLightingParams();
#endif // _LIGHT_HXX