diff --git a/Common/Context.h b/Common/Context.h
index c0fa44d04b175c030b7bbbc87f4a09b49aa0c188..0198c3059d62a872606e49aabd466a6b094f7dd6 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -123,7 +123,7 @@ public :
   int viewport[4];            // current viewport 
   double vxmin, vxmax, vymin, vymax; // current viewport in real coordinates 
   int light[6];               // status of lights
-  double light_position[6][3]; // light sources positions 
+  double light_position[6][4]; // light sources positions 
   double shine, shine_exponent; // material specular reflection parameters
   int render_mode;            // GMSH_RENDER, GMSH_SELECT, GMSH_FEEDBACK 
   int clip[6];                // status of clip planes (bit arrays)
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index d3493b4216abe419fb676ad4d35235bb980c7763..f0646ae8bf2d56e0a3c76a4a76b84cab99331fd5 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -479,6 +479,8 @@ StringXNumber GeneralOptions_Number[] = {
     "Y position of light source 0" },
   { F|O, "Light0Z" , opt_general_light02 , 1.0 , 
     "Z position of light source 0" },
+  { F|O, "Light0W" , opt_general_light03 , 0.0 , 
+    "Divisor of the X, Y and Z coordinates of light source 0 (W=0 means infinitely far source)" },
   { F|O, "Light1" , opt_general_light1 , 0.,
     "Enable light source 1" },
   { F|O, "Light1X" , opt_general_light10 , 0.5 , 
@@ -487,6 +489,8 @@ StringXNumber GeneralOptions_Number[] = {
     "Y position of light source 1" },
   { F|O, "Light1Z" , opt_general_light12 , 1.0 , 
     "Z position of light source 1" },
+  { F|O, "Light1W" , opt_general_light13 , 0.0 , 
+    "Divisor of the X, Y and Z coordinates of light source 1 (W=0 means infinitely far source)" },
   { F|O, "Light2" , opt_general_light2 , 0.,
     "Enable light source 2" },
   { F|O, "Light2X" , opt_general_light20 , 0.5 , 
@@ -495,6 +499,8 @@ StringXNumber GeneralOptions_Number[] = {
     "Y position of light source 2" },
   { F|O, "Light2Z" , opt_general_light22 , 1.0 , 
     "Z position of light source 2" },
+  { F|O, "Light2W" , opt_general_light23 , 0.0 , 
+    "Divisor of the X, Y and Z coordinates of light source 2 (W=0 means infinitely far source)" },
   { F|O, "Light3" , opt_general_light3 , 0.,
     "Enable light source 3" },
   { F|O, "Light3X" , opt_general_light30 , 0.5 , 
@@ -503,6 +509,8 @@ StringXNumber GeneralOptions_Number[] = {
     "Y position of light source 3" },
   { F|O, "Light3Z" , opt_general_light32 , 1.0 , 
     "Z position of light source 3" },
+  { F|O, "Light3W" , opt_general_light33 , 0.0 , 
+    "Divisor of the X, Y and Z coordinates of light source 3 (W=0 means infinitely far source)" },
   { F|O, "Light4" , opt_general_light4 , 0.,
     "Enable light source 4" },
   { F|O, "Light4X" , opt_general_light40 , 0.5 , 
@@ -511,6 +519,8 @@ StringXNumber GeneralOptions_Number[] = {
     "Y position of light source 4" },
   { F|O, "Light4Z" , opt_general_light42 , 1.0 , 
     "Z position of light source 4" },
+  { F|O, "Light4W" , opt_general_light43 , 0.0 , 
+    "Divisor of the X, Y and Z coordinates of light source 4 (W=0 means infinitely far source)" },
   { F|O, "Light5" , opt_general_light5 , 0.,
     "Enable light source 5" },
   { F|O, "Light5X" , opt_general_light50 , 0.5 , 
@@ -519,6 +529,8 @@ StringXNumber GeneralOptions_Number[] = {
     "Y position of light source 5" },
   { F|O, "Light5Z" , opt_general_light52 , 1.0 , 
     "Z position of light source 5" },
+  { F|O, "Light5W" , opt_general_light53 , 0.0 , 
+    "Divisor of the X, Y and Z coordinates of light source 5 (W=0 means infinitely far source)" },
   { F|O, "LineWidth" , opt_general_line_width , 1.0 , 
     "Display width of lines (in pixels)" },
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index f5a3c1e20a92cc22acf4fd9fd5157789589068c2..56306480fcf53ca15934c8ed4b8d61f082ab1cf9 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.180 2004-09-01 20:23:49 geuzaine Exp $
+// $Id: Options.cpp,v 1.181 2004-09-03 19:00:51 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -2852,6 +2852,17 @@ double opt_general_light02(OPT_ARGS_NUM)
   return CTX.light_position[0][2];
 }
 
+double opt_general_light03(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.light_position[0][3] = val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->gen_value[13]->value(CTX.light_position[0][3]);
+#endif
+  return CTX.light_position[0][3];
+}
+
 double opt_general_light1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -2880,6 +2891,13 @@ double opt_general_light12(OPT_ARGS_NUM)
   return CTX.light_position[1][2];
 }
 
+double opt_general_light13(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.light_position[1][3] = val;
+  return CTX.light_position[1][3];
+}
+
 double opt_general_light2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -2908,6 +2926,13 @@ double opt_general_light22(OPT_ARGS_NUM)
   return CTX.light_position[2][2];
 }
 
+double opt_general_light23(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.light_position[2][3] = val;
+  return CTX.light_position[2][3];
+}
+
 double opt_general_light3(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -2936,6 +2961,13 @@ double opt_general_light32(OPT_ARGS_NUM)
   return CTX.light_position[3][2];
 }
 
+double opt_general_light33(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.light_position[3][3] = val;
+  return CTX.light_position[3][3];
+}
+
 double opt_general_light4(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -2964,6 +2996,13 @@ double opt_general_light42(OPT_ARGS_NUM)
   return CTX.light_position[4][2];
 }
 
+double opt_general_light43(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.light_position[4][3] = val;
+  return CTX.light_position[4][3];
+}
+
 double opt_general_light5(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -2992,6 +3031,13 @@ double opt_general_light52(OPT_ARGS_NUM)
   return CTX.light_position[5][2];
 }
 
+double opt_general_light53(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.light_position[5][3] = val;
+  return CTX.light_position[5][3];
+}
+
 double opt_geometry_auto_coherence(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index c77df8a3df81f0006a37377219da808502440aff..a7d39948c253cef26baaba666602c71b54b707a2 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -293,26 +293,32 @@ double opt_general_light0(OPT_ARGS_NUM);
 double opt_general_light00(OPT_ARGS_NUM);
 double opt_general_light01(OPT_ARGS_NUM);
 double opt_general_light02(OPT_ARGS_NUM);
+double opt_general_light03(OPT_ARGS_NUM);
 double opt_general_light1(OPT_ARGS_NUM);
 double opt_general_light10(OPT_ARGS_NUM);
 double opt_general_light11(OPT_ARGS_NUM);
 double opt_general_light12(OPT_ARGS_NUM);
+double opt_general_light13(OPT_ARGS_NUM);
 double opt_general_light2(OPT_ARGS_NUM);
 double opt_general_light20(OPT_ARGS_NUM);
 double opt_general_light21(OPT_ARGS_NUM);
 double opt_general_light22(OPT_ARGS_NUM);
+double opt_general_light23(OPT_ARGS_NUM);
 double opt_general_light3(OPT_ARGS_NUM);
 double opt_general_light30(OPT_ARGS_NUM);
 double opt_general_light31(OPT_ARGS_NUM);
 double opt_general_light32(OPT_ARGS_NUM);
+double opt_general_light33(OPT_ARGS_NUM);
 double opt_general_light4(OPT_ARGS_NUM);
 double opt_general_light40(OPT_ARGS_NUM);
 double opt_general_light41(OPT_ARGS_NUM);
 double opt_general_light42(OPT_ARGS_NUM);
+double opt_general_light43(OPT_ARGS_NUM);
 double opt_general_light5(OPT_ARGS_NUM);
 double opt_general_light50(OPT_ARGS_NUM);
 double opt_general_light51(OPT_ARGS_NUM);
 double opt_general_light52(OPT_ARGS_NUM);
+double opt_general_light53(OPT_ARGS_NUM);
 double opt_geometry_auto_coherence(OPT_ARGS_NUM);
 double opt_geometry_normals(OPT_ARGS_NUM);
 double opt_geometry_tangents(OPT_ARGS_NUM);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 1a636869cf20bbe613556d53a699eeeefe965650..cc5fc6ce4111d9d01407b9a96ae8835ec28cc32f 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.266 2004-09-01 20:23:49 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.267 2004-09-03 19:00:51 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -878,6 +878,7 @@ void general_options_ok_cb(CALLBACK_ARGS)
   opt_general_light00(0, GMSH_SET, WID->gen_value[2]->value());
   opt_general_light01(0, GMSH_SET, WID->gen_value[3]->value());
   opt_general_light02(0, GMSH_SET, WID->gen_value[4]->value());
+  opt_general_light03(0, GMSH_SET, WID->gen_value[13]->value());
   opt_general_verbosity(0, GMSH_SET, WID->gen_value[5]->value());
   opt_general_point_size(0, GMSH_SET, WID->gen_value[6]->value());
   opt_general_line_width(0, GMSH_SET, WID->gen_value[7]->value());
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 8bcbd34dc7458ccf74f20611a6cec73722da9643..ac1d0141c4d3304dd8d848686ff73a58ba9cd345 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.337 2004-09-01 20:23:50 geuzaine Exp $
+// $Id: GUI.cpp,v 1.338 2004-09-03 19:00:51 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1655,19 +1655,25 @@ void GUI::create_option_window()
       gen_value[3]->maximum(1);
       gen_value[3]->step(0.01);
 
-      gen_value[4] = new Fl_Value_Input(2 * WB + 2 * IW / 3, 2 * WB + 1 * BH, IW/3, BH, "Light position");
+      gen_value[4] = new Fl_Value_Input(2 * WB + 2 * IW / 3, 2 * WB + 1 * BH, IW/3, BH, "Light origin");
       gen_value[4]->minimum(-1);
       gen_value[4]->maximum(1);
       gen_value[4]->step(0.01);
       gen_value[4]->align(FL_ALIGN_RIGHT);
 
-      gen_value[1] = new Fl_Value_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Material shininess");
+      gen_value[13] = new Fl_Value_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Light position divisor");
+      gen_value[13]->minimum(0.);
+      gen_value[13]->maximum(100.);
+      gen_value[13]->step(0.01);
+      gen_value[13]->align(FL_ALIGN_RIGHT);
+
+      gen_value[1] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Material shininess");
       gen_value[1]->minimum(0);
       gen_value[1]->maximum(10);
       gen_value[1]->step(0.1);
       gen_value[1]->align(FL_ALIGN_RIGHT);
 
-      gen_value[0] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Material shininess exponent");
+      gen_value[0] = new Fl_Value_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Material shininess exponent");
       gen_value[0]->minimum(0);
       gen_value[0]->maximum(128);
       gen_value[0]->step(1);
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index 2235d0bf42c2eb42f95316043fbc8d80b1a4c2b1..5b4d0b8638d1e6056cf99dfa6c9996b3b89dac73 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.61 2004-08-15 02:27:49 geuzaine Exp $
+// $Id: Draw.cpp,v 1.62 2004-09-03 19:00:52 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -154,7 +154,7 @@ void InitRenderModel(void)
       GLfloat position[4] = {(GLfloat)CTX.light_position[i][0],
 			     (GLfloat)CTX.light_position[i][1],
 			     (GLfloat)CTX.light_position[i][2],
-			     0.0};
+			     (GLfloat)CTX.light_position[i][3]};
       glLightfv((GLenum)(GL_LIGHT0 + i), GL_POSITION, position);
 
       r = UNPACK_RED(CTX.color.ambient_light[i])/255.;