Changeset View
Standalone View
source/blender/draw/engines/overlay/overlay_sculpt_curves.cc
- This file was added.
| /* SPDX-License-Identifier: GPL-2.0-or-later | |||||
| * Copyright 2022 Blender Foundation. */ | |||||
jbakker: Should be 2022 | |||||
| /** \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( | |||||
Done Inline ActionsWhy would you split the request and the actual texture getter? You can make DRW_curves_request_attribute a static and not expose it. fclem: Why would you split the request and the actual texture getter? You can make… | |||||
| 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) { | |||||
Done Inline ActionsCan we perform this before creating the sub group. The subgroup creation would already add a draw call what would then still draw, On AMD cards this could lead to drawing artifacts as all samplers must be bound, otherwise it can read from uninitialized memory. We often load a dummy texture in this case. jbakker: Can we perform this before creating the sub group. The subgroup creation would already add a… | |||||
Done Inline ActionsI switched the order. It required using a GPUTexture ** because the texture isn't created until DRW_shgroup_curves_create_sub runs. But hopefully this still accomplishes what you're talking about. HooglyBoogly: I switched the order. It required using a `GPUTexture **` because the texture isn't created… | |||||
| 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()) { | |||||
Done Inline ActionsThis will draw on the linear buffer. Normally for overlays we select the overlay framebuffers this will apply the effect in sRGB space what is more what the user expects (perceptual color spaces) jbakker: This will draw on the linear buffer. Normally for overlays we select the overlay framebuffers… | |||||
Done Inline ActionsHere I just copied the mesh sculpt mode overlay. Shouldn't they be consistent? HooglyBoogly: Here I just copied the mesh sculpt mode overlay. Shouldn't they be consistent?
I'm not sure… | |||||
Done Inline ActionsActually this problem is also present in the sculpt overlay which was duplicated here. I think we need to use fbl->overlay_in_front_fb / fbl->overlay_default_fb. The reason sculpt overlay did not use them is because it needed the color to be overlay color to be multiplied on top of the render. But here, in this case, since we only use grey scale, we can use black alpha blending on top of the overlay fb to make the selection visible. fclem: Actually this problem is also present in the sculpt overlay which was duplicated here. I think… | |||||
| GPU_framebuffer_bind(pd->painting.in_front ? fbl->overlay_in_front_fb : | |||||
| fbl->overlay_default_fb); | |||||
| } | |||||
| DRW_draw_pass(psl->sculpt_curves_selection_ps); | |||||
| } | |||||
Should be 2022