diff --git a/Common/Context.h b/Common/Context.h
index 16385a1ecb794b3db05bf203e50f20e7c0dbda0d..c0fa44d04b175c030b7bbbc87f4a09b49aa0c188 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -122,9 +122,9 @@ public :
 
   int viewport[4];            // current viewport 
   double vxmin, vxmax, vymin, vymax; // current viewport in real coordinates 
-  int light[6];               // status of light 
+  int light[6];               // status of lights
   double light_position[6][3]; // light sources positions 
-  double shine;                // specular value 
+  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)
   double clip_plane[6][4];    // clip planes 
@@ -210,6 +210,7 @@ public :
   // color options
   struct{
     unsigned int bg, fg, text, axes, small_axes;
+    unsigned int ambient_light[6], diffuse_light[6], specular_light[6];
     struct{
       unsigned int point, line, surface, volume;
       unsigned int point_sel, line_sel, surface_sel, volume_sel;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 3e5531fb2d6514e88cdf8c3c47c37e7c1b14ebb2..5404684228b127a225411128574faec52503035f 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -574,7 +574,9 @@ StringXNumber GeneralOptions_Number[] = {
   { F,   "ScaleZ" , opt_general_scale2 , 1.0 , 
     "Z-axis scale factor" },
   { F|O, "Shininess" , opt_general_shine , 0.4 , 
-    "Material shininess (must be > 0)" },
+    "Material shininess" },
+  { F|O, "ShininessExponent" , opt_general_shine_exponent , 40. , 
+    "Material shininess exponent (0 to 128)" },
   { F|O, "SmallAxes" , opt_general_small_axes , 1. ,
     "Display the small axes" },
   { F|O, "SmallAxesPositionX" , opt_general_small_axes_position0 , -60. ,
@@ -1120,6 +1122,21 @@ StringXColor GeneralOptions_Color[] = {
     PACK_COLOR(0,   0,   0,   255),
     PACK_COLOR(0,   0,   0,   255),
     "Small axes color" },
+  { F|O, "AmbientLight" , opt_general_color_ambient_light,
+    PACK_COLOR(25, 25, 25, 255),
+    PACK_COLOR(25, 25, 25, 255),
+    PACK_COLOR(25, 25, 25, 255),
+    "Ambiant light color" },
+  { F|O, "DiffuseLight" , opt_general_color_diffuse_light,
+    PACK_COLOR(255, 255, 255, 255),
+    PACK_COLOR(255, 255, 255, 255),
+    PACK_COLOR(255, 255, 255, 255),
+    "Diffuse light color" },
+  { F|O, "SpecularLight" , opt_general_color_specular_light,
+    PACK_COLOR(255, 255, 255, 255),
+    PACK_COLOR(255, 255, 255, 255),
+    PACK_COLOR(255, 255, 255, 255),
+    "Specular light color" },
   { 0, NULL , NULL ,  0, 0, 0 , NULL }
 } ;
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index a3ad3c0e3dc8f63658ee498976e56048c578590a..da00660582e8eff61bad355d34e62d549a497f70 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.177 2004-08-12 16:57:32 geuzaine Exp $
+// $Id: Options.cpp,v 1.178 2004-08-15 02:27:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -2193,6 +2193,17 @@ double opt_general_shine(OPT_ARGS_NUM)
   return CTX.shine;
 }
 
+double opt_general_shine_exponent(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.shine_exponent = val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->gen_value[0]->value(CTX.shine_exponent);
+#endif
+  return CTX.shine_exponent;
+}
+
 double opt_general_verbosity(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -5219,6 +5230,36 @@ unsigned int opt_general_color_small_axes(OPT_ARGS_COL)
 #endif
   return CTX.color.small_axes;
 }
+unsigned int opt_general_color_ambient_light(OPT_ARGS_COL)
+{
+  if(action & GMSH_SET)
+    for(int i = 0; i < 6; i++)
+      CTX.color.ambient_light[i] = val;
+#if defined(HAVE_FLTK)
+  CCC(CTX.color.ambient_light[0], WID->gen_col[5]);
+#endif
+  return CTX.color.ambient_light[0];
+}
+unsigned int opt_general_color_diffuse_light(OPT_ARGS_COL)
+{
+  if(action & GMSH_SET)
+    for(int i = 0; i < 6; i++)
+      CTX.color.diffuse_light[i] = val;
+#if defined(HAVE_FLTK)
+  CCC(CTX.color.diffuse_light[0], WID->gen_col[6]);
+#endif
+  return CTX.color.diffuse_light[0];
+}
+unsigned int opt_general_color_specular_light(OPT_ARGS_COL)
+{
+  if(action & GMSH_SET)
+    for(int i = 0; i < 6; i++)
+      CTX.color.specular_light[i] = val;
+#if defined(HAVE_FLTK)
+  CCC(CTX.color.specular_light[0], WID->gen_col[7]);
+#endif
+  return CTX.color.specular_light[0];
+}
 unsigned int opt_geometry_color_points(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index 5de90160e3eb74a40b4773c232561ab8e790c771..fa26a6296a61a8e9c5c09b4e165200d575113370 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -235,6 +235,7 @@ double opt_general_scale2(OPT_ARGS_NUM);
 double opt_general_point_size(OPT_ARGS_NUM);
 double opt_general_line_width(OPT_ARGS_NUM);
 double opt_general_shine(OPT_ARGS_NUM);
+double opt_general_shine_exponent(OPT_ARGS_NUM);
 double opt_general_color_scheme(OPT_ARGS_NUM);
 double opt_general_verbosity(OPT_ARGS_NUM);
 double opt_general_terminal(OPT_ARGS_NUM);
@@ -507,6 +508,9 @@ unsigned int opt_general_color_foreground(OPT_ARGS_COL);
 unsigned int opt_general_color_text(OPT_ARGS_COL);
 unsigned int opt_general_color_axes(OPT_ARGS_COL);
 unsigned int opt_general_color_small_axes(OPT_ARGS_COL);
+unsigned int opt_general_color_ambient_light(OPT_ARGS_COL);
+unsigned int opt_general_color_diffuse_light(OPT_ARGS_COL);
+unsigned int opt_general_color_specular_light(OPT_ARGS_COL);
 unsigned int opt_geometry_color_points(OPT_ARGS_COL); 
 unsigned int opt_geometry_color_lines(OPT_ARGS_COL);
 unsigned int opt_geometry_color_surfaces(OPT_ARGS_COL);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 85b549d5cc2bcdcc7308e037e480bb179761abd3..0db71a88de991855e4c65f20c81c76893bfa0eb7 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.264 2004-08-12 16:52:03 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.265 2004-08-15 02:27:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -874,6 +874,7 @@ void general_options_ok_cb(CALLBACK_ARGS)
   opt_general_draw_bounding_box(0, GMSH_SET, WID->gen_butt[6]->value());
 
   opt_general_shine(0, GMSH_SET, WID->gen_value[1]->value());
+  opt_general_shine_exponent(0, GMSH_SET, WID->gen_value[0]->value());
   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());
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 4eff361057d5658a5a80ddef2514c0ed6002299e..727bca6a00502b843709e3d3a0c1353840f826df 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.333 2004-08-13 20:59:44 geuzaine Exp $
+// $Id: GUI.cpp,v 1.334 2004-08-15 02:27:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1652,6 +1652,12 @@ void GUI::create_option_window()
       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]->minimum(0);
