Changeset View
Standalone View
source/blender/draw/intern/draw_cache_impl_curves.cc
| Show All 17 Lines | |||||||||||||||
| #include "BLI_span.hh" | #include "BLI_span.hh" | ||||||||||||||
| #include "BLI_task.hh" | #include "BLI_task.hh" | ||||||||||||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||||||||||||
| #include "DNA_curves_types.h" | #include "DNA_curves_types.h" | ||||||||||||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||||||||||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||||||||||||
| #include "DEG_depsgraph_query.h" | |||||||||||||||
| #include "BKE_curves.hh" | #include "BKE_curves.hh" | ||||||||||||||
| #include "BKE_geometry_set.hh" | #include "BKE_geometry_set.hh" | ||||||||||||||
| #include "GPU_batch.h" | #include "GPU_batch.h" | ||||||||||||||
| #include "GPU_material.h" | #include "GPU_material.h" | ||||||||||||||
| #include "GPU_texture.h" | #include "GPU_texture.h" | ||||||||||||||
| #include "DRW_render.h" | #include "DRW_render.h" | ||||||||||||||
| ▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | static void curves_discard_attributes(CurvesEvalCache &curves_cache) | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache) | static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache) | ||||||||||||||
| { | { | ||||||||||||||
| /* TODO: more granular update tagging. */ | /* TODO: more granular update tagging. */ | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.edit_pos); | |||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.data_edit_points); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.data_edit_points); | ||||||||||||||
| DRW_TEXTURE_FREE_SAFE(curves_cache.point_tex); | DRW_TEXTURE_FREE_SAFE(curves_cache.point_tex); | ||||||||||||||
| DRW_TEXTURE_FREE_SAFE(curves_cache.length_tex); | DRW_TEXTURE_FREE_SAFE(curves_cache.length_tex); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf); | ||||||||||||||
| DRW_TEXTURE_FREE_SAFE(curves_cache.strand_tex); | DRW_TEXTURE_FREE_SAFE(curves_cache.strand_tex); | ||||||||||||||
| DRW_TEXTURE_FREE_SAFE(curves_cache.strand_seg_tex); | DRW_TEXTURE_FREE_SAFE(curves_cache.strand_seg_tex); | ||||||||||||||
| ▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | |||||||||||||||
| static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, | static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, | ||||||||||||||
| CurvesEvalCache &cache, | CurvesEvalCache &cache, | ||||||||||||||
| GPUMaterial *gpu_material) | GPUMaterial *gpu_material) | ||||||||||||||
| { | { | ||||||||||||||
| if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) { | if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) { | ||||||||||||||
| /* Initialize vertex format. */ | /* Initialize vertex format. */ | ||||||||||||||
| GPUVertFormat format = {0}; | GPUVertFormat format = {0}; | ||||||||||||||
| GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); | GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); | ||||||||||||||
| GPU_vertformat_alias_add(&format, "pos"); | |||||||||||||||
| cache.proc_point_buf = GPU_vertbuf_create_with_format_ex( | cache.proc_point_buf = GPU_vertbuf_create_with_format_ex( | ||||||||||||||
| &format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); | &format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); | ||||||||||||||
| GPU_vertbuf_data_alloc(cache.proc_point_buf, cache.point_len); | GPU_vertbuf_data_alloc(cache.proc_point_buf, cache.point_len); | ||||||||||||||
| MutableSpan posTime_data{ | MutableSpan posTime_data{ | ||||||||||||||
| static_cast<PositionAndParameter *>(GPU_vertbuf_get_data(cache.proc_point_buf)), | static_cast<PositionAndParameter *>(GPU_vertbuf_get_data(cache.proc_point_buf)), | ||||||||||||||
| cache.point_len}; | cache.point_len}; | ||||||||||||||
| Show All 22 Lines | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &gpu_attrs) { | ||||||||||||||
| GPU_vertbuf_use(cache.proc_length_buf); | GPU_vertbuf_use(cache.proc_length_buf); | ||||||||||||||
| cache.length_tex = GPU_texture_create_from_vertbuf("hair_length", cache.proc_length_buf); | cache.length_tex = GPU_texture_create_from_vertbuf("hair_length", cache.proc_length_buf); | ||||||||||||||
| break; | break; | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| static void curves_batch_cache_ensure_edit_pos(const Curves &curves_id, | |||||||||||||||
| CurvesEvalCache &cache) | |||||||||||||||
HooglyBoogly: clang format | |||||||||||||||
| { | |||||||||||||||
| using namespace blender; | |||||||||||||||
| const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | |||||||||||||||
| static GPUVertFormat format_pos = {0}; | |||||||||||||||
| uint pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); | |||||||||||||||
| GPU_vertbuf_init_with_format(cache.edit_pos, &format_pos); | |||||||||||||||
| GPU_vertbuf_data_alloc(cache.edit_pos, curves.points_num()); | |||||||||||||||
| Span<float3> positions = curves.positions(); | |||||||||||||||
| for (const int point_i : positions.index_range()) { | |||||||||||||||
| GPU_vertbuf_attr_set(cache.edit_pos, pos, point_i, positions[point_i]); | |||||||||||||||
| } | |||||||||||||||
HooglyBooglyUnsubmitted Not Done Inline Actions
A simple copy is more obvious here and should be faster. HooglyBoogly: A simple copy is more obvious here and should be faster. | |||||||||||||||
| } | |||||||||||||||
| static void curves_batch_cache_ensure_data_edit_points(const Curves &curves_id, | static void curves_batch_cache_ensure_data_edit_points(const Curves &curves_id, | ||||||||||||||
| CurvesEvalCache &cache) | CurvesEvalCache &cache) | ||||||||||||||
| { | { | ||||||||||||||
| using namespace blender; | using namespace blender; | ||||||||||||||
| const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | ||||||||||||||
| static GPUVertFormat format_data = {0}; | static GPUVertFormat format_data = {0}; | ||||||||||||||
| uint data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); | uint data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); | ||||||||||||||
| GPU_vertbuf_init_with_format(cache.data_edit_points, &format_data); | GPU_vertbuf_init_with_format(cache.data_edit_points, &format_data); | ||||||||||||||
| GPU_vertbuf_data_alloc(cache.data_edit_points, curves.points_num()); | GPU_vertbuf_data_alloc(cache.data_edit_points, curves.points_num()); | ||||||||||||||
| VArray<float> selection; | VArray<float> selection; | ||||||||||||||
| switch (curves_id.selection_domain) { | switch (curves_id.selection_domain) { | ||||||||||||||
| case ATTR_DOMAIN_POINT: | case ATTR_DOMAIN_POINT: | ||||||||||||||
| selection = curves.selection_point_float(); | selection = curves.selection_point_float(); | ||||||||||||||
| for (const int point_i : selection.index_range()) { | for (const int point_i : selection.index_range()) { | ||||||||||||||
| uint8_t vflag = 0; | uint8_t vflag = 0; | ||||||||||||||
| const float point_selection = selection[point_i]; | const float point_selection = selection[point_i]; | ||||||||||||||
| SET_FLAG_FROM_TEST(vflag, (point_selection > 0.0f), VFLAG_VERT_SELECTED); | SET_FLAG_FROM_TEST(vflag, (point_selection > 0.0f), VFLAG_VERT_SELECTED); | ||||||||||||||
| GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag); | GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag); | ||||||||||||||
Not Done Inline ActionsI'd expect GPU_vertbuf_attr_fill to work fine here. Faster and simpler than setting the data per-element in a loop. HooglyBoogly: I'd expect `GPU_vertbuf_attr_fill` to work fine here. Faster and simpler than setting the data… | |||||||||||||||
| } | } | ||||||||||||||
Not Done Inline ActionsThese aren't really flags anymore are they? HooglyBoogly: These aren't really flags anymore are they?
Do we really have to upload a float for every point… | |||||||||||||||
Done Inline ActionsWill rename that function. Regarding the float: it is not deal, but the patch is now reusing the old particle line/point shaders (and these used a float to be able to show the weight gradient on the lines). We could get it back to just a flag, just dont think there is an existing shader that is capable of both selection and segment highlighting -- we would have to add one I think. lichtwerk: Will rename that function.
Regarding the float: it is not deal, but the patch is now reusing… | |||||||||||||||
Not Done Inline ActionsOkay, that will be much easier to change when the particle system is gone then. It's probably not worth adding a new shader right now. HooglyBoogly: Okay, that will be much easier to change when the particle system is gone then. It's probably… | |||||||||||||||
| break; | break; | ||||||||||||||
| case ATTR_DOMAIN_CURVE: | case ATTR_DOMAIN_CURVE: | ||||||||||||||
| selection = curves.selection_curve_float(); | selection = curves.selection_curve_float(); | ||||||||||||||
| for (const int curve_i : curves.curves_range()) { | for (const int curve_i : curves.curves_range()) { | ||||||||||||||
| uint8_t vflag = 0; | uint8_t vflag = 0; | ||||||||||||||
| const float curve_selection = selection[curve_i]; | const float curve_selection = selection[curve_i]; | ||||||||||||||
| SET_FLAG_FROM_TEST(vflag, (curve_selection > 0.0f), VFLAG_VERT_SELECTED); | SET_FLAG_FROM_TEST(vflag, (curve_selection > 0.0f), VFLAG_VERT_SELECTED); | ||||||||||||||
| const IndexRange points = curves.points_for_curve(curve_i); | const IndexRange points = curves.points_for_curve(curve_i); | ||||||||||||||
| ▲ Show 20 Lines • Show All 387 Lines • ▼ Show 20 Lines | default: | ||||||||||||||
| BLI_assert_unreachable(); | BLI_assert_unreachable(); | ||||||||||||||
| return nullptr; | return nullptr; | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| void DRW_curves_batch_cache_create_requested(Object *ob) | void DRW_curves_batch_cache_create_requested(Object *ob) | ||||||||||||||
| { | { | ||||||||||||||
| Curves *curves = static_cast<Curves *>(ob->data); | Curves *curves = static_cast<Curves *>(ob->data); | ||||||||||||||
| Object *orig = DEG_get_original_object(ob); | |||||||||||||||
HooglyBooglyUnsubmitted Not Done Inline ActionsWould DEG_get_original_id(curves) make more sense, since it's the original curves data-block we're drawing? HooglyBoogly: Would `DEG_get_original_id(curves)` make more sense, since it's the original curves data-block… | |||||||||||||||
lichtwerkAuthorUnsubmitted Not Done Inline ActionsHm, the object ID has an orig_id and is LIB_TAG_COPIED_ON_WRITE whereas the curves ID does not have an orig_id and is not LIB_TAG_COPIED_ON_WRITE Bit on shaky ground, will dig deeper... So, no, until further notice this would not work... lichtwerk: Hm, the object ID has an `orig_id` and is `LIB_TAG_COPIED_ON_WRITE` whereas the curves ID does… | |||||||||||||||
HooglyBooglyUnsubmitted Done Inline ActionsOh, I think this might make sense. The evaluated curves might be totally new (e.g. created from geometry nodes), so it won't have the "orig ID" pointer. But the object should, at least in most cases. So just ignore this comment :) HooglyBoogly: Oh, I think this might make sense. The evaluated curves might be totally new (e.g. created from… | |||||||||||||||
| Curves *curves_orig = static_cast<Curves *>(orig->data); | |||||||||||||||
| CurvesBatchCache &cache = curves_batch_cache_get(*curves); | CurvesBatchCache &cache = curves_batch_cache_get(*curves); | ||||||||||||||
| if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { | if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { | ||||||||||||||
| DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf); | DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf); | ||||||||||||||
| DRW_vbo_request(cache.edit_points, &cache.curves_cache.edit_pos); | |||||||||||||||
| DRW_vbo_request(cache.edit_points, &cache.curves_cache.data_edit_points); | DRW_vbo_request(cache.edit_points, &cache.curves_cache.data_edit_points); | ||||||||||||||
| } | } | ||||||||||||||
| if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) { | if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) { | ||||||||||||||
| curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr); | curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr); | ||||||||||||||
| } | } | ||||||||||||||
| if (DRW_vbo_requested(cache.curves_cache.edit_pos)) { | |||||||||||||||
| curves_batch_cache_ensure_edit_pos(*curves_orig, cache.curves_cache); | |||||||||||||||
| } | |||||||||||||||
| if (DRW_vbo_requested(cache.curves_cache.data_edit_points)) { | if (DRW_vbo_requested(cache.curves_cache.data_edit_points)) { | ||||||||||||||
| curves_batch_cache_ensure_data_edit_points(*curves, cache.curves_cache); | curves_batch_cache_ensure_data_edit_points(*curves_orig, cache.curves_cache); | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
clang format