From: curt Date: Tue, 26 Oct 1999 03:45:33 +0000 (+0000) Subject: Add a key mapping (F3) for taking a screen snap shot. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=a631bd2e55c764e3695ae49e8f760a12f876f649;p=flightgear.git Add a key mapping (F3) for taking a screen snap shot. Keep track of and free index arrays that are fed to ssg. Ssg branch deletion memory leak work around. --- diff --git a/src/GUI/gui.cxx b/src/GUI/gui.cxx index a084813c3..5158bd046 100644 --- a/src/GUI/gui.cxx +++ b/src/GUI/gui.cxx @@ -880,8 +880,13 @@ void printScreen ( puObject *obj ) { #endif // #ifdef WIN32 -// do a screen snap shot void dumpSnapShot ( puObject *obj ) { + fgDumpSnapShot(); +} + + +// do a screen snap shot +void fgDumpSnapShot () { bool show_pu_cursor = false; mainMenuBar->hide(); diff --git a/src/GUI/gui.h b/src/GUI/gui.h index 8a592de0f..ac820e27a 100644 --- a/src/GUI/gui.h +++ b/src/GUI/gui.h @@ -38,6 +38,8 @@ extern void mkDialog(const char *txt); extern void ConfirmExitDialog(void); extern void guiFixPanel( void ); +extern void fgDumpSnapShot(); + extern puFont guiFnt; extern fntTexFont *guiFntHandle; diff --git a/src/Main/keyboard.cxx b/src/Main/keyboard.cxx index 36d79c7ed..825f0860e 100644 --- a/src/Main/keyboard.cxx +++ b/src/Main/keyboard.cxx @@ -413,9 +413,12 @@ void GLUTspecialkey(int k, int x, int y) { t->togglePauseMode(); return; } + case GLUT_KEY_F3: // F2 Take a screen shot + fgDumpSnapShot(); + return; case GLUT_KEY_F6: // F6 toggles Autopilot target location - fgAPToggleWayPoint(); - return; + fgAPToggleWayPoint(); + return; case GLUT_KEY_F8: // F8 toggles fog ... off fastest nicest... current_options.cycle_fog(); diff --git a/src/Objects/obj.cxx b/src/Objects/obj.cxx index a7fc342e8..6c91c59ee 100644 --- a/src/Objects/obj.cxx +++ b/src/Objects/obj.cxx @@ -234,7 +234,9 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { } unsigned short *vindex = new unsigned short [ 4 ]; + t->free_ptrs.push_back( vindex ); unsigned short *tindex = new unsigned short [ 4 ]; + t->free_ptrs.push_back( tindex ); for ( i = 0; i < 4; ++i ) { vindex[i] = i; tindex[i] = i; @@ -284,6 +286,7 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t) { ssgSimpleState *state = NULL; ssgBranch *tile = new ssgBranch () ; + tile -> setName ( (char *)path.c_str() ) ; // Attempt to open "path.gz" or "path" @@ -726,8 +729,12 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t) { // build the ssg entity unsigned short *vindex = new unsigned short [ fan_vertices.size() ]; + t->free_ptrs.push_back( vindex ); + unsigned short *tindex = new unsigned short [ fan_tex_coords.size() ]; + t->free_ptrs.push_back( tindex ); + for ( i = 0; i < (int)fan_vertices.size(); ++i ) { vindex[i] = fan_vertices[i]; } diff --git a/src/Scenery/tilecache.cxx b/src/Scenery/tilecache.cxx index 1c82ca667..e3c5c61b6 100644 --- a/src/Scenery/tilecache.cxx +++ b/src/Scenery/tilecache.cxx @@ -81,11 +81,15 @@ FGTileCache::init( void ) FG_LOG( FG_TERRAIN, FG_DEBUG, " current cache size = " << tile_cache.size() ); FGTileEntry e; + e.mark_unused(); + e.vtlist = NULL; + e.vnlist = NULL; + e.tclist = NULL; + FG_LOG( FG_TERRAIN, FG_DEBUG, " size of tile = " << sizeof( e ) ); if ( target_cache_size > (int)tile_cache.size() ) { // FGTileEntry e; - e.mark_unused(); int expansion_amt = target_cache_size - (int)tile_cache.size(); for ( i = 0; i < expansion_amt; ++i ) { tile_cache.push_back( e ); @@ -129,18 +133,38 @@ FGTileCache::exists( const FGBucket& p ) } +#if 0 +static void print_refs( ssgSelector *sel, ssgTransform *trans, + ssgRangeSelector *range) +{ + cout << "selector -> " << sel->getRef() + << " transform -> " << trans->getRef() + << " range -> " << range->getRef() << endl; +} +#endif + + // Fill in a tile cache entry with real data for the specified bucket void FGTileCache::fill_in( int index, const FGBucket& p ) { // cout << "FILL IN CACHE ENTRY = " << index << endl; + tile_cache[index].center = Point3D( 0.0 ); + if ( (tile_cache[index].vtlist != NULL) || + (tile_cache[index].vnlist != NULL) || + (tile_cache[index].tclist != NULL) ) + { + FG_LOG( FG_TERRAIN, FG_ALERT, + "Attempting to overwrite existing or" + << " not properly freed leaf data." ); + exit(-1); + } // Force some values in case the tile fails to load (i.e. fill // doesn't exist) - tile_cache[index].center = Point3D( 0.0 ); - tile_cache[index].vtlist = NULL; - tile_cache[index].vnlist = NULL; - tile_cache[index].tclist = NULL; + // tile_cache[index].vtlist = NULL; + // tile_cache[index].vnlist = NULL; + // tile_cache[index].tclist = NULL; // Load the appropriate data file and build tile fragment list FGPath tile_path( current_options.get_fg_root() ); diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index a70904992..277dff4a5 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -58,6 +58,24 @@ FGTileEntry::~FGTileEntry ( void ) { } +// recurse an ssg tree and call removeKid() on every node from the +// bottom up. Leaves the original branch in existance, but empty so +// it can be removed by the calling routine. +static void my_remove_branch( ssgBranch * branch ) { + for ( ssgEntity *k = branch->getKid( 0 ); + k != NULL; + k = branch->getNextKid() ) + { + if ( k -> isAKindOf ( ssgTypeBranch() ) ) { + my_remove_branch( (ssgBranch *)k ); + branch -> removeKid ( k ); + } else if ( k -> isAKindOf ( ssgTypeLeaf() ) ) { + branch -> removeKid ( k ) ; + } + } +} + + // Step through the fragment list, deleting the display list, then the // fragment, until the list is empty. Also delete the arrays used by // ssg as well as the whole ssg branch @@ -85,17 +103,24 @@ FGTileEntry::free_tile() " deleting vertex array" ); if ( vtlist != NULL ) { delete vtlist; + vtlist = NULL; } FG_LOG( FG_TERRAIN, FG_DEBUG, " deleting normal array" ); if ( vnlist != NULL ) { delete vnlist; + vnlist = NULL; } FG_LOG( FG_TERRAIN, FG_DEBUG, " deleting texture coordinate array" ); if ( tclist != NULL ) { delete tclist; + tclist = NULL; + } + for ( int i = 0; i < (int)free_ptrs.size(); ++i ) { + delete free_ptrs[i]; } + free_ptrs.clear(); // delete the ssg branch @@ -104,34 +129,13 @@ FGTileEntry::free_tile() // find the first parent (should only be one) ssgBranch *parent = select_ptr->getParent( 0 ) ; if( parent ) { - parent->removeKid(select_ptr); + my_remove_branch( select_ptr ); + parent->removeKid( select_ptr ); } else { FG_LOG( FG_TERRAIN, FG_ALERT, "parent pointer is NULL! Dying" ); exit(-1); } - -#if 0 - // find the number of kids this parent has - int kcount = parent->getNumKids(); - // find the kid that matches our original select_ptr - bool found_kid = false; - for ( int i = 0; i < kcount; ++i ) { - ssgEntity *kid = parent->getKid( i ); - if ( kid == select_ptr ) { - FG_LOG( FG_TERRAIN, FG_DEBUG, - "Found a kid to delete " << kid); - found_kid = true; - parent->removeKid( i ); - } - } - if ( ! found_kid ) { - FG_LOG( FG_TERRAIN, FG_ALERT, - "Couldn't find the kid to delete! Dying" ); - exit(-1); - } -#endif - } else { FG_LOG( FG_TERRAIN, FG_ALERT, "Parent count is zero for an ssg tile! Dying" ); diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index 5b6824d6f..8607591ff 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -84,6 +84,8 @@ public: typedef container::iterator FragmentIterator; typedef container::const_iterator FragmentConstIterator; + typedef vector < unsigned short * > free_list; + public: // node list (the per fragment face lists reference this node list) point_list nodes; @@ -109,6 +111,8 @@ public: sgVec3 *vtlist; sgVec3 *vnlist; sgVec2 *tclist; + free_list free_ptrs; // list of pointers to free when tile + // entry goes away // ssg tree structure for this tile is as follows: // ssgRoot(scene) @@ -160,9 +164,9 @@ public: void free_tile(); // Calculate this tile's offset - void SetOffset( const Point3D& off) + void SetOffset( const Point3D& p) { - offset = center - off; + offset = center - p; } // Return this tile's offset diff --git a/src/WeatherCM/FGVoronoi.h b/src/WeatherCM/FGVoronoi.h index da4b337db..b2906dece 100644 --- a/src/WeatherCM/FGVoronoi.h +++ b/src/WeatherCM/FGVoronoi.h @@ -110,10 +110,3 @@ typedef vector FGVoronoiOutputList; FGVoronoiOutputList Voronoiate(const FGVoronoiInputList& input); #endif /*FGVoronoi_H*/ - - - - - - -