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.
This commit is contained in:
parent
3f00d7e8b6
commit
a631bd2e55
8 changed files with 82 additions and 40 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -110,10 +110,3 @@ typedef vector<FGVoronoiOutput> FGVoronoiOutputList;
|
|||
FGVoronoiOutputList Voronoiate(const FGVoronoiInputList& input);
|
||||
|
||||
#endif /*FGVoronoi_H*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue