Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/overlay/overlay_viewer_attribute.cc
- This file was added.
| /* 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) { | |||||
HooglyBoogly: Looking up the viewer attribute by name for every instance seems expensive. Do you have an idea… | |||||
Done Inline ActionsWell, long term we should just pass all the instances to the renderer in one go. We could probably cache the value on the DupliObject somehow but doesn't seem worth it right now. JacquesLucke: Well, long term we should just pass all the instances to the renderer in one go. We could… | |||||
| return; | |||||
Not Done Inline ActionsReturn early HooglyBoogly: Return early | |||||
| } | |||||
| 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); | |||||
Done Inline ActionsWould be preferable to use const pointers here where possible HooglyBoogly: Would be preferable to use const pointers here where possible | |||||
Done Inline ActionsNot sure which pointer you refer to exactly, but curves_id can't be const right now because DRW_curves_texture_for_evaluated_attribute takes a non const Curves. JacquesLucke: Not sure which pointer you refer to exactly, but `curves_id` can't be const right now because… | |||||
| 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); | |||||
| } | |||||
Looking up the viewer attribute by name for every instance seems expensive. Do you have an idea of how to improve this? Even if it isn't part of this patch.