From dbf997a2d3f38c05fd3844f77a1eca4699f4db1b Mon Sep 17 00:00:00 2001 From: curt Date: Fri, 1 Nov 2002 21:56:48 +0000 Subject: [PATCH] Put taxiway lights in their own scene graph so we can adjust their brightness (or fog punch through) independently from the ground or runway lighting. --- src/Main/main.cxx | 29 +++++++--- src/Objects/obj.cxx | 7 ++- src/Objects/obj.hxx | 1 + src/Objects/pt_lights.cxx | 2 - src/Scenery/scenery.cxx | 3 + src/Scenery/scenery.hxx | 8 +++ src/Scenery/tileentry.cxx | 116 +++++++++++++++++++++++++++++++++++--- src/Scenery/tileentry.hxx | 8 ++- src/Scenery/tilemgr.cxx | 3 +- 9 files changed, 153 insertions(+), 24 deletions(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 1c1de3625..ca1474683 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -220,7 +220,8 @@ static const double m_log01 = -log( 0.01 ); static const double sqrt_m_log01 = sqrt( m_log01 ); static GLfloat fog_exp_density; static GLfloat fog_exp2_density; -static GLfloat fog_exp2_punch_through; +static GLfloat rwy_exp2_punch_through; +static GLfloat taxi_exp2_punch_through; #ifdef FG_NETWORK_OLK ssgSelector *fgd_sel = NULL; @@ -415,11 +416,12 @@ void trRenderFrame( void ) { ssgCullAndDraw( globals->get_scenery()->get_scene_graph() ); // draw the lights - glFogf (GL_FOG_DENSITY, fog_exp2_punch_through); + glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through); ssgSetNearFar( scene_nearplane, scene_farplane ); - ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() ); ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() ); + ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() ); + if (fgGetBool("/environment/clouds/status")) thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER ); @@ -465,7 +467,8 @@ void fgRenderFrame() { fog_exp_density = m_log01 / actual_visibility; fog_exp2_density = sqrt_m_log01 / actual_visibility; - fog_exp2_punch_through = sqrt_m_log01 / ( actual_visibility * 2.5 ); + rwy_exp2_punch_through = sqrt_m_log01 / ( actual_visibility * 2.5 ); + taxi_exp2_punch_through = sqrt_m_log01 / ( actual_visibility * 1.5 ); } // double angle; @@ -734,12 +737,9 @@ void fgRenderFrame() { // change state for lighting here - // draw lighting - // Set punch through fog density - glFogf (GL_FOG_DENSITY, fog_exp2_punch_through); - + // draw runway lighting + glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through); ssgSetNearFar( scene_nearplane, scene_farplane ); - ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() ); #ifdef FG_EXPERIMENTAL_LIGHTING // Enable states for drawing points with GL_extension @@ -762,7 +762,15 @@ void fgRenderFrame() { glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glPolygonMode(GL_FRONT, GL_POINT); + + // draw runway lighting ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() ); + + // change punch through and then draw taxi lighting + glFogf (GL_FOG_DENSITY, taxi_exp2_punch_through); + ssgCullAndDraw( globals->get_scenery()->get_taxi_lights_root() ); + + // clean up lighting glPolygonMode(GL_FRONT, GL_FILL); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); @@ -787,6 +795,9 @@ void fgRenderFrame() { glDisable(GL_POINT_SMOOTH); #endif + // draw ground lighting + ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() ); + if ( fgGetBool("/sim/rendering/skyblend") ) { // draw the sky cloud layers if (fgGetBool("/environment/clouds/status")) { diff --git a/src/Objects/obj.cxx b/src/Objects/obj.cxx index 1160f7eb5..da11afd28 100644 --- a/src/Objects/obj.cxx +++ b/src/Objects/obj.cxx @@ -1368,6 +1368,7 @@ bool fgBinObjLoad( const string& path, const bool is_base, double *bounding_radius, ssgBranch* geometry, ssgBranch* rwy_lights, + ssgBranch* taxi_lights, ssgVertexArray *ground_lights ) { SGBinObject obj; @@ -1412,7 +1413,11 @@ bool fgBinObjLoad( const string& path, const bool is_base, // commenting this out to avoid a plib runtime warning. // branch->setCallback( SSG_CALLBACK_PREDRAW, // runway_lights_predraw ); - rwy_lights->addKid( branch ); + if ( pt_materials[i].substr(0, 16) == "RWY_BLUE_TAXIWAY" ) { + taxi_lights->addKid( branch ); + } else { + rwy_lights->addKid( branch ); + } } else { material = pt_materials[i]; tex_index.clear(); diff --git a/src/Objects/obj.hxx b/src/Objects/obj.hxx index 803e7c4d5..195cceabf 100644 --- a/src/Objects/obj.hxx +++ b/src/Objects/obj.hxx @@ -57,6 +57,7 @@ bool fgBinObjLoad( const string& path, const bool is_base, double *bounding_radius, ssgBranch* geometry, ssgBranch* rwy_lights, + ssgBranch* taxi_lights, ssgVertexArray *ground_lights ); // Load an ascii object file diff --git a/src/Objects/pt_lights.cxx b/src/Objects/pt_lights.cxx index 47358c045..161034441 100644 --- a/src/Objects/pt_lights.cxx +++ b/src/Objects/pt_lights.cxx @@ -491,8 +491,6 @@ ssgBranch *gen_directional_lights( const point_list &nodes, const string &material, sgVec3 up ) { - ssgBranch *result; - sgVec3 nup; sgNormalizeVec3( nup, up ); diff --git a/src/Scenery/scenery.cxx b/src/Scenery/scenery.cxx index 5323c05cb..50a8303d8 100644 --- a/src/Scenery/scenery.cxx +++ b/src/Scenery/scenery.cxx @@ -80,6 +80,9 @@ void FGScenery::init() { rwy_lights_root = new ssgRoot; rwy_lights_root->setName( "Runway Lighting Root" ); + + taxi_lights_root = new ssgRoot; + taxi_lights_root->setName( "Taxi Lighting Root" ); } diff --git a/src/Scenery/scenery.hxx b/src/Scenery/scenery.hxx index aa9e11103..4d506e4b7 100644 --- a/src/Scenery/scenery.hxx +++ b/src/Scenery/scenery.hxx @@ -65,6 +65,7 @@ class FGScenery : public FGSubsystem { ssgBranch *terrain_branch; ssgRoot *gnd_lights_root; ssgRoot *rwy_lights_root; + ssgRoot *taxi_lights_root; ssgBranch *models_branch; ssgBranch *aircraft_branch; @@ -111,6 +112,13 @@ public: rwy_lights_root = r; } + inline ssgRoot *get_taxi_lights_root () const { + return taxi_lights_root; + } + inline void set_taxi_lights_root (ssgRoot *r) { + taxi_lights_root = r; + } + inline ssgBranch *get_models_branch () const { return models_branch; } diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index 3536d469b..d8ba4e880 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -55,6 +55,7 @@ FGTileEntry::FGTileEntry ( const SGBucket& b ) tile_bucket( b ), terra_transform( new ssgTransform ), rwy_lights_transform( new ssgTransform ), + taxi_lights_transform( new ssgTransform ), terra_range( new ssgRangeSelector ), loaded(false), pending_models(0), @@ -786,13 +787,21 @@ bool FGTileEntry::free_tile() { free_tracker |= GROUND_LIGHTS; } } else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_transform ) { - // delete the terrain lighting branch (this should already have been - // disconnected from the scene graph) + // delete the runway lighting branch (this should already have + // been disconnected from the scene graph) SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING rwy_lights_transform" ); if ( fgPartialFreeSSGtree( rwy_lights_transform, delete_size ) == 0 ) { ssgDeRefDelete( rwy_lights_transform ); free_tracker |= RWY_LIGHTS; } + } else if ( !(free_tracker & TAXI_LIGHTS) && taxi_lights_transform ) { + // delete the taxi lighting branch (this should already have been + // disconnected from the scene graph) + SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING taxi_lights_transform" ); + if ( fgPartialFreeSSGtree( taxi_lights_transform, delete_size ) == 0 ) { + ssgDeRefDelete( taxi_lights_transform ); + free_tracker |= TAXI_LIGHTS; + } } else if ( !(free_tracker & LIGHTMAPS) && lightmaps_transform ) { // ADA // delete the terrain lighting branch (this should already have been @@ -924,6 +933,49 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { // } } + if ( taxi_lights_transform ) { + // we need to lift the lights above the terrain to avoid + // z-buffer fighting. We do this based on our altitude and + // the distance this tile is away from scenery center. + + sgVec3 lift_vec; + sgCopyVec3( lift_vec, up ); + + // we fudge agl by 30 meters so that the lifting function + // doesn't phase in until we are > 30m agl. + double agl; + agl = globals->get_current_view()->getAltitudeASL_ft() + * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev() + - 30.0; + if ( agl < 0.0 ) { + agl = 0.0; + } + + if ( general.get_glDepthBits() > 16 ) { + sgScaleVec3( lift_vec, 0.0 + agl / 500.0 ); + } else { + sgScaleVec3( lift_vec, 0.0 + agl / 20.0 ); + } + + sgVec3 lt_trans; + sgCopyVec3( lt_trans, sgTrans ); + + sgAddVec3( lt_trans, lift_vec ); + taxi_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; + // if ( sun_angle > 95 ) { + // gnd_lights_brightness->select(0x04); + // } else if ( sun_angle > 92 ) { + // gnd_lights_brightness->select(0x02); + // } else if ( sun_angle > 89 ) { + // gnd_lights_brightness->select(0x01); + // } else { + // gnd_lights_brightness->select(0x00); + // } + } + // ADA // Transform & Render runway lights - 23 Mar 2001 sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() ); @@ -1067,16 +1119,18 @@ ssgLeaf* FGTileEntry::gen_lights( ssgVertexArray *lights, int inc, float bright bool FGTileEntry::obj_load( const std::string& path, - ssgBranch* geometry, - ssgBranch* rwy_lights, - ssgVertexArray* ground_lights, bool is_base ) + ssgBranch* geometry, + ssgBranch* rwy_lights, + ssgBranch* taxi_lights, + ssgVertexArray* ground_lights, bool is_base ) { Point3D c; // returned center point double br; // returned bounding radius // try loading binary format if ( fgBinObjLoad( path, is_base, - &c, &br, geometry, rwy_lights, ground_lights ) ) + &c, &br, geometry, + rwy_lights, taxi_lights, ground_lights ) ) { if ( is_base ) { center = c; @@ -1158,7 +1212,7 @@ FGTileEntry::load( const SGPath& base, bool is_base ) ssgBranch *geometry = new ssgBranch; if ( obj_load( custom_path.str(), - geometry, NULL, light_pts, true ) ) + geometry, NULL, NULL, light_pts, true ) ) { new_tile -> addKid( geometry ); } else { @@ -1174,8 +1228,10 @@ FGTileEntry::load( const SGPath& base, bool is_base ) ssgBranch *geometry = new ssgBranch; ssgBranch *rwy_lights = new ssgBranch; + ssgBranch *taxi_lights = new ssgBranch; if ( obj_load( custom_path.str(), - geometry, rwy_lights, NULL, false ) ) + geometry, rwy_lights, taxi_lights, + NULL, false ) ) { if ( geometry -> getNumKids() > 0 ) { new_tile -> addKid( geometry ); @@ -1187,9 +1243,15 @@ FGTileEntry::load( const SGPath& base, bool is_base ) } else { delete rwy_lights; } + if ( taxi_lights -> getNumKids() > 0 ) { + taxi_lights_transform -> addKid( taxi_lights ); + } else { + delete taxi_lights; + } } else { delete geometry; delete rwy_lights; + delete taxi_lights; } } else if ( token == "OBJECT_STATIC" || @@ -1363,6 +1425,12 @@ FGTileEntry::load( const SGPath& base, bool is_base ) rwy_lights_transform->setTransform( &sgcoord ); } + // Add taxi lights to scene graph if any exist + if ( taxi_lights_transform->getNumKids() > 0 ) { + SG_LOG( SG_TERRAIN, SG_DEBUG, "adding taxi lights" ); + taxi_lights_transform->setTransform( &sgcoord ); + } + // ADA // Create runway lights - 23 Mar 2001 lightmaps_transform = NULL; @@ -1399,7 +1467,8 @@ FGTileEntry::load( const SGPath& base, bool is_base ) void FGTileEntry::add_ssg_nodes( ssgBranch* terrain_branch, ssgBranch* gnd_lights_branch, - ssgBranch* rwy_lights_branch ) + ssgBranch* rwy_lights_branch, + ssgBranch* taxi_lights_branch ) { // bump up the ref count so we can remove this later without // having ssg try to free the memory. @@ -1426,6 +1495,13 @@ FGTileEntry::add_ssg_nodes( ssgBranch* terrain_branch, rwy_lights_branch->addKid( rwy_lights_transform ); } + if ( taxi_lights_transform != NULL ) { + // bump up the ref count so we can remove this later without + // having ssg try to free the memory. + taxi_lights_transform->ref(); + taxi_lights_branch->addKid( taxi_lights_transform ); + } + // ADA if ( lightmaps_transform != 0 ) { // bump up the ref count so we can remove this later without @@ -1514,6 +1590,28 @@ FGTileEntry::disconnect_ssg_nodes() } } + // find the taxi lighting branch + if ( taxi_lights_transform ) { + pcount = taxi_lights_transform->getNumParents(); + if ( pcount > 0 ) { + // find the first parent (should only be one) + ssgBranch *parent = taxi_lights_transform->getParent( 0 ) ; + if( parent ) { + // disconnect the light branch (we previously ref()'d + // it so it won't get freed now) + parent->removeKid( taxi_lights_transform ); + } else { + SG_LOG( SG_TERRAIN, SG_ALERT, + "parent pointer is NULL! Dying" ); + exit(-1); + } + } else { + SG_LOG( SG_TERRAIN, SG_ALERT, + "Parent count is zero for an ssg light tile! Dying" ); + exit(-1); + } + } + // ADA //runway lights - 23 Mar 2001 // Delete runway lights and free memory diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index 94c9cd336..42e53b356 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -145,6 +145,7 @@ private: // pointer to ssg transform for this tile ssgTransform *terra_transform; ssgTransform *rwy_lights_transform; + ssgTransform *taxi_lights_transform; ssgTransform *gnd_lights_transform; // pointer to ssg range selector for this tile @@ -184,6 +185,7 @@ private: bool obj_load( const std::string& path, ssgBranch* geometry, ssgBranch* rwy_lights, + ssgBranch* taxi_lights, ssgVertexArray* gound_lights, bool is_base ); @@ -199,7 +201,8 @@ private: TERRA_NODE = 0x04, GROUND_LIGHTS = 0x08, RWY_LIGHTS = 0x10, - LIGHTMAPS = 0x20 + TAXI_LIGHTS = 0x20, + LIGHTMAPS = 0x40 }; int free_tracker; @@ -271,7 +274,8 @@ public: */ void add_ssg_nodes( ssgBranch* terrain_branch, ssgBranch* gnd_lights_branch, - ssgBranch* rwy_lights_branch ); + ssgBranch* rwy_lights_branch, + ssgBranch* taxi_lights_branch ); /** * disconnect terrain mesh and ground lighting nodes from scene diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 5793595f1..e969add81 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -371,7 +371,8 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters, #endif e->add_ssg_nodes( globals->get_scenery()->get_terrain_branch(), globals->get_scenery()->get_gnd_lights_root(), - globals->get_scenery()->get_rwy_lights_root() ); + globals->get_scenery()->get_rwy_lights_root(), + globals->get_scenery()->get_taxi_lights_root() ); // cout << "Adding ssg nodes for " } -- 2.39.5