X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Frenderer.cxx;h=4ba4649f050fa7c6be8e6334b9f54b416479daaa;hb=40170cb722a08f0ab93875e4e35e022941551c40;hp=3319a7e7a85447da2aa83863c460ceed131cd234;hpb=b2bc573205449372de55f2008fd609bfa3d270da;p=flightgear.git diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index 3319a7e7a..4ba4649f0 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -3,7 +3,7 @@ // Written by Curtis Olson, started May 1997. // This file contains parts of main.cxx prior to october 2004 // -// Copyright (C) 1997 - 2002 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 1997 - 2002 Curtis L. Olson - http://www.flightgear.org/~curt // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,6 +45,9 @@ #include #include #include +#ifdef FG_JPEG_SERVER +#include +#endif #ifdef FG_USE_CLOUDS_3D # include @@ -57,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -68,11 +70,6 @@ #include #include -#ifdef FG_MPLAYER_AS -#include -#include -#endif - #include "splash.hxx" #include "renderer.hxx" #include "main.hxx" @@ -126,19 +123,21 @@ ssgSimpleState *default_state; ssgSimpleState *hud_and_panel; ssgSimpleState *menus; - -void fgRenderFrame() { -#ifdef FG_MPLAYER_AS - // Update any multiplayer models - globals->get_multiplayer_rx_mgr()->Update(); +FGRenderer::FGRenderer() +{ +#ifdef FG_JPEG_SERVER + jpgRenderFrame = FGRenderer::update; #endif - globals->get_renderer()->update(delta_time_sec); } -void fgReshape(int width, int height) { - globals->get_renderer()->resize(width,height); +FGRenderer::~FGRenderer() +{ +#ifdef FG_JPEG_SERVER + jpgRenderFrame = NULL; +#endif } + void FGRenderer::build_states( void ) { default_state = new ssgSimpleState; @@ -229,132 +228,10 @@ FGRenderer::init( void ) { } -// For HiRes screen Dumps using Brian Pauls TR Library -void -FGRenderer::screendump( void ) { -#ifdef FG_ENABLE_MULTIPASS_CLOUDS - bool multi_pass_clouds = fgGetBool("/sim/rendering/multi-pass-clouds") && - !SGCloudLayer::enable_bump_mapping; // ugly artefact now -#else - bool multi_pass_clouds = false; -#endif - bool draw_clouds = fgGetBool("/environment/clouds/status"); - - if ( fgPanelVisible() ) { - GLfloat height = fgGetInt("/sim/startup/ysize"); - GLfloat view_h = - (globals->get_current_panel()->getViewHeight() - globals->get_current_panel()->getYOffset()) - * (height / 768.0) + 1; - glTranslatef( 0.0, view_h, 0.0 ); - } - - static GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 }; - static GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 }; - - FGLight *l = (FGLight *)(globals->get_subsystem("lighting")); - - glClearColor(l->adj_fog_color()[0], l->adj_fog_color()[1], - l->adj_fog_color()[2], l->adj_fog_color()[3]); - - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - - // set the opengl state to known default values - default_state->force(); - - glEnable( GL_FOG ); - glFogf ( GL_FOG_DENSITY, fog_exp2_density); - glFogi ( GL_FOG_MODE, GL_EXP2 ); - glFogfv ( GL_FOG_COLOR, l->adj_fog_color() ); - - // GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if - // we only update GL_AMBIENT for our lights we will never get - // a completely dark scene. So, we set GL_LIGHT_MODEL_AMBIENT - // explicitely to black. - glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black ); - glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE ); - - ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient() ); - - // texture parameters - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; - glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ; - - // we need a white diffuse light for the phase of the moon - ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, white ); - thesky->preDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER, - fog_exp2_density ); - - // draw the ssg scene - // return to the desired diffuse color - ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() ); - glEnable( GL_DEPTH_TEST ); - ssgSetNearFar( scene_nearplane, scene_farplane ); - if ( draw_clouds ) { - // Draw the terrain - FGTileMgr::set_tile_filter( true ); - sgSetModelFilter( false ); - globals->get_aircraft_model()->select( false ); - ssgCullAndDraw( globals->get_scenery()->get_scene_graph() ); - // Disable depth buffer update, draw the clouds - glDepthMask( GL_FALSE ); - thesky->drawUpperClouds(); - if ( multi_pass_clouds ) { - thesky->drawLowerClouds(); - } - glDepthMask( GL_TRUE ); - if ( multi_pass_clouds ) { - // Draw the objects except the aircraft - // and update the stencil buffer with 1 - glEnable( GL_STENCIL_TEST ); - glStencilFunc( GL_ALWAYS, 1, 1 ); - glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); - } - FGTileMgr::set_tile_filter( false ); - sgSetModelFilter( true ); - ssgCullAndDraw( globals->get_scenery()->get_scene_graph() ); - } else { - FGTileMgr::set_tile_filter( true ); - sgSetModelFilter( true ); - globals->get_aircraft_model()->select( false ); - ssgCullAndDraw( globals->get_scenery()->get_scene_graph() ); - } - - // draw the lights - glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through); - ssgSetNearFar( scene_nearplane, scene_farplane ); - ssgCullAndDraw( globals->get_scenery()->get_vasi_lights_root() ); - ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() ); - - ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() ); - - if ( draw_clouds ) { - if ( multi_pass_clouds ) { - // Disable depth buffer update, draw the clouds where the - // objects overwrite the already drawn clouds, by testing - // the stencil buffer against 1 - glDepthMask( GL_FALSE ); - glStencilFunc( GL_EQUAL, 1, 1 ); - glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); - thesky->drawUpperClouds(); - thesky->drawLowerClouds(); - glDepthMask( GL_TRUE ); - glDisable( GL_STENCIL_TEST ); - } else { - glDepthMask( GL_FALSE ); - thesky->drawLowerClouds(); - glDepthMask( GL_TRUE ); - } - } - - globals->get_aircraft_model()->select( true ); - globals->get_model_mgr()->draw(); - globals->get_aircraft_model()->draw(); -} - // Update all Visuals (redraws anything graphics related) void -FGRenderer::update(double dt) { +FGRenderer::update( bool refresh_camera_settings ) { bool scenery_loaded = fgGetBool("sim/sceneryloaded") || fgGetBool("sim/sceneryloaded-override"); bool draw_otw = fgGetBool("/sim/rendering/draw-otw"); bool skyblend = fgGetBool("/sim/rendering/skyblend"); @@ -385,10 +262,12 @@ FGRenderer::update(double dt) { // update fog params double actual_visibility; - if (fgGetBool("/environment/clouds/status")) + if (fgGetBool("/environment/clouds/status")) { actual_visibility = thesky->get_visibility(); - else + } else { actual_visibility = fgGetDouble("/environment/visibility-m"); + } + if ( actual_visibility != last_visibility ) { last_visibility = actual_visibility; @@ -429,9 +308,16 @@ FGRenderer::update(double dt) { // calculate our current position in cartesian space globals->get_scenery()->set_center( globals->get_scenery()->get_next_center() ); - // update view port - fgReshape( fgGetInt("/sim/startup/xsize"), - fgGetInt("/sim/startup/ysize") ); + if ( refresh_camera_settings ) { + // update view port + resize( fgGetInt("/sim/startup/xsize"), + fgGetInt("/sim/startup/ysize") ); + + // Tell GL we are switching to model view parameters + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + ssgSetCamera( (sgVec4 *)current__view->get_VIEW() ); + } if ( fgGetBool("/sim/rendering/clouds3d") ) { glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); @@ -477,16 +363,6 @@ FGRenderer::update(double dt) { } 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(); @@ -614,11 +490,6 @@ FGRenderer::update(double dt) { glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ; - // glMatrixMode( GL_PROJECTION ); - // glLoadIdentity(); - ssgSetFOV( current__view->get_h_fov(), - current__view->get_v_fov() ); - double agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev(); @@ -631,7 +502,7 @@ FGRenderer::update(double dt) { scene_farplane = 120000.0f; } - ssgSetNearFar( scene_nearplane, scene_farplane ); + setNearFar( scene_nearplane, scene_farplane ); if ( draw_otw && skyblend ) { // draw the sky backdrop @@ -647,8 +518,6 @@ FGRenderer::update(double dt) { // 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 ); @@ -695,7 +564,7 @@ FGRenderer::update(double dt) { // the current view frustum will still be freed properly. static int counter = 0; counter++; - if (counter == 200) { + if (counter >= 200) { sgFrustum f; f.setFOV(360, 360); // No need to put the near plane too close; @@ -714,7 +583,9 @@ FGRenderer::update(double dt) { // draw runway lighting glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through); - ssgSetNearFar( scene_nearplane, scene_farplane ); + + // CLO - 02/25/2005 - DO WE NEED THIS extra fgSetNearFar()? + // fgSetNearFar( scene_nearplane, scene_farplane ); if ( enhanced_lighting ) { @@ -924,12 +795,12 @@ FGRenderer::resize( int width, int height ) { set_aspect_ratio((float)view_h / (float)width); } - ssgSetFOV( viewmgr->get_current_view()->get_h_fov(), - viewmgr->get_current_view()->get_v_fov() ); + setFOV( viewmgr->get_current_view()->get_h_fov(), + viewmgr->get_current_view()->get_v_fov() ); #ifdef FG_USE_CLOUDS_3D sgClouds3d->Resize( viewmgr->get_current_view()->get_h_fov(), - viewmgr->get_current_view()->get_v_fov() ); + viewmgr->get_current_view()->get_v_fov() ); #endif } @@ -938,4 +809,69 @@ FGRenderer::resize( int width, int height ) { } +// These are wrapper functions around ssgSetNearFar() and ssgSetFOV() +// which will post process and rewrite the resulting frustum if we +// want to do asymmetric view frustums. + +static void fgHackFrustum() { + + /* experiment in assymetric view frustums */ + sgFrustum *f = ssgGetFrustum(); + cout << " l = " << f->getLeft() + << " r = " << f->getRight() + << " b = " << f->getBot() + << " t = " << f->getTop() + << " n = " << f->getNear() + << " f = " << f->getFar() + << endl; + static double incr = 0.0; + double factor = (sin(incr) + 1.0) / 2.0; // map to [0-1] + double w = (f->getRight() - f->getLeft()) / 2.0; + double l = f->getLeft() + w * factor; + double r = l + w; + ssgSetFrustum(l, r, f->getBot(), f->getTop(), f->getNear(), f->getFar()); + incr += 0.001; +} + + +// we need some static storage space for these values. However, we +// can't store it in a renderer class object because the functions +// that manipulate these are static. They are static so they can +// interface to the display callback system. There's probably a +// better way, there has to be a better way, but I'm not seeing it +// right now. +static float width, height, near, far; + + +/** FlightGear code should use this routine to set the FOV rather than + * calling the ssg routine directly + */ +void FGRenderer::setFOV( float w, float h ) { + width = w; + height = h; + + // fully specify the view frustum before hacking it (so we don't + // accumulate hacked effects + ssgSetFOV( w, h ); + ssgSetNearFar( near, far ); + + fgHackFrustum(); +} + + +/** FlightGear code should use this routine to set the Near/Far clip + * planes rather than calling the ssg routine directly + */ +void FGRenderer::setNearFar( float n, float f ) { + near = n; + far = f; + + // fully specify the view frustum before hacking it (so we don't + // accumulate hacked effects + ssgSetNearFar( n, f ); + ssgSetFOV( width, height ); + + fgHackFrustum(); +} + // end of renderer.cxx