+      gen_value[0]->maximum(128);
+      gen_value[0]->step(1);
+      gen_value[0]->align(FL_ALIGN_RIGHT);
+
       o->end();
     }
     {
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index f55afca8d004ecfe6e420d9ac80553398a20a1cf..2235d0bf42c2eb42f95316043fbc8d80b1a4c2b1 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.60 2004-07-22 19:32:02 geuzaine Exp $
+// $Id: Draw.cpp,v 1.61 2004-08-15 02:27:49 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -49,12 +49,9 @@ void Draw3d(void)
 
 void Draw2d(void)
 {
-  GLenum clip[6] = { GL_CLIP_PLANE0, GL_CLIP_PLANE1, GL_CLIP_PLANE2, 
-		     GL_CLIP_PLANE3, GL_CLIP_PLANE4, GL_CLIP_PLANE5 };
-
   glDisable(GL_DEPTH_TEST);
   for(int i = 0; i < 6; i++)
-    glDisable(clip[i]);
+    glDisable((GLenum)(GL_CLIP_PLANE0 + i));
 
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
@@ -150,34 +147,59 @@ void Orthogonalize(int x, int y)
 
 void InitRenderModel(void)
 {
-  GLenum light[6] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, 
-		     GL_LIGHT3, GL_LIGHT4, GL_LIGHT5};
-  GLfloat pos[4] = {0., 0., 0., 0.};
-  GLfloat spec[4] = {CTX.shine, CTX.shine, CTX.shine, 1.0};
+  GLfloat r, g, b;
 
   for(int i = 0; i < 6; i++) {
     if(CTX.light[i]) {
-      for(int j = 0; j < 3; j++) 
-	pos[j] = (GLfloat)CTX.light_position[i][j];
-      glEnable(light[i]);
-      glLightfv(light[i], GL_POSITION, pos);
+      GLfloat position[4] = {(GLfloat)CTX.light_position[i][0],
+			     (GLfloat)CTX.light_position[i][1],
+			     (GLfloat)CTX.light_position[i][2],
+			     0.0};
+      glLightfv((GLenum)(GL_LIGHT0 + i), GL_POSITION, position);
+
+      r = UNPACK_RED(CTX.color.ambient_light[i])/255.;
+      g = UNPACK_GREEN(CTX.color.ambient_light[i])/255.;
+      b = UNPACK_BLUE(CTX.color.ambient_light[i])/255.;
+      GLfloat ambient[4] = {r, g, b, 1.0};
+      glLightfv((GLenum)(GL_LIGHT0 + i), GL_AMBIENT, ambient);
+
+      r = UNPACK_RED(CTX.color.diffuse_light[i])/255.;
+      g = UNPACK_GREEN(CTX.color.diffuse_light[i])/255.;
+      b = UNPACK_BLUE(CTX.color.diffuse_light[i])/255.;
+      GLfloat diffuse[4] = {r, g, b, 1.0};
+      glLightfv((GLenum)(GL_LIGHT0 + i), GL_DIFFUSE, diffuse);
+
+      r = UNPACK_RED(CTX.color.specular_light[i])/255.;
+      g = UNPACK_GREEN(CTX.color.specular_light[i])/255.;
+      b = UNPACK_BLUE(CTX.color.specular_light[i])/255.;
+      GLfloat specular[4] = {r, g, b, 1.0};
+      glLightfv((GLenum)(GL_LIGHT0 + i), GL_SPECULAR, specular);
+
+      glEnable((GLenum)(GL_LIGHT0 + i));
     }
     else{
-      glDisable(light[i]);
+      glDisable((GLenum)(GL_LIGHT0 + i));
     }
   }
 
+  // ambient and diffuse material colors track glColor automatically
   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
-  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.);
-  glShadeModel(GL_SMOOTH);
+  glEnable(GL_COLOR_MATERIAL);
+  // "white"-only specular material reflection color
+  GLfloat spec[4] = {CTX.shine, CTX.shine, CTX.shine, 1.0};
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
+  // specular exponent in [0,128] (larger means more "focused"
+  // reflection)
+  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, CTX.shine_exponent);
+
+  glShadeModel(GL_SMOOTH);
 #if defined(GL_VERSION_1_2)
   // this is more efficient, since we already specify unit normals
   glEnable(GL_RESCALE_NORMAL);
 #else
   glEnable(GL_NORMALIZE);
 #endif
-  glEnable(GL_COLOR_MATERIAL);
+
   // lighting is enabled/disabled for each particular primitive later
   glDisable(GL_LIGHTING);
 }