changeset 28006:91316b5dc5a2

Only use ambient light for edge lighting on patches (bug #57553). * gl-render.cc (patch_tessellator): Add new property "face_lighting". If it is false (i.e. for edge lighting), only ambient lighting is set. (draw_patch): Edge lighting only uses ambient light.
author Markus Mützel <markus.muetzel@gmx.de>
date Sun, 26 Jan 2020 14:17:00 +0100
parents 4ee66fda87fb
children 7cc9f35c2829
files libinterp/corefcn/gl-render.cc
diffstat 1 files changed, 26 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/gl-render.cc	Sun Jan 26 10:29:18 2020 +0100
+++ b/libinterp/corefcn/gl-render.cc	Sun Jan 26 14:17:00 2020 +0100
@@ -514,9 +514,10 @@
   opengl_renderer::patch_tessellator : public opengl_tessellator
   {
   public:
-    patch_tessellator (opengl_renderer *r, int cmode, int lmode, float idx = 0.0)
+    patch_tessellator (opengl_renderer *r, int cmode, int lmode, bool fl,
+                       float idx = 0.0)
       : opengl_tessellator (), renderer (r),
-        color_mode (cmode), light_mode (lmode), index (idx),
+        color_mode (cmode), light_mode (lmode), face_lighting (fl), index (idx),
         first (true), tmp_vdata ()
     { }
 
@@ -568,21 +569,23 @@
               glfcns.glColor4d (col(0), col(1), col(2), v->alpha);
               if (light_mode > 0)
                 {
-                  float buf[4] = { 0, 0, 0, 1 };
+                  // edge lighting only uses ambient light
+                  float buf[4] = { 0.0f, 0.0f, 0.0f, 1.0f };;
+
+                  if (face_lighting)
+                    for (int k = 0; k < 3; k++)
+                      buf[k] = v->specular * (v->specular_color_refl +
+                                              (1 - v->specular_color_refl) * col(k));
+                  glfcns.glMaterialfv (LIGHT_MODE, GL_SPECULAR, buf);
+
+                  if (face_lighting)
+                    for (int k = 0; k < 3; k++)
+                      buf[k] = (v->diffuse * col(k));
+                  glfcns.glMaterialfv (LIGHT_MODE, GL_DIFFUSE, buf);
 
                   for (int k = 0; k < 3; k++)
                     buf[k] = (v->ambient * col(k));
                   glfcns.glMaterialfv (LIGHT_MODE, GL_AMBIENT, buf);
-
-                  for (int k = 0; k < 3; k++)
-                    buf[k] = (v->diffuse * col(k));
-                  glfcns.glMaterialfv (LIGHT_MODE, GL_DIFFUSE, buf);
-
-                  for (int k = 0; k < 3; k++)
-                    buf[k] = v->specular * (v->specular_color_refl +
-                                            (1 - v->specular_color_refl) * col(k));
-                  glfcns.glMaterialfv (LIGHT_MODE, GL_SPECULAR, buf);
-
                 }
             }
         }
@@ -666,6 +669,7 @@
     opengl_renderer *renderer;
     int color_mode;
     int light_mode;
+    bool face_lighting;
     int index;
     bool first;
     std::list<vertex_data> tmp_vdata;
@@ -2818,7 +2822,7 @@
             if (ec_mode == UNIFORM)
               {
                 m_glfcns.glColor3dv (ecolor.data ());
-                if (fl_mode > 0)
+                if (el_mode > 0)
                   {
                     for (int i = 0; i < 3; i++)
                       cb[i] = as * ecolor(i);
@@ -3347,7 +3351,7 @@
                 m_glfcns.glColor4d (fcolor(0), fcolor(1), fcolor(2), fa);
                 if (fl_mode > 0)
                   {
-                    float cb[4] = { 0, 0, 0, 1 };
+                    float cb[4] = { 0.0f, 0.0f, 0.0f, 1.0f };;
 
                     for (int i = 0; i < 3; i++)
                       cb[i] = as * fcolor(i);
@@ -3370,7 +3374,7 @@
             // with tessellator outline.  A value of 1.0 seems to work fine.
             // Value can't be too large or the patch will be pushed below the
             // axes planes at +2.5.
-            patch_tessellator tess (this, fc_mode, fl_mode, 1.0);
+            patch_tessellator tess (this, fc_mode, fl_mode, true, 1.0);
 
             std::vector<octave_idx_type>::const_iterator it;
             octave_idx_type i_start, i_end;
@@ -3435,7 +3439,7 @@
                                 m_glfcns.glColor4d (col(0), col(1), col(2), fa);
                                 if (fl_mode > 0)
                                   {
-                                    float cb[4] = { 0, 0, 0, 1 };
+                                    float cb[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
 
                                     for (int k = 0; k < 3; k++)
                                       cb[k] = (vv->ambient * col(k));
@@ -3483,19 +3487,14 @@
                 m_glfcns.glColor3dv (ecolor.data ());
                 if (el_mode > 0)
                   {
-                    float cb[4] = { 0, 0, 0, 1 };
+                    // edge lighting only uses ambient light
+                    float cb[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+                    m_glfcns.glMaterialfv (LIGHT_MODE, GL_SPECULAR, cb);
+                    m_glfcns.glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
 
                     for (int i = 0; i < 3; i++)
                       cb[i] = (as * ecolor(i));
                     m_glfcns.glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
-
-                    for (int i = 0; i < 3; i++)
-                      cb[i] = ds * ecolor(i);
-                    m_glfcns.glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
-
-                    for (int i = 0; i < 3; i++)
-                      cb[i] = ss * (scr + (1-scr) * ecolor(i));
-                    m_glfcns.glMaterialfv (LIGHT_MODE, GL_SPECULAR, cb);
                   }
               }
 
@@ -3513,7 +3512,7 @@
             // GLU_TESS_BOUNDARY_ONLY to get the outline of the patch and OpenGL
             // automatically sets the glType to GL_LINE_LOOP.  This primitive is
             // not supported by glPolygonOffset which is used to do Z offsets.
-            patch_tessellator tess (this, ec_mode, el_mode);
+            patch_tessellator tess (this, ec_mode, el_mode, false);
 
             for (int i = 0; i < nf; i++)
               {