diff --git a/Common/Context.h b/Common/Context.h
index 7b31ed1e89723ed67c5646b403bdce5a8cf775ae..c11bbbfbd5504943f211821b2eec565f2ab95001 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -165,7 +165,7 @@ public :
     double gamma_inf, gamma_sup, radius_inf, radius_sup;
     double scaling_factor, lc_factor, rand_factor;
     int dual, interactive;
-    int light;
+    int light, light_two_side;
     int format, nb_smoothing, algo, order;
     int point_insertion, speed_max, min_circ_points, constrained_bgmesh;
     int histogram, initial_only;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 5d591e1b9cb027142077ad70502937a0ec9381b5..496f8b4a2548b4223abe66a2c6391bd0c352f26c 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -746,6 +746,8 @@ StringXNumber MeshOptions_Number[] = {
 
   { F|O, "Light" , opt_mesh_light , 0. , 
     "Enable lighting for the mesh" },
+  { F|O, "LightTwoSide" , opt_mesh_light_two_side , 1. , 
+    "Light both sides of mesh elements (leads to slower rendering)" },
   { F|O, "Lines" , opt_mesh_lines , 0. , 
     "Display mesh lines (1D elements)?" },
   { F|O, "LineNumbers" , opt_mesh_lines_num , 0. , 
@@ -962,6 +964,8 @@ StringXNumber ViewOptions_Number[] = {
 
   { F|O, "Light" , opt_view_light , 1. ,
     "Enable lighting for the view" },
+  { F|O, "LightTwoSide" , opt_view_light_two_side , 1. , 
+    "Light both sides of view elements (leads to slower rendering)" },
   { F|O, "LineType" , opt_view_line_type , 0. , 
     "Display lines as solid color segments (0) or 3D cylinders (1)" },
   { F|O, "LineWidth" , opt_view_line_width , 1.0 , 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 406f34faa9e4ebf5e76675982acba88a1555e363..e6e946e9384fb378ec46a8e9086db48498de2b6e 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.160 2004-05-30 04:17:40 geuzaine Exp $
+// $Id: Options.cpp,v 1.161 2004-05-30 06:24:01 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -3411,6 +3411,17 @@ double opt_mesh_light(OPT_ARGS_NUM)
   return CTX.mesh.light;
 }
 
+double opt_mesh_light_two_side(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.mesh.light_two_side = (int)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_butt[23]->value(CTX.mesh.light_two_side);
+#endif
+  return CTX.mesh.light_two_side;
+}
+
 double opt_mesh_format(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -4360,6 +4371,19 @@ double opt_view_light(OPT_ARGS_NUM)
   return v->Light;
 }
 
+double opt_view_light_two_side(OPT_ARGS_NUM)
+{
+  GET_VIEW(0.);
+  if(action & GMSH_SET) {
+    v->LightTwoSide = (int)val;
+  }
+#if defined(HAVE_FLTK)
+  if(_gui_action_valid(action, num))
+    WID->view_butt[9]->value(v->LightTwoSide);
+#endif
+  return v->LightTwoSide;
+}
+
 double opt_view_smooth_normals(OPT_ARGS_NUM)
 {
   GET_VIEW(0.);
diff --git a/Common/Options.h b/Common/Options.h
index 2c68529ec208d06c2d8c296f15b84540ffb1d5e9..4650393da40c8a547c5923d56e8c011c35fe26c0 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -362,6 +362,7 @@ double opt_mesh_line_width(OPT_ARGS_NUM);
 double opt_mesh_line_type(OPT_ARGS_NUM);
 double opt_mesh_vertex_arrays(OPT_ARGS_NUM);
 double opt_mesh_light(OPT_ARGS_NUM);
+double opt_mesh_light_two_side(OPT_ARGS_NUM);
 double opt_mesh_format(OPT_ARGS_NUM);
 double opt_mesh_msh_file_version(OPT_ARGS_NUM);
 double opt_mesh_nb_smoothing(OPT_ARGS_NUM);
@@ -450,6 +451,7 @@ double opt_view_nb_iso(OPT_ARGS_NUM);
 double opt_view_nb_abscissa(OPT_ARGS_NUM);
 double opt_view_boundary(OPT_ARGS_NUM);
 double opt_view_light(OPT_ARGS_NUM);
+double opt_view_light_two_side(OPT_ARGS_NUM);
 double opt_view_smooth_normals(OPT_ARGS_NUM);
 double opt_view_angle_smooth_normals(OPT_ARGS_NUM);
 double opt_view_show_element(OPT_ARGS_NUM);
diff --git a/Common/Views.cpp b/Common/Views.cpp
index 1ed255961b8818d89f1cc6a5d7456525a2bfc002..76b0954f26b5e7ecd55256d9c64fea99ff55aaba 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.121 2004-05-29 23:22:19 geuzaine Exp $
+// $Id: Views.cpp,v 1.122 2004-05-30 06:24:01 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -634,6 +634,7 @@ void CopyViewOptions(Post_View * src, Post_View * dest)
   dest->NbAbscissa = src->NbAbscissa;
   dest->NbIso = src->NbIso;
   dest->Light = src->Light;
+  dest->LightTwoSide = src->LightTwoSide;
   dest->SmoothNormals = src->SmoothNormals;
   dest->AngleSmoothNormals = src->AngleSmoothNormals;
   dest->ShowElement = src->ShowElement;
diff --git a/Common/Views.h b/Common/Views.h
index 2ce699e3c593390ac41d5fa78bf103e16f6ace30..143007aea8b54629d89fc69642762015afc2aac9 100644
--- a/Common/Views.h
+++ b/Common/Views.h
@@ -69,7 +69,8 @@ class Post_View{
   double CustomMin, CustomMax;
   double Offset[3], Raise[3], DisplacementFactor, Explode;
   double ArrowSize, ArrowRelHeadRadius, ArrowRelStemRadius, ArrowRelStemLength;
-  int Visible, IntervalsType, NbIso, NbAbscissa, Light, SmoothNormals ;
+  int Visible, IntervalsType, NbIso, NbAbscissa;
+  int Light, LightTwoSide, SmoothNormals;
   double AngleSmoothNormals, AlphaChannel;
   int SaturateValues;
   int ShowElement, ShowTime, ShowScale;
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 6ab4ae5b333c2caa1d0f6082cbc6b2ba7dc56e18..5dc28409847ed5cdbc62a209bcce4f330c4c73c3 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.243 2004-05-29 20:25:28 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.244 2004-05-30 06:24:01 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -990,6 +990,7 @@ void mesh_options_ok_cb(CALLBACK_ARGS)
   opt_mesh_use_cut_plane(0, GMSH_SET, WID->mesh_butt[16]->value());
   opt_mesh_cut_plane_as_surface(0, GMSH_SET, WID->mesh_butt[22]->value());
   opt_mesh_light(0, GMSH_SET, WID->mesh_butt[17]->value());
+  opt_mesh_light_two_side(0, GMSH_SET, WID->mesh_butt[23]->value());
   opt_mesh_color_carousel(0, GMSH_SET,
 			  WID->mesh_butt[18]->value()? 0 :
 			  WID->mesh_butt[19]->value()? 1 : 
@@ -3439,6 +3440,9 @@ void view_options_ok_cb(CALLBACK_ARGS)
       if(force || WID->view_butt[11]->changed())
         opt_view_light(i, GMSH_SET, WID->view_butt[11]->value());
 
+      if(force || WID->view_butt[9]->changed())
+        opt_view_light_two_side(i, GMSH_SET, WID->view_butt[9]->value());
+
       if(force || WID->view_butt[12]->changed())
         opt_view_smooth_normals(i, GMSH_SET, WID->view_butt[12]->value());
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 89ceee76c085cfdf8f1d79c21b0b1e994b335c58..ecd257aecd50a2eaf85b7084ae22d7fbd76ef8b0 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.308 2004-05-29 10:11:11 geuzaine Exp $
+// $Id: GUI.cpp,v 1.309 2004-05-30 06:24:01 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1383,7 +1383,7 @@ void GUI::check_rotation_center_button()
 void GUI::create_option_window()
 {
   int i;
-  int width = 40 * fontsize;
+  int width = 41 * fontsize;
   int height = 12 * BH + 5 * WB;
   int BROWSERW = 105 + WB;
 
@@ -1836,15 +1836,20 @@ void GUI::create_option_window()
       mesh_butt[17]->down_box(TOGGLE_BOX);
       mesh_butt[17]->selection_color(TOGGLE_COLOR);
 
-      mesh_value[9] = new Fl_Value_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Explode elements");
+      mesh_butt[23] = new Fl_Check_Button(2 * WB, 2 * WB + 2 * BH, BW, BH, "Use two-side lighting");
+      mesh_butt[23]->type(FL_TOGGLE_BUTTON);
+      mesh_butt[23]->down_box(TOGGLE_BOX);
+      mesh_butt[23]->selection_color(TOGGLE_COLOR);
+
+      mesh_value[9] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Explode elements");
       mesh_value[9]->minimum(0);
       mesh_value[9]->maximum(1);
       mesh_value[9]->step(0.01);
-      mesh_value[10] = new Fl_Value_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Point size");
+      mesh_value[10] = new Fl_Value_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Point size");
       mesh_value[10]->minimum(0.1);
       mesh_value[10]->maximum(50);
       mesh_value[10]->step(0.1);
-      mesh_value[11] = new Fl_Value_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Line width");
+      mesh_value[11] = new Fl_Value_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Line width");
       mesh_value[11]->minimum(0.1);
       mesh_value[11]->maximum(50);
       mesh_value[11]->step(0.1);
@@ -1852,11 +1857,11 @@ void GUI::create_option_window()
         mesh_value[i]->align(FL_ALIGN_RIGHT);
       }
 
-      mesh_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 3 * BH, IW, BH, "Point display");
+      mesh_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 4 * BH, IW, BH, "Point display");
       mesh_choice[0]->menu(menu_point_display);
       mesh_choice[0]->align(FL_ALIGN_RIGHT);
 
-      mesh_choice[1] = new Fl_Choice(2 * WB, 2 * WB + 5 * BH, IW, BH, "Line display");
+      mesh_choice[1] = new Fl_Choice(2 * WB, 2 * WB + 6 * BH, IW, BH, "Line display");
       mesh_choice[1]->menu(menu_line_display);
       mesh_choice[1]->align(FL_ALIGN_RIGHT);
       mesh_choice[1]->deactivate(); // don't give false hopes, as it's not used anywhere right now
@@ -2063,24 +2068,25 @@ void GUI::create_option_window()
       view_3d = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "3D");
       view_3d->hide();
 
-      view_butt[10] = new Fl_Check_Button(width / 2, 2 * WB + 1 * BH, BW / 2 - WB, BH,"Show elements");
+      view_butt[10] = new Fl_Check_Button(width / 2, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Show elements");
       view_butt[11] = new Fl_Check_Button(width / 2, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Enable lighting");
-      view_butt[12] = new Fl_Check_Button(width / 2, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Smooth normals");
-      for(i = 10; i <= 12; i++) {
+      view_butt[9]  = new Fl_Check_Button(width / 2, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Use two-side lighting");
+      view_butt[12] = new Fl_Check_Button(width / 2, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Smooth normals");
+      for(i = 9; i <= 12; i++) {
         view_butt[i]->type(FL_TOGGLE_BUTTON);
         view_butt[i]->down_box(TOGGLE_BOX);
         view_butt[i]->selection_color(TOGGLE_COLOR);
         view_butt[i]->callback(set_changed_cb, 0);
       }
-      view_value[10] = new Fl_Value_Input(width / 2, 2 * WB + 4 * BH, IW, BH, "Angle");
+      view_value[10] = new Fl_Value_Input(width / 2, 2 * WB + 5 * BH, IW, BH, "Angle");
       view_value[10]->minimum(0.);
       view_value[10]->step(1.);
       view_value[10]->maximum(180.);
-      view_value[11] = new Fl_Value_Input(width / 2, 2 * WB + 5 * BH, IW, BH, "Boundary");
+      view_value[11] = new Fl_Value_Input(width / 2, 2 * WB + 6 * BH, IW, BH, "Boundary");
       view_value[11]->minimum(0);
       view_value[11]->step(1);
       view_value[11]->maximum(3);
-      view_value[12] = new Fl_Value_Input(width / 2, 2 * WB + 6 * BH, IW, BH, "Explode");
+      view_value[12] = new Fl_Value_Input(width / 2, 2 * WB + 7 * BH, IW, BH, "Explode");
       view_value[12]->minimum(0.);
       view_value[12]->step(0.01);
       view_value[12]->maximum(1.);
@@ -2097,9 +2103,9 @@ void GUI::create_option_window()
       view_butt[18] = new Fl_Check_Button(2 * WB, 2 * WB + 6 * BH, BW / 2 - WB, BH, "Show hexahedra");
       view_butt[19] = new Fl_Check_Button(2 * WB, 2 * WB + 7 * BH, BW / 2 - WB, BH, "Show prisms");
       view_butt[20] = new Fl_Check_Button(2 * WB, 2 * WB + 8 * BH, BW / 2 - WB, BH, "Show pyramids");
-      view_butt[21] = new Fl_Check_Button(width / 2, 2 * WB + 7 * BH, BW / 2 - WB, BH, "Show scalar values");
-      view_butt[22] = new Fl_Check_Button(width / 2, 2 * WB + 8 * BH, BW / 2 - WB, BH, "Show vector values");
-      view_butt[23] = new Fl_Check_Button(width / 2, 2 * WB + 9 * BH, BW / 2 - WB, BH, "Show tensor values");
+      view_butt[21] = new Fl_Check_Button(width / 2, 2 * WB + 8 * BH, BW / 2 - WB, BH, "Show scalar values");
+      view_butt[22] = new Fl_Check_Button(width / 2, 2 * WB + 9 * BH, BW / 2 - WB, BH, "Show vector values");
+      view_butt[23] = new Fl_Check_Button(width / 2, 2 * WB + 10 * BH, BW / 2 - WB, BH, "Show tensor values");
       for(i = 13; i <= 23; i++) {
         view_butt[i]->type(FL_TOGGLE_BUTTON);
         view_butt[i]->down_box(TOGGLE_BOX);
@@ -2359,6 +2365,7 @@ void GUI::update_view_window(int num)
   }
   opt_view_show_element(num, GMSH_GUI, 0);
   opt_view_light(num, GMSH_GUI, 0);
+  opt_view_light_two_side(num, GMSH_GUI, 0);
   opt_view_smooth_normals(num, GMSH_GUI, 0);
   opt_view_angle_smooth_normals(num, GMSH_GUI, 0);
   opt_view_boundary(num, GMSH_GUI, 0);
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index a017aece624102a8b8616020035a838a9f72aba2..0eb1b182f45c50f55d695cd613250039a47a0dfe 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.54 2004-05-28 21:06:11 geuzaine Exp $
+// $Id: Draw.cpp,v 1.55 2004-05-30 06:24:02 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -162,10 +162,12 @@ void InitRenderModel(void)
       glLightfv((GLenum) (GL_LIGHT0 + i), GL_POSITION, tmp);
       glEnable((GLenum) (GL_LIGHT0 + i));
     }
+    else{
+      glDisable((GLenum) (GL_LIGHT0 + i));
+    }
   }
   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.);
-  glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
   glShadeModel(GL_SMOOTH);
   float specular[4] = {CTX.shine, CTX.shine, CTX.shine, 1.0};
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 01c61580da686f9dd6f73afb0ef228862d2fefe8..9fffa0a6d67305536aaa583a3fae897dce46e9c5 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.92 2004-05-29 23:22:19 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.93 2004-05-30 06:24:02 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -116,8 +116,10 @@ void Draw_Mesh(Mesh * M)
 
   // draw the geometry
 
-  if(M->status >= 0)
+  if(M->status >= 0){
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
     Draw_Geom(M);
+  }
 
   // if we're in selection mode, we're done
 
@@ -173,6 +175,11 @@ void Draw_Mesh(Mesh * M)
     gl2psPointSize(CTX.mesh.point_size * CTX.print.eps_point_size_factor);
     glLineWidth(CTX.mesh.line_width);
     gl2psLineWidth(CTX.mesh.line_width * CTX.print.eps_line_width_factor);
+
+    if(CTX.mesh.light_two_side)
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+    else
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
    
     if(M->status >= 3 && (CTX.mesh.volumes_faces || CTX.mesh.volumes_edges ||
 			  CTX.mesh.volumes_num || 
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index 0bcc12adafceb0d5fd3a70a8d949acc004412823..6d3a5869010fef700b18d3cb162fabb72dec7e7f 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.65 2004-05-29 23:22:19 geuzaine Exp $
+// $Id: Post.cpp,v 1.66 2004-05-30 06:24:02 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -371,6 +371,11 @@ void Draw_Post(void)
       
       glLineWidth(v->LineWidth);
       gl2psLineWidth(v->LineWidth * CTX.print.eps_line_width_factor);
+
+      if(v->LightTwoSide)
+	glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+      else
+	glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
       
       switch (v->RangeType) {
       case DRAW_POST_RANGE_DEFAULT:
diff --git a/Graphics/PostElement.cpp b/Graphics/PostElement.cpp
index 697ebecb90a05185126498458967ee85144dcb0e..45ecc34f43c911753e09237d6203a3ed2701ee1b 100644
--- a/Graphics/PostElement.cpp
+++ b/Graphics/PostElement.cpp
@@ -1,4 +1,4 @@
-// $Id: PostElement.cpp,v 1.33 2004-05-29 23:22:19 geuzaine Exp $
+// $Id: PostElement.cpp,v 1.34 2004-05-30 06:24:02 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -608,15 +608,14 @@ void Draw_ScalarTetrahedron(Post_View * View, int preproNormals,
     View->Boundary--;
     int ts = View->TimeStep;
     View->TimeStep = 0;
-    Draw_ScalarTriangle(View, 0, ValMin, ValMax, &X[0], &Y[0], &Z[0], &vv[0]); // 012
-    Draw_ScalarTriangle(View, 0, ValMin, ValMax, &X[1], &Y[1], &Z[1], &vv[1]); // 123
+    REORDER3(0, 2, 1);
+    Draw_ScalarTriangle(View, 0, ValMin, ValMax, Xp, Yp, Zp, Val); // 021
     REORDER3(0, 1, 3);
     Draw_ScalarTriangle(View, 0, ValMin, ValMax, Xp, Yp, Zp, Val); // 013
-    Xp[1] = X[2];
-    Yp[1] = Y[2];
-    Zp[1] = Z[2];
-    Val[1] = vv[2];
-    Draw_ScalarTriangle(View, 0, ValMin, ValMax, Xp, Yp, Zp, Val); // 023
+    REORDER3(0, 3, 2);
+    Draw_ScalarTriangle(View, 0, ValMin, ValMax, Xp, Yp, Zp, Val); // 032
+    REORDER3(3, 1, 2);
+    Draw_ScalarTriangle(View, 0, ValMin, ValMax, Xp, Yp, Zp, Val); // 312
     View->TimeStep = ts;
     View->Boundary++;
     return;