# HG changeset patch # User Rik # Date 1400356571 25200 # Node ID 75f8926deef1d8f907171971d81f13dab8279adc # Parent 10082673a8f0739997a4b342843969e3978e4af7 Fix Z-order stacking of patches and axes grid lines (bug #40722). * gl-render.h (set_polygon_offset): Change function prototype for offset argument to float. * gl-render.cc (set_polygon_offset): Change offset argument to type float. Now matches OpenGL prototype for glPolygonOffset. * gl-render.cc (patch_tesselator::patch_tesselator): Change constructor variable idx to a float, from int. * gl-render.cc (patch_tesselator::begin): Pass index directly to set_polygon_offset. * gl-render.cc (opengl_renderer::draw_patch): Call patch_tesselator with index of 1.0 for filled portion of patch to push it down below outline of patch. * patch.m: For 2-D patches, set zlim to [-1,1] so that axes 'layer' property works. diff -r 10082673a8f0 -r 75f8926deef1 libinterp/corefcn/gl-render.cc --- a/libinterp/corefcn/gl-render.cc Fri May 16 08:20:11 2014 -0700 +++ b/libinterp/corefcn/gl-render.cc Sat May 17 12:56:11 2014 -0700 @@ -401,7 +401,7 @@ opengl_renderer::patch_tesselator : public opengl_tesselator { public: - patch_tesselator (opengl_renderer *r, int cmode, int lmode, int idx = 0) + patch_tesselator (opengl_renderer *r, int cmode, int lmode, float idx = 0.0) : opengl_tesselator (), renderer (r), color_mode (cmode), light_mode (lmode), index (idx), first (true), tmp_vdata () @@ -419,7 +419,7 @@ glShadeModel (GL_FLAT); if (is_filled ()) - renderer->set_polygon_offset (true, 1+index); + renderer->set_polygon_offset (true, index); glBegin (type); } @@ -437,9 +437,8 @@ = reinterpret_cast (data); //printf ("patch_tesselator::vertex (%g, %g, %g)\n", v->coords(0), v->coords(1), v->coords(2)); - // NOTE: OpenGL can re-order vertices so "first" is basically meaningless - // in this callback routine. For "flat" coloring of FaceColor the first - // vertex must be identified in the draw_patch routine. + // NOTE: OpenGL can re-order vertices. For "flat" coloring of FaceColor + // the first vertex must be identified in the draw_patch routine. if (color_mode == 2 || (color_mode == 1 && ! is_filled ())) { @@ -2338,11 +2337,11 @@ if (fl_mode > 0) glEnable (GL_LIGHTING); - // FIXME: use __index__ property from patch object - // -1.25 chosen to provide sufficient Z-offset for - // 'layer' property of 2-D plots and not to provoke - // Z-fighting with tesselator outline. - patch_tesselator tess (this, fc_mode, fl_mode, -1.25); + // NOTE: Push filled part of patch backwards to avoid Z-fighting with + // tesselator 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_tesselator tess (this, fc_mode, fl_mode, 1.0); for (int i = 0; i < nf; i++) { @@ -2431,9 +2430,11 @@ set_linestyle (props.get_linestyle (), false); set_linewidth (props.get_linewidth ()); - - // FIXME: use __index__ property from patch object; - // should we offset patch contour as well? + // NOTE: patch contour cannot be offset. Offset must occur with the + // filled portion of the patch above. The tesselator uses + // 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_tesselator tess (this, ec_mode, el_mode); for (int i = 0; i < nf; i++) @@ -2819,13 +2820,13 @@ } void -opengl_renderer::set_polygon_offset (bool on, double offset) +opengl_renderer::set_polygon_offset (bool on, float offset) { if (on) { - glPolygonOffset (offset, offset); glEnable (GL_POLYGON_OFFSET_FILL); glEnable (GL_POLYGON_OFFSET_LINE); + glPolygonOffset (offset, offset); } else { diff -r 10082673a8f0 -r 75f8926deef1 libinterp/corefcn/gl-render.h --- a/libinterp/corefcn/gl-render.h Fri May 16 08:20:11 2014 -0700 +++ b/libinterp/corefcn/gl-render.h Sat May 17 12:56:11 2014 -0700 @@ -93,7 +93,7 @@ virtual void setup_opengl_transformation (const axes::properties& props); virtual void set_color (const Matrix& c); - virtual void set_polygon_offset (bool on, double offset = 0.0); + virtual void set_polygon_offset (bool on, float offset = 0.0); virtual void set_linewidth (float w); virtual void set_linestyle (const std::string& s, bool stipple = false); virtual void set_clipbox (double x1, double x2, double y1, double y2, diff -r 10082673a8f0 -r 75f8926deef1 scripts/plot/draw/patch.m --- a/scripts/plot/draw/patch.m Fri May 16 08:20:11 2014 -0700 +++ b/scripts/plot/draw/patch.m Sat May 17 12:56:11 2014 -0700 @@ -88,6 +88,15 @@ print_usage (); endif + ## FIXME: This is a hack to get 'layer' command to work for 2D patches + ## Alternative is much more complicated surgery in graphics.cc. + ## of get_children_limits() for 'z' axis and 'patch' object type. + if (! ishold ()) + if (isempty (get (htmp, "zdata"))) + set (hax, "zlim", [-1 1]); + endif + endif + if (nargout > 0) h = htmp; endif