[Bf-blender-cvs] [14b34361bc4] temp-T95933-object-mode-curve-selection: Draw: Curve outline drawing in object mode.

Jeroen Bakker noreply at git.blender.org
Tue Jun 28 15:35:03 CEST 2022


Commit: 14b34361bc421c7acd8d82e65c2f64773545d0e4
Author: Jeroen Bakker
Date:   Tue Jun 28 10:53:27 2022 +0200
Branches: temp-T95933-object-mode-curve-selection
https://developer.blender.org/rB14b34361bc421c7acd8d82e65c2f64773545d0e4

Draw: Curve outline drawing in object mode.

## TODO

* [ ] drawing curves when performing GPU selection
* [ ] push radius to cover at least one pixel

Differential Revision: https://developer.blender.org/D15308

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/overlay/overlay_extra.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/infos/overlay_outline_info.hh
A	source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 9cb3743dd02..b211f91359b 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -531,6 +531,7 @@ set(GLSL_SRC
   engines/overlay/shaders/overlay_motion_path_line_vert.glsl
   engines/overlay/shaders/overlay_motion_path_point_vert.glsl
   engines/overlay/shaders/overlay_outline_detect_frag.glsl
+  engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
   engines/overlay/shaders/overlay_outline_prepass_frag.glsl
   engines/overlay/shaders/overlay_outline_prepass_geom.glsl
   engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl
diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c
index f875254a685..d43c49bfa85 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.c
@@ -1527,7 +1527,8 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
   const bool is_paint_mode = (draw_ctx->object_mode &
                               (OB_MODE_ALL_PAINT | OB_MODE_ALL_PAINT_GPENCIL)) != 0;
   const bool from_dupli = (ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) != 0;
-  const bool has_bounds = !ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_EMPTY, OB_SPEAKER, OB_LIGHTPROBE);
+  const bool has_bounds = !ELEM(
+      ob->type, OB_LAMP, OB_CAMERA, OB_EMPTY, OB_SPEAKER, OB_LIGHTPROBE, OB_CURVES);
   const bool has_texspace = has_bounds &&
                             !ELEM(ob->type, OB_EMPTY, OB_LATTICE, OB_ARMATURE, OB_GPENCIL);
 
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c
index eea9a1a1bef..f2e2acc98a9 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.c
@@ -133,6 +133,10 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
     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);
     DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", 0.0);
+
+    GPUShader *sh_curves = OVERLAY_shader_outline_prepass_curves();
+    pd->outlines_curves_grp = grp = DRW_shgroup_create(sh_curves, 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. */
@@ -267,6 +271,12 @@ static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob)
   DRW_shgroup_call(shgroup, geom, ob);
 }
 
+static void OVERLAY_outline_curves(OVERLAY_PrivateData *pd, Object *ob)
+{
+  DRWShadingGroup *shgroup = pd->outlines_curves_grp;
+  DRW_shgroup_curves_create_sub(ob, shgroup, NULL);
+}
+
 void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
                                     Object *ob,
                                     OVERLAY_DupliData *dupli,
@@ -293,6 +303,11 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
     return;
   }
 
