diff --git a/modules/base/pymod/__init__.py b/modules/base/pymod/__init__.py
index c6d7a8ec17b8085fb4412236f0bfbbf5f6cc648f..286bedced409ad9f66317d0ee7a71afde1c53082 100644
--- a/modules/base/pymod/__init__.py
+++ b/modules/base/pymod/__init__.py
@@ -27,6 +27,7 @@ from ost import seq
 try:
   from ost import gfx
   scene = gfx.Scene()
+  scene.Stereo=gfx.Stereo
 except ImportError:
   pass
   
diff --git a/modules/gfx/pymod/__init__.py b/modules/gfx/pymod/__init__.py
index 8c0b24a8872811e1cca02cd6a350b9fcf8d47de7..11fb994719d9243b29256afa445a0f5b488a82b5 100644
--- a/modules/gfx/pymod/__init__.py
+++ b/modules/gfx/pymod/__init__.py
@@ -47,6 +47,23 @@ DARKORANGE=Color(0.5,0.25,0.0)
 LIGHTORANGE=Color(1.0,0.75,0.5)
 
 
+def Stereo(mode,flip=None,alg=None):
+  """
+  Stereo control
+
+  :param mode: 0=off, 1=quad-buffered, 2=interlaced
+  :type mode: int
+  :param flip: invert order of left/right display
+  :type flip: bool
+  :param alg: stereo algorithm (0 or 1)
+  :type param: int
+  """
+  if(flip):
+    _gfx.Scene().SetStereoFlip(flip)
+  if(alg):
+    _gfx.Scene().SetStereoAlg(alg)
+  if(mode):
+    _gfx.Scene().SetStereoMode(mode)
 
 def FitToScreen(gfx_ent, width=None, height=None, margin=0.01):
   """
diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc
index b143288451273f7c9b81edffbc75b82933dbde1e..706767f8b2bfabffd6827e06c4aada663d986dc3 100644
--- a/modules/gfx/pymod/export_scene.cc
+++ b/modules/gfx/pymod/export_scene.cc
@@ -135,11 +135,21 @@ void export_Scene()
     .add_property("smode",
                  &Scene::GetSelectionMode,
                  &Scene::SetSelectionMode)
-    .def("Stereo",&Scene::Stereo)
-    .def("SetStereoInverted",&Scene::SetStereoInverted)
+    .def("SetStereoMode",&Scene::SetStereoMode)
+    .def("GetStereoMode",&Scene::GetStereoMode)
+    .add_property("stereo_mode",&Scene::GetStereoMode,&Scene::SetStereoMode)
+    .def("SetStereoFlip",&Scene::SetStereoFlip)
+    .def("GetStereoFlip",&Scene::GetStereoFlip)
+    .add_property("stereo_flip",&Scene::GetStereoFlip,&Scene::SetStereoFlip)
     .def("SetStereoView",&Scene::SetStereoView)
-    .def("SetStereoEyeDist",&Scene::SetStereoEyeDist)
-    .def("SetStereoEyeOff",&Scene::SetStereoEyeOff)
+    .def("GetStereoView",&Scene::GetStereoView)
+    .add_property("stereo_view",&Scene::GetStereoView,&Scene::SetStereoView)
+    .def("SetStereoIOD",&Scene::SetStereoIOD)
+    .def("GetStereoIOD",&Scene::GetStereoIOD)
+    .add_property("stereo_iod",&Scene::GetStereoIOD,&Scene::SetStereoIOD)
+    .def("SetStereoAlg",&Scene::SetStereoAlg)
+    .def("GetStereoAlg",&Scene::GetStereoAlg)
+    .add_property("stereo_alg",&Scene::GetStereoAlg,&Scene::SetStereoAlg)
     .def("SetLightDir",&Scene::SetLightDir)
     .def("SetLightProp",set_light_prop1)
     .def("SetLightProp",set_light_prop2)
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index 92707149d8f387dfbf80ebff41617d1c4b86e228..1574d5f509b871524a7b6e76674f18561316a059 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -123,11 +123,11 @@ Scene::Scene():
   def_text_size_(32.0),
   blur_count_(0),
   blur_buffer_(),
-  stereo_(0),
+  stereo_mode_(0),
+  stereo_alg_(0),
   stereo_inverted_(false),
   stereo_eye_(0),
-  stereo_eye_dist_(2.4),
-  stereo_eye_off_(0.0),
+  stereo_eye_dist_(40.0),
   scene_left_tex_(),
   scene_right_tex_()
 {
@@ -636,7 +636,7 @@ void Scene::RenderGL()
 
   prep_blur();
 
-  if(stereo_==1 || stereo_==2) {
+  if(stereo_mode_==1 || stereo_mode_==2) {
     render_stereo();
   } else {
     render_scene();
@@ -1279,48 +1279,52 @@ void Scene::SetFogOffsets(float no, float fo)
   RequestRedraw();
 }
 
-void Scene::Stereo(unsigned int m)
+void Scene::SetStereoMode(unsigned int m)
 {
   if(m==1) {
     if(win_ && win_->HasStereo()) {
-      stereo_=1;
+      stereo_mode_=1;
     } else {
       LOG_INFO("Scene: No visual present for quad-buffered stereo");
-      stereo_=0;
+      stereo_mode_=0;
     }
   } else if(m==2) {
-    stereo_=2;
+    stereo_mode_=2;
   } else {
-    stereo_=0;
+    stereo_mode_=0;
   }
   RequestRedraw();
 }
 
-void Scene::SetStereoInverted(bool f)
+void Scene::SetStereoFlip(bool f)
 {
   stereo_inverted_=f;
   RequestRedraw();
 }
 
-void Scene::SetStereoView(unsigned int m)
+void Scene::SetStereoView(int m)
 {
-  stereo_eye_= (m>2) ? 0: m;
+  stereo_eye_= m;
   ResetProjection();
   RequestRedraw();
 }
 
-void Scene::SetStereoEyeDist(float d)
+void Scene::SetStereoIOD(float d)
 {
   stereo_eye_dist_=d;
-  if(stereo_>0) {
+  if(stereo_mode_>0) {
     RequestRedraw();
   }
 }
 
-void Scene::SetStereoEyeOff(float d)
+void Scene::SetStereoAlg(unsigned int a)
 {
-  stereo_eye_off_=d;
-  if(stereo_>0) {
+  if(a==0 || a==1) {
+    stereo_alg_=a;
+  } else {
+    stereo_alg_=0;
+  }
+  if(stereo_mode_>0) {
     RequestRedraw();
   }
 }
@@ -1812,37 +1816,48 @@ void Scene::render_glow()
 #endif  
 }
 
-void Scene::stereo_projection(unsigned int view)
+void Scene::stereo_projection(int view)
 {
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
-  
-  GLdouble zn=std::max<float>(1.0,znear_);
-  GLdouble zf=std::max<float>(1.1,zfar_);
-
-  GLdouble top = zn * std::tan(fov_*M_PI/360.0);
-  GLdouble bot = -top;
-  GLdouble right = top*aspect_ratio_;
-  GLdouble left = -right;
 
+  Real zn=std::max<Real>(1.0,znear_);
+  Real zf=std::max<Real>(1.1,zfar_);
+  
+  Real top = zn * std::tan(fov_*M_PI/360.0);
+  Real bot = -top;
+  Real right = top*aspect_ratio_;
+  Real left = -right;
+  
   glFrustum(left,right,bot,top,zn,zf);
-
-  if(view==1 || view==2) {
-    float ff=(view==1 ? -1.0 : 1.0);
-    float dist=-transform_.GetTrans()[2];
-    geom::Mat4 skew=geom::Transpose(geom::Mat4(1.0,0.0,ff*stereo_eye_dist_/dist,ff*stereo_eye_dist_,
-                                               0.0,1.0,0.0,0.0,
-                                               0.0,0.0,1.0,0.0,
-                                               0.0,0.0,0.0,1.0));
-    glMultMatrix(skew.Data());
+  
+  if(view!=0) {
+    Real ff=(view<0 ? 1.0 : -1.0);
+    Real dist=-transform_.GetTrans()[2];
+    if(stereo_alg_==1) {
+      // physically precise stereo with skew, does
+      // not handle z translation well
+      // the 100.0 comes from visual matching with mode 0 at a reasonable distance
+      Real iod2=100.0/stereo_eye_dist_;
+      geom::Mat4 skew=geom::Transpose(geom::Mat4(1.0,0.0,ff*iod2/dist,ff*iod2,
+                                                 0.0,1.0,0.0,0.0,
+                                                 0.0,0.0,1.0,0.0,
+                                                 0.0,0.0,0.0,1.0));
+      glMultMatrix(skew.Data());
+    } else {
+      // default, dino style stereo, less physically precise but visually more pleasing
+      glTranslated(0.0,0.0,-dist);
+      glRotated(180.0/M_PI*atan(ff/stereo_eye_dist_),0.0,1.0,0.0);
+      glTranslated(0.0,0.0,dist);
+    }
   }
-
 }
 
 void Scene::render_stereo()
 {
-  stereo_eye_=1;
-  stereo_projection(1);
+  int old_stereo_eye=stereo_eye_;
+  stereo_eye_=-1;
+  stereo_projection(-1);
   render_scene();
 
   glEnable(GL_TEXTURE_2D);
@@ -1854,8 +1869,8 @@ void Scene::render_stereo()
   glBindTexture(GL_TEXTURE_2D, scene_left_tex_);
   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, vp_width_, vp_height_, 0);
 
-  stereo_eye_=2;
-  stereo_projection(2);
+  stereo_eye_=1;
+  stereo_projection(1);
   render_scene();
   glEnable(GL_TEXTURE_2D);
 #if OST_SHADER_SUPPORT_ENABLED
@@ -1865,7 +1880,7 @@ void Scene::render_stereo()
 #endif
   glBindTexture(GL_TEXTURE_2D, scene_right_tex_);
   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, vp_width_, vp_height_, 0);
-  stereo_eye_=0;
+  stereo_eye_=old_stereo_eye;
   stereo_projection(0);
 
 #if OST_SHADER_SUPPORT_ENABLED
@@ -1893,7 +1908,7 @@ void Scene::render_stereo()
   glPushMatrix();
   glLoadIdentity();
 
-  if(stereo_==2) {
+  if(stereo_mode_==2) {
     // draw interlace lines in stencil buffer
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glLineWidth(1.0);
@@ -1915,10 +1930,10 @@ void Scene::render_stereo()
   }
 
   // right eye
-  if(stereo_==1) {
+  if(stereo_mode_==1) {
     glDrawBuffer(GL_BACK_RIGHT);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-  } else if(stereo_==2) {
+  } else if(stereo_mode_==2) {
     glStencilFunc(GL_EQUAL,0x0,0x1);
   }
 #if OST_SHADER_SUPPORT_ENABLED
@@ -1937,10 +1952,10 @@ void Scene::render_stereo()
   glEnd();
 
   // left eye
-  if(stereo_==1) {
+  if(stereo_mode_==1) {
     glDrawBuffer(GL_BACK_LEFT);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-  } else if(stereo_==2) {
+  } else if(stereo_mode_==2) {
     glStencilFunc(GL_EQUAL,0x1,0x1);
   }
 #if OST_SHADER_SUPPORT_ENABLED
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index ec4c0e13745832a3117d050899bb518da29c6739..5a93998485fbbe8428074f71149e2e4bbc349445 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -168,34 +168,46 @@ class DLLEXPORT_OST_GFX Scene {
   void SetFogOffsets(float no, float fo);
   
   /// \brief adjust near and far clipping plane to fit visible objects
+  // TODO: use mode aka fast, precise, max
   void Autoslab(bool fast=false, bool redraw=true);
-  // \brief adjust clipping planes to fix maximal extent of all objects
-  //        even under rotation
+
+  /// \brief adjust clipping planes to fix maximal extent of all objects
+  ///        even under rotation
+  // TODO: merge with Autoslab
   void AutoslabMax();
 
   /// \brief turn on automatic auto-slabbing (using the fast bounding box alg)
+  // TODO: more sophisticated mode, aka fast, precise, max
   void AutoAutoslab(bool f);
   //@}
   
-  /// \brief switch stereo mode
-  /*
-    0=off
-    1=quad-buffered
-    2=interlaced stereo
-  */
-  void Stereo(unsigned int);
-
-  int GetStereo() const {return stereo_;}
+  /// \brief set stereo mode
+  /// one of 0 (off), 1 (quad-buffered) 2 (interlaced (for special monitors))
+  void SetStereoMode(unsigned int mode);
+  int GetStereoMode() const {return stereo_mode_;}
 
   /// \brief invert stereo eyes for stereo mode=0
-  void SetStereoInverted(bool f);
-
-  /// \brief stereo view mode, 0=center, 1=left, 2=right
-  void SetStereoView(unsigned int);
-
-  void SetStereoEyeDist(float);
-  void SetStereoEyeOff(float);
-
+  void SetStereoFlip(bool f);
+  /// \brief return invert flag for stereo
+  bool GetStereoFlip() const {return stereo_inverted_;}
+  
+  /// \brief stereo view mode
+  /// one of 0 (center), -1 (left), 1 (right)
+  void SetStereoView(int);
+  /// \brief return current stereo view mode
+  int GetStereoView() const {return stereo_eye_;}
+
+  /// \brief set stereo eye distance
+  void SetStereoIOD(float);
+  /// \brief return current stereo eye distance
+  float GetStereoIOD() const {return stereo_eye_dist_;}
+  
+  /// \brief set stereo algorithm
+  /// one of 0 or 1
+  void SetStereoAlg(unsigned int);
+  /// \brief return current stereo algorithm
+  unsigned int GetStereoAlg() const {return stereo_alg_;}
+  
   /// \brief set main light direction
   void SetLightDir(const geom::Vec3& dir);
   /// \brief set ambient, diffuse and specular light color
@@ -458,10 +470,11 @@ private:
 
   uint blur_count_;
   std::vector<boost::shared_array<unsigned char> > blur_buffer_;
-  unsigned int stereo_;
+  unsigned int stereo_mode_;
+  unsigned int stereo_alg_;
   bool stereo_inverted_;
   unsigned int stereo_eye_;
-  float stereo_eye_dist_,stereo_eye_off_;
+  float stereo_eye_dist_;
   unsigned int scene_left_tex_;
   unsigned int scene_right_tex_;
 
@@ -471,7 +484,7 @@ private:
   void flag_all_dirty();
   void prep_glyphs();
   void prep_blur();
-  void stereo_projection(unsigned int view);
+  void stereo_projection(int view);
   void render_scene();
   void render_glow();
   void render_stereo();
diff --git a/modules/gui/src/gl_canvas.cc b/modules/gui/src/gl_canvas.cc
index 98f9ccc8444ba88568aef81449ab961d501e9a8f..d1a7aa9b89c9c75b93e837cd48047b6339fedf1f 100644
--- a/modules/gui/src/gl_canvas.cc
+++ b/modules/gui/src/gl_canvas.cc
@@ -436,10 +436,10 @@ void GLCanvas::keyPressEvent(QKeyEvent* event)
       DoRefresh();
       return;
     } else if(event->key()==Qt::Key_Equal) {
-      if(gfx::Scene::Instance().GetStereo()>0) {
-        gfx::Scene::Instance().Stereo(0);
+      if(gfx::Scene::Instance().GetStereoMode()>0) {
+        gfx::Scene::Instance().SetStereoMode(0);
       } else {
-        gfx::Scene::Instance().Stereo(1);
+        gfx::Scene::Instance().SetStereoMode(1);
       }
       DoRefresh();
       return;