1
0
Fork 0
flightgear/src/Main/main.cxx

1783 lines
64 KiB
C++
Raw Normal View History

// main.cxx -- top level sim routines
1998-04-21 17:02:27 +00:00
//
2002-04-05 00:38:55 +00:00
// Written by Curtis Olson, started May 1997.
1998-04-21 17:02:27 +00:00
//
2002-04-05 00:38:55 +00:00
// Copyright (C) 1997 - 2002 Curtis L. Olson - curt@flightgear.org
1998-04-21 17:02:27 +00:00
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
1998-04-21 17:02:27 +00:00
2003-08-17 09:54:41 +00:00
#include <simgear/compiler.h>
#if defined(__linux__) && defined(__i386__)
# include <fpu_control.h>
# include <signal.h>
#endif
2001-03-23 22:42:49 +00:00
#ifdef SG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
1998-04-21 17:02:27 +00:00
#ifdef HAVE_WINDOWS_H
# include <windows.h>
# include <float.h>
1998-04-21 17:02:27 +00:00
#endif
2000-11-01 02:30:10 +00:00
#include <plib/ssg.h>
#include <plib/netSocket.h>
2003-08-17 09:54:41 +00:00
#include <simgear/screen/extensions.hxx>
#include <simgear/scene/material/matlib.hxx>
2003-08-17 09:54:41 +00:00
#include <simgear/props/props.hxx>
#include <simgear/scene/sky/sky.hxx>
#include <simgear/timing/sg_time.hxx>
#include <simgear/scene/model/animation.hxx>
2003-08-17 09:54:41 +00:00
#include <simgear/ephemeris/ephemeris.hxx>
#include <simgear/scene/model/placement.hxx>
#include <simgear/math/sg_random.h>
2003-05-15 21:35:51 +00:00
#include <simgear/scene/model/modellib.hxx>
2003-08-17 09:54:41 +00:00
#ifdef FG_USE_CLOUDS_3D
# include <simgear/scene/sky/clouds3d/SkySceneLoader.hpp>
# include <simgear/scene/sky/clouds3d/SkyUtil.hpp>
#endif
2000-02-15 03:30:01 +00:00
#include <Include/general.hxx>
2003-08-17 09:54:41 +00:00
#include <Scenery/tileentry.hxx>
#include <Time/light.hxx>
#include <Time/light.hxx>
1998-10-17 01:33:52 +00:00
#include <Aircraft/aircraft.hxx>
2003-08-17 09:54:41 +00:00
#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 <Model/acmodel.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <FDM/flight.hxx>
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
#include <FDM/ADA.hxx>
#include <ATC/ATCdisplay.hxx>
2003-08-17 09:54:41 +00:00
#include <ATC/ATCmgr.hxx>
#include <ATC/AIMgr.hxx>
2003-08-17 09:54:41 +00:00
#include <Replay/replay.hxx>
#include <Time/tmp.hxx>
#include <Time/fg_timer.hxx>
#include <Environment/environment_mgr.hxx>
#ifdef FG_MPLAYER_AS
#include <MultiPlayer/multiplaytxmgr.hxx>
#include <MultiPlayer/multiplayrxmgr.hxx>
#endif
2003-08-17 09:54:41 +00:00
#include "splash.hxx"
2002-10-29 19:44:03 +00:00
#include "fg_commands.hxx"
2003-08-17 09:54:41 +00:00
#include "fg_io.hxx"
#include "main.hxx"
2002-10-16 03:44:44 +00:00
float default_attenuation[3] = {1.0, 0.0, 0.0};
ssgSelector *ship_sel=NULL;
// upto 32 instances of a same object can be loaded.
ssgTransform *ship_pos[32];
double obj_lat[32],obj_lon[32],obj_alt[32],obj_pitch[32],obj_roll[32];
int objc=0;
ssgSelector *lightpoints_brightness = new ssgSelector;
ssgTransform *lightpoints_transform = new ssgTransform;
FGTileEntry *dummy_tile;
sgVec3 rway_ols;
// ADA
// Clip plane settings...
float scene_nearplane = 0.5f;
float scene_farplane = 120000.0f;
static double real_delta_time_sec = 0.0;
static double delta_time_sec = 0.0;
glPointParameterfProc glPointParameterfPtr = 0;
glPointParameterfvProc glPointParameterfvPtr = 0;
bool glPointParameterIsSupported = false;
2000-09-10 00:04:50 +00:00
#ifdef macintosh
# include <console.h> // -dw- for command line dialog
#endif
// This is a record containing a bit of global housekeeping information
FGGeneral general;
1998-04-21 17:02:27 +00:00
// Specify our current idle function state. This is used to run all
// our initializations out of the idle callback so that we can get a
// splash screen up and running right away.
static int idle_state = 0;
2001-01-17 23:30:35 +00:00
static long global_multi_loop;
// fog constants. I'm a little nervous about putting actual code out
// here but it seems to work (?)
static const double m_log01 = -log( 0.01 );
static const double sqrt_m_log01 = sqrt( m_log01 );
static GLfloat fog_exp_density;
static GLfloat fog_exp2_density;
static GLfloat rwy_exp2_punch_through;
static GLfloat taxi_exp2_punch_through;
static GLfloat ground_exp2_punch_through;
// Sky structures
SGSky *thesky;
#ifdef FG_USE_CLOUDS_3D
SkySceneLoader *sgClouds3d;
bool _bcloud_orig = true;
#endif
// hack
sgMat4 copy_of_ssgOpenGLAxisSwapMatrix =
{
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
ssgSimpleState *cloud3d_imposter_state;
ssgSimpleState *default_state;
ssgSimpleState *hud_and_panel;
ssgSimpleState *menus;
SGTimeStamp last_time_stamp;
SGTimeStamp current_time_stamp;
2003-03-22 10:38:15 +00:00
void fgBuildRenderStates( void ) {
default_state = new ssgSimpleState;
default_state->ref();
default_state->disable( GL_TEXTURE_2D );
default_state->enable( GL_CULL_FACE );
default_state->enable( GL_COLOR_MATERIAL );
default_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
default_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
default_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
default_state->disable( GL_BLEND );
default_state->disable( GL_ALPHA_TEST );
default_state->disable( GL_LIGHTING );
cloud3d_imposter_state = new ssgSimpleState;
cloud3d_imposter_state->ref();
cloud3d_imposter_state->enable( GL_TEXTURE_2D );
cloud3d_imposter_state->enable( GL_CULL_FACE );
cloud3d_imposter_state->enable( GL_COLOR_MATERIAL );
cloud3d_imposter_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
cloud3d_imposter_state->setMaterial( GL_DIFFUSE, 1, 1, 1, 1 );
cloud3d_imposter_state->setMaterial( GL_AMBIENT, 1, 1, 1, 1 );
cloud3d_imposter_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
cloud3d_imposter_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
cloud3d_imposter_state->enable( GL_BLEND );
cloud3d_imposter_state->enable( GL_ALPHA_TEST );
2002-09-19 02:21:23 +00:00
cloud3d_imposter_state->disable( GL_LIGHTING );
hud_and_panel = new ssgSimpleState;
hud_and_panel->ref();
hud_and_panel->disable( GL_CULL_FACE );
hud_and_panel->disable( GL_TEXTURE_2D );
hud_and_panel->disable( GL_LIGHTING );
hud_and_panel->enable( GL_BLEND );
menus = new ssgSimpleState;
menus->ref();
menus->disable( GL_CULL_FACE );
menus->disable( GL_TEXTURE_2D );
menus->enable( GL_BLEND );
}
2002-04-05 00:38:55 +00:00
1998-04-21 17:02:27 +00:00
// fgInitVisuals() -- Initialize various GL/view parameters
void fgInitVisuals( void ) {
1998-04-21 17:02:27 +00:00
FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
1998-04-21 17:02:27 +00:00
// Go full screen if requested ...
if ( fgGetBool("/sim/startup/fullscreen") ) {
fgOSFullScreen();
}
1998-04-21 17:02:27 +00:00
// If enabled, normal vectors specified with glNormal are scaled
2002-04-05 00:38:55 +00:00
// to unit length after transformation. Enabling this has
// performance implications. See the docs for glNormal.
2000-03-17 06:16:15 +00:00
// glEnable( GL_NORMALIZE );
1998-04-21 17:02:27 +00:00
2000-03-17 06:16:15 +00:00
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
// glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec ); // done later with ssg
1998-04-21 17:02:27 +00:00
sgVec3 sunpos;
sgSetVec3( sunpos, l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2] );
ssgGetLight( 0 ) -> setPosition( sunpos );
2000-03-17 06:16:15 +00:00
glFogi (GL_FOG_MODE, GL_EXP2);
if ( (!strcmp(fgGetString("/sim/rendering/fog"), "disabled")) ||
(!fgGetBool("/sim/rendering/shading"))) {
// if fastest fog requested, or if flat shading force fastest
glHint ( GL_FOG_HINT, GL_FASTEST );
} else if ( !strcmp(fgGetString("/sim/rendering/fog"), "nicest") ) {
glHint ( GL_FOG_HINT, GL_NICEST );
}
if ( fgGetBool("/sim/rendering/wireframe") ) {
// draw wire frame
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
// This is the default anyways, but it can't hurt
2000-03-17 06:16:15 +00:00
glFrontFace ( GL_CCW );
// Just testing ...
2000-03-17 06:16:15 +00:00
// glEnable(GL_POINT_SMOOTH);
// glEnable(GL_LINE_SMOOTH);
// glEnable(GL_POLYGON_SMOOTH);
1998-04-21 17:02:27 +00:00
}
// For HiRes screen Dumps using Brian Pauls TR Library
void trRenderFrame( void ) {
#ifdef FG_ENABLE_MULTIPASS_CLOUDS
bool multi_pass_clouds = fgGetBool("/sim/rendering/multi-pass-clouds");
#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 =
2003-03-30 12:46:08 +00:00
(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_REPLACE, GL_REPLACE, 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();
This patch includes the FGLocation class, a few fixes, cleanup in viewer code. Synced to CVS 19:36 EDT 2002-04-10 (after this evenings JSMsim and Base package updates). Description: Added FGLocation class which is new home for calculating matrix rotations. Viewer can now be configured to access rotations created by the model rather than repeating the same calculations again. Changed model initialization for the time being so that its location data is available for the viewer (currently required by other subsystems). At some point we can move this back to fg_init along with the viewer initialization. Seperated the update from the draw function in the model code. The viewer code needs the same matrix data, and moving the update portion at this time does not increase the number of matrix math iterations. Moved the model draw so that it always appears "in front" of lights and clouds. Reogranized viewer update routine for using the FGLocation class and simplified some more tasks. The routine is fairly easy to follow now, with the steps ordered and spelled out in comments. Viewmgr only updates the current (visible) view now, with the exception of an old reference to "chase view" that will be corrected in forthcoming changes. Also will be doing some work on the viewmgr outputs. Model is now clears the z-buffer in all modes. This will be changed with the next viewmgr update. The only side effect is that models always disappear when over 5km distant from the eye point (can't really see them anyway:-)). Other than a flag to indicate "internal" view I don't anticipate the configuration interface for viewmgr/views will be changed a lot for now. It is close to done. The next viewmgr update will however rework the outputs so may change location. This code will run with the previous version of preferences.xml, but will run faster with the newer version. I am attaching a preferences.xml that should not be commited before the code. All the changes are in the /sim/view section and should show a simpler view configuration that references model locations. Note that I've added a 2nd tower view in "lookfrom" mode for illustration purposes. You can look around using the mouse. You may want to remove that or comment it out.
2002-04-11 04:26:07 +00:00
globals->get_aircraft_model()->draw();
}
1998-04-21 17:02:27 +00:00
// Update all Visuals (redraws anything graphics related)
void fgRenderFrame() {
bool draw_otw = fgGetBool("/sim/rendering/draw-otw");
bool skyblend = fgGetBool("/sim/rendering/skyblend");
bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
bool distance_attenuation = fgGetBool("/sim/rendering/distance-attenuation");
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
#ifdef FG_ENABLE_MULTIPASS_CLOUDS
bool multi_pass_clouds = fgGetBool("/sim/rendering/multi-pass-clouds");
#else
bool multi_pass_clouds = false;
#endif
bool draw_clouds = fgGetBool("/environment/clouds/status");
GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
// static const SGPropertyNode *longitude
// = fgGetNode("/position/longitude-deg");
// static const SGPropertyNode *latitude
// = fgGetNode("/position/latitude-deg");
// static const SGPropertyNode *altitude
// = fgGetNode("/position/altitude-ft");
static const SGPropertyNode *groundlevel_nearplane
= fgGetNode("/sim/current-view/ground-level-nearplane-m");
FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
static double last_visibility = -9999;
2000-06-20 22:31:47 +00:00
// update fog params
double actual_visibility;
if (fgGetBool("/environment/clouds/status"))
actual_visibility = thesky->get_visibility();
else
actual_visibility = fgGetDouble("/environment/visibility-m");
if ( actual_visibility != last_visibility ) {
last_visibility = actual_visibility;
fog_exp_density = m_log01 / actual_visibility;
fog_exp2_density = sqrt_m_log01 / actual_visibility;
ground_exp2_punch_through = sqrt_m_log01 / (actual_visibility * 1.5);
if ( actual_visibility < 8000 ) {
rwy_exp2_punch_through = sqrt_m_log01 / (actual_visibility * 2.5);
taxi_exp2_punch_through = sqrt_m_log01 / (actual_visibility * 1.5);
} else {
rwy_exp2_punch_through = sqrt_m_log01 / ( 8000 * 2.5 );
taxi_exp2_punch_through = sqrt_m_log01 / ( 8000 * 1.5 );
}
}
// double angle;
// GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
// GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
// GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
// GLfloat mat_shininess[] = { 10.0 };
GLbitfield clear_mask;
if ( idle_state != 1000 ) {
// still initializing, draw the splash screen
if ( fgGetBool("/sim/startup/splash-screen") ) {
fgSplashUpdate(0.0, 1.0);
}
// Keep resetting sim time while the sim is initializing
globals->set_sim_time_sec( 0.0 );
SGAnimation::set_sim_time_sec( 0.0 );
} else {
// idle_state is now 1000 meaning we've finished all our
// initializations and are running the main loop, so this will
// now work without seg faulting the system.
1998-04-21 17:02:27 +00:00
FGViewer *current__view = globals->get_current_view();
// 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 ( fgGetBool("/sim/rendering/clouds3d") ) {
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
cloud3d_imposter_state->force();
glDisable( GL_FOG );
glColor4f( 1.0, 1.0, 1.0, 1.0 );
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ) ;
#ifdef FG_USE_CLOUDS_3D
if ( _bcloud_orig ) {
Point3D c = globals->get_scenery()->get_center();
sgClouds3d->Set_Cloud_Orig( &c );
_bcloud_orig = false;
}
sgClouds3d->Update( current__view->get_absolute_view_pos() );
#endif
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glDisable(GL_DEPTH_TEST);
}
clear_mask = GL_DEPTH_BUFFER_BIT;
if ( fgGetBool("/sim/rendering/wireframe") ) {
clear_mask |= GL_COLOR_BUFFER_BIT;
}
if ( skyblend ) {
if ( fgGetBool("/sim/rendering/textures") ) {
// glClearColor(black[0], black[1], black[2], black[3]);
glClearColor(l->adj_fog_color()[0], l->adj_fog_color()[1],
l->adj_fog_color()[2], l->adj_fog_color()[3]);
clear_mask |= GL_COLOR_BUFFER_BIT;
}
} else {
glClearColor(l->sky_color()[0], l->sky_color()[1],
l->sky_color()[2], l->sky_color()[3]);
clear_mask |= GL_COLOR_BUFFER_BIT;
}
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
if ( multi_pass_clouds && draw_clouds ) {
glClearStencil( 0 );
clear_mask |= GL_STENCIL_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();
// update fog params if visibility has changed
double visibility_meters = fgGetDouble("/environment/visibility-m");
thesky->set_visibility(visibility_meters);
thesky->modify_vis( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER,
( global_multi_loop * fgGetInt("/sim/speed-up") )
/ (double)fgGetInt("/sim/model-hz") );
2000-06-20 22:31:47 +00:00
// Set correct opengl fog density
glFogf (GL_FOG_DENSITY, fog_exp2_density);
// update the sky dome
if ( skyblend ) {
/*
SG_LOG( SG_GENERAL, SG_BULK, "thesky->repaint() sky_color = "
<< l->sky_color()[0] << " "
<< l->sky_color()[1] << " "
<< l->sky_color()[2] << " "
<< l->sky_color()[3] );
SG_LOG( SG_GENERAL, SG_BULK, " fog = "
<< l->fog_color()[0] << " "
<< l->fog_color()[1] << " "
<< l->fog_color()[2] << " "
<< l->fog_color()[3] );
SG_LOG( SG_GENERAL, SG_BULK,
" sun_angle = " << l->sun_angle
<< " moon_angle = " << l->moon_angle );
*/
static SGSkyColor scolor;
FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
scolor.sky_color = l->sky_color();
scolor.fog_color = l->adj_fog_color();
scolor.cloud_color = l->cloud_color();
scolor.sun_angle = l->get_sun_angle();
scolor.moon_angle = l->get_moon_angle();
scolor.nplanets = globals->get_ephem()->getNumPlanets();
scolor.nstars = globals->get_ephem()->getNumStars();
scolor.planet_data = globals->get_ephem()->getPlanets();
scolor.star_data = globals->get_ephem()->getStars();
thesky->repaint( scolor );
/*
SG_LOG( SG_GENERAL, SG_BULK,
"thesky->reposition( view_pos = " << view_pos[0] << " "
<< view_pos[1] << " " << view_pos[2] );
SG_LOG( SG_GENERAL, SG_BULK,
" zero_elev = " << zero_elev[0] << " "
<< zero_elev[1] << " " << zero_elev[2]
<< " lon = " << cur_fdm_state->get_Longitude()
<< " lat = " << cur_fdm_state->get_Latitude() );
SG_LOG( SG_GENERAL, SG_BULK,
" sun_rot = " << l->get_sun_rotation
<< " gst = " << SGTime::cur_time_params->getGst() );
SG_LOG( SG_GENERAL, SG_BULK,
" sun ra = " << globals->get_ephem()->getSunRightAscension()
<< " sun dec = " << globals->get_ephem()->getSunDeclination()
<< " moon ra = " << globals->get_ephem()->getMoonRightAscension()
<< " moon dec = " << globals->get_ephem()->getMoonDeclination() );
*/
// The sun and moon distances are scaled down versions
// of the actual distance to get both the moon and the sun
// within the range of the far clip plane.
// Moon distance: 384,467 kilometers
// Sun distance: 150,000,000 kilometers
double sun_horiz_eff, moon_horiz_eff;
if (fgGetBool("/sim/rendering/horizon-effect")) {
sun_horiz_eff = 0.67+pow(0.5+cos(l->get_sun_angle())*2/2, 0.33)/3;
moon_horiz_eff = 0.67+pow(0.5+cos(l->get_moon_angle())*2/2, 0.33)/3;
} else {
sun_horiz_eff = moon_horiz_eff = 1.0;
}
static SGSkyState sstate;
sstate.view_pos = current__view->get_view_pos();
sstate.zero_elev = current__view->get_zero_elev();
sstate.view_up = current__view->get_world_up();
sstate.lon = current__view->getLongitude_deg()
* SGD_DEGREES_TO_RADIANS;
sstate.lat = current__view->getLatitude_deg()
* SGD_DEGREES_TO_RADIANS;
sstate.alt = current__view->getAltitudeASL_ft()
* SG_FEET_TO_METER;
sstate.spin = l->get_sun_rotation();
sstate.gst = globals->get_time_params()->getGst();
sstate.sun_ra = globals->get_ephem()->getSunRightAscension();
sstate.sun_dec = globals->get_ephem()->getSunDeclination();
sstate.sun_dist = 50000.0 * sun_horiz_eff;
sstate.moon_ra = globals->get_ephem()->getMoonRightAscension();
sstate.moon_dec = globals->get_ephem()->getMoonDeclination();
sstate.moon_dist = 40000.0 * moon_horiz_eff;
2003-07-31 14:47:56 +00:00
thesky->reposition( sstate, delta_time_sec );
}
glEnable( GL_DEPTH_TEST );
if ( strcmp(fgGetString("/sim/rendering/fog"), "disabled") ) {
glEnable( GL_FOG );
glFogi( GL_FOG_MODE, GL_EXP2 );
glFogfv( GL_FOG_COLOR, l->adj_fog_color() );
}
// set sun/lighting parameters
ssgGetLight( 0 ) -> setPosition( l->sun_vec() );
// 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 );
ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient() );
ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
ssgGetLight( 0 ) -> setColour( GL_SPECULAR, l->scene_specular() );
// texture parameters
// glEnable( GL_TEXTURE_2D );
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() );
1999-06-29 14:57:00 +00:00
double agl =
current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
- globals->get_scenery()->get_cur_elev();
if ( agl > 10.0 ) {
scene_nearplane = 10.0f;
scene_farplane = 120000.0f;
} else {
scene_nearplane = groundlevel_nearplane->getDoubleValue();
scene_farplane = 120000.0f;
}
ssgSetNearFar( scene_nearplane, scene_farplane );
1999-06-19 04:48:07 +00:00
#ifdef FG_MPLAYER_AS
// Update any multiplayer models
globals->get_multiplayer_rx_mgr()->Update();
#endif
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
if ( draw_otw && skyblend ) {
// draw the sky backdrop
2001-03-28 17:52:40 +00:00
// 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 );
2001-03-28 17:52:40 +00:00
// return to the desired diffuse color
ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
}
2000-06-20 02:29:31 +00:00
// 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 );
}
if ( draw_otw ) {
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
if ( draw_clouds ) {
// Draw the terrain
FGTileMgr::set_tile_filter( true );
sgSetModelFilter( false );
globals->get_aircraft_model()->select( false );
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
// Disable depth buffer update, draw the clouds
glDepthMask( GL_FALSE );
thesky->drawUpperClouds();
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
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_REPLACE, GL_REPLACE, 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 );
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
}
}
// This is a bit kludgy. Every 200 frames, do an extra
// traversal of the scene graph without drawing anything, but
// with the field-of-view set to 360x360 degrees. This
// ensures that out-of-range random objects that are not in
// the current view frustum will still be freed properly.
static int counter = 0;
counter++;
if (counter == 200) {
sgFrustum f;
f.setFOV(360, 360);
// No need to put the near plane too close;
// this way, at least the aircraft can be
// culled.
f.setNearFar(1000, 1000000);
sgMat4 m;
ssgGetModelviewMatrix(m);
FGTileMgr::set_tile_filter( true );
sgSetModelFilter( true );
globals->get_scenery()->get_scene_graph()->cull(&f, m, true);
counter = 0;
}
// change state for lighting here
// draw runway lighting
glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
2002-10-17 04:34:32 +00:00
ssgSetNearFar( scene_nearplane, scene_farplane );
if ( enhanced_lighting ) {
// Enable states for drawing points with GL_extension
glEnable(GL_POINT_SMOOTH);
if ( distance_attenuation && glPointParameterIsSupported )
{
// Enable states for drawing points with GL_extension
glEnable(GL_POINT_SMOOTH);
float quadratic[3] = {1.0, 0.001, 0.0000001};
// makes the points fade as they move away
glPointParameterfvPtr(GL_DISTANCE_ATTENUATION_EXT, quadratic);
glPointParameterfPtr(GL_POINT_SIZE_MIN_EXT, 1.0);
}
glPointSize(4.0);
// blending function for runway lights
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glPolygonMode(GL_FRONT, GL_POINT);
// draw runway lighting
if ( draw_otw ) {
ssgCullAndDraw( globals->get_scenery()->get_vasi_lights_root() );
ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
}
// change punch through and then draw taxi lighting
glFogf ( GL_FOG_DENSITY, fog_exp2_density );
// sgVec3 taxi_fog;
// sgSetVec3( taxi_fog, 0.0, 0.0, 0.0 );
// glFogfv ( GL_FOG_COLOR, taxi_fog );
if ( draw_otw ) {
ssgCullAndDraw( globals->get_scenery()->get_taxi_lights_root() );
}
// clean up lighting
glPolygonMode(GL_FRONT, GL_FILL);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
//static int _frame_count = 0;
//if (_frame_count % 30 == 0) {
// printf("SSG: %s\n", ssgShowStats());
//}
//else {
// ssgShowStats();
//}
//_frame_count++;
if ( enhanced_lighting ) {
if ( distance_attenuation && glPointParameterIsSupported ) {
glPointParameterfvPtr(GL_DISTANCE_ATTENUATION_EXT,
default_attenuation);
}
glPointSize(1.0);
glDisable(GL_POINT_SMOOTH);
}
// draw ground lighting
glFogf (GL_FOG_DENSITY, ground_exp2_punch_through);
if ( draw_otw ) {
ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
}
if ( draw_otw && fgGetBool("/sim/rendering/clouds3d") ) {
glDisable( GL_FOG );
glDisable( GL_LIGHTING );
// cout << "drawing new clouds" << endl;
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ) ;
/*
glEnable( GL_TEXTURE_2D );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
*/
#ifdef FG_USE_CLOUDS_3D
sgClouds3d->Draw((sgVec4 *)current__view->get_VIEW());
#endif
glEnable( GL_FOG );
glEnable( GL_LIGHTING );
glEnable( GL_DEPTH_TEST );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
}
if ( draw_otw && 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 );
}
}
if ( draw_otw ) {
FGTileMgr::set_tile_filter( false );
sgSetModelFilter( false );
globals->get_aircraft_model()->select( true );
globals->get_model_mgr()->draw();
globals->get_aircraft_model()->draw();
// If the view is internal, the previous line draw the
// cockpit with modified near/far clip planes and deselect
// the aircraft in the global scenegraph
// Otherwise, it just enables the aircraft: The scenegraph
// must be drawn again to see the plane.
ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
FGTileMgr::set_tile_filter( true );
sgSetModelFilter( true );
globals->get_aircraft_model()->select( true );
}
// display HUD && Panel
glDisable( GL_FOG );
glDisable( GL_DEPTH_TEST );
// glDisable( GL_CULL_FACE );
// glDisable( GL_TEXTURE_2D );
// update the controls subsystem
globals->get_controls()->update(delta_time_sec);
hud_and_panel->apply();
fgCockpitUpdate();
// Use the hud_and_panel ssgSimpleState for rendering the ATC output
// This only works properly if called before the panel call
if((fgGetBool("/sim/ATC/enabled")) || (fgGetBool("/sim/ai-traffic/enabled")))
globals->get_ATC_display()->update(delta_time_sec);
// update the panel subsystem
if ( globals->get_current_panel() != NULL ) {
globals->get_current_panel()->update(delta_time_sec);
}
2002-10-29 19:44:03 +00:00
fgUpdate3DPanels();
// We can do translucent menus, so why not. :-)
menus->apply();
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
puDisplay();
// glDisable ( GL_BLEND ) ;
glEnable( GL_DEPTH_TEST );
glEnable( GL_FOG );
// Fade out the splash screen over the first three seconds.
double t = globals->get_sim_time_sec();
if ( t <= 1.0 ) {
fgSplashUpdate(0.0, 1.0);
} else if ( t <= 3.0) {
fgSplashUpdate(0.0, (3.0 - t) / 2.0);
}
}
1998-04-21 17:02:27 +00:00
}
// Update internal time dependent calculations (i.e. flight model)
2002-05-11 21:10:11 +00:00
// FIXME: this distinction is obsolete; all subsystems now get delta
// time on update.
void fgUpdateTimeDepCalcs() {
2001-01-17 23:30:35 +00:00
static bool inited = false;
static const SGPropertyNode *replay_master
= fgGetNode( "/sim/freeze/replay", true );
static SGPropertyNode *replay_time
= fgGetNode( "/sim/replay/time", true );
// static const SGPropertyNode *replay_end_time
// = fgGetNode( "/sim/replay/end-time", true );
//SG_LOG(SG_FLIGHT,SG_INFO, "Updating time dep calcs()");
// Initialize the FDM here if it hasn't been and if we have a
// scenery elevation hit.
// cout << "cur_fdm_state->get_inited() = " << cur_fdm_state->get_inited()
// << " cur_elev = " << scenery.get_cur_elev() << endl;
if ( !cur_fdm_state->get_inited() &&
globals->get_scenery()->get_cur_elev() > -9990 )
{
SG_LOG(SG_FLIGHT,SG_INFO, "Finally initializing fdm");
cur_fdm_state->init();
if ( cur_fdm_state->get_bound() ) {
cur_fdm_state->unbind();
}
cur_fdm_state->bind();
}
// conceptually, the following block could be done for each fdm
// instance ...
if ( cur_fdm_state->get_inited() ) {
// we have been inited, and we are good to go ...
2001-01-17 23:30:35 +00:00
if ( !inited ) {
inited = true;
}
2001-01-17 23:30:35 +00:00
if ( ! replay_master->getBoolValue() ) {
cur_fdm_state->update( delta_time_sec );
} else {
FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
r->replay( replay_time->getDoubleValue() );
replay_time->setDoubleValue( replay_time->getDoubleValue()
+ ( delta_time_sec
* fgGetInt("/sim/speed-up") ) );
}
} else {
// do nothing, fdm isn't inited yet
}
globals->get_model_mgr()->update(delta_time_sec);
globals->get_aircraft_model()->update(delta_time_sec);
// update the view angle
globals->get_viewmgr()->update(delta_time_sec);
// Update solar system
2000-07-08 05:09:24 +00:00
globals->get_ephem()->update( globals->get_time_params()->getMjd(),
globals->get_time_params()->getLst(),
cur_fdm_state->get_Latitude() );
// Update radio stack model
current_radiostack->update(delta_time_sec);
1998-04-21 17:02:27 +00:00
}
void fgInitTimeDepCalcs( void ) {
2002-04-05 00:38:55 +00:00
// noop for now
1998-04-21 17:02:27 +00:00
}
1999-09-01 20:24:54 +00:00
static const double alt_adjust_ft = 3.758099;
2001-03-24 04:56:46 +00:00
static const double alt_adjust_m = alt_adjust_ft * SG_FEET_TO_METER;
1998-04-21 17:02:27 +00:00
1999-09-01 20:24:54 +00:00
// What should we do when we have nothing else to do? Let's get ready
// for the next move and update the display?
1998-04-21 17:02:27 +00:00
static void fgMainLoop( void ) {
int model_hz = fgGetInt("/sim/model-hz");
static const SGPropertyNode *longitude
= fgGetNode("/position/longitude-deg");
static const SGPropertyNode *latitude
= fgGetNode("/position/latitude-deg");
static const SGPropertyNode *altitude
= fgGetNode("/position/altitude-ft");
static const SGPropertyNode *clock_freeze
= fgGetNode("/sim/freeze/clock", true);
static const SGPropertyNode *cur_time_override
= fgGetNode("/sim/time/cur-time-override", true);
// static const SGPropertyNode *replay_master
// = fgGetNode("/sim/freeze/replay", true);
// Update the elapsed time.
static bool first_time = true;
if ( first_time ) {
last_time_stamp.stamp();
first_time = false;
}
double throttle_hz = fgGetDouble("/sim/frame-rate-throttle-hz", 0.0);
if ( throttle_hz > 0.0 ) {
// simple frame rate throttle
double dt = 1000000.0 / throttle_hz;
current_time_stamp.stamp();
while ( current_time_stamp - last_time_stamp < dt ) {
current_time_stamp.stamp();
}
} else {
// run as fast as the app will go
current_time_stamp.stamp();
}
real_delta_time_sec
= double(current_time_stamp - last_time_stamp) / 1000000.0;
if ( clock_freeze->getBoolValue() ) {
delta_time_sec = 0;
} else {
delta_time_sec = real_delta_time_sec;
}
last_time_stamp = current_time_stamp;
globals->inc_sim_time_sec( delta_time_sec );
SGAnimation::set_sim_time_sec( globals->get_sim_time_sec() );
// These are useful, especially for Nasal scripts.
fgSetDouble("/sim/time/delta-realtime-sec", real_delta_time_sec);
fgSetDouble("/sim/time/delta-sec", delta_time_sec);
static long remainder = 0;
long elapsed;
#ifdef FANCY_FRAME_COUNTER
int i;
double accum;
#else
1998-12-18 23:40:55 +00:00
static time_t last_time = 0;
static int frames = 0;
#endif // FANCY_FRAME_COUNTER
1998-04-21 17:02:27 +00:00
2000-07-07 20:28:51 +00:00
SGTime *t = globals->get_time_params();
1998-04-21 17:02:27 +00:00
globals->get_event_mgr()->update(delta_time_sec);
2001-03-24 06:03:11 +00:00
SG_LOG( SG_ALL, SG_DEBUG, "Running Main Loop");
SG_LOG( SG_ALL, SG_DEBUG, "======= ==== ====");
#if defined( ENABLE_PLIB_JOYSTICK )
1998-12-18 23:40:55 +00:00
// Read joystick and update control settings
// if ( fgGetString("/sim/control-mode") == "joystick" )
// {
// fgJoystickRead();
// }
1998-12-18 23:40:55 +00:00
#endif
// Fix elevation. I'm just sticking this here for now, it should
// probably move eventually
/* printf("Before - ground = %.2f runway = %.2f alt = %.2f\n",
scenery.get_cur_elev(),
cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
/* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
scenery.get_cur_elev(),
cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
// cout << "Warp = " << globals->get_warp() << endl;
1998-04-21 17:02:27 +00:00
// update "time"
static bool last_clock_freeze = false;
if ( clock_freeze->getBoolValue() ) {
// clock freeze requested
if ( cur_time_override->getLongValue() == 0 ) {
fgSetLong( "/sim/time/cur-time-override", t->get_cur_time() );
globals->set_warp( 0 );
}
} else {
// no clock freeze requested
if ( last_clock_freeze == true ) {
// clock just unfroze, let's set warp as the difference
// between frozen time and current time so we don't get a
// time jump (and corresponding sky object and lighting
// jump.)
globals->set_warp( cur_time_override->getLongValue() - time(NULL) );
fgSetLong( "/sim/time/cur-time-override", 0 );
}
if ( globals->get_warp_delta() != 0 ) {
globals->inc_warp( globals->get_warp_delta() );
}
}
last_clock_freeze = clock_freeze->getBoolValue();
t->update( longitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS,
cur_time_override->getLongValue(),
globals->get_warp() );
1998-04-21 17:02:27 +00:00
if (globals->get_warp_delta() != 0) {
FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
l->update( 0.5 );
}
// update magvar model
globals->get_mag()->update( longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
altitude->getDoubleValue() * SG_FEET_TO_METER,
globals->get_time_params()->getJD() );
// Get elapsed time (in usec) for this past frame
1998-04-21 17:02:27 +00:00
elapsed = fgGetTimeInterval();
2001-03-24 06:03:11 +00:00
SG_LOG( SG_ALL, SG_DEBUG,
"Elapsed time interval is = " << elapsed
<< ", previous remainder is = " << remainder );
// Calculate frame rate average
#ifdef FANCY_FRAME_COUNTER
/* old fps calculation */
if ( elapsed > 0 ) {
double tmp;
accum = 0.0;
for ( i = FG_FRAME_RATE_HISTORY - 2; i >= 0; i-- ) {
tmp = general.get_frame(i);
accum += tmp;
// printf("frame[%d] = %.2f\n", i, g->frames[i]);
general.set_frame(i+1,tmp);
}
tmp = 1000000.0 / (float)elapsed;
general.set_frame(0,tmp);
// printf("frame[0] = %.2f\n", general.frames[0]);
accum += tmp;
general.set_frame_rate(accum / (float)FG_FRAME_RATE_HISTORY);
// printf("ave = %.2f\n", general.frame_rate);
}
#else
if ( (t->get_cur_time() != last_time) && (last_time > 0) ) {
general.set_frame_rate( frames );
fgSetInt("/sim/frame-rate", frames);
SG_LOG( SG_ALL, SG_DEBUG,
"--> Frame rate is = " << general.get_frame_rate() );
frames = 0;
1998-12-18 23:40:55 +00:00
}
last_time = t->get_cur_time();
1998-12-18 23:40:55 +00:00
++frames;
#endif
// Run ATC subsystem
if (fgGetBool("/sim/ATC/enabled"))
globals->get_ATC_mgr()->update(delta_time_sec);
// Run the AI subsystem
if (fgGetBool("/sim/ai-traffic/enabled"))
globals->get_AI_mgr()->update(delta_time_sec);
1998-04-21 17:02:27 +00:00
// Run flight model
// Calculate model iterations needed for next frame
elapsed += remainder;
global_multi_loop = (long)(((double)elapsed * 0.000001) * model_hz );
remainder = elapsed - ( (global_multi_loop*1000000) / model_hz );
2001-03-24 06:03:11 +00:00
SG_LOG( SG_ALL, SG_DEBUG,
"Model iterations needed = " << global_multi_loop
<< ", new remainder = " << remainder );
2001-01-17 23:30:35 +00:00
// chop max interations to something reasonable if the sim was
// delayed for an excesive amount of time
if ( global_multi_loop > 2.0 * model_hz ) {
global_multi_loop = (int)(2.0 * model_hz );
remainder = 0;
2001-01-17 23:30:35 +00:00
}
// flight model
if ( global_multi_loop > 0 ) {
fgUpdateTimeDepCalcs();
} else {
SG_LOG( SG_ALL, SG_DEBUG,
"Elapsed time is zero ... we're zinging" );
1998-04-21 17:02:27 +00:00
}
1999-11-19 02:10:24 +00:00
// Do any I/O channel work that might need to be done
globals->get_io()->update( real_delta_time_sec );
1998-04-21 17:02:27 +00:00
// see if we need to load any deferred-load textures
globals->get_matlib()->load_next_deferred();
// Run audio scheduler
#ifdef ENABLE_AUDIO_SUPPORT
if ( globals->get_soundmgr()->is_working() ) {
globals->get_soundmgr()->update( delta_time_sec );
}
#endif
globals->get_subsystem_mgr()->update(delta_time_sec);
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
//
// Tile Manager updates - see if we need to load any new scenery tiles.
// this code ties together the fdm, viewer and scenery classes...
// we may want to move this to it's own class at some point
//
double visibility_meters = fgGetDouble("/environment/visibility-m");
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
FGViewer *current_view = globals->get_current_view();
// get the location data for the primary FDM (now hardcoded to ac model)...
SGLocation *acmodel_loc = NULL;
acmodel_loc = (SGLocation *)globals->
get_aircraft_model()->get3DModel()->getSGLocation();
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
// update tile manager for FDM...
// ...only if location is different than the current-view location
// (to avoid duplicating effort)
if( !fgGetBool("/sim/current-view/config/from-model") ) {
if( acmodel_loc != NULL ) {
globals->get_tile_mgr()->prep_ssg_nodes( acmodel_loc,
visibility_meters );
globals->get_tile_mgr()->
update( acmodel_loc, visibility_meters,
acmodel_loc->
get_absolute_view_pos(globals->
get_scenery()->get_center()) );
// save results of update in SGLocation for fdm...
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
acmodel_loc->
set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
fgSetDouble("/position/ground-elev-m",
globals->get_scenery()->get_cur_elev());
}
acmodel_loc->
set_tile_center( globals->get_scenery()->get_next_center() );
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
}
}
globals->get_tile_mgr()->prep_ssg_nodes( current_view->getSGLocation(),
visibility_meters );
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
// update tile manager for view...
// IMPORTANT!!! the tilemgr update for view location _must_ be
// done last after the FDM's until all of Flight Gear code
// references the viewer's location for elevation instead of the
// "scenery's" current elevation.
SGLocation *view_location = globals->get_current_view()->getSGLocation();
globals->get_tile_mgr()->update( view_location, visibility_meters,
current_view->get_absolute_view_pos() );
// save results of update in SGLocation for fdm...
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
current_view->getSGLocation()->
set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
}
current_view->getSGLocation()->
set_tile_center( globals->get_scenery()->get_next_center() );
#ifdef ENABLE_AUDIO_SUPPORT
// Right now we make a simplifying assumption that the primary
// aircraft is the source of all sounds and that all sounds are
// positioned relative to the current view position.
static sgVec3 last_pos_offset;
// set positional offset for sources
sgVec3 source_pos_offset;
sgSubVec3( source_pos_offset,
view_location->get_view_pos(), acmodel_loc->get_view_pos() );
// cout << "pos all = " << source_pos_offset[0] << " " << source_pos_offset[1] << " " << source_pos_offset[2] << endl;
globals->get_soundmgr()->set_source_pos_all( source_pos_offset );
// set the velocity
sgVec3 source_vel;
sgSubVec3( source_vel, source_pos_offset, last_pos_offset );
sgScaleVec3( source_vel, delta_time_sec );
sgCopyVec3( last_pos_offset, source_pos_offset );
// cout << "vel = " << source_vel[0] << " " << source_vel[1] << " " << source_vel[2] << endl;
globals->get_soundmgr()->set_source_vel_all( source_vel );
// Right now we make a simplifying assumption that the listener is
// always positioned at the origin.
sgVec3 listener_pos;
sgSetVec3( listener_pos, 0.0, 0.0, 0.0 );
// cout << "listener = " << listener_pos[0] << " " << listener_pos[1] << " " << listener_pos[2] << endl;
globals->get_soundmgr()->set_listener_pos( listener_pos );
#endif
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
// If fdm location is same as viewer's then we didn't do the
// update for fdm location above so we need to save the viewer
// results in the fdm SGLocation as well...
if( fgGetBool("/sim/current-view/config/from-model") ) {
if( acmodel_loc != 0 ) {
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
acmodel_loc->set_cur_elev_m( globals->get_scenery()->
get_cur_elev() );
fgSetDouble("/position/ground-elev-m",
globals->get_scenery()->get_cur_elev());
}
acmodel_loc->set_tile_center( globals->get_scenery()->
get_next_center() );
From: "Jim Wilson" <jimw@kelcomaine.com> This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
2002-05-17 17:25:28 +00:00
}
}
// END Tile Manager udpates
if (fgGetBool("/sim/rendering/specular-highlight")) {
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
// glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
} else {
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
// glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
}
fgRequestRedraw();
2001-03-24 06:03:11 +00:00
SG_LOG( SG_ALL, SG_DEBUG, "" );
1998-04-21 17:02:27 +00:00
}
// This is the top level master main function that is registered as
// our idle funciton
// The first few passes take care of initialization things (a couple
// per pass) and once everything has been initialized fgMainLoop from
// then on.
static void fgIdleFunction ( void ) {
// printf("idle state == %d\n", idle_state);
if ( idle_state == 0 ) {
fgSetBool("sim/initialised", false);
// Initialize the splash screen right away
if ( fgGetBool("/sim/startup/splash-screen") ) {
fgSplashInit(fgGetString("/sim/startup/splash-texture"));
}
idle_state++;
} else if ( idle_state == 1 ) {
// Initialize audio support
#ifdef ENABLE_AUDIO_SUPPORT
// Start the intro music
if ( fgGetBool("/sim/startup/intro-music") ) {
SGPath mp3file( globals->get_fg_root() );
mp3file.append( "Sounds/intro.mp3" );
SG_LOG( SG_GENERAL, SG_INFO,
"Starting intro music: " << mp3file.str() );
#if defined( __CYGWIN__ )
string command = "start /m `cygpath -w " + mp3file.str() + "`";
#elif defined( WIN32 )
string command = "start /m " + mp3file.str();
#else
string command = "mpg123 " + mp3file.str() + "> /dev/null 2>&1";
#endif
system ( command.c_str() );
}
#endif
idle_state++;
} else if ( idle_state == 2 ) {
// These are a few miscellaneous things that aren't really
// "subsystems" but still need to be initialized.
#ifdef USE_GLIDE
if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
grTexLodBiasValue ( GR_TMU0, 1.0 ) ;
}
#endif
idle_state++;
} else if ( idle_state == 3 ) {
// This is the top level init routine which calls all the
// other subsystem initialization routines. If you are adding
// a subsystem to flightgear, its initialization call should
// located in this routine.
if( !fgInitSubsystems()) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Subsystem initializations failed ..." );
exit(-1);
}
idle_state++;
} else if ( idle_state == 4 ) {
// Initialize the time offset (warp) after fgInitSubsystem
// (which initializes the lighting interpolation tables.)
fgInitTimeOffset();
// setup OpenGL view parameters
fgInitVisuals();
// Read the list of available aircrafts
fgReadAircraft();
idle_state++;
} else if ( idle_state == 5 ) {
idle_state++;
} else if ( idle_state == 6 ) {
// sleep(1);
idle_state = 1000;
SG_LOG( SG_GENERAL, SG_INFO, "Panel visible = " << fgPanelVisible() );
fgReshape( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
}
if ( idle_state == 1000 ) {
// We've finished all our initialization steps, from now on we
// run the main loop.
fgSetBool("sim/initialised",true);
fgRegisterIdleHandler(fgMainLoop);
} else {
if ( fgGetBool("/sim/startup/splash-screen") ) {
fgSplashUpdate(0.0, 1.0);
}
}
}
1999-05-06 22:16:12 +00:00
// options.cxx needs to see this for toggle_panel()
1998-04-21 17:02:27 +00:00
// Handle new window size or exposure
1999-05-06 22:16:12 +00:00
void fgReshape( int width, int height ) {
int view_h;
Virtual cockpit patches from Andy Ross: What the attached patch does is map your panel definition onto a (non z-buffered) quad in front of your face. You can twist the view around and see it move in the appropriate ways. Apply the patch (let me know if folks need help with that step), and then set the /sim/virtual-cockpit property to true. You can do this on the command line with --prop:/sim/virtual-cockpit=1, or via the property picker. Bind it to a key for fast toggling if you like. The default bindings don't allow for "panning" the view, so you'll have to modify yours. These are the mappings to my joystick's hat switch, for those who need hints: <axis n="6"> <desc>View Direction</desc> <low> <repeatable>true</repeatable> <binding> <command>property-adjust</command> <property>/sim/view/goal-offset-deg</property> <step type="double">1.0</step> </binding> </low> <high> <repeatable>true</repeatable> <binding> <command>property-adjust</command> <property>/sim/view/goal-offset-deg</property> <step type="double">-1.0</step> </binding> </high> </axis> <axis n="7"> <desc>View Elevation</desc> <low> <repeatable>true</repeatable> <binding> <command>property-adjust</command> <property>/sim/view/goal-tilt-deg</property> <step type="double">1.0</step> </binding> </low> <high> <repeatable>true</repeatable> <binding> <command>property-adjust</command> <property>/sim/view/goal-tilt-deg</property> <step type="double">-1.0</step> </binding> </high> </axis> While the current implementation is happy with just plastering the panel's notion of "screen" into the 3D world, this is actually more general. Each panel can, in principle, have it's own coordinate system, and you could build a cockpit out of a bunch of them. The mapping is specified by providing a 3D coordinate for three corners of the quad the panel should be mapped to; this should be pretty simple to work with. All that's needed for a perfectly general solution is a convention on where to store the information (a cockpit xml file, or put it in the aircraft -set file, or...), and some work on the panel's coordinate system conventions (some of which don't coexist very nicely with a generalized 3D environment). Combine that with a plib model for the non-panel interior of the cockpit, and we're golden. I'm actually really pleased with this. It worked better and more quickly than I could have imagined, and impact on the surrounding code is quite light -- a few property tests only. But some stuff is still missing: + No equivalent work was done to the HUD, so it still displays incorrect headings when the view changes. The use of pixel coordinates deep in the HUD code is going to give me fits doing the port, I sure. It's not nearly so well put together as the panel (where I just changed the setup code -- none of the rendering code changed at all). + I forgot that the panel was clickable. :) Input events still have the screen coordinates, which essentially kills the interactivity when in virtual cockpit mode. This won't be hard to fix; it's only broken because I forgot the feature existed. And one note about the implementation choice: to get away from the inevitable near clip plane issue, the virtual cockpit renderer simply disables the z buffer. This means that cockpits built using these panels need to be z-sorted, which isn't too hard since they are static geometry. It also means that no two "virtual panels" can ever be allowed to interpenetrate. No biggie.
2002-03-03 00:06:24 +00:00
if ( (!fgGetBool("/sim/virtual-cockpit"))
&& fgPanelVisible() && idle_state == 1000 ) {
view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
globals->get_current_panel()->getYOffset()) / 768.0);
} else {
view_h = height;
}
glViewport( 0, (GLint)(height - view_h), (GLint)(width), (GLint)(view_h) );
1998-04-21 17:02:27 +00:00
fgSetInt("/sim/startup/xsize", width);
fgSetInt("/sim/startup/ysize", height);
guiInitMouse(width, height);
1999-09-28 22:43:52 +00:00
// for all views
FGViewMgr *viewmgr = globals->get_viewmgr();
if (viewmgr) {
for ( int i = 0; i < viewmgr->size(); ++i ) {
viewmgr->get_view(i)->
set_aspect_ratio((float)view_h / (float)width);
}
1999-08-31 23:22:05 +00:00
ssgSetFOV( 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() );
#endif
}
fgHUDReshape();
1998-04-21 17:02:27 +00:00
}
// do some clean up on exit. Specifically we want to call alutExit()
// which happens in the sound manager destructor.
void fgExitCleanup() {
delete globals;
2004-04-25 02:17:03 +00:00
fgOSExit(0);
}
// Main top level initialization
2003-08-17 09:54:41 +00:00
bool fgMainInit( int argc, char **argv ) {
2000-09-10 00:04:50 +00:00
#if defined( macintosh )
2000-04-27 21:57:08 +00:00
freopen ("stdout.txt", "w", stdout );
freopen ("stderr.txt", "w", stderr );
argc = ccommand( &argv );
#endif
// set default log levels
sglog().setLogLevels( SG_ALL, SG_ALERT );
atexit(fgExitCleanup);
string version;
#ifdef FLIGHTGEAR_VERSION
version = FLIGHTGEAR_VERSION;
#else
version = "unknown version";
#endif
2001-03-24 06:03:11 +00:00
SG_LOG( SG_GENERAL, SG_INFO, "FlightGear: Version "
<< version );
SG_LOG( SG_GENERAL, SG_INFO, "Built with " << SG_COMPILER_STR << endl );
// Allocate global data structures. This needs to happen before
// we parse command line options
globals = new FGGlobals;
// seed the random number generater
sg_srandom_time();
FGControls *controls = new FGControls;
globals->set_controls( controls );
string_list *col = new string_list;
globals->set_channel_options_list( col );
// Scan the config file(s) and command line options to see if
// fg_root was specified (ignore all other options for now)
fgInitFGRoot(argc, argv);
// Check for the correct base package version
static char required_version[] = "0.9.4";
string base_version = fgBasePackageVersion();
if ( !(base_version == required_version) ) {
// tell the operator how to use this application
SG_LOG( SG_GENERAL, SG_ALERT, "" ); // To popup the console on windows
cerr << endl << "Base package check failed ... " \
<< "Found version " << base_version << " at: " \
<< globals->get_fg_root() << endl;
cerr << "Please upgrade to version: " << required_version << endl;
#ifdef _MSC_VER
cerr << "Hit a key to continue..." << endl;
cin.get();
#endif
exit(-1);
}
// Initialize the Aircraft directory to "" (UIUC)
aircraft_dir = "";
// Load the configuration parameters. (Command line options
// overrides config file options. Config file options override
// defaults.)
if ( !fgInitConfig(argc, argv) ) {
SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." );
exit(-1);
}
1998-08-20 15:10:33 +00:00
// Initialize the Window/Graphics environment.
#if !defined(__APPLE__) || defined(OSX_BUNDLE)
// Mac OS X command line ("non-bundle") applications call this
// from main(), in bootstrap.cxx. Andy doesn't know why, someone
// feel free to add comments...
fgOSInit(&argc, argv);
#endif
1998-08-20 15:10:33 +00:00
fgRegisterWindowResizeHandler( fgReshape );
fgRegisterIdleHandler( fgIdleFunction );
fgRegisterDrawHandler( fgRenderFrame );
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
#ifdef FG_ENABLE_MULTIPASS_CLOUDS
bool get_stencil_buffer = true;
#else
bool get_stencil_buffer = false;
#endif
// Clouds3D requires an alpha channel
// clouds may require stencil buffer
fgOSOpenWindow( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize"),
2004-04-01 15:44:13 +00:00
fgGetInt("/sim/rendering/bits-per-pixel"),
Frederic Bouvier: FG_ENABLE_MULTIPASS_CLOUDS must be defined to enable the algorithm. I made this because the stencil buffer must be initialized at the beginning of the program and OpenGL can fallback to software rendering if it can't find a visual with stencil buffer. I didn't touch the configure script, so CXXFLAGS=-DFG_ENABLE_MULTIPASS_CLOUDS must be set before running ./configure. If FG_ENABLE_MULTIPASS_CLOUDS is defined, the main render loop begins by reading the /sim/rendering/multi-pass-clouds property. It is a boolean property so there are only two quality levels. false means no multi pass and no use of the stencil buffer, true means an additionnal pass for both upper and lower cloud layers. The algorithms are as follow : /sim/rendering/multi-pass-clouds=false 1. draw sky dome 2. draw terrain only 3. draw clouds above the viewer 4. draw models except the aircraft 5. draw clouds below the viewer 6. draw the aircraft. The cloud rendering doesn't update the depth buffer. This means that models overwrite clouds above the viewer. This is only noticeable for tall buildings and when flying very low. Also, drawing low clouds after models means that they are not blended with models' translucent surfaces. Large transparent area require alpha test enabled and AI aircraft canopy are making holes. The pilot's aircraft being rendered at the end, there is no problem with canopy or prop disc. /sim/rendering/multi-pass-clouds=true 1. draw the sky dome 2. draw the terrain only 3. draw all clouds 4. draw models except the aircraft 5. redraw the clouds where the models where drawn ( stencil test on ) 6. draw the aircraft The assumptions made by this algoritm are that the terrain is not transparent ( should be true in all cases and that there are no clouds between the aircraft and the viewer. Assuming these facts, there should be no blending bugs. The screenshot rendering is not updated yet.
2004-04-02 14:40:54 +00:00
fgGetBool("/sim/rendering/clouds3d"),
get_stencil_buffer,
fgGetBool("/sim/startup/fullscreen") );
// This seems to be the absolute earliest in the init sequence
// that these calls will return valid info. Too bad it's after
// we've already created and sized out window. :-(
general.set_glVendor( (char *)glGetString ( GL_VENDOR ) );
general.set_glRenderer( (char *)glGetString ( GL_RENDERER ) );
general.set_glVersion( (char *)glGetString ( GL_VERSION ) );
SG_LOG( SG_GENERAL, SG_INFO, general.get_glRenderer() );
GLint tmp;
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &tmp );
general.set_glMaxTexSize( tmp );
SG_LOG ( SG_GENERAL, SG_INFO, "Max texture size = " << tmp );
glGetIntegerv( GL_DEPTH_BITS, &tmp );
general.set_glDepthBits( tmp );
SG_LOG ( SG_GENERAL, SG_INFO, "Depth buffer bits = " << tmp );
// Initialize plib net interface
netInit( &argc, argv );
// Initialize ssg (from plib). Needs to come before we do any
// other ssg stuff, but after opengl has been initialized.
ssgInit();
1998-08-20 15:10:33 +00:00
// Initialize the user interface (we need to do this before
// passing off control to the OS main loop and before
// fgInitGeneral to get our fonts !!!
guiInit();
// Read the list of available aircrafts
fgReadAircraft();
2001-05-23 20:54:51 +00:00
#ifdef GL_EXT_texture_lod_bias
glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, -0.5 ) ;
#endif
2002-10-17 04:34:32 +00:00
// get the address of our OpenGL extensions
if ( fgGetBool("/sim/rendering/distance-attenuation") )
{
2003-06-20 20:18:40 +00:00
if (SGIsOpenGLExtensionSupported("GL_EXT_point_parameters") ) {
glPointParameterIsSupported = true;
2003-06-20 20:18:40 +00:00
glPointParameterfPtr = (glPointParameterfProc)
SGLookupFunction("glPointParameterfEXT");
glPointParameterfvPtr = (glPointParameterfvProc)
SGLookupFunction("glPointParameterfvEXT");
} else if ( SGIsOpenGLExtensionSupported("GL_ARB_point_parameters") ) {
glPointParameterIsSupported = true;
2003-06-20 20:18:40 +00:00
glPointParameterfPtr = (glPointParameterfProc)
SGLookupFunction("glPointParameterfARB");
glPointParameterfvPtr = (glPointParameterfvProc)
SGLookupFunction("glPointParameterfvARB");
} else
glPointParameterIsSupported = false;
}
2002-10-17 04:34:32 +00:00
// based on the requested presets, calculate the true starting
// lon, lat
2003-02-21 02:46:07 +00:00
fgInitNav();
fgInitPosition();
SGTime *t = fgInitTime();
2000-07-07 20:28:51 +00:00
globals->set_time_params( t );
// Do some quick general initializations
if( !fgInitGeneral()) {
SG_LOG( SG_GENERAL, SG_ALERT,
"General initializations failed ..." );
exit(-1);
}
2002-10-29 19:44:03 +00:00
////////////////////////////////////////////////////////////////////
// Initialize the property-based built-in commands
////////////////////////////////////////////////////////////////////
fgInitCommands();
////////////////////////////////////////////////////////////////////
// Initialize the material manager
////////////////////////////////////////////////////////////////////
globals->set_matlib( new SGMaterialLib );
2003-05-15 21:35:51 +00:00
globals->set_model_lib(new SGModelLib);
////////////////////////////////////////////////////////////////////
// Initialize the TG scenery subsystem.
////////////////////////////////////////////////////////////////////
globals->set_scenery( new FGScenery );
globals->get_scenery()->init();
globals->get_scenery()->bind();
globals->set_tile_mgr( new FGTileMgr );
////////////////////////////////////////////////////////////////////
// Initialize the general model subsystem.
////////////////////////////////////////////////////////////////////
globals->set_model_mgr(new FGModelMgr);
globals->get_model_mgr()->init();
globals->get_model_mgr()->bind();
////////////////////////////////////////////////////////////////////
// Initialize the 3D aircraft model subsystem (has a dependency on
// the scenery subsystem.)
////////////////////////////////////////////////////////////////////
globals->set_aircraft_model(new FGAircraftModel);
globals->get_aircraft_model()->init();
globals->get_aircraft_model()->bind();
////////////////////////////////////////////////////////////////////
// Initialize the view manager subsystem.
////////////////////////////////////////////////////////////////////
FGViewMgr *viewmgr = new FGViewMgr;
globals->set_viewmgr( viewmgr );
viewmgr->init();
viewmgr->bind();
// Initialize the sky
SGPath ephem_data_path( globals->get_fg_root() );
ephem_data_path.append( "Astro" );
2000-07-08 05:09:24 +00:00
SGEphemeris *ephem = new SGEphemeris( ephem_data_path.c_str() );
ephem->update( globals->get_time_params()->getMjd(),
globals->get_time_params()->getLst(),
0.0 );
2000-07-08 05:09:24 +00:00
globals->set_ephem( ephem );
// TODO: move to environment mgr
thesky = new SGSky;
SGPath texture_path(globals->get_fg_root());
texture_path.append("Textures");
texture_path.append("Sky");
for (int i = 0; i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) {
2002-12-21 05:01:51 +00:00
SGCloudLayer * layer = new SGCloudLayer(texture_path.str());
thesky->add_cloud_layer(layer);
}
SGPath sky_tex_path( globals->get_fg_root() );
2000-03-06 23:28:43 +00:00
sky_tex_path.append( "Textures" );
sky_tex_path.append( "Sky" );
thesky->texture_path( sky_tex_path.str() );
// The sun and moon diameters are scaled down numbers of the
// actual diameters. This was needed to fit bot the sun and the
// moon within the distance to the far clip plane.
// Moon diameter: 3,476 kilometers
// Sun diameter: 1,390,000 kilometers
thesky->build( 80000.0, 80000.0,
463.3, 361.8,
2003-06-09 20:24:50 +00:00
globals->get_ephem()->getNumPlanets(),
globals->get_ephem()->getPlanets(),
2003-06-09 20:24:50 +00:00
globals->get_ephem()->getNumStars(),
globals->get_ephem()->getStars() );
// Initialize MagVar model
SGMagVar *magvar = new SGMagVar();
globals->set_mag( magvar );
// kludge to initialize mag compass
// (should only be done for in-flight
// startup)
// update magvar model
globals->get_mag()->update( fgGetDouble("/position/longitude-deg")
* SGD_DEGREES_TO_RADIANS,
fgGetDouble("/position/latitude-deg")
* SGD_DEGREES_TO_RADIANS,
fgGetDouble("/position/altitude-ft")
* SG_FEET_TO_METER,
globals->get_time_params()->getJD() );
double var = globals->get_mag()->get_magvar() * SGD_RADIANS_TO_DEGREES;
fgSetDouble("/instrumentation/heading-indicator/offset-deg", -var);
// airport = new ssgBranch;
// airport->setName( "Airport Lighting" );
// lighting->addKid( airport );
// build our custom render states
fgBuildRenderStates();
// pass control off to the master event handler
fgOSMainLoop();
// we never actually get here ... but to avoid compiler warnings,
// etc.
return false;
1998-04-21 17:02:27 +00:00
}
// end of main.cxx