From 5fff95f5193ed22a5c06462bc073095eafdd53b4 Mon Sep 17 00:00:00 2001 From: YimingWu Date: Mon, 21 Oct 2024 18:47:24 +0200 Subject: [PATCH] Fix: Grease Pencil: Add back support for stroke direction overlay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since GPv3 shader currently uses particle strand/points shader, we need to modify that slightly to display the grease pencil overlays. This adds the missing `vflag` attribute to the edit gpencil batch. Co-authored-by: ClĂ©ment Foucault Pull Request: https://projects.blender.org/blender/blender/pulls/128116 --- .../engines/overlay/overlay_grease_pencil.cc | 3 +++ .../engines/overlay/overlay_next_curve.hh | 4 +++ .../overlay/overlay_next_grease_pencil.hh | 2 ++ .../draw/engines/overlay/overlay_particle.cc | 1 + .../shaders/infos/overlay_edit_mode_info.hh | 5 ++++ .../overlay_edit_particle_point_vert.glsl | 19 ++++++++++++- .../intern/draw_cache_impl_grease_pencil.cc | 27 +++++++++++++++++++ 7 files changed, 60 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/overlay/overlay_grease_pencil.cc b/source/blender/draw/engines/overlay/overlay_grease_pencil.cc index 16807e2f9a2..b206452509a 100644 --- a/source/blender/draw/engines/overlay/overlay_grease_pencil.cc +++ b/source/blender/draw/engines/overlay/overlay_grease_pencil.cc @@ -65,6 +65,7 @@ void OVERLAY_edit_grease_pencil_cache_init(OVERLAY_Data *vedata) OVERLAY_PrivateData *pd = vedata->stl->pd; const DRWContextState *draw_ctx = DRW_context_state_get(); const bool use_weight = (draw_ctx->object_mode & OB_MODE_WEIGHT_GREASE_PENCIL) != 0; + View3D *v3d = draw_ctx->v3d; GPUShader *sh; DRWShadingGroup *grp; @@ -96,6 +97,8 @@ void OVERLAY_edit_grease_pencil_cache_init(OVERLAY_Data *vedata) DRW_shgroup_uniform_bool_copy(grp, "useWeight", use_weight); DRW_shgroup_uniform_bool_copy(grp, "useGreasePencil", true); DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp); + const bool show_direction = (v3d->gp_flag & V3D_GP_SHOW_STROKE_DIRECTION) != 0; + DRW_shgroup_uniform_bool_copy(grp, "doStrokeEndpoints", show_direction); } else { pd->edit_grease_pencil_points_grp = nullptr; diff --git a/source/blender/draw/engines/overlay/overlay_next_curve.hh b/source/blender/draw/engines/overlay/overlay_next_curve.hh index 312c0650b7e..31d319dd0bb 100644 --- a/source/blender/draw/engines/overlay/overlay_next_curve.hh +++ b/source/blender/draw/engines/overlay/overlay_next_curve.hh @@ -91,6 +91,8 @@ class Curves { sub.bind_texture("weightTex", &res.weight_ramp_tx); sub.push_constant("useWeight", false); sub.push_constant("useGreasePencil", false); + sub.push_constant("doStrokeEndpoints", false); + sub.push_constant("curveHandleDisplay", int(state.overlay.handle_display)); edit_curves_points_ = ⊂ } } @@ -142,6 +144,8 @@ class Curves { sub.bind_ubo("globalsBlock", &res.globals_buf); sub.push_constant("showCurveHandles", state.overlay.handle_display != CURVE_HANDLE_NONE); sub.push_constant("curveHandleDisplay", int(state.overlay.handle_display)); + sub.push_constant("useGreasePencil", false); + sub.push_constant("doStrokeEndpoints", false); edit_legacy_curve_points_ = ⊂ } } diff --git a/source/blender/draw/engines/overlay/overlay_next_grease_pencil.hh b/source/blender/draw/engines/overlay/overlay_next_grease_pencil.hh index 079c07001eb..a335b032317 100644 --- a/source/blender/draw/engines/overlay/overlay_next_grease_pencil.hh +++ b/source/blender/draw/engines/overlay/overlay_next_grease_pencil.hh @@ -58,6 +58,7 @@ class GreasePencil { const bke::AttrDomain selection_domain_edit = ED_grease_pencil_edit_selection_domain_get(ts); const bool show_edit_point = selection_domain_edit == bke::AttrDomain::Point; const bool show_lines = (v3d->gp_flag & V3D_GP_SHOW_EDIT_LINES); + const bool show_direction = (v3d->gp_flag & V3D_GP_SHOW_STROKE_DIRECTION); show_points_ = show_lines_ = show_weight_ = false; @@ -106,6 +107,7 @@ class GreasePencil { sub.bind_texture("weightTex", &res.weight_ramp_tx); sub.push_constant("useWeight", show_weight_); sub.push_constant("useGreasePencil", true); + sub.push_constant("doStrokeEndpoints", show_direction); edit_points_ = ⊂ } diff --git a/source/blender/draw/engines/overlay/overlay_particle.cc b/source/blender/draw/engines/overlay/overlay_particle.cc index 3d684f9bcc3..ce1d3f4b9a6 100644 --- a/source/blender/draw/engines/overlay/overlay_particle.cc +++ b/source/blender/draw/engines/overlay/overlay_particle.cc @@ -49,6 +49,7 @@ void OVERLAY_edit_particle_cache_init(OVERLAY_Data *vedata) DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_bool_copy(grp, "useWeight", false); DRW_shgroup_uniform_bool_copy(grp, "useGreasePencil", false); + DRW_shgroup_uniform_bool_copy(grp, "doStrokeEndpoints", false); } void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob) diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh index d55c8cd7e12..b22afbca356 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh @@ -767,6 +767,11 @@ GPU_SHADER_CREATE_INFO(overlay_edit_particle_point) .push_constant(Type::BOOL, "useWeight") .push_constant(Type::BOOL, "useGreasePencil") .fragment_out(0, Type::VEC4, "fragColor") +#if 1 /* TODO(fclem): Required for legacy gpencil overlay. To be moved to specialized shader. */ + .typedef_source("overlay_shader_shared.h") + .vertex_in(3, Type::UINT, "vflag") + .push_constant(Type::BOOL, "doStrokeEndpoints") +#endif .vertex_source("overlay_edit_particle_point_vert.glsl") .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_mesh", "draw_globals"); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_point_vert.glsl index 236619a7669..de0f90cc0ed 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_point_vert.glsl @@ -26,6 +26,7 @@ void main() { vec3 world_pos = point_object_to_world(pos); gl_Position = point_world_to_ndc(world_pos); + float end_point_size_factor = 1.0f; if (useWeight) { finalColor = vec4(weight_to_rgb(selection), 1.0); @@ -33,10 +34,26 @@ void main() else { vec4 use_color = useGreasePencil ? colorGpencilVertexSelect : colorVertexSelect; finalColor = mix(colorWire, use_color, selection); + +#if 1 /* Should be checking CURVES_POINT */ + if (doStrokeEndpoints) { + bool is_stroke_start = (vflag & GP_EDIT_STROKE_START) != 0u; + bool is_stroke_end = (vflag & GP_EDIT_STROKE_END) != 0u; + + if (is_stroke_start) { + end_point_size_factor *= 2.0; + finalColor.rgb = vec3(0.0, 1.0, 0.0); + } + else if (is_stroke_end) { + end_point_size_factor *= 1.5; + finalColor.rgb = vec3(1.0, 0.0, 0.0); + } + } +#endif } float vsize = useGreasePencil ? sizeVertexGpencil : sizeVertex; - gl_PointSize = vsize * 2.0; + gl_PointSize = vsize * 2.0 * end_point_size_factor; view_clipping_distances(world_pos); } diff --git a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc index 5caf7a80136..16e15abc5d2 100644 --- a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc @@ -50,6 +50,8 @@ struct GreasePencilBatchCache { gpu::VertBuf *edit_points_pos; /* Selection of original points. */ gpu::VertBuf *edit_points_selection; + /* vflag of original points. */ + gpu::VertBuf *edit_points_vflag; /* Indices of visible points. */ gpu::IndexBuf *edit_points_indices; @@ -664,6 +666,14 @@ static void index_buf_add_bezier_line_points(Object &object, *r_drawing_start_offset += bezier_points.size() * 2; } +/* Still use legacy vflag for GPv3 for now due to common shader defines. */ +#define GREASE_PENCIL_EDIT_POINT_SELECTED (1 << 0) +#define GREASE_PENCIL_EDIT_STROKE_SELECTED (1 << 1) +#define GREASE_PENCIL_EDIT_MULTIFRAME (1 << 2) +#define GREASE_PENCIL_EDIT_STROKE_START (1 << 3) +#define GREASE_PENCIL_EDIT_STROKE_END (1 << 4) +#define GREASE_PENCIL_EDIT_POINT_DIMMED (1 << 5) + static void grease_pencil_edit_batch_ensure(Object &object, const GreasePencil &grease_pencil, const Scene &scene) @@ -702,6 +712,11 @@ static void grease_pencil_edit_batch_ensure(Object &object, &format_edit_points_selection, "selection", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); } + static GPUVertFormat format_edit_points_vflag = {0}; + if (format_edit_points_vflag.attr_len == 0) { + GPU_vertformat_attr_add(&format_edit_points_vflag, "vflag", GPU_COMP_U32, 1, GPU_FETCH_INT); + } + static GPUVertFormat format_edit_line_selection = {0}; if (format_edit_line_selection.attr_len == 0) { GPU_vertformat_attr_add( @@ -712,6 +727,7 @@ static void grease_pencil_edit_batch_ensure(Object &object, cache->edit_points_pos = GPU_vertbuf_create_with_format_ex(format_edit_points_pos, vbo_flag); cache->edit_points_selection = GPU_vertbuf_create_with_format_ex(format_edit_points_selection, vbo_flag); + cache->edit_points_vflag = GPU_vertbuf_create_with_format_ex(format_edit_points_vflag, vbo_flag); cache->edit_line_pos = GPU_vertbuf_create_with_format_ex(format_edit_line_pos, vbo_flag); cache->edit_line_selection = GPU_vertbuf_create_with_format_ex(format_edit_line_selection, vbo_flag); @@ -763,14 +779,17 @@ static void grease_pencil_edit_batch_ensure(Object &object, GPU_vertbuf_data_alloc(*cache->edit_points_pos, total_points_num); GPU_vertbuf_data_alloc(*cache->edit_points_selection, total_points_num); + GPU_vertbuf_data_alloc(*cache->edit_points_vflag, total_points_num); GPU_vertbuf_data_alloc(*cache->edit_line_pos, total_line_points_num); GPU_vertbuf_data_alloc(*cache->edit_line_selection, total_line_points_num); MutableSpan edit_points = cache->edit_points_pos->data(); MutableSpan edit_points_selection = cache->edit_points_selection->data(); + MutableSpan edit_points_vflag = cache->edit_points_vflag->data(); MutableSpan edit_line_points = cache->edit_line_pos->data(); MutableSpan edit_line_selection = cache->edit_line_selection->data(); edit_points_selection.fill(0.0f); + edit_points_vflag.fill(0); edit_line_selection.fill(0.0f); int visible_points_num = 0; @@ -808,6 +827,12 @@ static void grease_pencil_edit_batch_ensure(Object &object, positions_eval, range, layer_space_to_object_space, positions_eval_slice); }); + for (const int curve_i : points_by_curve_eval.index_range()) { + const IndexRange range = points_by_curve_eval[curve_i]; + edit_points_vflag[range.first()] |= GREASE_PENCIL_EDIT_STROKE_START; + edit_points_vflag[range.last()] |= GREASE_PENCIL_EDIT_STROKE_END; + } + /* Do not show selection for locked layers. */ if (!layer.is_locked()) { const IndexMask selected_editable_points = @@ -997,6 +1022,7 @@ static void grease_pencil_edit_batch_ensure(Object &object, cache->edit_points = GPU_batch_create( GPU_PRIM_POINTS, cache->edit_points_pos, cache->edit_points_indices); GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_selection, false); + GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_vflag, false); cache->edit_lines = GPU_batch_create( GPU_PRIM_LINE_STRIP, cache->edit_line_pos, cache->edit_line_indices); @@ -1007,6 +1033,7 @@ static void grease_pencil_edit_batch_ensure(Object &object, GPU_vertbuf_use(cache->edit_line_pos); GPU_vertbuf_use(cache->edit_points_selection); GPU_vertbuf_use(cache->edit_line_selection); + GPU_vertbuf_use(cache->edit_points_vflag); cache->is_dirty = false; }