diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc
index fe0aaad905afa939a5c464ffd2828df48b6273e9..884d9c15f2b4c1fa898660cb92271051e7f3f8e3 100644
--- a/modules/gfx/pymod/export_gfx_obj.cc
+++ b/modules/gfx/pymod/export_gfx_obj.cc
@@ -47,6 +47,17 @@ namespace {
     b->SetMatShin(p);
     set_mat_emm2(b,0.0);
   }
+
+  void set_outline(GfxObjBase* b, bool f)
+  {
+    LOGN_MESSAGE("Outline(bool) is deprecated, use SetOutline(bool) instead");
+    b->SetOutline(f);
+  }
+  void set_aalines(GfxObjBase* b, bool f)
+  {
+    LOGN_MESSAGE("AALines(bool) is deprecated, use SetAALines(bool) instead");
+    b->SetAALines(f);
+  }
 }
 
 void export_GfxObj()
@@ -69,9 +80,11 @@ void export_GfxObj()
     .def("GetCenter",&GfxObjBase::GetCenter)
     .def("SetLineWidth", &GfxObjBase::SetLineWidth)
     .def("SetPolyMode",&GfxObjBase::SetPolyMode)
-    .def("AALines",&GfxObjBase::AALines)
+    .def("AALines",set_aalines)
+    .def("SetAALines",&GfxObjBase::SetAALines)
     .def("SetLineHalo",&GfxObjBase::SetLineHalo)
-    .def("Outline",&GfxObjBase::Outline)
+    .def("Outline",set_outline)
+    .def("SetOutline",&GfxObjBase::SetOutline)
     .def("SetOutlineMode",&GfxObjBase::SetOutlineMode)
     .def("SetOutlineWidth",&GfxObjBase::SetOutlineWidth)
     .def("SetOutlineExpandFactor",&GfxObjBase::SetOutlineExpandFactor)
diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc
index 47bd793c04968f83922b373fd335e9ce3b53b569..d6b843c4a6c5a585881af022cf6c318d5f9db4e0 100644
--- a/modules/gfx/pymod/export_scene.cc
+++ b/modules/gfx/pymod/export_scene.cc
@@ -98,7 +98,6 @@ void export_Scene()
     .def("SetStereoInverted",&Scene::SetStereoInverted)
     .def("SetStereoView",&Scene::SetStereoView)
     .def("SetStereoEyeDist",&Scene::SetStereoEyeDist)
-    .def("SetStereoEyeOffset",&Scene::SetStereoEyeOffset)
     .def("SetLightDir",&Scene::SetLightDir)
     .def("SetLightProp",set_light_prop1)
     .def("SetLightProp",set_light_prop2)
@@ -119,11 +118,13 @@ void export_Scene()
     .def("BlurSnapshot",&Scene::BlurSnapshot)
     .def("SetShadow",&Scene::SetShadow)
     .def("SetShadowQuality",&Scene::SetShadowQuality)
+    .def("SetShadowWeight",&Scene::SetShadowWeight)
     .def("SetDepthDarkening",&Scene::SetDepthDarkening)
     .def("SetDepthDarkeningWeight",&Scene::SetDepthDarkeningWeight)
     .def("SetAmbientOcclusion",&Scene::SetAmbientOcclusion)
     .def("SetAmbientOcclusionWeight",&Scene::SetAmbientOcclusionWeight)
     .def("SetAmbientOcclusionMode",&Scene::SetAmbientOcclusionMode)
+    .def("SetAmbientOcclusionQuality",&Scene::SetAmbientOcclusionQuality)
     .def("AttachObserver",&Scene::AttachObserver)
     .def("StartOffscreenMode",&Scene::StartOffscreenMode)
     .def("StopOffscreenMode",&Scene::StopOffscreenMode)
diff --git a/modules/gfx/pymod/glwin_base_proxy.hh b/modules/gfx/pymod/glwin_base_proxy.hh
index 8bfea675ac76e98bdbc2a27aae075a915fa9fc4b..b8b47975fb06fc8ad1a61b0468de2e0faaed603c 100644
--- a/modules/gfx/pymod/glwin_base_proxy.hh
+++ b/modules/gfx/pymod/glwin_base_proxy.hh
@@ -22,7 +22,9 @@ public:
   virtual void DoRefresh() {
     call_method<void>(self, "DoRefresh");
   }
-  virtual void SetStereo(bool flag) { }
+  virtual bool HasStereo() const { 
+    return call_method<bool>(self,"HasStereo");
+  }
   virtual void StatusMessage(const String& m) {
     call_method<void, const String>(self, "StatusMessage", m);
   }
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index 10d4bf23dd9808a8dd25340d0bda4e36a2dad54f..8e992a0f7d763da5197e4c1f0395aaa24991836a 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -273,7 +273,7 @@ void GfxObj::SetPolyMode(unsigned int m)
   FlagRefresh();
 }
 
-void GfxObj::AALines(bool f)
+void GfxObj::SetAALines(bool f)
 {
   if(f==aalines_flag_) return;
   va_.SetAALines(f);
@@ -288,7 +288,7 @@ void GfxObj::SetLineHalo(float f)
   FlagRefresh();
 }
 
-void GfxObj::Outline(bool f)
+void GfxObj::SetOutline(bool f)
 {
   outline_flag_=f;
   FlagRefresh();
diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh
index 4f6ebb8a461b9355c6b92c6fc7ef27a4210512c2..42f9fbbfecca4636f2742edb573d468b5f0cf1d9 100644
--- a/modules/gfx/src/gfx_object.hh
+++ b/modules/gfx/src/gfx_object.hh
@@ -72,9 +72,9 @@ public:
   virtual geom::Vec3 GetCenter() const;
   virtual void SetLineWidth(float w);
   virtual void SetPolyMode(unsigned int m);
-  virtual void AALines(bool f);
+  virtual void SetAALines(bool f);
   virtual void SetLineHalo(float f);
-  virtual void Outline(bool f);
+  virtual void SetOutline(bool f);
   virtual void SetOutlineMode(int m);
   virtual void SetOutlineWidth(float f);
   virtual void SetOutlineExpandFactor(float f);
diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh
index 7b3812d6653d1e257f1e64a52f3c59897526b868..24b331a4134e87479dc2e5411affdb2f1477ddf3 100644
--- a/modules/gfx/src/gfx_object_base.hh
+++ b/modules/gfx/src/gfx_object_base.hh
@@ -84,13 +84,13 @@ class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode
   virtual void SetPolyMode(unsigned int m) = 0;
 
   /// \brief turn on sophisticated line anti-aliasing, requires shader
-  virtual void AALines(bool f) = 0;
+  virtual void SetAALines(bool f) = 0;
 
   /// \brief turn on line halo of given strength
   virtual void SetLineHalo(float f) = 0;
 
   /// \brief turn outline rendering on or off
-  virtual void Outline(bool f) = 0;
+  virtual void SetOutline(bool f) = 0;
   /// \brief set outline mode
   virtual void SetOutlineMode(int m) = 0;
   /// \brief set outline width (modes 1 + 2)
diff --git a/modules/gfx/src/glwin_base.hh b/modules/gfx/src/glwin_base.hh
index 996ed2ba117db2dd394f55d04849980e3f7b9a72..1be6d819f78fb15eba23eb82c440f59d8654ae09 100644
--- a/modules/gfx/src/glwin_base.hh
+++ b/modules/gfx/src/glwin_base.hh
@@ -39,7 +39,7 @@ public:
 
   virtual void StatusMessage(const String& m) = 0;
 
-  virtual void SetStereo(bool s) = 0;
+  virtual bool HasStereo() const = 0;
 
   virtual bool HasMultisample() const = 0;
 };
diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc
index 5b200f2747cd54cf0f976b8b596c5f16e7cca010..d0ef2cb703d78e1621d0a667765982456609d212 100644
--- a/modules/gfx/src/impl/scene_fx.cc
+++ b/modules/gfx/src/impl/scene_fx.cc
@@ -24,11 +24,13 @@ SceneFX& SceneFX::Instance()
 SceneFX::SceneFX():
   shadow_flag(false),
   shadow_quality(1),
+  shadow_weight(1.0),
   depth_dark_flag(false),
   depth_dark_factor(1.0),
   amb_occl_flag(false),
   amb_occl_factor(1.0),
   amb_occl_mode(1),
+  amb_occl_quality(1),
   scene_tex_id_(),
   depth_tex_id_(),
   shadow_tex_id_(),
@@ -259,6 +261,10 @@ void SceneFX::Postprocess()
   glUniform1i(glGetUniformLocation(cpr,"scene_map"),0);
   glUniform1i(glGetUniformLocation(cpr,"depth_map"),1);
 
+  glUniform2f(glGetUniformLocation(cpr,"i_vp"),
+              1.0/static_cast<float>(vp.width),
+              1.0/static_cast<float>(vp.height));
+
   if(shadow_flag) {
     glActiveTexture(GL_TEXTURE2);
     glBindTexture(GL_TEXTURE_2D,shadow_tex_id_);
@@ -273,6 +279,7 @@ void SceneFX::Postprocess()
     glUniform1f(glGetUniformLocation(cpr,"shadow_depth_bias"),0.008);
     glUniform1f(glGetUniformLocation(cpr,"shadow_epsilon"),0.002);
     glUniform1f(glGetUniformLocation(cpr,"shadow_multiplier"),0.4);
+    glUniform1f(glGetUniformLocation(cpr,"shadow_weight"),shadow_weight);
 
   } else {
     glUniform1i(glGetUniformLocation(cpr,"shadow_flag"),0);
@@ -414,7 +421,6 @@ void SceneFX::prep_shadow_map()
                   0.0,0.0,0.5,0.5,
                   0.0,0.0,0.0,1.0);
   //shadow_tex_mat_ = bias*pmat*ltrans.GetMatrix();
