#include <simgear/compiler.h>
#include STL_IOSTREAM
-#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
SG_USING_STD(cerr);
SG_USING_STD(endl);
-#endif
#include <simgear/misc/exception.hxx>
#include <simgear/ephemeris/ephemeris.hxx>
# include <float.h>
#endif
-#include <GL/glut.h>
-#include <GL/gl.h>
+#include GLUT_H
#include <stdio.h>
#include <string.h> // for strcmp()
#include <plib/netChat.h>
#include <plib/pu.h>
+#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/constants.h> // for VERSION
#include <simgear/math/polar3d.hxx>
#include <simgear/math/sg_random.h>
#include <simgear/misc/sg_path.hxx>
+#ifdef FG_USE_CLOUDS_3D
+# include <simgear/sky/clouds3d/SkySceneLoader.hpp>
+# include <simgear/sky/clouds3d/SkyUtil.hpp>
+#endif
#include <simgear/sky/sky.hxx>
#include <simgear/timing/sg_time.hxx>
#include <ATC/ATCdisplay.hxx>
#include <ATC/AIMgr.hxx>
+
#include <Autopilot/newauto.hxx>
+#include <Cockpit/hud.hxx>
#include <Cockpit/cockpit.hxx>
#include <Cockpit/radiostack.hxx>
-#include <Cockpit/steam.hxx>
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
#include <GUI/gui.h>
#include <Model/acmodel.hxx>
-#include <Model/modelmgr.hxx>
+#include <Model/loader.hxx>
#include <Model/model.hxx>
+#include <Model/modelmgr.hxx>
#include <Main/location.hxx>
+#include <Model/panelnode.hxx>
#ifdef FG_NETWORK_OLK
#include <NetworkOLK/network.h>
#endif
+
+#ifdef FG_MPLAYER_AS
+#include <MultiPlayer/multiplaytxmgr.hxx>
+#include <MultiPlayer/multiplayrxmgr.hxx>
+#endif
+
#include <Objects/matlib.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
# include <Sound/fg_fx.hxx>
# include <Sound/morse.hxx>
#endif
+#include <Systems/system_mgr.hxx>
+#include <Instrumentation/instrument_mgr.hxx>
#include <Time/FGEventMgr.hxx>
#include <Time/fg_timer.hxx>
#include <Time/light.hxx>
#include <Time/sunpos.hxx>
#include <Time/tmp.hxx>
-#include <Input/input.hxx>
-
// ADA
#include <simgear/misc/sgstream.hxx>
#include <simgear/math/point3d.hxx>
#include <FDM/ADA.hxx>
#include <Scenery/tileentry.hxx>
-#if !defined(sgi)
-// PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT = 0;
-// PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT = 0;
+#include "fg_commands.hxx"
+
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
+#ifdef WIN32
+ typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC)(GLenum pname,
+ GLfloat param);
+ typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC)(GLenum pname,
+ const GLfloat *params);
+
+ PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT = 0;
+ PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT = 0;
+#elif linux
+ #include <GL/glx.h>
+
+ typedef void (* OpenGLFuncExt)(GLenum pname, GLfloat param);
+ typedef void (* OpenGLFuncExtv)(GLenum pname, const GLfloat *params);
+
+ OpenGLFuncExt glPointParameterfEXT = 0;
+ OpenGLFuncExtv glPointParameterfvEXT = 0;
+#endif
#endif
+
float default_attenuation[3] = {1.0, 0.0, 0.0};
//Required for using GL_extensions
void fgLoadDCS (void);
static int idle_state = 0;
static long global_multi_loop;
-// forward declaration
-void fgReshape( int width, int height );
-
// 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 fog_exp2_punch_through;
+static GLfloat rwy_exp2_punch_through;
+static GLfloat taxi_exp2_punch_through;
+static GLfloat ground_exp2_punch_through;
#ifdef FG_NETWORK_OLK
ssgSelector *fgd_sel = NULL;
ssgTransform *fgd_pos = NULL;
#endif
-// current fdm/position used for view
-FGInterface cur_view_fdm;
-
// Sky structures
SGSky *thesky;
+#ifdef FG_USE_CLOUDS_3D
+ SkySceneLoader *sgClouds3d;
+ bool _bcloud_orig = true;
+#endif
+
// hack
sgMat4 copy_of_ssgOpenGLAxisSwapMatrix =
{
//
+ssgSimpleState *cloud3d_imposter_state;
ssgSimpleState *default_state;
ssgSimpleState *hud_and_panel;
ssgSimpleState *menus;
SGTimeStamp last_time_stamp;
SGTimeStamp current_time_stamp;
+
void fgBuildRenderStates( void ) {
default_state = new ssgSimpleState;
default_state->ref();
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 );
+ cloud3d_imposter_state->disable( GL_LIGHTING );
+
hud_and_panel = new ssgSimpleState;
hud_and_panel->ref();
hud_and_panel->disable( GL_CULL_FACE );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
- glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
+ // glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec ); // done later with ssg
sgVec3 sunpos;
sgSetVec3( sunpos, l->sun_vec[0], l->sun_vec[1], l->sun_vec[2] );
if ( fgPanelVisible() ) {
GLfloat height = fgGetInt("/sim/startup/ysize");
GLfloat view_h =
- (current_panel->getViewHeight() - current_panel->getYOffset())
+ (globals->get_current_panel()->getViewHeight() - globals->get_current_panel()->getYOffset())
* (height / 768.0) + 1;
glTranslatef( 0.0, view_h, 0.0 );
}
// 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 );
ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
// draw the lights
- glFogf (GL_FOG_DENSITY, fog_exp2_punch_through);
+ glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
ssgSetNearFar( scene_nearplane, scene_farplane );
- ssgCullAndDraw( globals->get_scenery()->get_lighting() );
+ ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
+
+ ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
if (fgGetBool("/environment/clouds/status"))
- thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
+ thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
globals->get_model_mgr()->draw();
globals->get_aircraft_model()->draw();
-
- // need to do this here as hud_and_panel state is static to
- // main.cxx and HUD and Panel routines have to be called with
- // knowledge of the the TR struct < see gui.cxx::HighResDump()
- hud_and_panel->apply();
}
// Update all Visuals (redraws anything graphics related)
void fgRenderFrame() {
-
+
+ GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
+
// Process/manage pending events
global_events.update( delta_time_sec );
static double last_visibility = -9999;
// update fog params
- double actual_visibility = thesky->get_visibility();
+ 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;
- fog_exp2_punch_through = sqrt_m_log01 / ( actual_visibility * 2.5 );
+ 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 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);
+ fgSplashUpdate(0.0, 1.0);
}
// Keep resetting sim time while the sim is initializing
globals->set_sim_time_sec( 0.0 );
fgReshape( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
- // set the sun position
- glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
+ 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") ) {
if ( fgGetBool("/sim/rendering/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],
+ 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],
+ glClearColor(l->sky_color[0], l->sky_color[1],
l->sky_color[2], l->sky_color[3]);
clear_mask |= GL_COLOR_BUFFER_BIT;
}
// update the sky dome
if ( fgGetBool("/sim/rendering/skyblend") ) {
- /* cout << "thesky->repaint() sky_color = "
+ /*
+ SG_LOG( SG_GENERAL, SG_BULK, "thesky->repaint() sky_color = "
<< cur_light_params.sky_color[0] << " "
<< cur_light_params.sky_color[1] << " "
<< cur_light_params.sky_color[2] << " "
- << cur_light_params.sky_color[3] << endl;
- cout << " fog = "
+ << cur_light_params.sky_color[3] );
+ SG_LOG( SG_GENERAL, SG_BULK, " fog = "
<< cur_light_params.fog_color[0] << " "
<< cur_light_params.fog_color[1] << " "
<< cur_light_params.fog_color[2] << " "
- << cur_light_params.fog_color[3] << endl;
- cout << " sun_angle = " << cur_light_params.sun_angle
- << " moon_angle = " << cur_light_params.moon_angle
- << endl; */
+ << cur_light_params.fog_color[3] );
+ SG_LOG( SG_GENERAL, SG_BULK,
+ " sun_angle = " << cur_light_params.sun_angle
+ << " moon_angle = " << cur_light_params.moon_angle );
+ */
thesky->repaint( cur_light_params.sky_color,
cur_light_params.adj_fog_color,
cur_light_params.sun_angle,
globals->get_ephem()->getPlanets(),
globals->get_ephem()->getNumStars(),
globals->get_ephem()->getStars() );
-
- /* cout << "thesky->reposition( view_pos = " << view_pos[0] << " "
- << view_pos[1] << " " << view_pos[2] << endl;
- cout << " zero_elev = " << zero_elev[0] << " "
+
+ /*
+ 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() << endl;
- cout << " sun_rot = " << cur_light_params.sun_rotation
- << " gst = " << SGTime::cur_time_params->getGst() << endl;
- cout << " sun ra = " << globals->get_ephem()->getSunRightAscension()
- << " sun dec = " << globals->get_ephem()->getSunDeclination()
- << " moon ra = " << globals->get_ephem()->getMoonRightAscension()
- << " moon dec = " << globals->get_ephem()->getMoonDeclination() << endl; */
+ << " lat = " << cur_fdm_state->get_Latitude() );
+ SG_LOG( SG_GENERAL, SG_BULK,
+ " sun_rot = " << cur_light_params.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() );
+ */
thesky->reposition( current__view->get_view_pos(),
current__view->get_zero_elev(),
// 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.
- GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
- GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
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_white );
+ ssgGetLight( 0 ) -> setColour( GL_SPECULAR, l->scene_specular );
// texture parameters
// glEnable( GL_TEXTURE_2D );
}
# endif
- // position tile nodes and update range selectors
- global_tile_mgr.prep_ssg_nodes(visibility_meters);
+#ifdef FG_MPLAYER_AS
+ // Update any multiplayer models
+ globals->get_multiplayer_rx_mgr()->Update();
+#endif
- if ( fgGetBool("/sim/rendering/skyblend") ) {
+ if ( fgGetBool("/sim/rendering/skyblend") &&
+ fgGetBool("/sim/rendering/draw-otw") )
+ {
// draw the sky backdrop
// we need a white diffuse light for the phase of the moon
glEnable( GL_DEPTH_TEST );
ssgSetNearFar( scene_nearplane, scene_farplane );
- ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
+
+ if ( fgGetBool("/sim/rendering/wireframe") ) {
+ // draw wire frame
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ }
+ if ( fgGetBool("/sim/rendering/draw-otw") ) {
+ 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);
+ globals->get_scenery()->get_scene_graph()->cull(&f, m, true);
+ counter = 0;
+ }
// change state for lighting here
- // draw lighting
- // Set punch through fog density
- glFogf (GL_FOG_DENSITY, fog_exp2_punch_through);
+ // draw runway lighting
+ glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
+ ssgSetNearFar( scene_nearplane, scene_farplane );
-#ifdef FG_EXPERIMENTAL_LIGHTING
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
// Enable states for drawing points with GL_extension
- if (glutExtensionSupported("GL_EXT_point_parameters")) {
- glEnable(GL_POINT_SMOOTH);
- float quadratic[3] = {1.0, 0.01, 0.0001};
- // get the address of our OpenGL extensions
-#if !defined(sgi)
- glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)
- wglGetProcAddress("glPointParameterfEXT");
- glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)
- wglGetProcAddress("glPointParameterfvEXT");
-#endif
+ glEnable(GL_POINT_SMOOTH);
+
+ if ( fgGetBool("/sim/rendering/distance-attenuation")
+ && glutExtensionSupported("GL_EXT_point_parameters") )
+ {
+ float quadratic[3] = {1.0, 0.001, 0.0000001};
// makes the points fade as they move away
glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, quadratic);
glPointParameterfEXT(GL_POINT_SIZE_MIN_EXT, 1.0);
- glPointSize(4.0);
-
- // Enable states for drawing runway lights with spherical mapping
- 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);
-
- //Maybe this is not the best way, but it works !!
- glPolygonMode(GL_FRONT, GL_POINT);
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
- }
+ }
+ glPointSize(4.0);
- glDisable( GL_LIGHTING );
// blending function for runway lights
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
- glEnable(GL_BLEND);
#endif
- ssgSetNearFar( scene_nearplane, scene_farplane );
- ssgCullAndDraw( globals->get_scenery()->get_lighting() );
+ 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 ( fgGetBool("/sim/rendering/draw-otw") ) {
+ 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 ( fgGetBool("/sim/rendering/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++;
-#ifdef FG_EXPERIMENTAL_LIGHTING
- if (glutExtensionSupported("GL_EXT_point_parameters")) {
- // Disable states used for runway lighting
- glPolygonMode(GL_FRONT, GL_FILL);
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
+ if ( fgGetBool("/sim/rendering/distance-attenuation")
+ && glutExtensionSupported("GL_EXT_point_parameters") )
+ {
glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT,
default_attenuation);
- }
+ }
glPointSize(1.0);
+ glDisable(GL_POINT_SMOOTH);
#endif
+ // draw ground lighting
+ glFogf (GL_FOG_DENSITY, ground_exp2_punch_through);
+ if ( fgGetBool("/sim/rendering/draw-otw") ) {
+ ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
+ }
+
if ( fgGetBool("/sim/rendering/skyblend") ) {
// draw the sky cloud layers
- if (fgGetBool("/environment/clouds/status"))
- thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
+ if ( fgGetBool("/environment/clouds/status") &&
+ fgGetBool("/sim/rendering/draw-otw") )
+ {
+ thesky->postDraw( cur_fdm_state->get_Altitude()
+ * SG_FEET_TO_METER );
+ }
}
- globals->get_model_mgr()->draw();
- globals->get_aircraft_model()->draw();
+ if ( fgGetBool("/sim/rendering/clouds3d") &&
+ fgGetBool("/sim/rendering/draw-otw") )
+ {
+ 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 ( fgGetBool("/sim/rendering/draw-otw") ) {
+ globals->get_model_mgr()->draw();
+ globals->get_aircraft_model()->draw();
+ }
// display HUD && Panel
glDisable( GL_FOG );
// glDisable( GL_CULL_FACE );
// glDisable( GL_TEXTURE_2D );
- // update the input subsystem
- current_input.update(delta_time_sec);
-
// update the controls subsystem
globals->get_controls()->update(delta_time_sec);
// Use the hud_and_panel ssgSimpleState for rendering the ATC output
// This only works properly if called before the panel call
- globals->get_ATC_display()->update(delta_time_sec);
+ if((fgGetBool("/sim/ATC/enabled")) || (fgGetBool("/sim/ai-traffic/enabled")))
+ globals->get_ATC_display()->update(delta_time_sec);
// update the panel subsystem
- if ( current_panel != NULL ) {
- current_panel->update(delta_time_sec);
+ if ( globals->get_current_panel() != NULL ) {
+ globals->get_current_panel()->update(delta_time_sec);
}
+ fgUpdate3DPanels();
// We can do translucent menus, so why not. :-)
menus->apply();
puDisplay();
// glDisable ( GL_BLEND ) ;
- // glEnable( GL_FOG );
+ glEnable( GL_DEPTH_TEST );
+ glEnable( GL_FOG );
- globals->get_logger()->update(delta_time_sec);
+ // 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);
+ }
}
glutSwapBuffers();
//SG_LOG(SG_FLIGHT,SG_INFO, "Updating time dep calcs()");
fgLIGHT *l = &cur_light_params;
- int i;
-
- long multi_loop = 1;
// Initialize the FDM here if it hasn't been and if we have a
// scenery elevation hit.
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();
}
+#ifndef FG_WEATHERCM
+ globals->get_environment_mgr()->update(delta_time_sec);
+#endif
+
// conceptually, the following block could be done for each fdm
// instance ...
if ( !cur_fdm_state->get_inited() ) {
globals->get_autopilot()->update(delta_time_sec);
cur_fdm_state->update(delta_time_sec);
- FGSteam::update(delta_time_sec);
- }
-
- if ( !strcmp(fgGetString("/sim/view-mode"), "pilot") ) {
- cur_view_fdm = *cur_fdm_state;
- // do nothing
}
globals->get_model_mgr()->update(delta_time_sec);
// for the next move and update the display?
static void fgMainLoop( void ) {
- // Update the elapsed time.
- current_time_stamp.stamp();
- delta_time_sec = double(current_time_stamp - last_time_stamp) / 1000000.0;
- last_time_stamp = current_time_stamp;
- globals->inc_sim_time_sec( delta_time_sec );
-
static const SGPropertyNode *longitude
= fgGetNode("/position/longitude-deg");
static const SGPropertyNode *latitude
static const SGPropertyNode *cur_time_override
= fgGetNode("/sim/time/cur-time-override", true);
+ // Update the elapsed time.
+ static bool first_time = true;
+ if ( first_time ) {
+ last_time_stamp.stamp();
+ first_time = false;
+ }
+ current_time_stamp.stamp();
+ delta_time_sec = double(current_time_stamp - last_time_stamp) / 1000000.0;
+ if (clock_freeze->getBoolValue())
+ delta_time_sec = 0;
+ last_time_stamp = current_time_stamp;
+ globals->inc_sim_time_sec( delta_time_sec );
+
static long remainder = 0;
long elapsed;
#ifdef FANCY_FRAME_COUNTER
SGTime *t = globals->get_time_params();
+ sglog().setLogLevels( SG_ALL, (sgDebugPriority)fgGetInt("/sim/log-level") );
+
FGLocation * acmodel_location = 0;
if(cur_fdm_state->getACModel() != 0) {
acmodel_location = (FGLocation *) cur_fdm_state->getACModel()->get3DModel()->getFGLocation();
// init routine and we don't have to worry about it again.
#endif
-#ifndef FG_WEATHERCM
- globals->get_environment_mgr()->update(delta_time_sec);
-#endif
-
// Fix elevation. I'm just sticking this here for now, it should
// probably move eventually
#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;
#endif
// Run ATC subsystem
- globals->get_ATC_mgr()->update(delta_time_sec);
+ if (fgGetBool("/sim/ATC/enabled"))
+ globals->get_ATC_mgr()->update(delta_time_sec);
// Run the AI subsystem
- // globals->get_AI_mgr()->update(delta_time_sec);
+ if (fgGetBool("/sim/ai-traffic/enabled"))
+ globals->get_AI_mgr()->update(delta_time_sec);
// Run flight model
"Elapsed time is zero ... we're zinging" );
}
-#if ! defined( macintosh )
// Do any I/O channel work that might need to be done
- fgIOProcess();
-#endif
+ globals->get_io()->update( delta_time_sec );
// see if we need to load any deferred-load textures
material_lib.load_next_deferred();
#ifdef ENABLE_AUDIO_SUPPORT
if ( fgGetBool("/sim/sound/audible")
&& globals->get_soundmgr()->is_working() ) {
- globals->get_fx()->update(1); // FIXME: use dt
- globals->get_soundmgr()->update(1); // FIXME: use dt
+ globals->get_soundmgr()->update( delta_time_sec );
}
#endif
- // redraw display
- fgRenderFrame();
-
+ globals->get_subsystem_mgr()->update(delta_time_sec);
//
// Tile Manager updates - see if we need to load any new scenery tiles.
// ...only if location is different than the viewer (to avoid duplicating effort)
if( acmodel_location != current_view->getFGLocation() ) {
if( acmodel_location != 0 ) {
- global_tile_mgr.update( acmodel_location->getLongitude_deg(),
- acmodel_location->getLatitude_deg(),
- visibility_meters,
- acmodel_location->get_absolute_view_pos(),
- acmodel_location->get_current_bucket(),
- acmodel_location->get_previous_bucket()
- );
+ globals->get_tile_mgr()->prep_ssg_nodes( acmodel_location,
+ visibility_meters );
+ globals->get_tile_mgr()->
+ update( acmodel_location, visibility_meters,
+ acmodel_location->get_absolute_view_pos() );
// save results of update in FGLocation for fdm...
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
- acmodel_location->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
+ acmodel_location->
+ set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
}
- acmodel_location->set_current_bucket( global_tile_mgr.get_current_bucket() );
- acmodel_location->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
+ acmodel_location->
+ set_tile_center( globals->get_scenery()->get_next_center() );
}
}
+ globals->get_tile_mgr()->prep_ssg_nodes( current_view->getFGLocation(),
+ visibility_meters );
// 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.
- global_tile_mgr.update( current_view->getLongitude_deg(),
- current_view->getLatitude_deg(),
- visibility_meters,
- current_view->get_absolute_view_pos(),
- current_view->getFGLocation()->get_current_bucket(),
- current_view->getFGLocation()->get_previous_bucket()
- );
+ FGLocation *view_location = globals->get_current_view()->getFGLocation();
+ globals->get_tile_mgr()->update( view_location, visibility_meters,
+ current_view->get_absolute_view_pos() );
// save results of update in FGLocation for fdm...
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
current_view->getFGLocation()->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
}
- current_view->getFGLocation()->set_current_bucket( global_tile_mgr.get_current_bucket() );
- current_view->getFGLocation()->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
+ current_view->getFGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
// 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 FGLocation as well...
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
acmodel_location->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
}
- acmodel_location->set_current_bucket( global_tile_mgr.get_current_bucket() );
- acmodel_location->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
+ acmodel_location->set_tile_center( globals->get_scenery()->get_next_center() );
}
}
// END Tile Manager udpates
+ // redraw display
+ fgRenderFrame();
SG_LOG( SG_ALL, SG_DEBUG, "" );
}
system ( command.c_str() );
}
-
- // This is an 'easter egg' which is kind of a hard thing to
- // hide in an open source project -- so I won't try very hard
- // to hide it. If you are looking at this now, please, you
- // don't want to ruin the surprise. :-) Just forget about it
- // and don't look any further; unless it is causing an actual
- // problem for you, which it shouldn't, and I hope it doesn't!
- // :-)
- if ( globals->get_time_params()->getGmt()->tm_mon == 4
- && globals->get_time_params()->getGmt()->tm_mday == 19 )
- {
- string url = "http://www.flightgear.org/Music/invasion.mp3";
-#if defined( __CYGWIN__ ) || defined( WIN32 )
- string command = "start /m " + url;
-#else
- string command = "mpg123 " + url + "> /dev/null 2>&1";
-#endif
- system( command.c_str() );
- }
-
#endif
idle_state++;
// setup OpenGL view parameters
fgInitVisuals();
+ // Read the list of available aircrafts
+ fgReadAircraft();
+
idle_state++;
} else if ( idle_state == 5 ) {
// sleep(1);
idle_state = 1000;
- cout << "Panel visible = " << fgPanelVisible() << endl;
+ SG_LOG( SG_GENERAL, SG_INFO, "Panel visible = " << fgPanelVisible() );
fgReshape( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
}
glutIdleFunc(fgMainLoop);
} else {
if ( fgGetBool("/sim/startup/splash-screen") ) {
- fgSplashUpdate(0.0);
+ fgSplashUpdate(0.0, 1.0);
}
}
}
if ( (!fgGetBool("/sim/virtual-cockpit"))
&& fgPanelVisible() && idle_state == 1000 ) {
- view_h = (int)(height * (current_panel->getViewHeight() -
- current_panel->getYOffset()) / 768.0);
+ view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
+ globals->get_current_panel()->getYOffset()) / 768.0);
} else {
view_h = height;
}
viewmgr->get_current_view()->get_v_fov() );
fgHUDReshape();
+
+#ifdef FG_USE_CLOUDS_3D
+ sgClouds3d->Resize( viewmgr->get_current_view()->get_h_fov(),
+ viewmgr->get_current_view()->get_v_fov() );
+#endif
+
}
// Initialize GLUT and define a main window
-int fgGlutInit( int *argc, char **argv ) {
+static bool fgGlutInit( int *argc, char **argv ) {
#if !defined( macintosh )
// GLUT will extract all glut specific options so later on we only
glutInit(argc, argv);
#endif
- // Define Display Parameters
- glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+ // Define Display Parameters. Clouds3d works best with --bpp32 option
+ if ( fgGetBool("/sim/rendering/clouds3d") ) {
+ glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_ALPHA );
+ } else {
+ glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+ }
SG_LOG( SG_GENERAL, SG_INFO, "Opening a window: " <<
fgGetInt("/sim/startup/xsize") << "x"
general.set_glDepthBits( tmp );
SG_LOG ( SG_GENERAL, SG_INFO, "Depth buffer bits = " << tmp );
- return 1;
+ return true;
}
// Initialize GLUT event handlers
-int fgGlutInitEvents( void ) {
+static bool fgGlutInitEvents( void ) {
// call fgReshape() on window resizes
glutReshapeFunc( fgReshape );
// draw the scene
glutDisplayFunc( fgRenderFrame );
- return 1;
+ return true;
}
-
-// Main loop
-int mainLoop( int argc, char **argv ) {
+// Main top level initialization
+static bool fgMainInit( int argc, char **argv ) {
#if defined( macintosh )
freopen ("stdout.txt", "w", stdout );
fgInitFGRoot(argc, argv);
// Check for the correct base package version
+ static char required_version[] = "0.9.1";
string base_version = fgBasePackageVersion();
- if ( !(base_version == "0.7.9") ) {
+ if ( !(base_version == required_version) ) {
// tell the operator how to use this application
- fgUsage();
- SG_LOG( SG_GENERAL, SG_ALERT, "Base package check failed ... "
- << "Found version " << base_version << " at: "
- << globals->get_fg_root() );
- SG_LOG( SG_GENERAL, SG_ALERT, "Please upgrade to version 0.7.9" );
+ cerr << endl << "Base package check failed ... " \
+ << "Found version " << base_version << " at: " \
+ << globals->get_fg_root() << endl;
+ cerr << "Please upgrade to version: " << required_version << endl;
exit(-1);
}
// Initialize the Aircraft directory to "" (UIUC)
aircraft_dir = "";
- // Load the configuration parameters
+ // 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);
// fonts !!!
guiInit();
+ // Read the list of available aircrafts
+ fgReadAircraft();
+
#ifdef GL_EXT_texture_lod_bias
glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, -0.5 ) ;
#endif
- // Set position relative to glide slope if requested
- fgSetPosFromGlideSlope();
-
- // If we have an explicit, in-range lon/lat, use it.
- // If not, check for an airport-id and use that.
- // If not, default to the middle of the KSFO field.
- // The default values for lon/lat are deliberately out of range
- // so that the airport-id can take effect; valid lon/lat will
- // override airport-id, however.
- double lon_deg = fgGetDouble("/position/longitude-deg");
- double lat_deg = fgGetDouble("/position/latitude-deg");
- if (lon_deg < -180 || lon_deg > 180 || lat_deg < -90 || lat_deg > 90) {
- if ( fgGetString("/sim/startup/airport-id")[0] != '\0' ) {
- fgSetPosFromAirportIDandHdg( fgGetString("/sim/startup/airport-id"),
- fgGetDouble("/orientation/heading-deg") );
- // set tower position (a little off the heading for single
- // runway airports)
- fgSetTowerPosFromAirportID( fgGetString("/sim/startup/airport-id"),
- fgGetDouble("orientation/heading") );
- } else {
- // Default to middle of KSFO field
- fgSetDouble("/position/longitude-deg", -122.374843);
- fgSetDouble("/position/latitude-deg", 37.619002);
- }
- }
+#ifdef FG_EXPERIMENTAL_POINT_LIGHTING
+ // get the address of our OpenGL extensions
+ if ( fgGetBool("/sim/rendering/distance-attenuation") )
+ {
+#ifdef WIN32
+ glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)
+ wglGetProcAddress("glPointParameterfEXT");
+ glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)
+ wglGetProcAddress("glPointParameterfvEXT");
+#elif linux
+ glPointParameterfEXT = (OpenGLFuncExt)
+ glXGetProcAddressARB((GLubyte *)"glPointParameterfEXT");
+ glPointParameterfvEXT = (OpenGLFuncExtv)
+ glXGetProcAddressARB((GLubyte *)"glPointParameterfvEXT");
+#endif
+ }
+#endif
+
+ // based on the requested presets, calculate the true starting
+ // lon, lat
+ fgInitNav();
+ fgInitPosition();
SGTime *t = fgInitTime();
globals->set_time_params( t );
globals->get_scenery()->init();
globals->get_scenery()->bind();
+ // Initialize the global tile manager
+ globals->set_tile_mgr( new FGTileMgr );
+
+ ////////////////////////////////////////////////////////////////////
+ // Initialize the property-based built-in commands
+ ////////////////////////////////////////////////////////////////////
+ fgInitCommands();
+
////////////////////////////////////////////////////////////////////
// Initialize the general model subsystem.
////////////////////////////////////////////////////////////////////
+ globals->set_model_loader(new FGModelLoader);
+ globals->set_texture_loader(new FGTextureLoader);
globals->set_model_mgr(new FGModelMgr);
globals->get_model_mgr()->init();
globals->get_model_mgr()->bind();
0.0 );
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++) {
+ SGCloudLayer * layer = new SGCloudLayer(texture_path.str());
+ thesky->add_cloud_layer(layer);
+ }
+
SGPath sky_tex_path( globals->get_fg_root() );
sky_tex_path.append( "Textures" );
// we never actually get here ... but to avoid compiler warnings,
// etc.
- return 0;
+ return false;
}
}
#endif
+#ifdef __APPLE__
+
+typedef struct
+{
+ int lo;
+ int hi;
+} PSN;
+
+extern "C" {
+ short CPSGetCurrentProcess(PSN *psn);
+ short CPSSetProcessName (PSN *psn, char *processname);
+ short CPSEnableForegroundOperation(PSN *psn, int _arg2, int _arg3, int _arg4, int _arg5);
+ short CPSSetFrontProcess(PSN *psn);
+};
+
+#define CPSEnableFG(psn) CPSEnableForegroundOperation(psn,0x03,0x3C,0x2C,0x1103)
+
+#endif
+
// Main entry point; catch any exceptions that have made it this far.
int main ( int argc, char **argv ) {
_control87(MCW_EM, MCW_EM); /* defined in float.h */
#endif
+ // Keyboard focus hack
+#ifdef __APPLE__
+ {
+ PSN psn;
+
+ glutInit (&argc, argv);
+
+ CPSGetCurrentProcess(&psn);
+ CPSSetProcessName(&psn, "FlightGear");
+ CPSEnableFG(&psn);
+ CPSSetFrontProcess(&psn);
+ }
+#endif
+
// FIXME: add other, more specific
// exceptions.
try {
- mainLoop(argc, argv);
+ fgMainInit(argc, argv);
} catch (sg_throwable &t) {
// We must use cerr rather than
// logging, since logging may be
// instance of the last object.
if ( strcmp(obj_filename,"repeat") != 0) {
- ship_obj = ssgLoad( obj_filename );
+ ship_obj =
+ globals->get_model_loader()->load_model( obj_filename );
}
if ( ship_obj != NULL ) {
//dummy_tile->lightmaps_sequence->setTraversalMaskBits( SSGTRAV_HOT );
lightpoints_transform->addKid( dummy_tile->lightmaps_sequence );
lightpoints_transform->ref();
- globals->get_scenery()->get_gnd_lights_branch()->addKid( lightpoints_transform );
+ globals->get_scenery()->get_gnd_lights_root()->addKid( lightpoints_transform );
}
} //if in1
} //if objc