[Bf-blender-cvs] [2e75172c45f] master: Fix T75677: Annotation in compositor/shading tabs loose AA after drawing stroke

Antonio Vazquez noreply at git.blender.org
Mon Apr 13 15:16:03 CEST 2020


Commit: 2e75172c45fd7f434aa80d4bb04d74e3449a4ea1
Author: Antonio Vazquez
Date:   Mon Apr 13 15:15:47 2020 +0200
Branches: master
https://developer.blender.org/rB2e75172c45fd7f434aa80d4bb04d74e3449a4ea1

Fix T75677: Annotation in compositor/shading tabs loose AA after drawing stroke

The drawing of annotations in 2D was using a very old code created in 2.6x versions. Now it's using a standard shader as it's done while drawing.

===================================================================

M	source/blender/editors/gpencil/annotate_draw.c

===================================================================

diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index 26ba2661072..adaf4ab2459 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -328,13 +328,10 @@ static void annotation_draw_stroke_3d(
   immUnbindProgram();
 }
 
-/* ----- Fancy 2D-Stroke Drawing ------ */
-
-/* draw a given stroke in 2d */
+/* Draw a given stroke in 2d. */
 static void annotation_draw_stroke_2d(const bGPDspoint *points,
                                       int totpoints,
                                       short thickness_s,
-                                      short dflag,
                                       short sflag,
                                       int offsx,
                                       int offsy,
@@ -342,167 +339,84 @@ static void annotation_draw_stroke_2d(const bGPDspoint *points,
                                       int winy,
                                       const float ink[4])
 {
-  /* otherwise thickness is twice that of the 3D view */
-  float thickness = (float)thickness_s * 0.5f;
-
-  /* strokes in Image Editor need a scale factor, since units there are not pixels! */
-  float scalefac = 1.0f;
-  if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) {
-    scalefac = 0.001f;
+  if (totpoints == 0) {
+    return;
   }
+  float thickness = (float)thickness_s;
 
-  /* Tessellation code - draw stroke as series of connected quads
-   * (triangle strips in fact) with connection edges rotated to minimize shrinking artifacts,
-   * and rounded end-caps.
-   */
-  {
-    const bGPDspoint *pt1, *pt2;
-    float s0[2], s1[2]; /* segment 'center' points */
-    float pm[2];        /* normal from previous segment. */
-    int i;
+  GPUVertFormat *format = immVertexFormat();
+  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
 
-    GPUVertFormat *format = immVertexFormat();
-    uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+  const bGPDspoint *pt;
+  const bGPDspoint *pt_prev;
+  int draw_points = 0;
+  float co[2];
+  float oldpressure = points[0].pressure;
+  if (totpoints == 1) {
+    /* if drawing a single point, draw it larger */
+    GPU_point_size((float)(thickness + 2) * points->pressure);
+    immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+    immUniformColor3fvAlpha(ink, ink[3]);
+    immBegin(GPU_PRIM_POINTS, 1);
+
+    annotation_calc_2d_stroke_fxy(&points->x, sflag, offsx, offsy, winx, winy, co);
+    immVertex2fv(pos, co);
+  }
+  else {
+    /* draw stroke curve */
+    GPU_line_width(max_ff(oldpressure * thickness, 1.0));
 
     immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
     immUniformColor3fvAlpha(ink, ink[3]);
-    immBegin(GPU_PRIM_TRI_STRIP, totpoints * 2 + 4);
-
-    /* get x and y coordinates from first point */
-    annotation_calc_2d_stroke_fxy(&points->x, sflag, offsx, offsy, winx, winy, s0);
-
-    for (i = 0, pt1 = points, pt2 = points + 1; i < (totpoints - 1); i++, pt1++, pt2++) {
-      float t0[2], t1[2]; /* tessellated coordinates */
-      float m1[2], m2[2]; /* gradient and normal */
-      float mt[2], sc[2]; /* gradient for thickness, point for end-cap */
-      float pthick;       /* thickness at segment point */
-
-      /* Get x and y coordinates from point2
-       * (point1 has already been computed in previous iteration). */
-      annotation_calc_2d_stroke_fxy(&pt2->x, sflag, offsx, offsy, winx, winy, s1);
-
-      /* calculate gradient and normal - 'angle'=(ny/nx) */
-      m1[1] = s1[1] - s0[1];
-      m1[0] = s1[0] - s0[0];
-      normalize_v2(m1);
-      m2[1] = -m1[0];
-      m2[0] = m1[1];
-
-      /* always use pressure from first point here */
-      pthick = (pt1->pressure * thickness * scalefac);
-
-      /* if the first segment, start of segment is segment's normal */
-      if (i == 0) {
-        /* draw start cap first
-         * - make points slightly closer to center (about halfway across)
-         */
-        mt[0] = m2[0] * pthick * 0.5f;
-        mt[1] = m2[1] * pthick * 0.5f;
-        sc[0] = s0[0] - (m1[0] * pthick * 0.75f);
-        sc[1] = s0[1] - (m1[1] * pthick * 0.75f);
-
-        t0[0] = sc[0] - mt[0];
-        t0[1] = sc[1] - mt[1];
-        t1[0] = sc[0] + mt[0];
-        t1[1] = sc[1] + mt[1];
-
-        /* First two points of cap. */
-        immVertex2fv(pos, t0);
-        immVertex2fv(pos, t1);
-
-        /* calculate points for start of segment */
-        mt[0] = m2[0] * pthick;
-        mt[1] = m2[1] * pthick;
-
-        t0[0] = s0[0] - mt[0];
-        t0[1] = s0[1] - mt[1];
-        t1[0] = s0[0] + mt[0];
-        t1[1] = s0[1] + mt[1];
-
-        /* Last two points of start cap (and first two points of first segment). */
-        immVertex2fv(pos, t0);
-        immVertex2fv(pos, t1);
-      }
-      /* if not the first segment, use bisector of angle between segments */
-      else {
-        float mb[2];        /* bisector normal */
-        float athick, dfac; /* actual thickness, difference between thicknesses */
-
-        /* calculate gradient of bisector (as average of normals) */
-        mb[0] = (pm[0] + m2[0]) / 2;
-        mb[1] = (pm[1] + m2[1]) / 2;
-        normalize_v2(mb);
-
-        /* calculate gradient to apply
-         *  - as basis, use just pthick * bisector gradient
-         * - if cross-section not as thick as it should be, add extra padding to fix it
-         */
-        mt[0] = mb[0] * pthick;
-        mt[1] = mb[1] * pthick;
-        athick = len_v2(mt);
-        dfac = pthick - (athick * 2);
-
-        if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) {
-          mt[0] += (mb[0] * dfac);
-          mt[1] += (mb[1] * dfac);
+
+    immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints);
+
+    for (int i = 0; i < totpoints; i++) {
+      pt = &points[i];
+      /* If there was a significant pressure change,
+       * stop the curve, change the thickness of the stroke,
+       * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP).
+       */
+      if (fabsf(pt->pressure - oldpressure) > 0.2f) {
+        /* need to have 2 points to avoid immEnd assert error */
+        if (draw_points < 2) {
+          pt_prev = &points[i - 1];
+          annotation_calc_2d_stroke_fxy(&pt_prev->x, sflag, offsx, offsy, winx, winy, co);
+          immVertex2fv(pos, co);
         }
 
-        /* calculate points for start of segment */
-        t0[0] = s0[0] - mt[0];
-        t0[1] = s0[1] - mt[1];
-        t1[0] = s0[0] + mt[0];
-        t1[1] = s0[1] + mt[1];
+        immEnd();
+        draw_points = 0;
 
-        /* Last two points of previous segment, and first two points of current segment. */
-        immVertex2fv(pos, t0);
-        immVertex2fv(pos, t1);
-      }
+        GPU_line_width(max_ff(pt->pressure * thickness, 1.0f));
+        immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1);
+
+        /* need to roll-back one point to ensure that there are no gaps in the stroke */
+        if (i != 0) {
+          pt_prev = &points[i - 1];
+          annotation_calc_2d_stroke_fxy(&pt_prev->x, sflag, offsx, offsy, winx, winy, co);
+          immVertex2fv(pos, co);
+          draw_points++;
+        }
 
-      /* if last segment, also draw end of segment (defined as segment's normal) */
-      if (i == totpoints - 2) {
-        /* for once, we use second point's pressure (otherwise it won't be drawn) */
-        pthick = (pt2->pressure * thickness * scalefac);
-
-        /* calculate points for end of segment */
-        mt[0] = m2[0] * pthick;
-        mt[1] = m2[1] * pthick;
-
-        t0[0] = s1[0] - mt[0];
-        t0[1] = s1[1] - mt[1];
-        t1[0] = s1[0] + mt[0];
-        t1[1] = s1[1] + mt[1];
-
-        /* Last two points of last segment (and first two points of end cap). */
-        immVertex2fv(pos, t0);
-        immVertex2fv(pos, t1);
-
-        /* draw end cap as last step
-         * - make points slightly closer to center (about halfway across)
-         */
-        mt[0] = m2[0] * pthick * 0.5f;
-        mt[1] = m2[1] * pthick * 0.5f;
-        sc[0] = s1[0] + (m1[0] * pthick * 0.75f);
-        sc[1] = s1[1] + (m1[1] * pthick * 0.75f);
-
-        t0[0] = sc[0] - mt[0];
-        t0[1] = sc[1] - mt[1];
-        t1[0] = sc[0] + mt[0];
-        t1[1] = sc[1] + mt[1];
-
-        /* Last two points of end cap. */
-        immVertex2fv(pos, t0);
-        immVertex2fv(pos, t1);
+        oldpressure = pt->pressure; /* reset our threshold */
       }
 
-      /* store computed point2 coordinates as point1 ones of next segment. */
-      copy_v2_v2(s0, s1);
-      /* store stroke's 'natural' normal for next stroke to use */
-      copy_v2_v2(pm, m2);
+      /* now the point we want */
+      annotation_calc_2d_stroke_fxy(&pt->x, sflag, offsx, offsy, winx, winy, co);
+      immVertex2fv(pos, co);
+      draw_points++;
+    }
+    /* need to have 2 points to avoid immEnd assert error */
+    if (draw_points < 2) {
+      pt_prev = &points[0];
+      annotation_calc_2d_stroke_fxy(&pt_prev->x, sflag, offsx, offsy, winx, winy, co);
+      immVertex2fv(pos, co);
     }
-
-    immEnd();
-    immUnbindProgram();
   }
+
+  immEnd();
+  immUnbindProgram();
 }
 
 /* ----- Strokes Drawing ------ */
@@ -601,16 +515,8 @@ static void annotation_draw_strokes(const bGPDframe *gpf,
             gps->points, lthick, gps->flag, offsx, offsy, winx, winy, color);
       }
       else {
-        annotation_draw_stroke_2d(gps->points,
-                                  gps->totpoints,
-                                  lthick,
-                                  dflag,
-                                  gps->flag,
-                                  offsx,
-                                  offsy,
-                                  winx,
-                                  winy,
-                                  color);
+        annotation_draw_stroke_2d(
+            gps->points, gps->totpoints, lthick, gps->flag, offsx, offsy, winx, winy, color);
       }
     }
   }
@@ -862,7 +768,8 @@ static void annotation_draw_data_layers(
     annotation_draw_strokes(gpf, offsx, offs

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list