diff --git a/examples/gfx/solid.py b/examples/gfx/solid.py
new file mode 100644
index 0000000000000000000000000000000000000000..1840068d410410c1b0394ae2becab4ba2dfe6c99
--- /dev/null
+++ b/examples/gfx/solid.py
@@ -0,0 +1,18 @@
+s=io.LoadSurface("../demos/data/sh2","msms")
+scene.Add(gfx.Surface("s",s))
+
+# alternative shading mode
+scene.SetShadingMode("hf")
+
+# add outlines to surface
+scene["s"].SetOutline(True)
+scene["s"].SetOutlineMode(3)
+
+# turn on solid rendering
+scene["s"].solid=True
+scene["s"].solid_color=gfx.RGB(0.8,0.8,0.7)
+
+scene.AutoAutoslab(False)
+scene.far=170
+scene.near=100
+scene.fog=False
diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc
index 5f9ad7d1a4ecfc29a4b1aadf18b42c4d4f81e6e0..07d845636676fbd2c381ee1bbab25a4bf8aa0ca4 100644
--- a/modules/gfx/pymod/export_gfx_obj.cc
+++ b/modules/gfx/pymod/export_gfx_obj.cc
@@ -155,6 +155,8 @@ void export_GfxObj()
     .def("SetOpacity",&GfxObjBase::SetOpacity)
     .def("GetOpacity",&GfxObjBase::GetOpacity)
     .add_property("opacity",&GfxObjBase::GetOpacity,&GfxObjBase::SetOpacity)
+    .add_property("solid",&GfxObjBase::GetSolid,&GfxObjBase::SetSolid)
+    .add_property("solid_color",&GfxObjBase::GetSolidColor,&GfxObjBase::SetSolidColor)
     COLOR_BY_DEF()
    ;
 
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index f7e3b06a5af9a5b1962156db728b4556e331c98c..63003cd5bce9481772ed5d8f3f1e8aa919e2e7c8 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -64,6 +64,8 @@ GfxObj::GfxObj(const String& name):
 #else
   outline_mode_(1),
 #endif
+  solid_(false),
+  solid_color_(RGB(0.7,0.7,0.7)),
   c_ops_(),
   labels_(),
   use_occlusion_(false)
@@ -128,6 +130,8 @@ void GfxObj::RenderGL(RenderPass pass)
       // there really needs to be a central place
       // where the va attributes are re-applied
       va_.SetOpacity(opacity_);
+      va_.SetSolid(solid_);
+      va_.SetSolidColor(solid_color_);
     }
   }
   if(IsVisible()) {
@@ -375,6 +379,20 @@ void GfxObj::SetOpacity(float o)
   Scene::Instance().RequestRedraw();
 }
 
+void GfxObj::SetSolid(bool f)
+{
+  solid_=f;
+  va_.SetSolid(solid_);
+  Scene::Instance().RequestRedraw();
+}
+
+void GfxObj::SetSolidColor(const Color& c)
+{
+  solid_color_=c;
+  va_.SetSolidColor(solid_color_);
+  Scene::Instance().RequestRedraw();
+}
+
 void GfxObj::ColorBy(const mol::EntityView& ev, 
                       const String& prop,
                       const Gradient& g, float minv, float maxv)
diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh
index fc906c35c9fdb7c563417c6785e5023d2dabe594..0b70065d7f820ca924ef07b3d2ad3005fe4e71b2 100644
--- a/modules/gfx/src/gfx_object.hh
+++ b/modules/gfx/src/gfx_object.hh
@@ -88,6 +88,11 @@ public:
   virtual Color GetOutlineExpandColor() const;
   virtual void SetOpacity(float f);
   virtual float GetOpacity() const {return opacity_;}
+  virtual void SetSolid(bool f);
+  virtual bool GetSolid() const {return solid_;}
+  virtual void SetSolidColor(const Color& c);
+  virtual Color GetSolidColor() const {return solid_color_;}
+  
   virtual void ColorBy(const mol::EntityView& ev, 
                        const String& prop,
                        const Gradient& g, float minv, float maxv);
@@ -242,6 +247,9 @@ public:
   bool outline_flag_;
   int outline_mode_;
 
+  bool solid_;
+  Color solid_color_;
+
   boost::ptr_vector<gfx::ColorOp> c_ops_;
 
   TextPrimList labels_;
diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh
index eb6c7c21743805e237377bc64e15ced0d61f3885..448de0cf2687781045e7b59bc72b145be0ee1c2d 100644
--- a/modules/gfx/src/gfx_object_base.hh
+++ b/modules/gfx/src/gfx_object_base.hh
@@ -117,6 +117,11 @@ class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode
   /// \brief returns a value smaller than 1.0 if transparency is used in this object
   virtual float GetOpacity() const = 0;
 
+  virtual void SetSolid(bool f) = 0;
+  virtual bool GetSolid() const = 0;
+  virtual void SetSolidColor(const Color& c) = 0;
+  virtual Color GetSolidColor() const = 0;
+  
   /// \brief color each component based on the gradient-mapped property of 
   ///    the given entity
   virtual void ColorBy(const mol::EntityView& ev, 
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index 02b3b3367b5933a10162d094bf89bc561b76a74e..f6f4c87f1544b091d0e51777b7b254501ae4d22b 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -174,6 +174,8 @@ class DLLEXPORT_OST_GFX Scene {
   // \brief get the field of view
   float GetFOV() const;
 
+  float GetAspect() const {return aspect_ratio_;}
+
   /// \brief offset between near clipping plane and start of fog
   void SetFogNearOffset(float o);
 
diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc
index b9c45e5a7ce54f274b2b1e0b029f100fd81772ec..155417b65e2cb2080bd6a5230ee30b936c3f5134 100644
--- a/modules/gfx/src/vertex_array.cc
+++ b/modules/gfx/src/vertex_array.cc
@@ -141,7 +141,6 @@ void IndexedVertexArray::SetOutlineMaterial(const Material& m)
 void IndexedVertexArray::SetOutlineExpandFactor(float f) { outline_exp_factor_=f;}
 void IndexedVertexArray::SetOutlineExpandColor(const Color& c) {outline_exp_color_=c;}
 
-
 VertexID IndexedVertexArray::Add(const Vec3& vert, 
                                  const Vec3& norm,
                                  const Color& col,
@@ -494,7 +493,7 @@ void IndexedVertexArray::RenderGL()
     } else {
       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
     }
-    if(cull_face_) {
+    if(cull_face_ && !solid_) {
       glEnable(GL_CULL_FACE);
     } else { 
       glDisable(GL_CULL_FACE); 
@@ -699,6 +698,8 @@ void IndexedVertexArray::Reset()
   outline_mat_update_=true;
   outline_exp_factor_=0.1;
   outline_exp_color_=Color(0,0,0);
+  solid_=false;
+  solid_color_=RGB(1,1,1);
   draw_normals_=false;
   use_tex_=false;
 }
@@ -1095,6 +1096,8 @@ void IndexedVertexArray::copy(const IndexedVertexArray& va)
   outline_mat_update_=true;
   outline_exp_factor_=va.outline_exp_factor_;
   outline_exp_color_=va.outline_exp_color_;
+  solid_=va.solid_;
+  solid_color_=va.solid_color_;
   draw_normals_=va.draw_normals_;
   use_tex_=va.use_tex_;
 }
@@ -1174,6 +1177,14 @@ bool IndexedVertexArray::prep_buff()
 
 void IndexedVertexArray::draw_ltq(bool use_buff)
 {
+  if(solid_) {
+    glClearStencil(0x0);
+    glClear(GL_STENCIL_BUFFER_BIT);
+    glEnable(GL_STENCIL_TEST);
+    glStencilFunc(GL_ALWAYS,0x0,0x1);
+    glStencilOp(GL_KEEP,GL_INVERT,GL_INVERT);
+  }
+
   if(use_buff && !Scene::Instance().InOffscreenMode()) {
 #if OST_SHADER_SUPPORT_ENABLED
 #if 0
@@ -1230,8 +1241,35 @@ void IndexedVertexArray::draw_ltq(bool use_buff)
       glDrawElements(GL_LINES,line_index_list_.size(),GL_UNSIGNED_INT,&line_index_list_[0]);
     }
   }
+
+  if(solid_) {
+    glStencilFunc(GL_EQUAL,0x1,0x1);
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+
+    float fov=Scene::Instance().GetFOV()*M_PI/180.0;
+    float znear=Scene::Instance().GetNear();
+    float aspect=Scene::Instance().GetAspect();
+    float rh=2.0*fabs(tan(fov)*znear);
+    float rw=rh*aspect;
+    float rz=-znear-0.1;
+
+    glDisable(GL_LIGHTING);
+  
+    glBegin(GL_TRIANGLE_STRIP);
+    glColor3fv(solid_color_);
+    glNormal3f(0,0,1);
+    glVertex3f(-rw,-rh,rz);
+    glVertex3f(rw,-rh,rz);
+    glVertex3f(-rw,rh,rz);
+    glVertex3f(rw,rh,rz);
+    glEnd();
+    glDisable(GL_STENCIL_TEST);
+    glPopMatrix();
+  }
 }
-    
+
 void IndexedVertexArray::draw_p(bool use_buff)
 {
   if(use_buff && !Scene::Instance().InOffscreenMode()) {
@@ -1254,115 +1292,115 @@ void IndexedVertexArray::draw_p(bool use_buff)
 
 namespace {
 
-struct AALineEntry {
-  float p0[3], p1[3];
-  float edge0[3],edge1[3],edge2[3],edge3[3];
-  float c0[4], c1[4];
-  float z;
-};
+  struct AALineEntry {
+    float p0[3], p1[3];
+    float edge0[3],edge1[3],edge2[3],edge3[3];
+    float c0[4], c1[4];
+    float z;
+  };
 
-typedef std::vector<AALineEntry> AALineList;
+  typedef std::vector<AALineEntry> AALineList;
 
-struct AALineEntryLess
-{
-  bool operator()(const AALineEntry& e1, const AALineEntry& e2)
+  struct AALineEntryLess
   {
-    return e1.z<e2.z;
-  }
-};
+    bool operator()(const AALineEntry& e1, const AALineEntry& e2)
+    {
+      return e1.z<e2.z;
+    }
+  };
 
-/*
-  Adapted after Chan and Durand, "Fast Prefiltered Lines",
-  in GPU Gems 2
-*/
-void render_aalines(AALineList& line_list, float w, float r)
-{
+  /*
+     Adapted after Chan and Durand, "Fast Prefiltered Lines",
+     in GPU Gems 2
+     */
+  void render_aalines(AALineList& line_list, float w, float r)
+  {
 #if OST_SHADER_SUPPORT_ENABLED
-  static GLuint table_tex_id=0;
-  std::vector<unsigned char> tex_table(32);
+    static GLuint table_tex_id=0;
+    std::vector<unsigned char> tex_table(32);
 
-  if(table_tex_id==0) {
-    for(int i=0;i<32;++i) {
-      float x=static_cast<float>(i)/31.0;
-      tex_table[31-i]=static_cast<unsigned char>(255.0*exp(-4.0*x*x));
+    if(table_tex_id==0) {
+      for(int i=0;i<32;++i) {
+        float x=static_cast<float>(i)/31.0;
+        tex_table[31-i]=static_cast<unsigned char>(255.0*exp(-4.0*x*x));
+      }
+      glGenTextures(1,&table_tex_id);
+      glBindTexture(GL_TEXTURE_1D,table_tex_id);
+      glPixelStorei(GL_UNPACK_ALIGNMENT,1);
+      glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+      glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      glTexImage1D(GL_TEXTURE_1D,0,GL_LUMINANCE,32,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,&tex_table[0]);
     }
-    glGenTextures(1,&table_tex_id);
-    glBindTexture(GL_TEXTURE_1D,table_tex_id);
-    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
-    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexImage1D(GL_TEXTURE_1D,0,GL_LUMINANCE,32,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,&tex_table[0]);
-  }
-  std::sort(line_list.begin(),line_list.end(),AALineEntryLess());
-  
-  Shader::Instance().PushProgram();
-  Shader::Instance().Activate("aaline");
+    std::sort(line_list.begin(),line_list.end(),AALineEntryLess());
 
-  glLineWidth(ceil((2.0f*r+w)*1.5));
+    Shader::Instance().PushProgram();
+    Shader::Instance().Activate("aaline");
 
-  glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
-  glDisable(GL_NORMALIZE);
-  glDisable(GL_CULL_FACE);
-  glDisable(GL_LIGHTING);
-  glDisable(GL_COLOR_MATERIAL);
-  //glDisable(GL_DEPTH_TEST);
-  glDisable(GL_LINE_SMOOTH);
-  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-  glEnable(GL_BLEND);
-  glDepthMask(0);
-  Shader::Instance().UpdateState();
-  
-  GLuint cpr = Shader::Instance().GetCurrentProgram();
-  GLint edge0_id = glGetUniformLocation(cpr,"edge0");
-  GLint edge1_id = glGetUniformLocation(cpr,"edge1");
-  GLint edge2_id = glGetUniformLocation(cpr,"edge2");
-  GLint edge3_id = glGetUniformLocation(cpr,"edge3");
-  GLint table_id = glGetUniformLocation(cpr,"table");
-
-  glActiveTexture(GL_TEXTURE0);
-  glDisable(GL_TEXTURE_2D);
-  glEnable(GL_TEXTURE_1D);
-  glBindTexture(GL_TEXTURE_1D,table_tex_id);
-  glUniform1i(table_id,0);
-
-  for(AALineList::iterator it=line_list.begin();
-      it!=line_list.end();++it) {
-    glUniform3fv(edge0_id,1,it->edge0);
-    glUniform3fv(edge1_id,1,it->edge1);
-    glUniform3fv(edge2_id,1,it->edge2);
-    glUniform3fv(edge3_id,1,it->edge3);
-    // glUniform cannot be inside a glBegin / glEnd
-    glBegin(GL_LINES);
-    glColor4fv(it->c0);
-    glVertex3fv(it->p0);
-    glColor4fv(it->c1);
-    glVertex3fv(it->p1); 
-    glEnd();
-  }
+    glLineWidth(ceil((2.0f*r+w)*1.5));
 
-  glPopAttrib();
+    glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
+    glDisable(GL_NORMALIZE);
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_LIGHTING);
+    glDisable(GL_COLOR_MATERIAL);
+    //glDisable(GL_DEPTH_TEST);
+    glDisable(GL_LINE_SMOOTH);
+    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+    glEnable(GL_BLEND);
+    glDepthMask(0);
+    Shader::Instance().UpdateState();
+
+    GLuint cpr = Shader::Instance().GetCurrentProgram();
+    GLint edge0_id = glGetUniformLocation(cpr,"edge0");
+    GLint edge1_id = glGetUniformLocation(cpr,"edge1");
+    GLint edge2_id = glGetUniformLocation(cpr,"edge2");
+    GLint edge3_id = glGetUniformLocation(cpr,"edge3");
+    GLint table_id = glGetUniformLocation(cpr,"table");
 
-  Shader::Instance().PopProgram();
+    glActiveTexture(GL_TEXTURE0);
+    glDisable(GL_TEXTURE_2D);
+    glEnable(GL_TEXTURE_1D);
+    glBindTexture(GL_TEXTURE_1D,table_tex_id);
+    glUniform1i(table_id,0);
+
+    for(AALineList::iterator it=line_list.begin();
+        it!=line_list.end();++it) {
+      glUniform3fv(edge0_id,1,it->edge0);
+      glUniform3fv(edge1_id,1,it->edge1);
+      glUniform3fv(edge2_id,1,it->edge2);
+      glUniform3fv(edge3_id,1,it->edge3);
+      // glUniform cannot be inside a glBegin / glEnd
+      glBegin(GL_LINES);
+      glColor4fv(it->c0);
+      glVertex3fv(it->p0);
+      glColor4fv(it->c1);
+      glVertex3fv(it->p1); 
+      glEnd();
+    }
+
+    glPopAttrib();
+
+    Shader::Instance().PopProgram();
 #endif
-}
+  }
 
-Vec3 make_aaline_edge(const Vec2& c1, const Vec2& c0, float s)
-{
-  Vec3 nrvo(c1[1]-c0[1],c0[0]-c1[0],c1[0]*c0[1]-c0[0]*c1[1]);
-  nrvo*=1.0/(s*Length(c1-c0));
-  return nrvo;
-}
+  Vec3 make_aaline_edge(const Vec2& c1, const Vec2& c0, float s)
+  {
+    Vec3 nrvo(c1[1]-c0[1],c0[0]-c1[0],c1[0]*c0[1]-c0[0]*c1[1]);
+    nrvo*=1.0/(s*Length(c1-c0));
+    return nrvo;
+  }
 
 }
-    
+
 void IndexedVertexArray::draw_aalines()
 {
 #if OST_SHADER_SUPPORT_ENABLED
   float w=0.5*line_width_;
   float r=w;
   float hwr = 0.5*w+r;
-  
+
   AALineList line_list;
   for(unsigned int i=0;i<line_index_list_.size();i+=2) {
     Entry& ve0 = entry_list_[line_index_list_[i]];
@@ -1381,26 +1419,26 @@ void IndexedVertexArray::draw_aalines()
     Vec3 e1=make_aaline_edge(c1,c2,r);
     Vec3 e2=make_aaline_edge(c2,c3,r);
     Vec3 e3=make_aaline_edge(c3,c0,r);
-    
+
     // TODO: it should be possible to avoid the unproject and
     // pass the projected coordinates directly to GL, setting
     // modelview and projection to unity; requires handling of
     // the viewport though!
     Vec3 np1=Scene::Instance().UnProject(q0-Vec3(hwr*d),false);
     Vec3 np2=Scene::Instance().UnProject(q1+Vec3(hwr*d),false);
-    
+
     AALineEntry le={{np1[0],np1[1],np1[2]},
-                    {np2[0],np2[1],np2[2]},
-                    {e0[0],e0[1],e0[2]},
-                    {e1[0],e1[1],e1[2]},
-                    {e2[0],e2[1],e2[2]},
-                    {e3[0],e3[1],e3[2]},
-                    {ve0.c[0],ve0.c[1],ve0.c[2],ve0.c[3]},
-                    {ve1.c[0],ve1.c[1],ve1.c[2],ve1.c[3]},
-                    -0.5*(q0[2]+q1[2])};
+      {np2[0],np2[1],np2[2]},
+      {e0[0],e0[1],e0[2]},
+      {e1[0],e1[1],e1[2]},
+      {e2[0],e2[1],e2[2]},
+      {e3[0],e3[1],e3[2]},
+      {ve0.c[0],ve0.c[1],ve0.c[2],ve0.c[3]},
+      {ve1.c[0],ve1.c[1],ve1.c[2],ve1.c[3]},
+      -0.5*(q0[2]+q1[2])};
     line_list.push_back(le);
   }
-  
+
   render_aalines(line_list,w,r);
 #endif
 }
@@ -1434,11 +1472,11 @@ geom::AlignedCuboid IndexedVertexArray::GetBoundingBox() const
     return geom::AlignedCuboid(geom::Vec3(0,0,0),geom::Vec3(0,0,0));
   } else {
     geom::Vec3 minc(std::numeric_limits<float>::max(),
-                    std::numeric_limits<float>::max(),
-                    std::numeric_limits<float>::max());
+        std::numeric_limits<float>::max(),
+        std::numeric_limits<float>::max());
     geom::Vec3 maxc(-std::numeric_limits<float>::max(),
-                    -std::numeric_limits<float>::max(),
-                    -std::numeric_limits<float>::max());
+        -std::numeric_limits<float>::max(),
+        -std::numeric_limits<float>::max());
     for(EntryList::const_iterator it=entry_list_.begin();it!=entry_list_.end();++it) {
       geom::Vec3 p(it->v[0],it->v[1],it->v[2]);
       minc=geom::Min(minc,p);
diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh
index ee63c939aae475959cfa12963b730f7326392df6..539d871b775c6219a397c0ca4795a23baa8c402b 100644
--- a/modules/gfx/src/vertex_array.hh
+++ b/modules/gfx/src/vertex_array.hh
@@ -117,6 +117,11 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   void SetOutlineExpandColor(const Color& c);
   Color GetOutlineExpandColor() const {return outline_exp_color_;}
 
+  void SetSolid(bool f) {solid_=f;}
+  bool GetSolid() const {return solid_;}
+  void SetSolidColor(const Color& c) {solid_color_=c;}
+  bool GetSolidcolor() const {return solid_color_;}
+
   // vertex, normal, color and texcoord (T2F_C4F_N3F_V3F)
   VertexID Add(const geom::Vec3& vert, const geom::Vec3& norm, const Color& col, const geom::Vec2& tex=geom::Vec2());
 
@@ -233,7 +238,8 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   unsigned int outline_mat_dlist_;
   float outline_exp_factor_;
   Color outline_exp_color_;
-
+  bool solid_;
+  Color solid_color_;
   bool draw_normals_;
 
   bool use_tex_;