]> git.mxchange.org Git - flightgear.git/commitdiff
Fix main window aspect ratios other than 4/3
authortimoore <timoore>
Fri, 25 Jan 2008 18:44:45 +0000 (18:44 +0000)
committertimoore <timoore>
Fri, 25 Jan 2008 18:44:45 +0000 (18:44 +0000)
This also fixes distortion weirdness in the osgviewer version. That
was caused by osg::GraphicsContext getting in the act on resize events
and adding its own scaling to the projectionOffset of slave cameras!

src/Main/fg_os_osgviewer.cxx
src/Main/renderer.cxx
src/Main/renderer.hxx

index 63bb3e41e6101cb538ab74a8ad3d2588bcd9bf87..087d29757998f520ae32e28c6fdaafaaf3cf0873 100644 (file)
@@ -33,6 +33,7 @@
 #include <osg/Matrixd>
 #include <osg/Viewport>
 #include <osg/Version>
+#include <osg/View>
 #include <osgViewer/ViewerEventHandlers>
 #include <osgViewer/Viewer>
 #include <osgGA/MatrixManipulator>
 // fg_os implementation
 //
 
+using namespace osg;
+
 static osg::ref_ptr<osgViewer::Viewer> viewer;
 static osg::ref_ptr<osg::Camera> mainCamera;
 
+// Callback to prevent the GraphicsContext resized function from messing
+// with the projection matrix of the slave
+
+namespace
+{
+struct fgResizeCallback : public GraphicsContext::ResizedCallback
+{
+    fgResizeCallback(Camera* slaveCamera)
+        : mainSlaveCamera(slaveCamera)
+    {}
+    
+    virtual void resizedImplementation(GraphicsContext* gc, int x, int y,
+                                       int width, int height);
+    ref_ptr<Camera> mainSlaveCamera;
+};
+
+void fgResizeCallback::resizedImplementation(GraphicsContext* gc,
+                                             int x, int y,
+                                             int width, int height)
+{
+    View* view = mainSlaveCamera->getView();
+    View::Slave* slave = (view ?
+                          view->findSlaveForCamera(mainSlaveCamera.get()) : 0);
+    if (slave) {
+        Matrixd projOffset(slave->_projectionOffset);
+        gc->resizedImplementation(x, y, width, height);
+        // Restore projection offsets changed by
+        // GraphicsContext::resizedImplementation
+        slave->_projectionOffset = projOffset;
+    } else {
+        gc->resizedImplementation(x, y, width, height);
+    }
+    
+}
+
+}
 void fgOSOpenWindow(int w, int h, int bpp,
                     bool alpha, bool stencil, bool fullscreen)
 {
@@ -67,7 +106,6 @@ void fgOSOpenWindow(int w, int h, int bpp,
 
     viewer = new osgViewer::Viewer;
     viewer->setDatabasePager(FGScenery::getPagerSingleton());
-    // Avoid complications with fg's custom drawables.
     std::string mode;
     mode = fgGetString("/sim/rendering/multithreading-mode", "SingleThreaded");
     if (mode == "AutomaticSelection")
@@ -196,6 +234,12 @@ void fgOSOpenWindow(int w, int h, int bpp,
     // of mouse events are somewhat bizzare.
     camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
     camera->setProjectionResizePolicy(rsp);
+    if (nCameras == 0) {
+        // Only one principal camera
+        gc->setResizedCallback(new fgResizeCallback(camera.get()));
+    }
+    // Why a slave? It seems to be the easiest way to assign cameras,
+    // for which we've created the graphics context ourselves, to the viewer.
     viewer->addSlave(camera.get());
 
     viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
index 40cce615b8caace5601ef785986a6334bf7e638b..41e313c099bda3ba5aebb2321fbac3fc9f13a88f 100644 (file)
@@ -751,6 +751,9 @@ FGRenderer::update( bool refresh_camera_settings ) {
       - current__view->getSGLocation()->get_cur_elev_m();
 
     float scene_nearplane, scene_farplane;
+    // XXX Given that the own airplane model is part of the scene
+    // graph, should this business be ripped out? The near plane is
+    // ignored by setCameraParameters.
     if ( agl > 10.0 ) {
         scene_nearplane = 10.0f;
         scene_farplane = 120000.0f;
@@ -758,7 +761,9 @@ FGRenderer::update( bool refresh_camera_settings ) {
         scene_nearplane = groundlevel_nearplane->getDoubleValue();
         scene_farplane = 120000.0f;
     }
-    setNearFar( scene_nearplane, scene_farplane );
+    setCameraParameters(current__view->get_v_fov(),
+                        current__view->get_aspect_ratio(),
+                        scene_nearplane, scene_farplane);
 
 //     sgEnviro.startOfFrame(current__view->get_view_pos(), 
 //         current__view->get_world_up(),
@@ -846,50 +851,19 @@ FGRenderer::resize( int width, int height ) {
         viewmgr->get_view(i)->
           set_aspect_ratio((float)view_h / (float)width);
       }
-
-      setFOV( viewmgr->get_current_view()->get_h_fov(),
-              viewmgr->get_current_view()->get_v_fov() );
     }
 }
 
-
-// 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 fov_width = 55.0;
-static float fov_height = 42.0;
-static float fov_near = 1.0;
-static float fov_far = 1000.0;
-
-
-/** FlightGear code should use this routine to set the FOV rather than
- *  calling the ssg routine directly
- */
-void FGRenderer::setFOV( float w, float h ) {
-    fov_width = w;
-    fov_height = h;
-    osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
-    viewer->getCamera()->setProjectionMatrixAsPerspective(fov_height, 4.0/3.0,
-                                                          fov_near, fov_far);
-}
-
-
-/** 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 ) {
-// OSGFIXME: we have currently too much z-buffer fights
-n = 0.1;
-    fov_near = n;
-    fov_far = f;
+void FGRenderer::setCameraParameters(float vfov, float aspectRatio,
+                                     float near, float far)
+{
+    near = .1;
     osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
-    viewer->getCamera()->setProjectionMatrixAsPerspective(fov_height, 4.0/3.0,
-                                                          fov_near, fov_far);
+    viewer->getCamera()->setProjectionMatrixAsPerspective(vfov,
+                                                          1.0f / aspectRatio,
+                                                          near, far);
+    
 }
-
 bool
 FGRenderer::pick( unsigned x, unsigned y,
                   std::vector<SGSceneryPick>& pickList,
index de21b932e3c501657b48b23539a8fef1c41cc0f2..f651be821b4c951a8ae715f775b5a35218d363ea 100644 (file)
@@ -40,18 +40,10 @@ public:
     static void update( bool refresh_camera_settings );
     inline static void update() { update( true ); }
 
-
-    /** FlightGear code should use this routine to set the FOV rather
-     *  than calling the ssg routine directly
+    /** Set all the camera parameters at once. aspectRatio is height / width.
      */
-    static void setFOV( float w, float h );
-
-
-    /** FlightGear code should use this routine to set the Near/Far
-     *  clip planes rather than calling the ssg routine directly
-     */
-    static void setNearFar( float n, float f );
-
+    static void setCameraParameters(float vfov, float aspectRatio,
+                                    float near, float far);
     /** Just pick into the scene and return the pick callbacks on the way ...
      */
     static bool pick( unsigned x, unsigned y,