]> git.mxchange.org Git - flightgear.git/commitdiff
Continued work to clean up the hires screen shot code and move it back towards
authorcurt <curt>
Wed, 6 Oct 2004 03:29:14 +0000 (03:29 +0000)
committercurt <curt>
Wed, 6 Oct 2004 03:29:14 +0000 (03:29 +0000)
a working state.  I still see an anomoly when taking a screen shot from inside
a 3d cockpit, but external (chase/tower) views seem to work well.  I also
added a property to control how many screen-res tiles are generated in the
output.  Theoretically, you can now generate unlimited resolution screen shots,
or limited only by your disk space and patience.

Today I successfully generated a 20*1024 x 20*768 (20480x15360) resolution
screen shot.  If you rendered that at 100 dpi it would cover a poster of
about 17 feet by 12.8 feet.

Good luck trying to display something that big or convert it to anything
useful on a typical PC. :-)

src/GUI/gui.h
src/GUI/gui_funcs.cxx
src/Main/renderer.cxx
src/Main/renderer.hxx

index 2ce8bd6a2a331e015bd60d3e5a4310e46e3b0555..2920e48e8c6f72a30733b0a3eabc9758025aacf8 100644 (file)
@@ -57,9 +57,9 @@ extern int gui_menu_on;
 extern void saveFlight(puObject *);
 extern void loadFlight(puObject *);
 extern void reInit(puObject *);
-extern void dumpSnapShot(puObject *);
+extern void fgDumpSnapShotWrapper(puObject *);
 #ifdef TR_HIRES_SNAP
-extern void dumpHiResSnapShot(puObject *);
+extern void fgHiResDumpWrapper(puObject *);
 extern void fgHiResDump();
 #endif
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
index 4f51dcc7d3f5eb7b18927e81ec2f221619bb2072..c44e695779d0cb883b2ba7e34c67eb12cde87c4f 100644 (file)
@@ -138,9 +138,9 @@ const __fg_gui_fn_t __fg_gui_fn[] = {
         {"loadFlight", loadFlight},
         {"reInit", reInit},
 #ifdef TR_HIRES_SNAP
-        {"dumpHiResSnapShot", dumpHiResSnapShot},
+        {"dumpHiResSnapShot", fgHiResDumpWrapper},
 #endif
-        {"dumpSnapShot", dumpSnapShot},
+        {"dumpSnapShot", fgDumpSnapShotWrapper},
 #if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
         {"printScreen", printScreen},
 #endif
@@ -528,9 +528,10 @@ void fgHiResDump()
         fgSetBool("/sim/freeze/master", true);
     }
 
+    TurnCursorOff();
     if ( !puCursorIsHidden() ) {
-        show_pu_cursor = true;
-        puHideCursor();
+       show_pu_cursor = true;
+       puHideCursor();
     }
 
     FGRenderer *renderer = globals->get_renderer();
@@ -541,22 +542,9 @@ void fgHiResDump()
     // we need two render frames here to clear the menu and cursor
     // ... not sure why but doing an extra fgRenderFrame() shouldn't
     // hurt anything
-    renderer->update();
-    renderer->update();
-
-    // Make sure we have SSG projection primed for current view
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    ssgSetCamera( (sgVec4 *)globals->get_current_view()->get_VIEW() );
-    ssgSetFOV( globals->get_current_view()->get_h_fov(),
-              globals->get_current_view()->get_v_fov() );
-    cout << "FOV = " << globals->get_current_view()->get_h_fov()
-         << ", " << globals->get_current_view()->get_v_fov() << endl;
-    // ssgSetNearFar( 10.0f, 120000.0f );
-    ssgSetNearFar( 0.5f, 1200000.0f );
+    renderer->update( true );
+    renderer->update( true );
 
-       
     // This ImageSize stuff is a temporary hack
     // should probably use 128x128 tile size and
     // support any image size
@@ -636,7 +624,7 @@ void fgHiResDump()
         trBeginTile(tr);
         int curColumn = trGet(tr, TR_CURRENT_COLUMN);
         int curRow =  trGet(tr, TR_CURRENT_ROW);
-        renderer->screendump();
+        renderer->update( false );
         if ( do_hud )
             fgUpdateHUD( curColumn*hud_col_step,      curRow*hud_row_step,
                          (curColumn+1)*hud_col_step, (curRow+1)*hud_row_step );
@@ -696,6 +684,8 @@ void fgHiResDump()
         puShowCursor();
     }
 
+    TurnCursorOn();
+
     if ( !freeze ) {
         fgSetBool("/sim/freeze/master", false);
     }
@@ -729,7 +719,7 @@ GLubyte *hiResScreenCapture( int multiplier )
            globals->get_renderer()->resize( cur_width, cur_height );
            // pan to tile
            rotateView( 0, (y*fov)-((multiplier-1)*fov/2), (x*fov)-((multiplier-1)*fov/2) );
-           globals->get_renderer()->update();
+           globals->get_renderer()->update( false );
            // restore view
            GlBitmap b2;
            b1->copyBitmap( &b2, cur_width*x, cur_height*y );
