[Bf-blender-cvs] [08fa158f7af] greasepencil-refactor: GPencil: Refactor: Improve current stroke drawing interleaving

Clément Foucault noreply at git.blender.org
Fri Jan 3 22:28:31 CET 2020


Commit: 08fa158f7af6d2127d5e27b1fe3527b5775f488d
Author: Clément Foucault
Date:   Fri Jan 3 17:58:46 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB08fa158f7af6d2127d5e27b1fe3527b5775f488d

GPencil: Refactor: Improve current stroke drawing interleaving

This fixes issues with stroke sorting. The previous strokes were masking
the current stroke.

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

M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 59631b96114..8ee57a71e1b 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -472,7 +472,7 @@ static void GPENCIL_cache_init_new(void *ved)
     pd->sbuffer_layer = NULL;
     pd->stroke_batch = NULL;
     pd->fill_batch = NULL;
-    pd->do_stroke_fast_drawing = false;
+    pd->do_stroke_fast_drawing = true;
 
     Object *ob = draw_ctx->obact;
     if (ob && ob->type == OB_GPENCIL) {
@@ -894,6 +894,9 @@ typedef struct gpIterPopulateData {
   GPUTexture *tex_stroke;
   /* Is the sbuffer call need to be issued. */
   int do_sbuffer_call;
+  /* Indices to do correct insertion of the sbuffer stroke. */
+  int stroke_index_last;
+  int stroke_index_offset;
 } gpIterPopulateData;
 
 static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
@@ -901,6 +904,22 @@ static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
                                      bGPDstroke *gps,
                                      void *thunk);
 
+static void gp_sbuffer_cache_populate(gpIterPopulateData *iter)
+{
+  iter->do_sbuffer_call = DRAW_NOW;
+  /* In order to draw the sbuffer stroke correctly mixed with other storkes,
+   * we need to offset the stroke index of the sbuffer stroke and the subsequent strokes.
+   * Remember, sbuffer stroke indices start from 0. So we add last index to avoid
+   * masking issues. */
+  iter->grp = DRW_shgroup_create_sub(iter->grp);
+  DRW_shgroup_uniform_float_copy(iter->grp, "strokeIndexOffset", iter->stroke_index_last);
+
+  gp_stroke_cache_populate(NULL, NULL, iter->pd->sbuffer_stroke, iter);
+
+  iter->stroke_index_offset = iter->pd->sbuffer_stroke->totpoints + 1;
+  iter->do_sbuffer_call = 0;
+}
+
 static void gp_layer_cache_populate(bGPDlayer *gpl,
                                     bGPDframe *gpf,
                                     bGPDstroke *UNUSED(gps),
@@ -910,9 +929,7 @@ static void gp_layer_cache_populate(bGPDlayer *gpl,
   bGPdata *gpd = (bGPdata *)iter->ob->data;
 
   if (iter->do_sbuffer_call) {
-    iter->do_sbuffer_call = DRAW_NOW;
-    gp_stroke_cache_populate(NULL, NULL, iter->pd->sbuffer_stroke, thunk);
-    iter->do_sbuffer_call = 0;
+    gp_sbuffer_cache_populate(iter);
   }
   else {
     iter->do_sbuffer_call = (gpd == iter->pd->sbuffer_gpd) && (gpl == iter->pd->sbuffer_layer);
@@ -959,6 +976,7 @@ static void gp_layer_cache_populate(bGPDlayer *gpl,
   DRW_shgroup_uniform_float_copy(iter->grp, "thicknessOffset", (float)gpl->line_change);
   DRW_shgroup_uniform_float_copy(iter->grp, "thicknessWorldScale", thickness_scale);
   DRW_shgroup_uniform_float_copy(iter->grp, "vertexColorOpacity", gpl->vertex_paint_opacity);
+  DRW_shgroup_uniform_float_copy(iter->grp, "strokeIndexOffset", iter->stroke_index_offset);
   DRW_shgroup_stencil_mask(iter->grp, 0xFF);
 
   bool use_onion = gpf->runtime.onion_id != 0.0f;
@@ -1040,6 +1058,8 @@ static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
     int vcount = gps->totpoints + 1 + 1;
     DRW_shgroup_call_instance_range(iter->grp, geom, vfirst, vcount);
   }
+
+  iter->stroke_index_last = gps->runtime.stroke_start + gps->totpoints + 1;
 }
 
 static void GPENCIL_cache_populate_new(void *ved, Object *ob)
@@ -1066,8 +1086,7 @@ static void GPENCIL_cache_populate_new(void *ved, Object *ob)
         ob, gp_layer_cache_populate, gp_stroke_cache_populate, &iter, pd->do_onion);
 
     if (iter.do_sbuffer_call) {
-      iter.do_sbuffer_call = DRAW_NOW;
-      gp_stroke_cache_populate(NULL, NULL, iter.pd->sbuffer_stroke, &iter);
+      gp_sbuffer_cache_populate(&iter);
     }
 
     gpencil_vfx_cache_populate(vedata, ob, iter.tgp_ob);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index d62824c1da6..c23167c9223 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -502,8 +502,6 @@ typedef struct GPENCIL_PrivateData {
   /* Batches containing the temp stroke. */
   GPUBatch *stroke_batch;
   GPUBatch *fill_batch;
-  /* A stroke is currently in progress, do special drawing.  */
-  bool do_stroke_fast_drawing;
 
   /* Display onion skinning */
   bool do_onion;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
index d71c08d75c5..98687d6d4a0 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
@@ -15,6 +15,7 @@ uniform float thicknessOffset;
 uniform float vertexColorOpacity;
 uniform vec4 layerTint;
 uniform float layerOpacity; /* Used for onion skin. */
+uniform float strokeIndexOffset;
 
 in vec4 ma;
 in vec4 ma1;
@@ -262,7 +263,7 @@ void stroke_vertex()
     /* Use the fragment depth (see fragment shader). */
     depth = -1.0;
     /* We still offset the fills a little to avoid overlaps */
-    gl_Position.z -= (stroke_id1 + 1) * 0.000002;
+    gl_Position.z -= (stroke_id1 + strokeIndexOffset + 1.0) * 0.000002;
   }
   else if (GP_FLAG_TEST(materials[m].flag, GP_STROKE_OVERLAP)) {
     /* Use the index of the point as depth.
@@ -275,7 +276,7 @@ void stroke_vertex()
      * cannot overlap itself.
      * We offset by one so that the fill can be overlapped by its stroke.
      * The offset is ok since we pad the strokes data because of adjacency infos. */
-    depth = (stroke_id1 + 1.0) * 0.0000002;
+    depth = (stroke_id1 + strokeIndexOffset + 1.0) * 0.0000002;
   }
 }
 
@@ -313,11 +314,11 @@ void fill_vertex()
     /* Use the fragment depth (see fragment shader). */
     depth = -1.0;
     /* We still offset the fills a little to avoid overlaps */
-    gl_Position.z -= stroke_id1 * 0.000002;
+    gl_Position.z -= (stroke_id1 + strokeIndexOffset) * 0.000002;
   }
   else {
     /* Use the index of first point of the stroke as depth. */
-    depth = stroke_id1 * 0.0000002;
+    depth = (stroke_id1 + strokeIndexOffset) * 0.0000002;
   }
 }



More information about the Bf-blender-cvs mailing list