]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/renderer.cxx
The view frustum is defined in plib apps using calls to ssgSetFOV() and
[flightgear.git] / src / Main / renderer.cxx
index fa780f36cd44778dae95d3c2a6c8f7cd43a5ee56..4ba4649f050fa7c6be8e6334b9f54b416479daaa 100644 (file)
@@ -3,7 +3,7 @@
 // Written by Curtis Olson, started May 1997.
 // This file contains parts of main.cxx prior to october 2004
 //
-// Copyright (C) 1997 - 2002  Curtis L. Olson  - curt@flightgear.org
+// Copyright (C) 1997 - 2002  Curtis L. Olson  - http://www.flightgear.org/~curt
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
@@ -45,6 +45,9 @@
 #include <simgear/math/sg_random.h>
 #include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/model/model.hxx>
+#ifdef FG_JPEG_SERVER
+#include <simgear/screen/jpgfactory.hxx>
+#endif
 
 #ifdef FG_USE_CLOUDS_3D
 #  include <simgear/scene/sky/clouds3d/SkySceneLoader.hpp>
@@ -57,7 +60,6 @@
 #include <Aircraft/aircraft.hxx>
 #include <Cockpit/panel.hxx>
 #include <Cockpit/cockpit.hxx>
-#include <Cockpit/radiostack.hxx>
 #include <Cockpit/hud.hxx>
 #include <Model/panelnode.hxx>
 #include <Model/modelmgr.hxx>
@@ -121,6 +123,20 @@ ssgSimpleState *default_state;
 ssgSimpleState *hud_and_panel;
 ssgSimpleState *menus;
 
+FGRenderer::FGRenderer()
+{
+#ifdef FG_JPEG_SERVER
+   jpgRenderFrame = FGRenderer::update;
+#endif
+}
+
+FGRenderer::~FGRenderer()
+{
+#ifdef FG_JPEG_SERVER
+   jpgRenderFrame = NULL;
+#endif
+}
+
 
 void
 FGRenderer::build_states( void ) {
@@ -212,6 +228,7 @@ FGRenderer::init( void ) {
 }
 
 
+
 // Update all Visuals (redraws anything graphics related)
 void
 FGRenderer::update( bool refresh_camera_settings ) {
@@ -485,7 +502,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
             scene_farplane = 120000.0f;
         }
 
-        ssgSetNearFar( scene_nearplane, scene_farplane );
+        setNearFar( scene_nearplane, scene_farplane );
 
         if ( draw_otw && skyblend ) {
             // draw the sky backdrop
@@ -501,8 +518,6 @@ FGRenderer::update( bool refresh_camera_settings ) {
         // draw the ssg scene
         glEnable( GL_DEPTH_TEST );
 
-        ssgSetNearFar( scene_nearplane, scene_farplane );
-
         if ( fgGetBool("/sim/rendering/wireframe") ) {
             // draw wire frame
             glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
@@ -549,7 +564,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
         // the current view frustum will still be freed properly.
         static int counter = 0;
         counter++;
-        if (counter == 200) {
+        if (counter >= 200) {
             sgFrustum f;
             f.setFOV(360, 360);
                     // No need to put the near plane too close;
@@ -568,7 +583,9 @@ FGRenderer::update( bool refresh_camera_settings ) {
 
         // draw runway lighting
         glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
-        ssgSetNearFar( scene_nearplane, scene_farplane );
+
+        // CLO - 02/25/2005 - DO WE NEED THIS extra fgSetNearFar()?
+        // fgSetNearFar( scene_nearplane, scene_farplane );
 
         if ( enhanced_lighting ) {
 
@@ -778,8 +795,8 @@ FGRenderer::resize( int width, int height ) {
           set_aspect_ratio((float)view_h / (float)width);
       }
 
-      ssgSetFOV( viewmgr->get_current_view()->get_h_fov(),
-                 viewmgr->get_current_view()->get_v_fov() );
+      setFOV( viewmgr->get_current_view()->get_h_fov(),
+              viewmgr->get_current_view()->get_v_fov() );
 
 #ifdef FG_USE_CLOUDS_3D
       sgClouds3d->Resize( viewmgr->get_current_view()->get_h_fov(),
@@ -792,141 +809,69 @@ 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") &&
-                            !SGCloudLayer::enable_bump_mapping; // ugly artefact now
-#else
-    bool multi_pass_clouds = false;
-#endif
-    bool draw_clouds = fgGetBool("/environment/clouds/status");
+// These are wrapper functions around ssgSetNearFar() and ssgSetFOV()
+// which will post process and rewrite the resulting frustum if we
+// want to do asymmetric view frustums.
+
+static void fgHackFrustum() {
+
+    /* experiment in assymetric view frustums */
+    sgFrustum *f = ssgGetFrustum();
+    cout << " l = " << f->getLeft()
+         << " r = " << f->getRight()
+         << " b = " << f->getBot()
+         << " t = " << f->getTop()
+         << " n = " << f->getNear()
+         << " f = " << f->getFar()
+         << endl;
+    static double incr = 0.0;
+    double factor = (sin(incr) + 1.0) / 2.0; // map to [0-1]
+    double w = (f->getRight() - f->getLeft()) / 2.0;
+    double l = f->getLeft() + w * factor;
+    double r = l + w;
+    ssgSetFrustum(l, r, f->getBot(), f->getTop(), f->getNear(), f->getFar());
+    incr += 0.001;
+}
 
-    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 };
+// we need some static storage space for these values.  However, we
+// can't store it in a renderer class object because the functions
+// that manipulate these are static.  They are static so they can
+// interface to the display callback system.  There's probably a
+// better way, there has to be a better way, but I'm not seeing it
+// right now.
+static float width, height, near, far;
 
-    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() );
-    }
+/** FlightGear code should use this routine to set the FOV rather than
+ *  calling the ssg routine directly
+ */
+void FGRenderer::setFOV( float w, float h ) {
+    width = w;
+    height = h;
 
-    // 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 );
-        }
-    }
+    // fully specify the view frustum before hacking it (so we don't
+    // accumulate hacked effects
+    ssgSetFOV( w, h );
+    ssgSetNearFar( near, far );
 
-    globals->get_aircraft_model()->select( true );
-    globals->get_model_mgr()->draw();
-    globals->get_aircraft_model()->draw();
+    fgHackFrustum();
 }
 
 
+/** FlightGear code should use this routine to set the Near/Far clip
+ *  planes rather than calling the ssg routine directly
+ */
+void FGRenderer::setNearFar( float n, float f ) {
+    near = n;
+    far = f;
+
+    // fully specify the view frustum before hacking it (so we don't
+    // accumulate hacked effects
+    ssgSetNearFar( n, f );
+    ssgSetFOV( width, height );
+
+    fgHackFrustum();
+}
+
 // end of renderer.cxx