diff options
Diffstat (limited to 'source/blender/draw')
25 files changed, 632 insertions, 3 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 540041ed02a..45a7e3410eb 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -201,6 +201,7 @@ set(SRC engines/overlay/overlay_sculpt.cc engines/overlay/overlay_sculpt_curves.cc engines/overlay/overlay_shader.cc + engines/overlay/overlay_viewer_attribute.cc engines/overlay/overlay_volume.cc engines/overlay/overlay_wireframe.cc @@ -645,12 +646,18 @@ set(GLSL_SRC engines/overlay/shaders/overlay_particle_vert.glsl engines/overlay/shaders/overlay_point_varying_color_frag.glsl engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl + engines/overlay/shaders/overlay_pointcloud_only_vert.glsl engines/overlay/shaders/overlay_sculpt_curves_selection_frag.glsl engines/overlay/shaders/overlay_sculpt_curves_selection_vert.glsl engines/overlay/shaders/overlay_sculpt_mask_frag.glsl engines/overlay/shaders/overlay_sculpt_mask_vert.glsl engines/overlay/shaders/overlay_uniform_color_frag.glsl engines/overlay/shaders/overlay_varying_color.glsl + engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl + engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl + engines/overlay/shaders/overlay_viewer_attribute_frag.glsl + engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl + engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl engines/overlay/shaders/overlay_volume_gridlines_vert.glsl engines/overlay/shaders/overlay_volume_velocity_vert.glsl engines/overlay/shaders/overlay_wireframe_frag.glsl diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index bbcae92561d..c2c4706138f 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -16,6 +16,7 @@ #include "UI_interface.h" +#include "BKE_duplilist.h" #include "BKE_object.h" #include "BKE_paint.h" @@ -204,6 +205,7 @@ static void OVERLAY_cache_init(void *vedata) } OVERLAY_antialiasing_cache_init(data); OVERLAY_armature_cache_init(data); + OVERLAY_viewer_attribute_cache_init(data); OVERLAY_background_cache_init(data); OVERLAY_fade_cache_init(data); OVERLAY_mode_transfer_cache_init(data); @@ -300,8 +302,12 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) } const DRWContextState *draw_ctx = DRW_context_state_get(); + DupliObject *dupli_object = DRW_object_get_dupli(ob); + Object *dupli_parent = DRW_object_get_dupli_parent(ob); const bool is_select = DRW_state_is_select(); const bool renderable = DRW_object_is_renderable(ob); + const bool is_preview = dupli_object != nullptr && + dupli_object->preview_base_geometry != nullptr; const bool in_pose_mode = ob->type == OB_ARMATURE && OVERLAY_armature_is_pose_mode(ob, draw_ctx); const bool in_edit_mode = overlay_object_is_edit_mode(pd, ob); const bool is_instance = (ob->base_flag & BASE_FROM_DUPLI); @@ -313,7 +319,8 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) (pd->ctx_mode == CTX_MODE_PARTICLE); const bool in_paint_mode = (ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT); - const bool in_sculpt_curve_mode = (ob == draw_ctx->obact) && + const bool in_sculpt_curve_mode = (ob == draw_ctx->obact || + (is_preview && dupli_parent == draw_ctx->obact)) && (draw_ctx->object_mode & OB_MODE_SCULPT_CURVES); const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != nullptr) && (ob->sculpt->mode_type == OB_MODE_SCULPT); @@ -374,6 +381,12 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) OVERLAY_pose_cache_populate(data, ob); } + if (pd->overlay.flag & V3D_OVERLAY_VIEWER_ATTRIBUTE) { + if (is_preview) { + OVERLAY_viewer_attribute_cache_populate(data, ob); + } + } + if (ob->type == OB_VOLUME) { OVERLAY_volume_cache_populate(data, ob); } @@ -627,6 +640,9 @@ static void OVERLAY_draw_scene(void *vedata) OVERLAY_metaball_draw(data); OVERLAY_gpencil_draw(data); OVERLAY_extra_draw(data); + if (pd->overlay.flag & V3D_OVERLAY_VIEWER_ATTRIBUTE) { + OVERLAY_viewer_attribute_draw(data); + } if (DRW_state_is_fbo()) { GPU_framebuffer_bind(fbl->overlay_color_only_fb); diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index 0a783c44029..b1118e084a6 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -61,6 +61,7 @@ typedef struct OVERLAY_PassList { DRWPass *armature_ps[2]; DRWPass *armature_bone_select_ps; DRWPass *armature_transp_ps[2]; + DRWPass *attribute_ps; DRWPass *background_ps; DRWPass *clipping_frustum_ps; DRWPass *edit_curve_wire_ps[2]; @@ -284,6 +285,12 @@ typedef struct OVERLAY_PrivateData { DRWShadingGroup *pointcloud_dots_grp; DRWShadingGroup *sculpt_mask_grp; DRWShadingGroup *sculpt_curves_selection_grp; + DRWShadingGroup *viewer_attribute_curve_grp; + DRWShadingGroup *viewer_attribute_curves_grp; + DRWShadingGroup *viewer_attribute_mesh_grp; + DRWShadingGroup *viewer_attribute_pointcloud_grp; + DRWShadingGroup *viewer_attribute_instance_grp; + DRWShadingGroup *viewer_attribute_instance_pointcloud_grp; DRWShadingGroup *volume_selection_surface_grp; DRWShadingGroup *wires_grp[2][2]; /* With and without coloring. */ DRWShadingGroup *wires_all_grp[2][2]; /* With and without coloring. */ @@ -678,6 +685,10 @@ void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata); void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *ob); void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata); +void OVERLAY_viewer_attribute_cache_init(OVERLAY_Data *vedata); +void OVERLAY_viewer_attribute_cache_populate(OVERLAY_Data *vedata, Object *object); +void OVERLAY_viewer_attribute_draw(OVERLAY_Data *vedata); + void OVERLAY_wireframe_init(OVERLAY_Data *vedata); void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata); void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata, @@ -745,6 +756,7 @@ GPUShader *OVERLAY_shader_image(void); GPUShader *OVERLAY_shader_motion_path_line(void); GPUShader *OVERLAY_shader_motion_path_vert(void); GPUShader *OVERLAY_shader_uniform_color(void); +GPUShader *OVERLAY_shader_uniform_color_pointcloud(void); GPUShader *OVERLAY_shader_outline_prepass(bool use_wire); GPUShader *OVERLAY_shader_outline_prepass_curves(void); GPUShader *OVERLAY_shader_outline_prepass_gpencil(void); @@ -761,6 +773,10 @@ GPUShader *OVERLAY_shader_particle_dot(void); GPUShader *OVERLAY_shader_particle_shape(void); GPUShader *OVERLAY_shader_sculpt_mask(void); GPUShader *OVERLAY_shader_sculpt_curves_selection(void); +GPUShader *OVERLAY_shader_viewer_attribute_curve(void); +GPUShader *OVERLAY_shader_viewer_attribute_curves(void); +GPUShader *OVERLAY_shader_viewer_attribute_mesh(void); +GPUShader *OVERLAY_shader_viewer_attribute_pointcloud(void); GPUShader *OVERLAY_shader_volume_velocity(bool use_needle, bool use_mac); GPUShader *OVERLAY_shader_volume_gridlines(bool color_with_flags, bool color_range); GPUShader *OVERLAY_shader_wireframe(bool custom_bias); diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index b0a6926a57f..b7e5e8c56b7 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -93,6 +93,11 @@ typedef struct OVERLAY_Shaders { GPUShader *sculpt_mask; GPUShader *sculpt_curves_selection; GPUShader *uniform_color; + GPUShader *uniform_color_pointcloud; + GPUShader *viewer_attribute_mesh; + GPUShader *viewer_attribute_pointcloud; + GPUShader *viewer_attribute_curve; + GPUShader *viewer_attribute_curves; GPUShader *volume_velocity_needle_sh; GPUShader *volume_velocity_mac_sh; GPUShader *volume_velocity_sh; @@ -818,6 +823,55 @@ GPUShader *OVERLAY_shader_sculpt_curves_selection(void) return sh_data->sculpt_curves_selection; } +GPUShader *OVERLAY_shader_viewer_attribute_mesh(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->viewer_attribute_mesh) { + sh_data->viewer_attribute_mesh = GPU_shader_create_from_info_name( + draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_mesh_clipped" : + "overlay_viewer_attribute_mesh"); + } + return sh_data->viewer_attribute_mesh; +} + +GPUShader *OVERLAY_shader_viewer_attribute_pointcloud(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->viewer_attribute_pointcloud) { + sh_data->viewer_attribute_pointcloud = GPU_shader_create_from_info_name( + draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? + "overlay_viewer_attribute_pointcloud_clipped" : + "overlay_viewer_attribute_pointcloud"); + } + return sh_data->viewer_attribute_pointcloud; +} + +GPUShader *OVERLAY_shader_viewer_attribute_curve(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->viewer_attribute_curve) { + sh_data->viewer_attribute_curve = GPU_shader_create_from_info_name( + draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_curve_clipped" : + "overlay_viewer_attribute_curve"); + } + return sh_data->viewer_attribute_curve; +} + +GPUShader *OVERLAY_shader_viewer_attribute_curves(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->viewer_attribute_curves) { + sh_data->viewer_attribute_curves = GPU_shader_create_from_info_name( + draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_curves_clipped" : + "overlay_viewer_attribute_curves"); + } + return sh_data->viewer_attribute_curves; +} + struct GPUShader *OVERLAY_shader_uniform_color(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -829,6 +883,18 @@ struct GPUShader *OVERLAY_shader_uniform_color(void) return sh_data->uniform_color; } +struct GPUShader *OVERLAY_shader_uniform_color_pointcloud() +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->uniform_color_pointcloud) { + sh_data->uniform_color_pointcloud = GPU_shader_create_from_info_name( + draw_ctx->sh_cfg ? "overlay_uniform_color_pointcloud_clipped" : + "overlay_uniform_color_pointcloud"); + } + return sh_data->uniform_color_pointcloud; +} + struct GPUShader *OVERLAY_shader_volume_velocity(bool use_needle, bool use_mac) { OVERLAY_Shaders *sh_data = &e_data.sh_data[0]; diff --git a/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc b/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc new file mode 100644 index 00000000000..7e1949c5261 --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup draw_engine + */ + +#include "DRW_render.h" + +#include "DNA_mesh_types.h" +#include "DNA_pointcloud_types.h" + +#include "BLI_math_vector.hh" +#include "BLI_span.hh" + +#include "GPU_batch.h" + +#include "BKE_attribute.hh" +#include "BKE_curves.hh" +#include "BKE_duplilist.h" +#include "BKE_geometry_set.hh" + +#include "draw_cache_extract.hh" +#include "draw_cache_impl.h" +#include "overlay_private.hh" + +void OVERLAY_viewer_attribute_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_LESS_EQUAL | + DRW_STATE_BLEND_ALPHA; + DRW_PASS_CREATE(psl->attribute_ps, state | pd->clipping_state); + + GPUShader *mesh_sh = OVERLAY_shader_viewer_attribute_mesh(); + GPUShader *pointcloud_sh = OVERLAY_shader_viewer_attribute_pointcloud(); + GPUShader *curve_sh = OVERLAY_shader_viewer_attribute_curve(); + GPUShader *curves_sh = OVERLAY_shader_viewer_attribute_curves(); + GPUShader *uniform_sh = OVERLAY_shader_uniform_color(); + GPUShader *uniform_pointcloud_sh = OVERLAY_shader_uniform_color_pointcloud(); + pd->viewer_attribute_mesh_grp = DRW_shgroup_create(mesh_sh, psl->attribute_ps); + pd->viewer_attribute_pointcloud_grp = DRW_shgroup_create(pointcloud_sh, psl->attribute_ps); + pd->viewer_attribute_curve_grp = DRW_shgroup_create(curve_sh, psl->attribute_ps); + pd->viewer_attribute_curves_grp = DRW_shgroup_create(curves_sh, psl->attribute_ps); + pd->viewer_attribute_instance_grp = DRW_shgroup_create(uniform_sh, psl->attribute_ps); + pd->viewer_attribute_instance_pointcloud_grp = DRW_shgroup_create(uniform_pointcloud_sh, + psl->attribute_ps); +} + +static void populate_cache_for_instance(Object &object, + OVERLAY_PrivateData &pd, + const DupliObject &dupli_object, + const float opacity) +{ + using namespace blender; + using namespace blender::bke; + + const GeometrySet &base_geometry = *dupli_object.preview_base_geometry; + const InstancesComponent &instances = + *base_geometry.get_component_for_read<InstancesComponent>(); + const AttributeAccessor instance_attributes = *instances.attributes(); + const VArray attribute = instance_attributes.lookup<ColorGeometry4f>(".viewer"); + if (!attribute) { + return; + } + ColorGeometry4f color = attribute.get(dupli_object.preview_instance_index); + color.a *= opacity; + switch (object.type) { + case OB_MESH: { + { + DRWShadingGroup *sub_grp = DRW_shgroup_create_sub(pd.viewer_attribute_instance_grp); + DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color); + GPUBatch *batch = DRW_cache_mesh_surface_get(&object); + DRW_shgroup_call(sub_grp, batch, &object); + } + if (GPUBatch *batch = DRW_cache_mesh_loose_edges_get(&object)) { + DRWShadingGroup *sub_grp = DRW_shgroup_create_sub(pd.viewer_attribute_instance_grp); + DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color); + DRW_shgroup_call(sub_grp, batch, &object); + } + break; + } + case OB_POINTCLOUD: { + DRWShadingGroup *sub_grp = DRW_shgroup_create_sub( + pd.viewer_attribute_instance_pointcloud_grp); + DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color); + GPUBatch *batch = DRW_cache_pointcloud_surface_get(&object); + DRW_shgroup_call_instance_range(sub_grp, &object, batch, 0, 0); + break; + } + case OB_CURVES_LEGACY: { + DRWShadingGroup *sub_grp = DRW_shgroup_create_sub(pd.viewer_attribute_instance_grp); + DRW_shgroup_uniform_vec4_copy(sub_grp, "ucolor", color); + GPUBatch *batch = DRW_cache_curve_edge_wire_get(&object); + DRW_shgroup_call(sub_grp, batch, &object); + break; + } + case OB_CURVES: { + /* Not supported yet because instances of this type are currently drawn as legacy curves. + */ + break; + } + } +} + +static void populate_cache_for_geometry(Object &object, + OVERLAY_PrivateData &pd, + const float opacity) +{ + using namespace blender; + using namespace blender::bke; + + switch (object.type) { + case OB_MESH: { + Mesh *mesh = static_cast<Mesh *>(object.data); + if (mesh->attributes().contains(".viewer")) { + GPUBatch *batch = DRW_cache_mesh_surface_viewer_attribute_get(&object); + DRW_shgroup_uniform_float_copy(pd.viewer_attribute_mesh_grp, "opacity", opacity); + DRW_shgroup_call(pd.viewer_attribute_mesh_grp, batch, &object); + } + break; + } + case OB_POINTCLOUD: { + PointCloud *pointcloud = static_cast<PointCloud *>(object.data); + if (pointcloud->attributes().contains(".viewer")) { + GPUBatch *batch = DRW_cache_pointcloud_surface_viewer_attribute_get(&object); + DRW_shgroup_uniform_float_copy(pd.viewer_attribute_pointcloud_grp, "opacity", opacity); + DRW_shgroup_call_instance_range(pd.viewer_attribute_pointcloud_grp, &object, batch, 0, 0); + } + break; + } + case OB_CURVES_LEGACY: { + Curve *curve = static_cast<Curve *>(object.data); + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curve->curve_eval->geometry); + if (curves.attributes().contains(".viewer")) { + GPUBatch *batch = DRW_cache_curve_edge_wire_viewer_attribute_get(&object); + DRW_shgroup_uniform_float_copy(pd.viewer_attribute_curve_grp, "opacity", opacity); + DRW_shgroup_call(pd.viewer_attribute_curve_grp, batch, &object); + } + break; + } + case OB_CURVES: { + Curves *curves_id = static_cast<Curves *>(object.data); + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + if (curves.attributes().contains(".viewer")) { + bool is_point_domain; + GPUTexture **texture = DRW_curves_texture_for_evaluated_attribute( + curves_id, ".viewer", &is_point_domain); + DRWShadingGroup *grp = DRW_shgroup_curves_create_sub( + &object, pd.viewer_attribute_curves_grp, nullptr); + DRW_shgroup_uniform_float_copy(pd.viewer_attribute_curves_grp, "opacity", opacity); + DRW_shgroup_uniform_bool_copy(grp, "is_point_domain", is_point_domain); + DRW_shgroup_uniform_texture(grp, "color_tx", *texture); + } + break; + } + } +} + +void OVERLAY_viewer_attribute_cache_populate(OVERLAY_Data *vedata, Object *object) +{ + OVERLAY_PrivateData *pd = vedata->stl->pd; + const float opacity = vedata->stl->pd->overlay.viewer_attribute_opacity; + DupliObject *dupli_object = DRW_object_get_dupli(object); + + if (dupli_object->preview_instance_index >= 0) { + const InstancesComponent &instances = + *dupli_object->preview_base_geometry->get_component_for_read<InstancesComponent>(); + if (instances.attributes()->contains(".viewer")) { + populate_cache_for_instance(*object, *pd, *dupli_object, opacity); + return; + } + } + populate_cache_for_geometry(*object, *pd, opacity); +} + +void OVERLAY_viewer_attribute_draw(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + DRW_draw_pass(psl->attribute_ps); +} 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 8c9c943393f..40b7249a997 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 @@ -587,8 +587,20 @@ GPU_SHADER_CREATE_INFO(overlay_uniform_color) .fragment_source("overlay_uniform_color_frag.glsl") .additional_info("draw_mesh"); +GPU_SHADER_CREATE_INFO(overlay_uniform_color_pointcloud) + .do_static_compilation(true) + .push_constant(Type::VEC4, "ucolor") + .fragment_out(0, Type::VEC4, "fragColor") + .vertex_source("overlay_pointcloud_only_vert.glsl") + .fragment_source("overlay_uniform_color_frag.glsl") + .additional_info("draw_pointcloud"); + GPU_SHADER_CREATE_INFO(overlay_uniform_color_clipped) .do_static_compilation(true) .additional_info("overlay_depth_only", "drw_clipped"); +GPU_SHADER_CREATE_INFO(overlay_uniform_color_pointcloud_clipped) + .do_static_compilation(true) + .additional_info("overlay_uniform_color_pointcloud", "drw_clipped"); + /** \} */ diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh new file mode 100644 index 00000000000..aca80992622 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_viewer_attribute_info.hh @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_INTERFACE_INFO(overlay_viewer_attribute_iface, "").smooth(Type::VEC4, "finalColor"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_common).push_constant(Type::FLOAT, "opacity"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_mesh) + .do_static_compilation(true) + .vertex_source("overlay_viewer_attribute_mesh_vert.glsl") + .fragment_source("overlay_viewer_attribute_frag.glsl") + .fragment_out(0, Type::VEC4, "out_color") + .vertex_in(0, Type::VEC3, "pos") + .vertex_in(1, Type::VEC4, "attribute_value") + .vertex_out(overlay_viewer_attribute_iface) + .additional_info("overlay_viewer_attribute_common", "draw_mesh"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_mesh_clipped) + .do_static_compilation(true) + .additional_info("overlay_viewer_attribute_mesh", "drw_clipped"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_pointcloud) + .do_static_compilation(true) + .vertex_source("overlay_viewer_attribute_pointcloud_vert.glsl") + .fragment_source("overlay_viewer_attribute_frag.glsl") + .fragment_out(0, Type::VEC4, "out_color") + .vertex_in(3, Type::VEC4, "attribute_value") + .vertex_out(overlay_viewer_attribute_iface) + .additional_info("overlay_viewer_attribute_common", "draw_pointcloud"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_pointcloud_clipped) + .do_static_compilation(true) + .additional_info("overlay_viewer_attribute_pointcloud", "drw_clipped"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curve) + .do_static_compilation(true) + .vertex_source("overlay_viewer_attribute_curve_vert.glsl") + .fragment_source("overlay_viewer_attribute_frag.glsl") + .fragment_out(0, Type::VEC4, "out_color") + .vertex_in(0, Type::VEC3, "pos") + .vertex_in(1, Type::VEC4, "attribute_value") + .vertex_out(overlay_viewer_attribute_iface) + .additional_info("overlay_viewer_attribute_common", "draw_modelmat", "draw_resource_id"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curve_clipped) + .do_static_compilation(true) + .additional_info("overlay_viewer_attribute_curve", "drw_clipped"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curves) + .do_static_compilation(true) + .vertex_source("overlay_viewer_attribute_curves_vert.glsl") + .fragment_source("overlay_viewer_attribute_frag.glsl") + .fragment_out(0, Type::VEC4, "out_color") + .sampler(0, ImageType::FLOAT_BUFFER, "color_tx") + .push_constant(Type::BOOL, "is_point_domain") + .vertex_out(overlay_viewer_attribute_iface) + .additional_info("overlay_viewer_attribute_common", "draw_hair"); + +GPU_SHADER_CREATE_INFO(overlay_viewer_attribute_curves_clipped) + .do_static_compilation(true) + .additional_info("overlay_viewer_attribute_curves", "drw_clipped"); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_pointcloud_only_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_pointcloud_only_vert.glsl new file mode 100644 index 00000000000..8a7e81028d3 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_pointcloud_only_vert.glsl @@ -0,0 +1,9 @@ +#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl) + +void main() +{ + vec3 world_pos = pointcloud_get_pos(); + gl_Position = point_world_to_ndc(world_pos); +} diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl new file mode 100644 index 00000000000..7c2c386b2f5 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curve_vert.glsl @@ -0,0 +1,9 @@ +#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +void main() +{ + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + finalColor = attribute_value; +} diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl new file mode 100644 index 00000000000..23d313e036f --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_curves_vert.glsl @@ -0,0 +1,28 @@ +#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_hair_lib.glsl) + +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); + + if (is_point_domain) { + finalColor = texelFetch(color_tx, hair_get_base_id()); + } + else { + finalColor = texelFetch(color_tx, hair_get_strand_id()); + } +} diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_frag.glsl new file mode 100644 index 00000000000..6176a6b96ba --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_frag.glsl @@ -0,0 +1,6 @@ + +void main() +{ + out_color = finalColor; + out_color.a *= opacity; +} diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl new file mode 100644 index 00000000000..7c2c386b2f5 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_mesh_vert.glsl @@ -0,0 +1,9 @@ +#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +void main() +{ + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + finalColor = attribute_value; +} diff --git a/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl new file mode 100644 index 00000000000..e706e8f9033 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_viewer_attribute_pointcloud_vert.glsl @@ -0,0 +1,10 @@ +#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl) + +void main() +{ + vec3 world_pos = pointcloud_get_pos(); + gl_Position = point_world_to_ndc(world_pos); + finalColor = attribute_value; +} diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 6537490c06c..6da22039c2f 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2889,6 +2889,12 @@ GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob) return DRW_mesh_batch_cache_get_edit_mesh_analysis(ob->data); } +GPUBatch *DRW_cache_mesh_surface_viewer_attribute_get(Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + return DRW_mesh_batch_cache_get_surface_viewer_attribute(ob->data); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -2902,6 +2908,13 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob) return DRW_curve_batch_cache_get_wire_edge(cu); } +GPUBatch *DRW_cache_curve_edge_wire_viewer_attribute_get(Object *ob) +{ + BLI_assert(ob->type == OB_CURVES_LEGACY); + struct Curve *cu = ob->data; + return DRW_curve_batch_cache_get_wire_edge_viewer_attribute(cu); +} + GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob) { BLI_assert(ob->type == OB_CURVES_LEGACY); @@ -3005,6 +3018,12 @@ GPUBatch *DRW_cache_pointcloud_surface_get(Object *object) return DRW_pointcloud_batch_cache_get_surface(object); } +GPUBatch *DRW_cache_pointcloud_surface_viewer_attribute_get(Object *object) +{ + BLI_assert(object->type == OB_POINTCLOUD); + return DRW_pointcloud_batch_cache_get_surface_viewer_attribute(object); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 4e8788ada08..058f28f094d 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -170,10 +170,12 @@ struct GPUBatch *DRW_cache_mesh_surface_sculptcolors_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_surface_viewer_attribute_get(struct Object *ob); /* Curve */ struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob); +struct GPUBatch *DRW_cache_curve_edge_wire_viewer_attribute_get(struct Object *ob); /* edit-mode */ @@ -226,6 +228,7 @@ struct GPUBatch *DRW_cache_curves_edge_detection_get(struct Object *ob, bool *r_ struct GPUBatch *DRW_cache_pointcloud_get_dots(struct Object *obj); struct GPUBatch *DRW_cache_pointcloud_surface_get(struct Object *obj); +struct GPUBatch *DRW_cache_pointcloud_surface_viewer_attribute_get(struct Object *obj); /* Volume */ diff --git a/source/blender/draw/intern/draw_cache_extract.hh b/source/blender/draw/intern/draw_cache_extract.hh index 203da22406c..6f4a652ce24 100644 --- a/source/blender/draw/intern/draw_cache_extract.hh +++ b/source/blender/draw/intern/draw_cache_extract.hh @@ -130,6 +130,7 @@ struct MeshBufferList { GPUVertBuf *poly_idx; GPUVertBuf *fdot_idx; GPUVertBuf *attr[GPU_MAX_ATTR]; + GPUVertBuf *attr_viewer; } vbo; /* Index Buffers: * Only need to be updated when topology changes. */ @@ -191,6 +192,7 @@ struct MeshBatchList { /* Same as wire_loops but only has uvs. */ GPUBatch *wire_loops_uvs; GPUBatch *sculpt_overlays; + GPUBatch *surface_viewer_attribute; }; #define MBC_BATCH_LEN (sizeof(MeshBatchList) / sizeof(void *)) @@ -228,6 +230,7 @@ enum DRWBatchFlag { MBC_WIRE_LOOPS = (1u << MBC_BATCH_INDEX(wire_loops)), MBC_WIRE_LOOPS_UVS = (1u << MBC_BATCH_INDEX(wire_loops_uvs)), MBC_SCULPT_OVERLAYS = (1u << MBC_BATCH_INDEX(sculpt_overlays)), + MBC_VIEWER_ATTRIBUTE_OVERLAY = (1u << MBC_BATCH_INDEX(surface_viewer_attribute)), MBC_SURFACE_PER_MAT = (1u << MBC_BATCH_LEN), }; ENUM_OPERATORS(DRWBatchFlag, MBC_SURFACE_PER_MAT); diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index fd00059bac6..d3170f4c776 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -640,6 +640,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph, for (int i = 0; i < GPU_MAX_ATTR; i++) { EXTRACT_ADD_REQUESTED(vbo, attr[i]); } + EXTRACT_ADD_REQUESTED(vbo, attr_viewer); EXTRACT_ADD_REQUESTED(ibo, tris); if (DRW_ibo_requested(mbuflist->ibo.lines_loose)) { diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 7f7d0a7613f..89432b0da83 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -100,6 +100,7 @@ void DRW_curve_batch_cache_create_requested(struct Object *ob, const struct Scen int DRW_curve_material_count_get(struct Curve *cu); struct GPUBatch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu); +struct GPUBatch *DRW_curve_batch_cache_get_wire_edge_viewer_attribute(struct Curve *cu); struct GPUBatch *DRW_curve_batch_cache_get_normal_edge(struct Curve *cu); struct GPUBatch *DRW_curve_batch_cache_get_edit_edges(struct Curve *cu); struct GPUBatch *DRW_curve_batch_cache_get_edit_verts(struct Curve *cu); @@ -148,6 +149,7 @@ int DRW_pointcloud_material_count_get(struct PointCloud *pointcloud); struct GPUBatch *DRW_pointcloud_batch_cache_get_dots(struct Object *ob); struct GPUBatch *DRW_pointcloud_batch_cache_get_surface(struct Object *ob); +struct GPUBatch *DRW_pointcloud_batch_cache_get_surface_viewer_attribute(struct Object *ob); struct GPUBatch **DRW_cache_pointcloud_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); @@ -198,6 +200,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(struct Object *objec struct GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(struct Object *object, struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_surface_weights(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_sculpt_overlays(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_surface_viewer_attribute(struct Mesh *me); /** \} */ diff --git a/source/blender/draw/intern/draw_cache_impl_curve.cc b/source/blender/draw/intern/draw_cache_impl_curve.cc index 695c348d8e2..6188b1e0544 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.cc +++ b/source/blender/draw/intern/draw_cache_impl_curve.cc @@ -10,6 +10,7 @@ #include "MEM_guardedalloc.h" #include "BLI_array.hh" +#include "BLI_color.hh" #include "BLI_listbase.h" #include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" @@ -38,6 +39,7 @@ #include "draw_cache_impl.h" /* own include */ using blender::Array; +using blender::ColorGeometry4f; using blender::float3; using blender::IndexRange; using blender::Span; @@ -296,6 +298,7 @@ static int curve_render_data_normal_len_get(const CurveRenderData *rdata) struct CurveBatchCache { struct { GPUVertBuf *curves_pos; + GPUVertBuf *attr_viewer; } ordered; struct { @@ -314,6 +317,7 @@ struct CurveBatchCache { struct { GPUBatch *curves; + GPUBatch *curves_viewer_attribute; /* control handles and vertices */ GPUBatch *edit_edges; GPUBatch *edit_verts; @@ -474,6 +478,31 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv GPU_vertbuf_attr_fill(vbo_curves_pos, attr_id.pos, positions.data()); } +static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr) +{ + if (rdata->curve_eval == nullptr) { + return; + } + + static GPUVertFormat format = {0}; + if (format.attr_len == 0) { + GPU_vertformat_attr_add(&format, "attribute_value", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + } + + const int vert_len = curve_render_data_wire_verts_len_get(rdata); + GPU_vertbuf_init_with_format(vbo_attr, &format); + GPU_vertbuf_data_alloc(vbo_attr, vert_len); + + const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( + rdata->curve_eval->geometry); + curves.ensure_can_interpolate_to_evaluated(); + const blender::VArraySpan<ColorGeometry4f> colors = curves.attributes().lookup<ColorGeometry4f>( + ".viewer", ATTR_DOMAIN_POINT); + ColorGeometry4f *vbo_data = static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(vbo_attr)); + curves.interpolate_to_evaluated(colors, + blender::MutableSpan<ColorGeometry4f>{vbo_data, vert_len}); +} + static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines) { if (rdata->curve_eval == nullptr) { @@ -769,6 +798,12 @@ GPUBatch *DRW_curve_batch_cache_get_wire_edge(Curve *cu) return DRW_batch_request(&cache->batch.curves); } +GPUBatch *DRW_curve_batch_cache_get_wire_edge_viewer_attribute(Curve *cu) +{ + CurveBatchCache *cache = curve_batch_cache_get(cu); + return DRW_batch_request(&cache->batch.curves_viewer_attribute); +} + GPUBatch *DRW_curve_batch_cache_get_normal_edge(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); @@ -810,6 +845,11 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen DRW_ibo_request(cache->batch.curves, &cache->ibo.curves_lines); DRW_vbo_request(cache->batch.curves, &cache->ordered.curves_pos); } + if (DRW_batch_requested(cache->batch.curves_viewer_attribute, GPU_PRIM_LINE_STRIP)) { + DRW_ibo_request(cache->batch.curves_viewer_attribute, &cache->ibo.curves_lines); + DRW_vbo_request(cache->batch.curves_viewer_attribute, &cache->ordered.curves_pos); + DRW_vbo_request(cache->batch.curves_viewer_attribute, &cache->ordered.attr_viewer); + } /* Edit mode */ if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) { @@ -833,6 +873,8 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen /* Generate MeshRenderData flags */ int mr_flag = 0; DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.curves_pos, CU_DATATYPE_WIRE); + DRW_ADD_FLAG_FROM_VBO_REQUEST( + mr_flag, cache->ordered.attr_viewer, CU_DATATYPE_WIRE | CU_DATATYPE_OVERLAY); DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.curves_lines, CU_DATATYPE_WIRE); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.pos, CU_DATATYPE_OVERLAY); @@ -851,6 +893,9 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen if (DRW_vbo_requested(cache->ordered.curves_pos)) { curve_create_curves_pos(rdata, cache->ordered.curves_pos); } + if (DRW_vbo_requested(cache->ordered.attr_viewer)) { + curve_create_attribute(rdata, cache->ordered.attr_viewer); + } if (DRW_ibo_requested(cache->ibo.curves_lines)) { curve_create_curves_lines(rdata, cache->ibo.curves_lines); } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index c22382b3e09..ed78cbbda39 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -104,7 +104,8 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index) MBC_EDIT_EDGES | MBC_EDIT_VNOR | MBC_EDIT_LNOR | MBC_EDIT_MESH_ANALYSIS | MBC_EDIT_SELECTION_VERTS | MBC_EDIT_SELECTION_EDGES | MBC_EDIT_SELECTION_FACES | MBC_ALL_VERTS | MBC_ALL_EDGES | MBC_LOOSE_EDGES | MBC_EDGE_DETECTION | - MBC_WIRE_EDGES | MBC_WIRE_LOOPS | MBC_SCULPT_OVERLAYS | MBC_SURFACE_PER_MAT; + MBC_WIRE_EDGES | MBC_WIRE_LOOPS | MBC_SCULPT_OVERLAYS | MBC_VIEWER_ATTRIBUTE_OVERLAY | + MBC_SURFACE_PER_MAT; case BUFFER_INDEX(vbo.lnor): return MBC_SURFACE | MBC_EDIT_LNOR | MBC_WIRE_LOOPS | MBC_SURFACE_PER_MAT; case BUFFER_INDEX(vbo.edge_fac): @@ -166,9 +167,12 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index) case BUFFER_INDEX(vbo.attr[13]): case BUFFER_INDEX(vbo.attr[14]): return MBC_SURFACE | MBC_SURFACE_PER_MAT; + case BUFFER_INDEX(vbo.attr_viewer): + return MBC_VIEWER_ATTRIBUTE_OVERLAY; case BUFFER_INDEX(ibo.tris): return MBC_SURFACE | MBC_SURFACE_WEIGHTS | MBC_EDIT_TRIANGLES | MBC_EDIT_LNOR | - MBC_EDIT_MESH_ANALYSIS | MBC_EDIT_SELECTION_FACES | MBC_SCULPT_OVERLAYS; + MBC_EDIT_MESH_ANALYSIS | MBC_EDIT_SELECTION_FACES | MBC_SCULPT_OVERLAYS | + MBC_VIEWER_ATTRIBUTE_OVERLAY; case BUFFER_INDEX(ibo.lines): return MBC_EDIT_EDGES | MBC_EDIT_SELECTION_EDGES | MBC_ALL_EDGES | MBC_WIRE_EDGES; case BUFFER_INDEX(ibo.lines_loose): @@ -1057,6 +1061,16 @@ GPUBatch *DRW_mesh_batch_cache_get_sculpt_overlays(Mesh *me) return cache->batch.sculpt_overlays; } +GPUBatch *DRW_mesh_batch_cache_get_surface_viewer_attribute(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + + mesh_batch_cache_add_request(cache, MBC_VIEWER_ATTRIBUTE_OVERLAY); + DRW_batch_request(&cache->batch.surface_viewer_attribute); + + return cache->batch.surface_viewer_attribute; +} + /** \} */ /* ---------------------------------------------------------------------- */ @@ -1802,6 +1816,14 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, DRW_vbo_request(cache->batch.edituv_fdots, &mbuflist->vbo.fdots_uv); DRW_vbo_request(cache->batch.edituv_fdots, &mbuflist->vbo.fdots_edituv_data); } + assert_deps_valid( + MBC_VIEWER_ATTRIBUTE_OVERLAY, + {BUFFER_INDEX(ibo.tris), BUFFER_INDEX(vbo.pos_nor), BUFFER_INDEX(vbo.attr_viewer)}); + if (DRW_batch_requested(cache->batch.surface_viewer_attribute, GPU_PRIM_TRIS)) { + DRW_ibo_request(cache->batch.surface_viewer_attribute, &mbuflist->ibo.tris); + DRW_vbo_request(cache->batch.surface_viewer_attribute, &mbuflist->vbo.pos_nor); + DRW_vbo_request(cache->batch.surface_viewer_attribute, &mbuflist->vbo.attr_viewer); + } #ifdef DEBUG auto assert_final_deps_valid = [&](const int buffer_index) { @@ -1833,6 +1855,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, for (const int i : IndexRange(GPU_MAX_ATTR)) { assert_final_deps_valid(BUFFER_INDEX(vbo.attr[i])); } + assert_final_deps_valid(BUFFER_INDEX(vbo.attr_viewer)); assert_final_deps_valid(BUFFER_INDEX(ibo.tris)); assert_final_deps_valid(BUFFER_INDEX(ibo.lines)); diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc index a43b23c8969..72be5b37652 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc @@ -32,11 +32,13 @@ struct PointCloudBatchCache { GPUVertBuf *pos; /* Position and radius. */ GPUVertBuf *geom; /* Instanced geometry for each point in the cloud (small sphere). */ + GPUVertBuf *attr_viewer; GPUIndexBuf *geom_indices; GPUBatch *dots; GPUBatch *surface; GPUBatch **surface_per_mat; + GPUBatch *surface_viewer_attribute; /* settings to determine if cache is invalid */ bool is_dirty; @@ -109,6 +111,7 @@ static void pointcloud_batch_cache_clear(PointCloud &pointcloud) GPU_BATCH_DISCARD_SAFE(cache->surface); GPU_VERTBUF_DISCARD_SAFE(cache->pos); GPU_VERTBUF_DISCARD_SAFE(cache->geom); + GPU_VERTBUF_DISCARD_SAFE(cache->attr_viewer); GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices); if (cache->surface_per_mat) { @@ -116,6 +119,7 @@ static void pointcloud_batch_cache_clear(PointCloud &pointcloud) GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]); } } + GPU_BATCH_DISCARD_SAFE(cache->surface_viewer_attribute); MEM_SAFE_FREE(cache->surface_per_mat); } @@ -227,6 +231,30 @@ static void pointcloud_batch_cache_ensure_geom(PointCloudBatchCache &cache) cache.geom_indices = GPU_indexbuf_build(&builder); } +static void pointcloud_batch_cache_ensure_attribute_overlay(const PointCloud &pointcloud, + PointCloudBatchCache &cache) +{ + using namespace blender; + if (cache.attr_viewer != nullptr) { + return; + } + + const bke::AttributeAccessor attributes = pointcloud.attributes(); + const VArray<ColorGeometry4f> colors = attributes.lookup_or_default<ColorGeometry4f>( + ".viewer", ATTR_DOMAIN_POINT, {1.0f, 0.0f, 1.0f, 1.0f}); + + static GPUVertFormat format = {0}; + if (format.attr_len == 0) { + GPU_vertformat_attr_add(&format, "attribute_value", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + } + cache.attr_viewer = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(cache.attr_viewer, pointcloud.totpoint); + MutableSpan<ColorGeometry4f> vbo_data{ + static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(cache.attr_viewer)), + pointcloud.totpoint}; + colors.materialize(vbo_data); +} + GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob) { PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data); @@ -256,6 +284,25 @@ GPUBatch *DRW_pointcloud_batch_cache_get_surface(Object *ob) return cache->surface; } +GPUBatch *DRW_pointcloud_batch_cache_get_surface_viewer_attribute(Object *ob) +{ + PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data); + PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud); + + if (cache->surface_viewer_attribute == nullptr) { + pointcloud_batch_cache_ensure_pos(pointcloud, *cache); + pointcloud_batch_cache_ensure_geom(*cache); + pointcloud_batch_cache_ensure_attribute_overlay(pointcloud, *cache); + + cache->surface_viewer_attribute = GPU_batch_create( + GPU_PRIM_TRIS, cache->geom, cache->geom_indices); + GPU_batch_instbuf_add_ex(cache->surface_viewer_attribute, cache->attr_viewer, false); + GPU_batch_instbuf_add_ex(cache->surface_viewer_attribute, cache->pos, false); + } + + return cache->surface_viewer_attribute; +} + GPUBatch **DRW_cache_pointcloud_surface_shaded_get(Object *ob, struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 51762e29506..99f75581a47 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -38,6 +38,7 @@ #include "BKE_pointcloud.h" #include "BKE_screen.h" #include "BKE_subdiv_modifier.h" +#include "BKE_viewer_path.h" #include "BKE_volume.h" #include "DNA_camera_types.h" @@ -1695,6 +1696,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, DEGObjectIterSettings deg_iter_settings = {0}; deg_iter_settings.depsgraph = depsgraph; deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS; + if (v3d->flag2 & V3D_SHOW_VIEWER) { + deg_iter_settings.viewer_path = &v3d->viewer_path; + } DEG_OBJECT_ITER_BEGIN (°_iter_settings, ob) { if ((object_type_exclude_viewport & (1 << ob->type)) != 0) { continue; @@ -2497,6 +2501,9 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, DEGObjectIterSettings deg_iter_settings = {0}; deg_iter_settings.depsgraph = depsgraph; deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS; + if (v3d->flag2 & V3D_SHOW_VIEWER) { + deg_iter_settings.viewer_path = &v3d->viewer_path; + } DEG_OBJECT_ITER_BEGIN (°_iter_settings, ob) { if (!BKE_object_is_visible_in_viewport(v3d, ob)) { continue; @@ -2662,6 +2669,9 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph, DEGObjectIterSettings deg_iter_settings = {0}; deg_iter_settings.depsgraph = DST.draw_ctx.depsgraph; deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS; + if (v3d->flag2 & V3D_SHOW_VIEWER) { + deg_iter_settings.viewer_path = &v3d->viewer_path; + } DEG_OBJECT_ITER_BEGIN (°_iter_settings, ob) { if ((object_type_exclude_viewport & (1 << ob->type)) != 0) { continue; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index 0bce05577b2..d9bb8d1d2b4 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -440,3 +440,4 @@ extern const MeshExtract extract_edge_idx; extern const MeshExtract extract_vert_idx; extern const MeshExtract extract_fdot_idx; extern const MeshExtract extract_attr[GPU_MAX_ATTR]; +extern const MeshExtract extract_attr_viewer; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index 240e9b4fa60..c602b768df9 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -14,6 +14,8 @@ #include "BLI_string.h" #include "BKE_attribute.h" +#include "BKE_attribute.hh" +#include "BKE_mesh.h" #include "draw_attributes.h" #include "draw_subdivision.h" @@ -432,6 +434,40 @@ constexpr MeshExtract create_extractor_attr(ExtractInitFn fn, ExtractInitSubdivF return extractor; } +static void extract_mesh_attr_viewer_init(const MeshRenderData *mr, + MeshBatchCache *UNUSED(cache), + void *buf, + void *UNUSED(tls_data)) +{ + GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf); + static GPUVertFormat format = {0}; + if (format.attr_len == 0) { + GPU_vertformat_attr_add(&format, "attribute_value", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + } + + GPU_vertbuf_init_with_format(vbo, &format); + GPU_vertbuf_data_alloc(vbo, mr->loop_len); + MutableSpan<ColorGeometry4f> attr{static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(vbo)), + mr->loop_len}; + + const StringRefNull attr_name = ".viewer"; + const bke::AttributeAccessor attributes = mr->me->attributes(); + attributes + .lookup_or_default<ColorGeometry4f>(attr_name, ATTR_DOMAIN_CORNER, {1.0f, 0.0f, 1.0f, 1.0f}) + .materialize(attr); +} + +constexpr MeshExtract create_extractor_attr_viewer() +{ + MeshExtract extractor = {nullptr}; + extractor.init = extract_mesh_attr_viewer_init; + extractor.data_type = MR_DATA_NONE; + extractor.data_size = 0; + extractor.use_threading = false; + extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.attr_viewer); + return extractor; +} + /** \} */ } // namespace blender::draw @@ -457,3 +493,5 @@ const MeshExtract extract_attr[GPU_MAX_ATTR] = { CREATE_EXTRACTOR_ATTR(13), CREATE_EXTRACTOR_ATTR(14), }; + +const MeshExtract extract_attr_viewer = blender::draw::create_extractor_attr_viewer(); diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index dc631483857..f238c7e25b1 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -254,6 +254,7 @@ static void test_overlay_glsl_shaders() EXPECT_NE(OVERLAY_shader_motion_path_line(), nullptr); EXPECT_NE(OVERLAY_shader_motion_path_vert(), nullptr); EXPECT_NE(OVERLAY_shader_uniform_color(), nullptr); + EXPECT_NE(OVERLAY_shader_uniform_color_pointcloud(), nullptr); EXPECT_NE(OVERLAY_shader_outline_prepass(false), nullptr); EXPECT_NE(OVERLAY_shader_outline_prepass(true), nullptr); EXPECT_NE(OVERLAY_shader_outline_prepass_curves(), nullptr); @@ -272,6 +273,10 @@ static void test_overlay_glsl_shaders() EXPECT_NE(OVERLAY_shader_particle_shape(), nullptr); EXPECT_NE(OVERLAY_shader_sculpt_mask(), nullptr); EXPECT_NE(OVERLAY_shader_sculpt_curves_selection(), nullptr); + EXPECT_NE(OVERLAY_shader_viewer_attribute_curve(), nullptr); + EXPECT_NE(OVERLAY_shader_viewer_attribute_curves(), nullptr); + EXPECT_NE(OVERLAY_shader_viewer_attribute_mesh(), nullptr); + EXPECT_NE(OVERLAY_shader_viewer_attribute_pointcloud(), nullptr); EXPECT_NE(OVERLAY_shader_volume_velocity(false, false), nullptr); EXPECT_NE(OVERLAY_shader_volume_velocity(false, true), nullptr); EXPECT_NE(OVERLAY_shader_volume_velocity(true, false), nullptr); |