[Bf-blender-cvs] [981c49ff4c2] greasepencil-refactor: GPencil: Refactor: Add outline overlay

Clément Foucault noreply at git.blender.org
Tue Jan 7 15:31:33 CET 2020


Commit: 981c49ff4c250625ca688a1b5fff788b2143e0db
Author: Clément Foucault
Date:   Mon Jan 6 18:33:30 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB981c49ff4c250625ca688a1b5fff788b2143e0db

GPencil: Refactor: Add outline overlay

This does not work correctly on square & dot strokes.

Also another issue is the depth blending. We need to fix the depth of
the outline geometry to match the 2D projection we do in the gpencil engine.

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

M	source/blender/draw/engines/overlay/overlay_engine.c
M	source/blender/draw/engines/overlay/overlay_outline.c
M	source/blender/draw/engines/overlay/overlay_private.h
M	source/blender/draw/engines/overlay/overlay_shader.c
M	source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl
M	source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl

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

diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index 38ab3d348ea..dab307dc6ee 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -25,6 +25,8 @@
 #include "DRW_engine.h"
 #include "DRW_render.h"
 
+#include "DEG_depsgraph_query.h"
+
 #include "ED_view3d.h"
 
 #include "BKE_object.h"
@@ -78,6 +80,7 @@ static void OVERLAY_engine_init(void *vedata)
   pd->xray_enabled = XRAY_ACTIVE(v3d);
   pd->xray_enabled_and_not_wire = pd->xray_enabled && v3d->shading.type > OB_WIRE;
   pd->clear_in_front = (v3d->shading.type != OB_SOLID);
+  pd->cfra = DEG_get_ctime(draw_ctx->depsgraph);
 
   OVERLAY_antialiasing_init(vedata);
 
@@ -184,6 +187,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
   OVERLAY_PrivateData *pd = data->stl->pd;
   const DRWContextState *draw_ctx = DRW_context_state_get();
   const bool is_select = DRW_state_is_select();
+  const bool is_gpencil = ob->type == OB_GPENCIL;
   const bool renderable = DRW_object_is_renderable(ob);
   const bool in_pose_mode = ob->type == OB_ARMATURE && OVERLAY_armature_is_pose_mode(ob, draw_ctx);
   const bool in_edit_mode = BKE_object_is_in_editmode(ob);
@@ -197,8 +201,8 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
   const bool draw_bones = (pd->overlay.flag & V3D_OVERLAY_HIDE_BONES) == 0;
   const bool draw_wires = draw_surface && has_surface &&
                           (pd->wireframe_mode || !pd->hide_overlays);
-  const bool draw_outlines = !in_edit_mode && !in_paint_mode && renderable && has_surface &&
-                             (pd->v3d_flag & V3D_SELECT_OUTLINE) &&
+  const bool draw_outlines = !in_edit_mode && !in_paint_mode && renderable &&
+                             (has_surface || is_gpencil) && (pd->v3d_flag & V3D_SELECT_OUTLINE) &&
                              (ob->base_flag & BASE_SELECTED);
   const bool draw_bone_selection = (ob->type == OB_MESH) && pd->armature.do_pose_fade_geom &&
                                    !is_select;
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c
index 63738b3c214..12ba0fbb4b9 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.c
@@ -23,8 +23,10 @@
 #include "DRW_render.h"
 
 #include "BKE_global.h"
+#include "BKE_gpencil.h"
 
-#include "DNA_lightprobe_types.h"
+// #include "DNA_lightprobe_types.h"
+#include "DNA_gpencil_types.h"
 
 #include "UI_resources.h"
 
@@ -79,6 +81,11 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
 
     pd->outlines_grp = grp = DRW_shgroup_create(sh_geom, psl->outlines_prepass_ps);
     DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
+
+    GPUShader *sh_gpencil = OVERLAY_shader_outline_prepass_gpencil();
+
+    pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
+    DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
   }
 
   /* outlines_prepass_ps is still needed for selection of probes. */
@@ -107,6 +114,85 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
   }
 }
 
