Keep track of and free index arrays that are fed to ssg.
Ssg branch deletion memory leak work around.
#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();
extern void ConfirmExitDialog(void);
extern void guiFixPanel( void );
+extern void fgDumpSnapShot();
+
extern puFont guiFnt;
extern fntTexFont *guiFntHandle;
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();
}
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;
ssgSimpleState *state = NULL;
ssgBranch *tile = new ssgBranch () ;
+
tile -> setName ( (char *)path.c_str() ) ;
// Attempt to open "path.gz" or "path"
// 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];
}
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 );
}
+#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() );
}
+// 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
" 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
// 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" );
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;
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)
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
FGVoronoiOutputList Voronoiate(const FGVoronoiInputList& input);
#endif /*FGVoronoi_H*/
-
-
-
-
-
-
-