diff options
Diffstat (limited to 'source/blender/draw/engines/overlay/overlay_sculpt_curves.cc')
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_sculpt_curves.cc | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc new file mode 100644 index 00000000000..b8021124f27 --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +/** \file + * \ingroup draw_engine + */ + +#include "DRW_render.h" + +#include "draw_cache_impl.h" +#include "overlay_private.h" + +#include "BKE_curves.hh" + +void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + OVERLAY_PrivateData *pd = vedata->stl->pd; + + const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA; + DRW_PASS_CREATE(psl->sculpt_curves_selection_ps, state | pd->clipping_state); + + GPUShader *sh = OVERLAY_shader_sculpt_curves_selection(); + pd->sculpt_curves_selection_grp = DRW_shgroup_create(sh, psl->sculpt_curves_selection_ps); + DRWShadingGroup *grp = pd->sculpt_curves_selection_grp; + + /* Reuse the same mask opacity from sculpt mode, since it wasn't worth it to add a different + * property yet. */ + DRW_shgroup_uniform_float_copy(grp, "selection_opacity", pd->overlay.sculpt_mode_mask_opacity); +} + +static bool everything_selected(const Curves &curves_id) +{ + if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { + /* When the selection is disabled, conceptually everything is selected. */ + return true; + } + const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( + curves_id.geometry); + blender::VArray<float> selection; + switch (curves_id.selection_domain) { + case ATTR_DOMAIN_POINT: + selection = curves.selection_point_float(); + break; + case ATTR_DOMAIN_CURVE: + selection = curves.selection_curve_float(); + break; + } + return selection.is_single() && selection.get_internal_single() == 1.0f; +} + +void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object) +{ + OVERLAY_PrivateData *pd = vedata->stl->pd; + Curves *curves = static_cast<Curves *>(object->data); + + /* As an optimization, return early if everything is selected. */ + if (everything_selected(*curves)) { + return; + } + + /* Retrieve the location of the texture. */ + const char *name = curves->selection_domain == ATTR_DOMAIN_POINT ? ".selection_point_float" : + ".selection_curve_float"; + + bool is_point_domain; + GPUTexture **texture = DRW_curves_texture_for_evaluated_attribute( + curves, name, &is_point_domain); + if (texture == nullptr) { + return; + } + + /* Evaluate curves and their attributes if necessary. */ + DRWShadingGroup *grp = DRW_shgroup_curves_create_sub( + object, pd->sculpt_curves_selection_grp, nullptr); + if (*texture == nullptr) { + return; + } + + DRW_shgroup_uniform_bool_copy(grp, "is_point_domain", is_point_domain); + DRW_shgroup_uniform_texture(grp, "selection_tx", *texture); +} + +void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + OVERLAY_PrivateData *pd = vedata->stl->pd; + OVERLAY_FramebufferList *fbl = vedata->fbl; + + if (DRW_state_is_fbo()) { + GPU_framebuffer_bind(pd->painting.in_front ? fbl->overlay_in_front_fb : + fbl->overlay_default_fb); + } + + DRW_draw_pass(psl->sculpt_curves_selection_ps); +} |