+typedef struct iterData {
+  Object *ob;
+  DRWShadingGroup *stroke_grp;
+  DRWShadingGroup *fill_grp;
+  int cfra;
+} iterData;
+
+static void gp_layer_cache_populate(bGPDlayer *gpl,
+                                    bGPDframe *UNUSED(gpf),
+                                    bGPDstroke *UNUSED(gps),
+                                    void *thunk)
+{
+  iterData *iter = (iterData *)thunk;
+  bGPdata *gpd = (bGPdata *)iter->ob->data;
+
+  const bool is_screenspace = (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0;
+
+  float object_scale = mat4_to_scale(iter->ob->obmat);
+  /* Negate thickness sign to tag that strokes are in screen space.
+   * Convert to world units (by default, 1 meter = 2000 px). */
+  float thickness_scale = (is_screenspace) ? -1.0f : (gpd->pixfactor / 2000.0f);
+
+  DRWShadingGroup *grp = iter->stroke_grp = DRW_shgroup_create_sub(iter->stroke_grp);
+  DRW_shgroup_uniform_bool_copy(grp, "strokeOrder3d", true);
+  DRW_shgroup_uniform_vec2_copy(grp, "sizeViewportInv", DRW_viewport_invert_size_get());
+  DRW_shgroup_uniform_vec2_copy(grp, "sizeViewport", DRW_viewport_size_get());
+  DRW_shgroup_uniform_float_copy(grp, "thicknessScale", object_scale);
+  DRW_shgroup_uniform_float_copy(grp, "thicknessOffset", (float)gpl->line_change);
+  DRW_shgroup_uniform_float_copy(grp, "thicknessWorldScale", thickness_scale);
+}
+
+static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
+                                     bGPDframe *UNUSED(gpf),
+                                     bGPDstroke *gps,
+                                     void *thunk)
+{
+  iterData *iter = (iterData *)thunk;
+
+  MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(iter->ob, gps->mat_nr + 1);
+
+  bool hide_material = (gp_style->flag & GP_STYLE_COLOR_HIDE) != 0;
+  bool show_stroke = (gp_style->flag & GP_STYLE_STROKE_SHOW) != 0;
+  // TODO: What about simplify Fill?
+  bool show_fill = (gps->tot_triangles > 0) && (gp_style->flag & GP_STYLE_FILL_SHOW) != 0;
+
+  if (hide_material) {
+    return;
+  }
+
+  if (show_fill) {
+    struct GPUBatch *geom = DRW_cache_gpencil_fills_get(iter->ob, iter->cfra);
+    int vfirst = gps->runtime.fill_start * 3;
+    int vcount = gps->tot_triangles * 3;
+    DRW_shgroup_call_range(iter->fill_grp, iter->ob, geom, vfirst, vcount);
+  }
+
+  if (show_stroke) {
+    struct GPUBatch *geom = DRW_cache_gpencil_strokes_get(iter->ob, iter->cfra);
+    /* Start one vert before to have gl_InstanceID > 0 (see shader). */
+    int vfirst = gps->runtime.stroke_start - 1;
+    /* Include "potential" cyclic vertex and start adj vertex (see shader). */
+    int vcount = gps->totpoints + 1 + 1;
+    DRW_shgroup_call_instance_range(iter->stroke_grp, iter->ob, geom, vfirst, vcount);
+  }
+}
+
+static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
+{
+  iterData iter = {
+      .ob = ob,
+      .stroke_grp = pd->outlines_gpencil_grp,
+      .fill_grp = DRW_shgroup_create_sub(pd->outlines_gpencil_grp),
+      .cfra = pd->cfra,
+  };
+
+  BKE_gpencil_visible_stroke_iter(
+      ob, gp_layer_cache_populate, gp_stroke_cache_populate, &iter, false, pd->cfra);
+}
+
 void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
                                     Object *ob,
                                     OVERLAY_DupliData *dupli,
@@ -123,6 +209,11 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
     return;
   }
 
+  if (ob->type == OB_GPENCIL) {
+    OVERLAY_outline_gpencil(pd, ob);
+    return;
+  }
+
   if (dupli && !init_dupli) {
     geom = dupli->outline_geom;
     shgroup = dupli->outline_shgrp;
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 996ee845799..4bda0cc8ed2 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -229,6 +229,7 @@ typedef struct OVERLAY_PrivateData {
   DRWShadingGroup *motion_path_lines_grp;
   DRWShadingGroup *motion_path_points_grp;
   DRWShadingGroup *outlines_grp;
+  DRWShadingGroup *outlines_gpencil_grp;
   DRWShadingGroup *paint_surf_grp;
   DRWShadingGroup *paint_wire_grp;
   DRWShadingGroup *paint_wire_selected_grp;
@@ -267,6 +268,7 @@ typedef struct OVERLAY_PrivateData {
   bool xray_enabled_and_not_wire;
   short v3d_flag;     /* TODO move to View3DOverlay */
   short v3d_gridflag; /* TODO move to View3DOverlay */
+  int cfra;
   DRWState clipping_state;
   OVERLAY_ShadingData shdata;
 
@@ -552,6 +554,7 @@ GPUShader *OVERLAY_shader_motion_path_line(void);
 GPUShader *OVERLAY_shader_motion_path_vert(void);
 GPUShader *OVERLAY_shader_uniform_color(void);
 GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
+GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
 GPUShader *OVERLAY_shader_extra_grid(void);
 GPUShader *OVERLAY_shader_outline_detect(void);
 GPUShader *OVERLAY_shader_paint_face(void);
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index 7bd3cf4a067..4b63eda9444 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -110,6 +110,8 @@ extern char datatoc_gpu_shader_flat_color_frag_glsl[];
 extern char datatoc_gpu_shader_point_varying_color_varying_outline_aa_frag_glsl[];
 extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
 
+extern char datatoc_gpencil_common_lib_glsl[];
+
 extern char datatoc_common_colormanagement_lib_glsl[];
 extern char datatoc_common_fullscreen_vert_glsl[];
 extern char datatoc_common_fxaa_lib_glsl[];
@@ -159,6 +161,7 @@ typedef struct OVERLAY_Shaders {
   GPUShader *motion_path_line;
   GPUShader *motion_path_vert;
   GPUShader *outline_prepass;
+  GPUShader *outline_prepass_gpencil;
   GPUShader *outline_prepass_wire;
   GPUShader *outline_detect;
   GPUShader *paint_face;
@@ -967,6 +970,31 @@ GPUShader *OVERLAY_shader_outline_prepass(bool use_wire)
   return use_wire ? sh_data->outline_prepass_wire : sh_data->outline_prepass;
 }
 
+GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
+{
+  const DRWContextState *draw_ctx = DRW_context_state_get();
+  const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
+  OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+  if (!sh_data->outline_prepass_gpencil) {
+    sh_data->outline_prepass_gpencil = GPU_shader_create_from_arrays({
+        .vert = (const char *[]){sh_cfg->lib,
+                                 datatoc_common_view_lib_glsl,
+                                 datatoc_gpencil_common_lib_glsl,
+                                 datatoc_gpu_shader_common_obinfos_lib_glsl,
+                                 datatoc_outline_prepass_vert_glsl,
+                                 NULL},
+        .frag = (const char *[]){datatoc_gpencil_common_lib_glsl,
+                                 data

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list