+  if (ob->type == OB_CURVES) {
+    OVERLAY_outline_curves(pd, ob);
+    return;
+  }
+
   if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) {
     /* Looks bad in this case. Could be relaxed if we draw a
      * wireframe of some sort in the future. */
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 23c20a186a0..a05d82d2638 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -267,6 +267,7 @@ typedef struct OVERLAY_PrivateData {
   DRWShadingGroup *motion_path_lines_grp;
   DRWShadingGroup *motion_path_points_grp;
   DRWShadingGroup *outlines_grp;
+  DRWShadingGroup *outlines_curves_grp;
   DRWShadingGroup *outlines_ptcloud_grp;
   DRWShadingGroup *outlines_gpencil_grp;
   DRWShadingGroup *paint_depth_grp;
@@ -737,6 +738,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_curves(void);
 GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
 GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void);
 GPUShader *OVERLAY_shader_extra_grid(void);
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index 48146fbddfb..115d87cf58c 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -76,6 +76,7 @@ typedef struct OVERLAY_Shaders {
   GPUShader *motion_path_line;
   GPUShader *motion_path_vert;
   GPUShader *outline_prepass;
+  GPUShader *outline_prepass_curves;
   GPUShader *outline_prepass_gpencil;
   GPUShader *outline_prepass_pointcloud;
   GPUShader *outline_prepass_wire;
@@ -650,6 +651,18 @@ 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_curves()
+{
+  const DRWContextState *draw_ctx = DRW_context_state_get();
+  OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+  if (!sh_data->outline_prepass_curves) {
+    sh_data->outline_prepass_curves = GPU_shader_create_from_info_name(
+        // draw_ctx->sh_cfg ? "overlay_outline_prepass_curves_clipped" :
+        "overlay_outline_prepass_curves");
+  }
+  return sh_data->outline_prepass_curves;
+}
+
 GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
 {
   const DRWContextState *draw_ctx = DRW_context_state_get();
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh
index 6f6a9c1622d..05286d21b55 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh
@@ -29,6 +29,12 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass_mesh_clipped)
 
 GPU_SHADER_INTERFACE_INFO(overlay_outline_prepass_wire_iface, "vert").flat(Type::VEC3, "pos");
 
+GPU_SHADER_CREATE_INFO(overlay_outline_prepass_curves)
+    .do_static_compilation(true)
+    .vertex_source("overlay_outline_prepass_curves_vert.glsl")
+    .additional_info("draw_hair", "overlay_outline_prepass")
+    .additional_info("draw_object_infos");
+
 GPU_SHADER_CREATE_INFO(overlay_outline_prepass_wire)
     .do_static_compilation(true)
     .define("USE_GEOM")
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
new file mode 100644
index 00000000000..94cba760f9d
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
@@ -0,0 +1,64 @@
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+
+uint outline_colorid_get(void)
+{
+  int flag = int(abs(ObjectInfo.w));
+  bool is_active = (flag & DRW_BASE_ACTIVE) != 0;
+
+  if (isTransform) {
+    return 0u; /* colorTransform */
+  }
+  else if (is_active) {
+    return 3u; /* colorActive */
+  }
+  else {
+    return 1u; /* colorSelect */
+  }
+
+  return 0u;
+}
+
+/* Replace top 2 bits (of the 16bit output) by outlineId.
+ * This leaves 16K different IDs to create outlines between objects.
+  vec3 world_pos = point_object_to_world(pos);
+ * SHIFT = (32 - (16 - 2)) */
+#define SHIFT 18u
+
+void main()
+{
+  bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+  float time, thick_time, thickness;
+  vec3 world_pos, tan, binor;
+  hair_get_pos_tan_binor_time(is_persp,
+                              ModelMatrixInverse,
+                              ViewMatrixInverse[3].xyz,
+                              ViewMatrixInverse[2].xyz,
+                              world_pos,
+                              tan,
+                              binor,
+                              time,
+                              thickness,
+                              thick_time);
+
+  gl_Position = point_world_to_ndc(world_pos);
+#ifdef USE_GEOM
+  vert.pos = point_world_to_view(world_pos);
+#endif
+
+  /* Small bias to always be on top of the geom. */
+  gl_Position.z -= 1e-3;
+
+  /* ID 0 is nothing (background) */
+  interp.ob_id = uint(resource_handle + 1);
+
+  /* Should be 2 bits only [0..3]. */
+  uint outline_id = outline_colorid_get();
+
+  /* Combine for 16bit uint target. */
+  interp.ob_id = (outline_id << 14u) | ((interp.ob_id << SHIFT) >> SHIFT);
+
+  view_clipping_distances(world_pos);
+}



More information about the Bf-blender-cvs mailing list