@@ -755,7 +745,7 @@ void printScreen ( puObject *obj ) {
     int cur_width = fgGetInt("/sim/startup/xsize");
     int cur_height = fgGetInt("/sim/startup/ysize");
     p.Begin( "FlightGear", cur_width*3, cur_height*3 );
-       p.End( hiResScreenCapture(3) );
+    p.End( hiResScreenCapture(3) );
 
     // BusyCursor(1);
     if ( show_pu_cursor ) {
@@ -766,12 +756,12 @@ void printScreen ( puObject *obj ) {
 #endif // #ifdef WIN32
 
 
-void dumpSnapShot ( puObject *obj ) {
+void fgDumpSnapShotWrapper ( puObject *obj ) {
     fgDumpSnapShot();
 }
 
 
-void dumpHiResSnapShot ( puObject *obj ) {
+void fgHiResDumpWrapper ( puObject *obj ) {
     fgHiResDump();
 }
 
@@ -805,8 +795,8 @@ void fgDumpSnapShot () {
     // we need two render frames here to clear the menu and cursor
     // ... not sure why but doing an extra fgRenderFrame() shouldn't
     // hurt anything
-    renderer->update();
-    renderer->update();
+    renderer->update( true );
+    renderer->update( true );
 
     while (count < 1000) {
         FILE *fp;
index 7f1e76474c8b8596281161b28c042f91663e3a28..fa780f36cd44778dae95d3c2a6c8f7cd43a5ee56 100644 (file)
@@ -212,132 +212,9 @@ FGRenderer::init( void ) {
 }
 
 
-// For HiRes screen Dumps using Brian Pauls TR Library
-void
-FGRenderer::screendump( void ) {
-#ifdef FG_ENABLE_MULTIPASS_CLOUDS
-    bool multi_pass_clouds = fgGetBool("/sim/rendering/multi-pass-clouds") &&
-                            !SGCloudLayer::enable_bump_mapping; // ugly artefact now
-#else
-    bool multi_pass_clouds = false;
-#endif
-    bool draw_clouds = fgGetBool("/environment/clouds/status");
-
-    if ( fgPanelVisible() ) {
-        GLfloat height = fgGetInt("/sim/startup/ysize");
-        GLfloat view_h =
-            (globals->get_current_panel()->getViewHeight() - globals->get_current_panel()->getYOffset())
-            * (height / 768.0) + 1;
-        glTranslatef( 0.0, view_h, 0.0 );
-    }
-
-    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 = (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]);
-
-    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
-    // set the opengl state to known default values
-    default_state->force();
-
-    glEnable( GL_FOG );
-    glFogf  ( GL_FOG_DENSITY, fog_exp2_density);
-    glFogi  ( GL_FOG_MODE,    GL_EXP2 );
-    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
-    // a completely dark scene.  So, we set GL_LIGHT_MODEL_AMBIENT
-    // explicitely to black.
-    glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
-    glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE );
-
-    ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient() );
-
-    // texture parameters
-    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
-    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
-
-    // we need a white diffuse light for the phase of the moon
-    ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, white );
-    thesky->preDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER,
-                     fog_exp2_density );
-
-    // draw the ssg scene
-    // return to the desired diffuse color
-    ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
-    glEnable( GL_DEPTH_TEST );
-    ssgSetNearFar( scene_nearplane, scene_farplane );
-    if ( draw_clouds ) {
-        // Draw the terrain
-        FGTileMgr::set_tile_filter( true );
-        sgSetModelFilter( false );
-        globals->get_aircraft_model()->select( false );
-        ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
-        // Disable depth buffer update, draw the clouds
-        glDepthMask( GL_FALSE );
-        thesky->drawUpperClouds();
-        if ( multi_pass_clouds ) {
-            thesky->drawLowerClouds();
-        }
-        glDepthMask( GL_TRUE );
-        if ( multi_pass_clouds ) {
-            // Draw the objects except the aircraft
-            //  and update the stencil buffer with 1
-            glEnable( GL_STENCIL_TEST );
-            glStencilFunc( GL_ALWAYS, 1, 1 );
-            glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
-        }
-        FGTileMgr::set_tile_filter( false );
-        sgSetModelFilter( true );
-        ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
-    } else {
-        FGTileMgr::set_tile_filter( true );
-        sgSetModelFilter( true );
-        globals->get_aircraft_model()->select( false );
-        ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
-    }
-
-    // draw the lights
-    glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
-    ssgSetNearFar( scene_nearplane, scene_farplane );
-    ssgCullAndDraw( globals->get_scenery()->get_vasi_lights_root() );
-    ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
-
-    ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
-
-    if ( draw_clouds ) {
-        if ( multi_pass_clouds ) {
-            // Disable depth buffer update, draw the clouds where the
-            //  objects overwrite the already drawn clouds, by testing
-            //  the stencil buffer against 1
-            glDepthMask( GL_FALSE );
-            glStencilFunc( GL_EQUAL, 1, 1 );
-            glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
-            thesky->drawUpperClouds();
-            thesky->drawLowerClouds();
-            glDepthMask( GL_TRUE );
-            glDisable( GL_STENCIL_TEST );
-        } else {
-            glDepthMask( GL_FALSE );
-            thesky->drawLowerClouds();
-            glDepthMask( GL_TRUE );
-        }
-    }
-
-    globals->get_aircraft_model()->select( true );
-    globals->get_model_mgr()->draw();
-    globals->get_aircraft_model()->draw();
-}
-
-
 // Update all Visuals (redraws anything graphics related)
 void
-FGRenderer::update() {
+FGRenderer::update( bool refresh_camera_settings ) {
     bool scenery_loaded = fgGetBool("sim/sceneryloaded") || fgGetBool("sim/sceneryloaded-override");
     bool draw_otw = fgGetBool("/sim/rendering/draw-otw");
     bool skyblend = fgGetBool("/sim/rendering/skyblend");
@@ -368,10 +245,12 @@ FGRenderer::update() {
 
     // update fog params
     double actual_visibility;
-    if (fgGetBool("/environment/clouds/status"))
+    if (fgGetBool("/environment/clouds/status")) {
         actual_visibility = thesky->get_visibility();
-    else
+    } else {
         actual_visibility = fgGetDouble("/environment/visibility-m");
+    }
+
     if ( actual_visibility != last_visibility ) {
         last_visibility = actual_visibility;
 
@@ -412,9 +291,16 @@ FGRenderer::update() {
         // calculate our current position in cartesian space
         globals->get_scenery()->set_center( globals->get_scenery()->get_next_center() );
 
-        // update view port
-        resize( fgGetInt("/sim/startup/xsize"),
-                   fgGetInt("/sim/startup/ysize") );
+        if ( refresh_camera_settings ) {
+            // update view port
+            resize( fgGetInt("/sim/startup/xsize"),
+                    fgGetInt("/sim/startup/ysize") );
+
+            // Tell GL we are switching to model view parameters
+            glMatrixMode(GL_MODELVIEW);
+            glLoadIdentity();
+            ssgSetCamera( (sgVec4 *)current__view->get_VIEW() );
+        }
 
         if ( fgGetBool("/sim/rendering/clouds3d") ) {
             glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
@@ -460,16 +346,6 @@ FGRenderer::update() {
         }
         glClear( clear_mask );
 
-        // Tell GL we are switching to model view parameters
-
-        // I really should create a derived ssg node or use a call
-        // back or something so that I can draw the sky within the
-        // ssgCullAndDraw() function, but for now I just mimic what
-        // ssg does to set up the model view matrix
-        glMatrixMode(GL_MODELVIEW);
-        glLoadIdentity();
-        ssgSetCamera( (sgVec4 *)current__view->get_VIEW() );
-
         // set the opengl state to known default values
         default_state->force();
 
@@ -597,11 +473,6 @@ FGRenderer::update() {
         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
         glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
 
-        // glMatrixMode( GL_PROJECTION );
-        // glLoadIdentity();
-        ssgSetFOV( current__view->get_h_fov(),
-                   current__view->get_v_fov() );
-
         double agl =
             current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
             - globals->get_scenery()->get_cur_elev();
@@ -920,7 +791,23 @@ FGRenderer::resize( int width, int height ) {
 
 }
 
+
 // For HiRes screen Dumps using Brian Pauls TR Library
+//
+// Curt writes: Unfortunately, if the jpeg image server code is
+// compiled into simgear and flightgear, this function get's called
+// from simgear which is not the direction we want our dependencies to
+// go, but it's the way things are right now.
+//
+// If I had to guess, I would speculate that this code probably
+// doesn't work, at least not 100% correctly, but I don't have time
+// right now to sort this one out.  Also the jpeg server was very
+// experimental and was extremely limited in the resolution images it
+// could serve out for some never debugged reason.  It's a novel
+// feature, but I wouldn't be entirely opposed to seeing it go away
+// unless someone wants to fix it so it works right and robustly and
+// can serve full resolution images without crashing ourselves.
+
 void trRenderFrame( void ) {
 #ifdef FG_ENABLE_MULTIPASS_CLOUDS
     bool multi_pass_clouds = fgGetBool("/sim/rendering/multi-pass-clouds") &&
@@ -1041,4 +928,5 @@ void trRenderFrame( void ) {
     globals->get_aircraft_model()->draw();
 }
 
+
 // end of renderer.cxx
index c8db96d5e4185eced02a995baef31797cf1d41a7..62f3f205359e613ca43e2483e0903bcf91997bf3 100644 (file)
@@ -22,11 +22,15 @@ public:
     ~FGRenderer() {}
 
     void init();
-    static void update();
-    static void resize(int width, int height );
 
-    void screendump();
     void build_states();
+    static void resize(int width, int height );
+
+    // calling update( refresh_camera_settings = false ) will not
+    // touch window or camera settings.  This is useful for the tiled
+    // renderer which needs to set the view frustum itself.
+    static void update( bool refresh_camera_settings );
+    inline static void update() { update( true ); }
 };
 
 #endif