-  Scene::Instance().ResetProjection();
   glGetv(GL_PROJECTION_MATRIX, glpmat);
   geom::Mat4 pmat2(geom::Transpose(geom::Mat4(glpmat)));
   /*
@@ -429,8 +435,11 @@ void SceneFX::prep_amb_occlusion()
 {
   Viewport vp=Scene::Instance().GetViewport();
 
-  uint width=vp.width/2;
-  uint height=vp.height/2;
+  uint qf=1;
+  if(amb_occl_quality==0) {qf=4;}
+  else if(amb_occl_quality==1) {qf=2;}
+  uint width=vp.width/qf;
+  uint height=vp.height/qf;
 
   Shader::Instance().PushProgram();
   Shader::Instance().Activate("amboccl");
@@ -451,6 +460,7 @@ void SceneFX::prep_amb_occlusion()
   double pm[16];
   glGetDoublev(GL_PROJECTION_MATRIX,pm);
   glUniform4f(glGetUniformLocation(cpr,"abcd"),pm[0],pm[5],pm[10],pm[14]);
+
   glMatrixMode(GL_TEXTURE);
   glPushMatrix();
   geom::Mat4 ipm(geom::Transpose(geom::Invert(geom::Transpose(geom::Mat4(pm)))));
@@ -460,6 +470,10 @@ void SceneFX::prep_amb_occlusion()
   // set up viewport filling quad to run the fragment shader
   draw_screen_quad(width,height);
 
+  glMatrixMode(GL_TEXTURE);
+  glPopMatrix();
+  glMatrixMode(GL_MODELVIEW);
+
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, occl_tex_id_);
   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, width, height, 0);
diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh
index f24e4596e5e84ef52d1d34087c6261332b0ed7de..fb19525a835740cbd496d6cde85f369360cf4aa4 100644
--- a/modules/gfx/src/impl/scene_fx.hh
+++ b/modules/gfx/src/impl/scene_fx.hh
@@ -52,11 +52,13 @@ public:
 
   bool shadow_flag;
   int shadow_quality;
+  float shadow_weight;
   bool depth_dark_flag;
   float depth_dark_factor;
   bool amb_occl_flag;
   float amb_occl_factor;
   uint amb_occl_mode;
+  uint amb_occl_quality;
 
 private:
   SceneFX();
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index cad6fc6033900bfec37afcce00f0410be7ae8079..1a4a540416dda64f63234cd66ce63057cacdba6e 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -125,8 +125,7 @@ Scene::Scene():
   stereo_(0),
   stereo_inverted_(false),
   stereo_eye_(0),
-  stereo_eye_dist_(5.0),
-  stereo_eye_offset_(10.0),
+  stereo_eye_dist_(10.0),
   scene_left_tex_(),
   scene_right_tex_()
 {
@@ -186,6 +185,14 @@ void Scene::SetShadowQuality(int q)
 #endif
 }
 
+void Scene::SetShadowWeight(float w)
+{
+#if OST_SHADER_SUPPORT_ENABLED
+  impl::SceneFX::Instance().shadow_weight=w;
+  RequestRedraw();
+#endif
+}
+
 void Scene::SetDepthDarkening(bool f)
 {
 #if OST_SHADER_SUPPORT_ENABLED
@@ -213,6 +220,15 @@ void Scene::SetAmbientOcclusion(bool f)
 #endif
 } 
 
+bool Scene::GetAmbientOcclusion() const
+{
+#if OST_SHADER_SUPPORT_ENABLED
+  return impl::SceneFX::Instance().amb_occl_flag;
+#else
+  return false;
+#endif
+} 
+
 void Scene::SetAmbientOcclusionWeight(float f)
 {
 #if OST_SHADER_SUPPORT_ENABLED
@@ -231,6 +247,15 @@ void Scene::SetAmbientOcclusionMode(uint m)
 #endif
 }
 
+void Scene::SetAmbientOcclusionQuality(uint m)
+{
+#if OST_SHADER_SUPPORT_ENABLED
+  impl::SceneFX::Instance().amb_occl_quality=m;
+  // the redraw routine will deal with the Shader
+  RequestRedraw();
+#endif
+}
+
 void Scene::SetShadingMode(const std::string& smode)
 {
 #if OST_SHADER_SUPPORT_ENABLED
@@ -570,10 +595,8 @@ void Scene::RenderGL()
 
   prep_blur();
 
-  if(stereo_==1) {
-    render_quad_buffered_stereo();
-  } else if (stereo_==2) {
-    render_interlaced_stereo();
+  if(stereo_==1 || stereo_==2) {
+    render_stereo();
   } else {
     render_scene();
   }
@@ -1208,14 +1231,16 @@ void Scene::SetFogOffsets(float no, float fo)
 void Scene::Stereo(unsigned int m)
 {
   if(m==1) {
-    stereo_=m;
-    //if(win_) win_->SetStereo(true);
-  } else if(m==2 || m==3) {
-    stereo_=m;
-    //if(win_) win_->SetStereo(false);
+    if(win_ && win_->HasStereo()) {
+      stereo_=1;
+    } else {
+      LOGN_MESSAGE("No visual present for quad-buffered stereo");
+      stereo_=0;
+    }
+  } else if(m==2) {
+    stereo_=2;
   } else {
     stereo_=0;
-    //if(win_) win_->SetStereo(false);
   }
   RequestRedraw();
 }
@@ -1241,16 +1266,6 @@ void Scene::SetStereoEyeDist(float d)
   }
 }
 
-void Scene::SetStereoEyeOffset(float o)
-{
-  stereo_eye_offset_=o;
-  if(stereo_>0) {
-    RequestRedraw();
-  }
-}
-
-
-
 void Scene::SetLightDir(const Vec3& dir)
 {
   if(Length2(dir)>0.0) {
@@ -1791,14 +1806,13 @@ void Scene::stereo_projection(unsigned int view)
   GLdouble zn=std::max<float>(1.0,znear_);
   GLdouble zf=std::max<float>(1.1,zfar_);
 
-#if 1
   GLdouble top = zn * std::tan(fov_*M_PI/360.0);
   GLdouble bot = -top;
   GLdouble right = top*aspect_ratio_;
   GLdouble left = -right;
   GLdouble shift=0.0;
   if(view==1 || view==2) {
-    shift = 0.5*stereo_eye_dist_*zn/zf * (view==1 ? 1.0 : -1.0);
+    shift = 0.5*stereo_eye_dist_*zn/zf * (view==1 ? -1.0 : 1.0);
     left+=shift;
     right+=shift*0.5;
   }
@@ -1811,22 +1825,11 @@ void Scene::stereo_projection(unsigned int view)
   trans[15]=1.0;
   trans[12]=shift;
   glMultMatrixd(trans);
-#else
-  gluPerspective(fov_,aspect_ratio_,zn,zf);
-  if(view==1 || view==2) {
-    float iod = (view==1) ? -stereo_eye_dist_ : stereo_eye_dist_;
-    //float fr=(-stereo_eye_offset_-zn)/(zf-zn);
-    float angle=180.0f/M_PI*std::atan(stereo_eye_offset_/(2.0*iod));
-    glTranslated(0.0,0.0,transform_.GetTrans()[2]);
-    glRotated(-angle,0.0,1.0,0.0);
-    glTranslated(0.0,0.0,-transform_.GetTrans()[2]);
-  }
-#endif
 }
 
-void Scene::render_interlaced_stereo()
+void Scene::render_stereo()
 {
-  glGetError();
+  stereo_eye_=1;
   stereo_projection(1);
   render_scene();
 
@@ -1834,8 +1837,8 @@ void Scene::render_interlaced_stereo()
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, scene_left_tex_);
   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, vp_width_, vp_height_, 0);
-  check_gl_error();
 
+  stereo_eye_=2;
   stereo_projection(2);
   render_scene();
   glEnable(GL_TEXTURE_2D);
@@ -1843,6 +1846,7 @@ void Scene::render_interlaced_stereo()
   glBindTexture(GL_TEXTURE_2D, scene_right_tex_);
   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, vp_width_, vp_height_, 0);
   check_gl_error();
+  stereo_eye_=0;
   stereo_projection(0);
 
 #if OST_SHADER_SUPPORT_ENABLED
@@ -1868,30 +1872,36 @@ void Scene::render_interlaced_stereo()
   glPushMatrix();
   glLoadIdentity();
 
-  // draw interlace lines in stencil buffer
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-  glLineWidth(1.0);
-  glEnable(GL_STENCIL_TEST);
-  glStencilMask(0x1);
-  glClearStencil(0x0);
-  glClear(GL_STENCIL_BUFFER_BIT);
-  glStencilFunc(GL_ALWAYS,0x1,0x1);
-  glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
-  glBegin(GL_LINES);
-  glColor3f(1.0,1.0,1.0);
-  for(unsigned int i=0;i<vp_height_;i+=2) {
-    glVertex2i(0,i);
-    glVertex2i(vp_width_-1,i);
-  } 
-  glEnd();
-
-  glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
-
-  // left eye
-  glStencilFunc(GL_EQUAL,0x1,0x1);
+  if(stereo_==2) {
+    // draw interlace lines in stencil buffer
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glLineWidth(1.0);
+    glEnable(GL_STENCIL_TEST);
+    glStencilMask(0x1);
+    glClearStencil(0x0);
+    glClear(GL_STENCIL_BUFFER_BIT);
+    glStencilFunc(GL_ALWAYS,0x1,0x1);
+    glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
+    glBegin(GL_LINES);
+    glColor3f(1.0,1.0,1.0);
+    for(unsigned int i=0;i<vp_height_;i+=2) {
+      glVertex2i(0,i);
+      glVertex2i(vp_width_-1,i);
+    } 
+    glEnd();
+    
+    glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
+  }
 
+  // right eye
+  if(stereo_==1) {
+    glDrawBuffer(GL_BACK_RIGHT);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  } else if(stereo_==2) {
+    glStencilFunc(GL_EQUAL,0x0,0x1);
+  }
   glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, stereo_inverted_ ? scene_right_tex_ : scene_left_tex_);
+  glBindTexture(GL_TEXTURE_2D, stereo_inverted_ ? scene_left_tex_ : scene_right_tex_);
   // draw
   glColor3f(1.0,0.0,1.0);
   glBegin(GL_QUADS);
@@ -1901,9 +1911,15 @@ void Scene::render_interlaced_stereo()
   glTexCoord2f(1.0,0.0); glVertex2i(vp_width_,0);
   glEnd();
 
-  // right eye
-  glStencilFunc(GL_EQUAL,0x0,0x1);
-  glBindTexture(GL_TEXTURE_2D, stereo_inverted_ ? scene_left_tex_ : scene_right_tex_);
+  // left eye
+  if(stereo_==1) {
+    glDrawBuffer(GL_BACK_LEFT);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  } else if(stereo_==2) {
+    glStencilFunc(GL_EQUAL,0x1,0x1);
+  }
+  glActiveTexture(GL_TEXTURE0);
+  glBindTexture(GL_TEXTURE_2D, stereo_inverted_ ? scene_right_tex_ : scene_left_tex_);
   // draw
   glColor3f(1.0,0.0,1.0);
   glBegin(GL_QUADS);
@@ -1912,7 +1928,7 @@ void Scene::render_interlaced_stereo()
   glTexCoord2f(1.0,1.0); glVertex2i(vp_width_,vp_height_);
   glTexCoord2f(1.0,0.0); glVertex2i(vp_width_,0);
   glEnd();
-
+  
   // restore settings
   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
@@ -1924,14 +1940,4 @@ void Scene::render_interlaced_stereo()
 #endif
 }
 
-void Scene::render_quad_buffered_stereo()
-{
-  glDrawBuffer(GL_BACK_LEFT);
-  stereo_projection(stereo_inverted_ ? 1 : 2);
-  render_scene();
-  glDrawBuffer(GL_BACK_RIGHT);
-  stereo_projection(stereo_inverted_ ? 2 : 1);
-  render_scene();
-}
-
 }} // ns
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index 1b798d24b113c291eeff7d82c2894b2b8db8324d..d9eacf632e322711ab8a35afa48f27d292726d07 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -111,12 +111,16 @@ class DLLEXPORT_OST_GFX Scene {
   /// \brief shadow quality from 0 (low) to 3 (high), default=1
   void SetShadowQuality(int q);
 
+  void SetShadowWeight(float w);
+
   void SetDepthDarkening(bool f);
   void SetDepthDarkeningWeight(float f);
 
   void SetAmbientOcclusion(bool f);
+  bool GetAmbientOcclusion() const;
   void SetAmbientOcclusionWeight(float f);
   void SetAmbientOcclusionMode(uint m);
+  void SetAmbientOcclusionQuality(uint q);
   
   /// \brief select shading mode
   /// one of fallback, basic, default, hf, toon1, toon2
@@ -185,7 +189,6 @@ class DLLEXPORT_OST_GFX Scene {
   void SetStereoView(unsigned int);
 
   void SetStereoEyeDist(float);
-  void SetStereoEyeOffset(float);
 
   /// \brief set main light direction
   void SetLightDir(const geom::Vec3& dir);
@@ -435,7 +438,7 @@ private:
   unsigned int stereo_;
   bool stereo_inverted_;
   unsigned int stereo_eye_;
-  float stereo_eye_dist_,stereo_eye_offset_;
+  float stereo_eye_dist_;
   unsigned int scene_left_tex_;
   unsigned int scene_right_tex_;
 
@@ -448,8 +451,7 @@ private:
   void stereo_projection(unsigned int view);
   void render_scene();
   void render_glow();
-  void render_interlaced_stereo();
-  void render_quad_buffered_stereo();
+  void render_stereo();
   bool IsNameAvailable(String name);
 };
 
diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc
index f6d83bb3f175420b656aa62c98ab95d71de76fb9..49f86a1a974ad3a13f7b64059e67efa3f6d582b9 100644
--- a/modules/gfx/src/shader.cc
+++ b/modules/gfx/src/shader.cc
@@ -76,7 +76,7 @@ bool compile_shader(String shader_name, String shader_code, GLenum shader_type,
   GLint sh_compiled;
   glGetShaderiv(shader_id, GL_COMPILE_STATUS, &sh_compiled);
   if(sh_compiled==GL_TRUE) {
-    LOGN_VERBOSE("shader [" << shader_name << "] successfully compiled (" << shader_id << ")");
+    LOGN_DEBUG("shader [" << shader_name << "] successfully compiled (" << shader_id << ")");
   } else {
     GLint sh_log_length;
     glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &sh_log_length);
@@ -93,7 +93,7 @@ bool link_shader(const std::vector<GLuint>& code_list, String pr_name, GLuint& s
   shader_pr = glCreateProgram();
   for(std::vector<GLuint>::const_iterator it=code_list.begin();it!=code_list.end();++it) {
     if(*it == 0) {
-      LOGN_VERBOSE("skipping shader [" << pr_name << "] due to missing compiled code");
+      LOGN_DEBUG("skipping shader [" << pr_name << "] due to missing compiled code");
       return false;
     }
     LOGN_DEBUG("attaching compiled shader id " << *it << " to " << shader_pr);
@@ -104,7 +104,7 @@ bool link_shader(const std::vector<GLuint>& code_list, String pr_name, GLuint& s
   GLint pr_linked;
   glGetProgramiv(shader_pr,GL_LINK_STATUS,&pr_linked);
   if(pr_linked==GL_TRUE) {
-    LOGN_VERBOSE("shader [" << pr_name << "] sucessfully linked");
+    LOGN_DEBUG("shader [" << pr_name << "] sucessfully linked");
   } else {
     GLint pr_log_length;
     glGetProgramiv(shader_pr, GL_INFO_LOG_LENGTH, &pr_log_length);
diff --git a/modules/gfx/src/shader/scenefx_fs.glsl b/modules/gfx/src/shader/scenefx_fs.glsl
index e8acfcefcca8289305183381e403b1999efbce5c..277647ee47f603fa25782d291142f4ec30463231 100644
--- a/modules/gfx/src/shader/scenefx_fs.glsl
+++ b/modules/gfx/src/shader/scenefx_fs.glsl
@@ -1,7 +1,9 @@
 uniform sampler2D scene_map;
 uniform sampler2D depth_map;
+uniform vec2 i_vp;
 uniform bool shadow_flag;
 uniform sampler2D shadow_map;
+uniform float shadow_weight;
 uniform float shadow_depth_bias;
 uniform float shadow_epsilon;
 uniform float shadow_multiplier;
@@ -33,15 +35,13 @@ void main()
     vec4 pcoord = vec4(gl_TexCoord[0].xy*2.0-1.0,depth*2.0-1.0,1.0);
     vec4 coord = gl_TextureMatrix[2]*pcoord;
     coord/=coord.w;
-    //float d = texture2D(shadow_map, coord.xy).r;
-    //gl_FragColor.rgb=vec3(1.0,d,0.0);
-    //return;
     shadow_factor = 0.0;
     shadow_factor += 0.18*CalcShadowFactor(coord, vec2(-0.7, -0.7));
     shadow_factor += 0.18*CalcShadowFactor(coord, vec2(0.7, -0.7));
     shadow_factor += 0.18*CalcShadowFactor(coord, vec2(0.7, 0.7));
     shadow_factor += 0.18*CalcShadowFactor(coord, vec2(-0.7, 0.7));
     shadow_factor += 0.28*CalcShadowFactor(coord, vec2(0, 0));
+    shadow_factor = mix(1.0, shadow_factor, shadow_weight);
   }
 
   float occl_factor=1.0;
diff --git a/modules/gfx/src/surface.cc b/modules/gfx/src/surface.cc
index f5142f5692ac212ab79ca0f119ae125a0db35196..7bce8bb48e78176a9c2583cc667790354bc4dcaa 100644
--- a/modules/gfx/src/surface.cc
+++ b/modules/gfx/src/surface.cc
@@ -384,17 +384,26 @@ RSurface::RSurface(const String& name, const RSurfP& rs):
   SphereList slist = rs->GetSphereList();
 
 
-#if 0
+#if 1
   for(TetList::const_iterator it=tlist.begin();it!=tlist.end();++it) {
-    VertexID id1 = va_.Add((*it)->A->pos,Vec3(),Color(1,1,1));
-    VertexID id2 = va_.Add((*it)->B->pos,Vec3(),Color(1,1,1));
-    VertexID id3 = va_.Add((*it)->C->pos,Vec3(),Color(1,1,1));
-    VertexID id4 = va_.Add((*it)->cA,Vec3(),Color(0,1,0));
-    VertexID id5 = va_.Add((*it)->cB,Vec3(),Color(0,1,0));
-    VertexID id6 = va_.Add((*it)->cC,Vec3(),Color(0,1,0));
-    va_.AddLine(id1,id4);
-    va_.AddLine(id2,id5);
-    va_.AddLine(id3,id6);
+    Color col(1,1,0);
+    if((*it)->depth==0) {
+      col=Color(0.5,0,0);
+    } else if((*it)->depth==1) {
+      col=Color(1,0,0);
+    } else if((*it)->depth==2) {
+      col=Color(1,0.5,0);
+    }
+    VertexID id0 = va_.Add((*it)->S->pos,geom::Vec3(),col);
+    VertexID id1 = va_.Add((*it)->A->pos,geom::Vec3(),Color(1,1,1));
+    VertexID id2 = va_.Add((*it)->B->pos,geom::Vec3(),Color(1,1,1));
+    VertexID id3 = va_.Add((*it)->C->pos,geom::Vec3(),Color(1,1,1));
+    VertexID id4 = va_.Add((*it)->cA,geom::Vec3(),Color(0,1,0));
+    VertexID id5 = va_.Add((*it)->cB,geom::Vec3(),Color(0,1,0));
+    VertexID id6 = va_.Add((*it)->cC,geom::Vec3(),Color(0,1,0));
+    va_.AddLine(id1,id0);
+    va_.AddLine(id2,id0);
+    va_.AddLine(id3,id0);
     va_.AddLine(id4,id5);
     va_.AddLine(id5,id6);
     va_.AddLine(id6,id4);
@@ -418,96 +427,6 @@ RSurface::RSurface(const String& name, const RSurfP& rs):
   }
 #endif
 
-
-  for(SphereList::const_iterator it=slist.begin();it!=slist.end();++it) {
-    for(uint l=0;l<(*it)->arc_list_list.size();++l) {
-      const Sphere& sp = *(*it);
-      const ArcDirDeque& alist=sp.arc_list_list[l];
-      if(alist.empty()) continue; 
-
-      if(alist.size()<4) continue;
-      Vec3 a0 = alist[0].inv_arc ? -alist[0].arc->axis : alist[0].arc->axis;
-      Vec3 a1 = alist[1].inv_arc ? -alist[1].arc->axis : alist[1].arc->axis;
-      Vec3 s0 = alist[0].inv_arc ? alist[0].arc->T->pos : alist[0].arc->S->pos;
-      Vec3 s1 = alist[1].inv_arc ? alist[1].arc->T->pos : alist[1].arc->S->pos;
-      Vec3 p0 = sp.pos+sp.rad*(s0-sp.pos)/((sp.rad+alist[0].arc->S->rad));
-      Vec3 p1 = sp.pos+sp.rad*(s1-sp.pos)/((sp.rad+alist[1].arc->S->rad));
-
-      VertexID id00 = va_.Add(p0,Vec3(),Color(1,1,1));
-      VertexID id10 = va_.Add(p1,Vec3(),Color(1,1,1));
-      VertexID id20 = id00;
-
-      for(float c=0.0;c<=1.0;c+=0.1) {
-        Mat3 r0 = AxisRotation(a0,c*alist[0].arc->phi);
-        Mat3 r1 = AxisRotation(a1,c*alist[1].arc->phi);
-        Vec3 v0 = r0*(p0-alist[0].arc->fixpoint)+alist[0].arc->fixpoint;
-        Vec3 v1 = r1*(p1-alist[1].arc->fixpoint)+alist[1].arc->fixpoint;
-        Vec3 v2 = r1*(v0-alist[1].arc->fixpoint)+alist[1].arc->fixpoint;
-        VertexID id01 = va_.Add(v0,Vec3(),Color(1,1,1));
-        VertexID id11 = va_.Add(v1,Vec3(),Color(1,1,1));
-        VertexID id21 = va_.Add(v2,Vec3(),Color(1,c,0));
-        va_.AddLine(id00,id01);
-        va_.AddLine(id10,id11);
-        va_.AddLine(id20,id21);
-        id00=id01;
-        id10=id11;
-        id20=id21;
-      }
-
-#if 0
-      Vec3 sum1;
-      Vec3 sum2;
-      Vec3 sum3;
-      Vec3 prev;
-      float plan=0.0;
-      for(uint i=0;i<alist.size();++i) {
-        uint j = (i-1+alist.size())%alist.size();
-        uint k = (i+1)%alist.size();
-        sum1+=(alist[i].arc->mid-sp.pos)*alist[i].arc->phi;
-        Vec3 d0 = alist[i].arc->S->pos-sp.pos;
-        Vec3 d1 = alist[i].arc->mid-sp.pos;
-        Vec3 d2 = alist[i].arc->T->pos-sp.pos;
-
-        Vec3 p0 = sp.pos+sp.rad*(d0)/(sp.rad+alist[i].arc->S->rad);
-        Vec3 p1 = sp.pos+sp.rad*(d1)/(sp.rad+alist[i].arc->S->rad);
-        Vec3 p2 = sp.pos+sp.rad*(d2)/(sp.rad+alist[i].arc->S->rad);
-        Vec3 c0 = Normalize(Cross(Normalize(alist[i].w.pos-alist[i].v.pos),
-                                  Normalize(alist[k].w.pos-alist[k].v.pos))+
-                            Cross(Normalize(alist[j].w.pos-alist[j].v.pos),
-                                  Normalize(alist[i].w.pos-alist[i].v.pos)));
-        Vec3 c1 = Normalize(Cross(Normalize(p0-p1),Normalize(p2-p1)));
-
-        if(i>0) {
-          plan+=Dot(prev,Normalize(d1));
-        }
-        prev=Normalize(d1);
-        sum2+=c0*alist[i].arc->phi;
-
-        VertexID id0 = va_.Add(p0,Vec3(),Color(1,1,0));
-        VertexID id1 = va_.Add(p1,Vec3(),Color(1,1,1));
-        VertexID id2 = va_.Add(p2,Vec3(),Color(1,1,0));
-        VertexID id3 = va_.Add(sp.pos,Vec3(),Color(1,1,1));
-        va_.AddLine(id0,id1);
-        va_.AddLine(id1,id2);
-        //va_.AddLine(id1,id3);
-      }
-      float f = plan/static_cast<float>(alist.size());
-      VertexID id8 = va_.Add(sp.pos,Vec3(),Color(1,1,1));
-      VertexID id9 = va_.Add(sp.pos+1.1*sp.rad*Normalize(sum1),Vec3(),Color(0,0,1));
-      VertexID idA = va_.Add(sp.pos+1.1*sp.rad*Normalize(sum2),Vec3(),Color(1,0,0));
-      VertexID idB = va_.Add(sp.pos+1.1*sp.rad*Normalize(f*sum1+(1.0-f)*sum2),Vec3(),Color(0,1,0));
-      va_.AddLine(id8,id9);
-      va_.AddLine(id8,idA);
-      va_.AddLine(id8,idB);
-#endif
-#if 0
-      VertexID id0 = va_.Add(sp.pos,Vec3(),Color(1,1,1));
-      VertexID id1 = va_.Add(sp.top_list[l],Vec3(),Color(1,1,0));
-      va_.AddLine(id0,id1);
-#endif
-    }
-  }
-
   va_.SetMode(0x2);
   va_.SetLighting(false);
   va_.SetCullFace(false);
diff --git a/modules/gui/pymod/export_gosty.cc b/modules/gui/pymod/export_gosty.cc
index 88bb732874744cec1e379365cece71efc413b166..8b9e815d2b66756d3bf72a324b8f1a7c0829b2cc 100644
--- a/modules/gui/pymod/export_gosty.cc
+++ b/modules/gui/pymod/export_gosty.cc
@@ -112,6 +112,7 @@ void export_Gosty()
     .def("AddWidgetToApp", &app_add_widget_to_app_b)
     .def("GetPerspective", &GostyApp::GetPerspective, 
          return_value_policy<reference_existing_object>())
+    .def("TryStereo",&GostyApp::TryStereo)
   ;
   register_ptr_to_python<GostyApp*>();
 }
diff --git a/modules/gui/src/gl_canvas.cc b/modules/gui/src/gl_canvas.cc
index 1b953d77ce40e08ac05766da1995fdc9fca9b286..73ebee84600d6088efee685a05a674428c68314a 100644
--- a/modules/gui/src/gl_canvas.cc
+++ b/modules/gui/src/gl_canvas.cc
@@ -76,13 +76,6 @@ void GLCanvas::StatusMessage(const String& m)
   glwin_->StatusMessage(m);
 }
 
-void GLCanvas::SetStereo(bool s)
-{
-  QGLFormat f=this->format();
-  f.setStereo(s);
-  this->setFormat(f);
-}
-
 void GLCanvas::OnTransform(gfx::InputCommand com, int indx, 
                            gfx::TransformTarget trg, Real val)
 {
@@ -365,10 +358,14 @@ void GLCanvas::keyPressEvent(QKeyEvent* event)
       gfx::Scene::Instance().SetShadingMode("toon2");
       DoRefresh();
       return;
-    } else if(event->key()==Qt::Key_P) {
+    } else if(event->key()==Qt::Key_0) {
       gfx::Scene::Instance().SetShadow(!gfx::Scene::Instance().GetShadow());
       DoRefresh();
       return;
+    } else if(event->key()==Qt::Key_9) {
+      gfx::Scene::Instance().SetAmbientOcclusion(!gfx::Scene::Instance().GetAmbientOcclusion());
+      DoRefresh();
+      return;
     }    
   }
   event->ignore();
diff --git a/modules/gui/src/gl_canvas.hh b/modules/gui/src/gl_canvas.hh
index 631aa624d9cffc8fd68e20da0477728a5dd7e8fe..e55ff8fd066fb4ce621b9ec508a4dad9f0ce37aa 100644
--- a/modules/gui/src/gl_canvas.hh
+++ b/modules/gui/src/gl_canvas.hh
@@ -54,7 +54,7 @@ public:
   virtual void MakeActive();
   virtual void DoRefresh();
   virtual void StatusMessage(const String& m);
-  virtual void SetStereo(bool s);
+  virtual bool HasStereo() const {return format().stereo();};
   virtual bool HasMultisample() const {return format().sampleBuffers();}
 
   // central point for sending input to the gfx layer
diff --git a/modules/gui/src/gl_win.cc b/modules/gui/src/gl_win.cc
index 693a9197a821b10e5d9d69d0fc0dd1f755ffa99c..90bb1d9a73bdbf964bfb40717195b745a25eb757 100644
--- a/modules/gui/src/gl_win.cc
+++ b/modules/gui/src/gl_win.cc
@@ -46,29 +46,51 @@
 
 namespace ost { namespace gui {
 
-GLWin::GLWin(QWidget* p):
-  Widget(NULL, p), 
-  gl_canvas_(NULL)
+GLWin::GLWin(QWidget* p, bool try_stereo):
+Widget(NULL, p), 
+gl_canvas_(NULL)
 {
   QMainWindow* main=new QMainWindow;
-  for(int format_id=2;format_id>=0;--format_id) {
-    gl_canvas_=new GLCanvas(this, main, GLWin::CreateFormat(format_id));
-    if(gl_canvas_->isValid()) {
-      break; // format is fine
-    } else {
-      delete gl_canvas_; // delete this canvas and try a less sophisticated format
+  
+  if(try_stereo) {
+    LOGN_VERBOSE("GLCanvas: trying stereo visuals first");
+    for(int format_id=3;format_id>=0;--format_id) {
+      QGLFormat format=GLWin::CreateFormat(format_id);
+      format.setStereo(true);
+      gl_canvas_=new GLCanvas(this, main, format);
+      if(gl_canvas_->isValid() && gl_canvas_->format().stereo()) {
+        break; // format is fine
+      } else {
+        delete gl_canvas_; // delete this canvas and try a less sophisticated format
+        gl_canvas_=0;
+      }
+    }
+  }
+  if(!gl_canvas_) {
+    if(try_stereo) {
+      LOGN_VERBOSE("GLCanvas: no stereo visual found, trying normal ones");
+    }
+    for(int format_id=3;format_id>=0;--format_id) {
+      QGLFormat format=GLWin::CreateFormat(format_id);
+      gl_canvas_=new GLCanvas(this, main, format);
+      if(gl_canvas_->isValid()) {
+        break; // format is fine
+      } else {
+        delete gl_canvas_; // delete this canvas and try a less sophisticated format
+        gl_canvas_=0;
+      }
     }
   }
 
-  if(!gl_canvas_->isValid()) {
-    LOGN_ERROR("no valid GL context found, GL canvas could not be created");
+  if(!gl_canvas_ || !gl_canvas_->isValid()) {
+    LOGN_ERROR("GLCanvas: no valid GL context found, this is pretty fatal");
     return;
   }
 
   this->SetInternalWidget(main);
   gfx::Scene::Instance().AttachObserver(this);
   QGLFormat format = gl_canvas_->format();
-  LOGN_VERBOSE("GLCanvas created with rbits=" << format.redBufferSize() 
+  LOGN_VERBOSE("GLCanvas: rbits=" << format.redBufferSize() 
                << " gbits=" << format.greenBufferSize() 
                << " bbits=" << format.blueBufferSize() 
                << " abits=" << format.alphaBufferSize() 
@@ -76,6 +98,9 @@ GLWin::GLWin(QWidget* p):
                << " accumbits=" << format.accumBufferSize()
                << " multisample=" << format.sampleBuffers()
                << " with samples=" << format.samples());
+  if(gl_canvas_->format().stereo()) {
+    LOGN_VERBOSE("GLCanvas: using stereo visual");
+  }
   main->setCentralWidget(gl_canvas_);
   connect(gl_canvas_, SIGNAL(ReleaseFocus()), this, SIGNAL(ReleaseFocus()));
   connect(&ToolManager::Instance(), SIGNAL(ActiveToolChanged(Tool*)), this, SLOT(ActiveToolChanged(Tool*)));
@@ -101,7 +126,16 @@ void GLWin::ActiveToolChanged(Tool* t)
 QGLFormat GLWin::CreateFormat(int fid)
 {
   QGLFormat format = QGLFormat::defaultFormat();
-  if(fid==2) {
+  if(fid==3) {
+    format.setDepthBufferSize(24);
+    format.setRedBufferSize(8);
+    format.setGreenBufferSize(8);
+    format.setBlueBufferSize(8);
+    format.setAlpha(true);
+    format.setAlphaBufferSize(8);
+    format.setAccum(true);
+    format.setSampleBuffers(true);
+  } else if(fid==2) {
     format.setDepthBufferSize(12);
     format.setRedBufferSize(8);
     format.setGreenBufferSize(8);
diff --git a/modules/gui/src/gl_win.hh b/modules/gui/src/gl_win.hh
index c5d0efb2d46a65f1154384ba3af21bf45b28f25b..08cecfcad2c3c3162d80c4cec561fa485ab6d580 100644
--- a/modules/gui/src/gl_win.hh
+++ b/modules/gui/src/gl_win.hh
@@ -43,7 +43,7 @@ class DLLEXPORT_OST_GUI GLWin: public Widget, public gfx::SceneObserver
 {
   Q_OBJECT;
 public:
-  GLWin(QWidget* p);
+  GLWin(QWidget* p, bool try_stereo=false);
   ~GLWin();
   void SetTestMode(bool f);
 
diff --git a/modules/gui/src/gosty_app.cc b/modules/gui/src/gosty_app.cc
index 8eed58bea578fe8bed58d89d65f30ef264138248..840008f79e405272409b2d3378b88b924c5c41ae 100644
--- a/modules/gui/src/gosty_app.cc
+++ b/modules/gui/src/gosty_app.cc
@@ -48,7 +48,8 @@ GostyApp::GostyApp():
   py_shell_(NULL), w_py_shell_(NULL), gl_win_(NULL), w_gl_win_(NULL),
   scene_win_(NULL), w_scene_win_(NULL), seq_viewer_(NULL), tool_options_win_(NULL),
   w_tool_options_(NULL), main_(new GostyMainWindow), 
-  perspective_(NULL), external_widgets_(QMap<QString,WidgetGeomHandler *>())
+  perspective_(NULL), external_widgets_(QMap<QString,WidgetGeomHandler *>()),
+  try_stereo_(false)
 {
   assert(GostyApp::app_==NULL);
   GostyApp::app_=this;
@@ -141,10 +142,10 @@ PythonShell* GostyApp::GetPyShell()
   return py_shell_;
 }
 
-GLWin*  GostyApp::GetGLWin()
+GLWin* GostyApp::GetGLWin()
 {
   if (gl_win_==NULL) {
-    gl_win_=new GLWin(main_);
+    gl_win_=new GLWin(main_,try_stereo_);
     gl_win_->SetDestroyOnClose(false);    
   }
   return gl_win_;  
diff --git a/modules/gui/src/gosty_app.hh b/modules/gui/src/gosty_app.hh
index 2bf1e2eee3f5a5b14b22d8835a48cb97597e512a..5c62ac345b0b157f5f389da12f819b7fbfc9b72e 100644
--- a/modules/gui/src/gosty_app.hh
+++ b/modules/gui/src/gosty_app.hh
@@ -37,14 +37,10 @@
   #include <ost/gui/data_viewer/data_viewer.hh>
 #endif
 
-
-
-
 class QMainWindow;
 class QMdiArea;
 class QWidget;
 
-
 namespace ost { namespace gui {
 
 class PythonShell;
@@ -80,7 +76,7 @@ public:
   /// The GL window is initialized when this method is first called. All 
   /// subsequent calls will return the same GLWin instance.
   GLWin* GetGLWin();
-  
+
   /// \brief get scene menu
   /// 
   /// The scene menu window is initialized when this method is first called. All 
@@ -138,6 +134,9 @@ public:
   /// \param app_title Title that will be displayed in the title bar
   void SetAppTitle(const QString& app_title);
 
+  /// \brief attempt to get a stereo visual upon startup
+  void TryStereo(bool f) {try_stereo_=f;}
+  
 public slots:
   /// \brief This slot must be called when the application is going to be terminated.
   void OnQuit();
@@ -164,6 +163,8 @@ private:
   
   QMap<QString,WidgetGeomHandler *> external_widgets_;
 
+  bool try_stereo_;
+
   static GostyApp*  app_;
 };
 
diff --git a/modules/mol/base/src/impl/rsurf_impl.cc b/modules/mol/base/src/impl/rsurf_impl.cc
index 283671fdf161989a2db83c5cc4fdc357b9769125..13b8484c0eff528af63057708c6b4b1d6313450f 100644
--- a/modules/mol/base/src/impl/rsurf_impl.cc
+++ b/modules/mol/base/src/impl/rsurf_impl.cc
@@ -313,9 +313,11 @@ void RSurf::Build()
   ntet->W = ArcP(new Arc(ntet->C, ntet->A, ntet->S));
   ntet->W->A = ntet;
   // note: creation of all three prior to traversal is necessary!
-  traverse_arc(ntet,ntet->U,ntet->C);
-  traverse_arc(ntet,ntet->V,ntet->A);
-  traverse_arc(ntet,ntet->W,ntet->B);
+  
+  ntet->depth=0;
+  traverse_arc(ntet,ntet->U,ntet->C,1);
+  //traverse_arc(ntet,ntet->V,ntet->A,1);
+  //traverse_arc(ntet,ntet->W,ntet->B,1);
 
   LOGN_DUMP("build " << tet_list_.size() << " tets and " << arc_list_.size() << " arcs");
 
@@ -325,8 +327,10 @@ void RSurf::Build()
   }
 }
 
-void RSurf::traverse_arc(TetP tet, ArcP& arc, SphereP c)
+void RSurf::traverse_arc(TetP tet, ArcP& arc, SphereP c, uint depth)
 {
+  if(depth>4) return;
+
   if(tet->S!=arc->S) {
     LOGN_VERBOSE("unexpected error during arc traversal: tet->S != arc->S; aborting arc traversal (" <<arc->H->name << "," << arc->K->name << ")");
     return;
@@ -364,6 +368,7 @@ void RSurf::traverse_arc(TetP tet, ArcP& arc, SphereP c)
 
 
   // given the new tet, handle current arc
+  ntet->depth=depth;
   ntet->U = arc;
   arc->SetT(ntet->S);
   arc->B=ntet;
@@ -375,15 +380,15 @@ void RSurf::traverse_arc(TetP tet, ArcP& arc, SphereP c)
     ntet->V->A = ntet;
     ntet->W = ArcP(new Arc(ntet->B, ntet->A, ntet->S));
     ntet->W->A = ntet;
-    traverse_arc(ntet,ntet->V,ntet->A);
-    traverse_arc(ntet,ntet->W,ntet->C);
+    traverse_arc(ntet,ntet->V,ntet->A,depth+1);
+    traverse_arc(ntet,ntet->W,ntet->C,depth+1);
   } else {
     ntet->V = ArcP(new Arc(ntet->B, ntet->C, ntet->S));
     ntet->V->A = ntet;
     ntet->W = ArcP(new Arc(ntet->C, ntet->A, ntet->S));
     ntet->W->A = ntet;
-    traverse_arc(ntet,ntet->V,ntet->A);
-    traverse_arc(ntet,ntet->W,ntet->B);
+    traverse_arc(ntet,ntet->V,ntet->A,depth+1);
+    traverse_arc(ntet,ntet->W,ntet->B,depth+1);
   }
 
 }
@@ -391,28 +396,49 @@ void RSurf::traverse_arc(TetP tet, ArcP& arc, SphereP c)
 std::pair<TetP,bool> RSurf::get_tet(SphereP a, SphereP b, SphereP c, const Sphere& s, bool create)
 {
   // TODO: this could use a hash table instead of a list for faster lookup
-  for(TetList::const_iterator it=tet_list_.begin();it!=tet_list_.end();++it) {
+  bool parity_swap=false;
+  TetList::const_iterator it=tet_list_.begin();
+  for(;it!=tet_list_.end();++it) {
     Tet& tet=*(*it);
-    // only compare same parity
-    if(tet.parity_swap) {
-      if((tet.A==a && tet.C==b && tet.B==c) ||
-         (tet.A==c && tet.C==a && tet.B==b) ||
-         (tet.A==b && tet.C==c && tet.B==a)) {
-        return std::make_pair(*it,true);
-      }
+
+    // first find matching triplet
+    if((tet.A==a && tet.B==b && tet.C==c) ||
+       (tet.A==c && tet.B==a && tet.C==b) ||
+       (tet.A==b && tet.B==c && tet.C==a)) {
+      parity_swap=false;
+      LOGN_DUMP("found tet with order 0");
+      break;
+    } else if((tet.A==a && tet.C==b && tet.B==c) ||
+	      (tet.A==c && tet.C==a && tet.B==b) ||
+	      (tet.A==b && tet.C==c && tet.B==a)) {
+      parity_swap=true;
+      LOGN_DUMP("found tet with order 1");
+      break;
+    }
+  }
+
+  if(it==tet_list_.end()) {
+    if(create) {
+      LOGN_DUMP("no tet found, making new one");
+      TetP tet(new Tet(a,b,c,s));
+      tet_list_.push_back(tet);
+      return std::make_pair(tet,false);
+    }
+
+  } else {
+    if(parity_swap==(*it)->parity_swap) {
+      LOGN_DUMP("parities match, returning old one");
+      return std::make_pair(*it,true);
     } else {
-      if((tet.A==a && tet.B==b && tet.C==c) ||
-         (tet.A==c && tet.B==a && tet.C==b) ||
-         (tet.A==b && tet.B==c && tet.C==a)) {
-        return std::make_pair(*it,true);
+      // re-use ABC assignment from tet
+      if(create) {
+	LOGN_DUMP("parities don't match, creating new one");
+	TetP tet(new Tet((*it)->A,(*it)->B,(*it)->C,s));
+	tet_list_.push_back(tet);
+	return std::make_pair(tet,false);
       }
     }
   }
-  if(create) {
-    TetP tet(new Tet(a,b,c,s));
-    tet_list_.push_back(tet);
-    return std::make_pair(tet,false);
-  }
   return std::make_pair(TetP(),false);
 }
 
diff --git a/modules/mol/base/src/impl/rsurf_impl.hh b/modules/mol/base/src/impl/rsurf_impl.hh
index 5f7755afeebde926f9057c3aec6d25ec72e6d276..c22e8b7cd683088808273c4b31927c4c385c81de 100644
--- a/modules/mol/base/src/impl/rsurf_impl.hh
+++ b/modules/mol/base/src/impl/rsurf_impl.hh
@@ -84,14 +84,13 @@ struct Sphere {
   std::vector<geom::Vec3> top_list;
   std::vector<ArcDirDeque> arc_list_list;
 };
-  
+
 typedef boost::shared_ptr<Sphere> SphereP;
 typedef std::vector<SphereP> SphereList;
 
 struct Tet;
 typedef boost::shared_ptr<Tet> TetP;
 
-
 // arc that bridges two tets
 /*
   the orientation of H,K,S,T is such that the rotation of S
@@ -145,6 +144,8 @@ struct Tet {
 
   bool parity_swap;
 
+  uint depth; // debug
+
   void init();
 };
   
@@ -180,7 +181,7 @@ public:
 private:
 
   // main recursive routine
-  void traverse_arc(TetP tet, ArcP& arc, SphereP c);
+  void traverse_arc(TetP tet, ArcP& arc, SphereP c, uint depth);
 
   // get tet from list, optionally creating it if necessary
   // the solvent s is either used as a parity check, or as the new sphere
diff --git a/scripts/init.py b/scripts/init.py
index 6df88ea013347837d43e8b155141325da09f6fb2..17a421695fbf509a9497b2361205364d383e8eea 100644
--- a/scripts/init.py
+++ b/scripts/init.py
@@ -45,9 +45,10 @@ def _InitPanels(app):
     panels.AddWidget(gui.PanelPosition.BOTTOM_PANEL, app.seq_viewer)
     panels.AddWidget(gui.PanelPosition.BOTTOM_PANEL, app.py_shell)
 
-def _InitFrontEnd():
+def _InitFrontEnd(try_stereo):
   app=gui.GostyApp.Instance()
   app.SetAppTitle("DNG")
+  app.TryStereo(try_stereo)
   main_area=app.perspective.main_area
   _InitPanels(app)
   _InitMenuBar(app)
@@ -129,6 +130,7 @@ parser.add_option("-p", "--pdb_id", dest="pdb_ids", default=[],action="append",
 parser.add_option("-b", "--builder", dest="builder", default="HEURISTIC", help="Type of builder used by the progam (either RULE_BASED or HEURISTIC) [default: %default]")
 parser.add_option("-c", "--compound_library", dest="complib", default="compounds.chemlib", help="Compound library for the RULE_BASED builder (only used if --builder option is set to RULE_BASED, otherwise ignored [default: %default]")
 parser.add_option("-q", "--query", dest="query", default="", help="Selection query to be highlighted automatically upon loading (only used together with -p option or when a PDB file is loaded, otherwise ignored [default: None]")
+parser.add_option("-S","--stereo", dest="try_stereo", default=False, action="store_true",help="try to get a quad-buffer stereo visual")
 parser.disable_interspersed_args()
 (options, args) = parser.parse_args()
 
@@ -152,7 +154,7 @@ if options.builder=="RULE_BASED":
   conop.Conopology.Instance().SetDefaultBuilder('rbb')
 
 PushVerbosityLevel(options.vlevel)
-_InitFrontEnd()
+_InitFrontEnd(options.try_stereo)
 
 if len(loading_list)!=0 or len(options.pdb_ids)!=0:
   _load_files()