// 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
#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>
#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>
#include <Replay/replay.hxx>
#include <GUI/new_gui.hxx>
-#ifdef FG_MPLAYER_AS
-#include <MultiPlayer/multiplaytxmgr.hxx>
-#include <MultiPlayer/multiplayrxmgr.hxx>
-#endif
-
#include "splash.hxx"
#include "renderer.hxx"
#include "main.hxx"
ssgSimpleState *hud_and_panel;
ssgSimpleState *menus;
+FGRenderer::FGRenderer()
+{
+#ifdef FG_JPEG_SERVER
+ jpgRenderFrame = FGRenderer::update;
+#endif
+}
-void fgRenderFrame() {
-#ifdef FG_MPLAYER_AS
- // Update any multiplayer models
- globals->get_multiplayer_rx_mgr()->Update();
+FGRenderer::~FGRenderer()
+{
+#ifdef FG_JPEG_SERVER
+ jpgRenderFrame = NULL;
#endif
- globals->get_renderer()->update(delta_time_sec);
}
+
void
FGRenderer::build_states( void ) {
default_state = new ssgSimpleState;
}
-// 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(double dt) {
+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");
// 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;
// calculate our current position in cartesian space
globals->get_scenery()->set_center( globals->get_scenery()->get_next_center() );
- // update view port
- fgReshape( 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 );
}
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();
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();
scene_farplane = 120000.0f;
}
- ssgSetNearFar( scene_nearplane, scene_farplane );
+ setNearFar( scene_nearplane, scene_farplane );
if ( draw_otw && skyblend ) {
// draw the sky backdrop
// 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 );
// 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;
// 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 ) {
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(),
- viewmgr->get_current_view()->get_v_fov() );
+ viewmgr->get_current_view()->get_v_fov() );
#endif
}
}
+// 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;
+}
+
+
+// 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;
+
+
+/** 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;
+
+ // fully specify the view frustum before hacking it (so we don't
+ // accumulate hacked effects
+ ssgSetFOV( w, h );
+ ssgSetNearFar( near, far );
+
+ 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