From 8466fd4bd1fe0f07b272e6d54b0b3404448a92b4 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 30 Mar 2022 18:25:06 -0500 Subject: Cleanup: Curves draw cache renaming, use references Also change some remaining cases of "hair object" to "curves object". --- .../blender/draw/intern/draw_cache_impl_curves.cc | 243 ++++++++++----------- source/blender/draw/intern/draw_hair.c | 8 +- source/blender/draw/intern/draw_hair_private.h | 10 +- 3 files changed, 128 insertions(+), 133 deletions(-) (limited to 'source/blender/draw/intern') diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index a21a6409ca5..0b8913402e6 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -4,7 +4,7 @@ /** \file * \ingroup draw * - * \brief Hair API for render engines + * \brief Curves API for render engines */ #include @@ -35,33 +35,29 @@ using blender::float3; using blender::IndexRange; using blender::Span; -static void curves_batch_cache_clear(Curves *curves); - /* ---------------------------------------------------------------------- */ -/* Hair GPUBatch Cache */ +/* Curves GPUBatch Cache */ -struct HairBatchCache { +struct CurvesBatchCache { ParticleHairCache hair; - /* settings to determine if cache is invalid */ + /* To determine if cache is invalid. */ bool is_dirty; }; -/* GPUBatch cache management. */ - -static bool curves_batch_cache_valid(Curves *curves) +static bool curves_batch_cache_valid(const Curves &curves) { - HairBatchCache *cache = static_cast(curves->batch_cache); + const CurvesBatchCache *cache = static_cast(curves.batch_cache); return (cache && cache->is_dirty == false); } -static void curves_batch_cache_init(Curves *curves) +static void curves_batch_cache_init(Curves &curves) { - HairBatchCache *cache = static_cast(curves->batch_cache); + CurvesBatchCache *cache = static_cast(curves.batch_cache); if (!cache) { - cache = MEM_cnew(__func__); - curves->batch_cache = cache; + cache = MEM_cnew(__func__); + curves.batch_cache = cache; } else { memset(cache, 0, sizeof(*cache)); @@ -70,23 +66,33 @@ static void curves_batch_cache_init(Curves *curves) cache->is_dirty = false; } +static void curves_batch_cache_clear(Curves &curves) +{ + CurvesBatchCache *cache = static_cast(curves.batch_cache); + if (!cache) { + return; + } + + particle_batch_cache_clear_hair(&cache->hair); +} + void DRW_curves_batch_cache_validate(Curves *curves) { - if (!curves_batch_cache_valid(curves)) { - curves_batch_cache_clear(curves); - curves_batch_cache_init(curves); + if (!curves_batch_cache_valid(*curves)) { + curves_batch_cache_clear(*curves); + curves_batch_cache_init(*curves); } } -static HairBatchCache *curves_batch_cache_get(Curves *curves) +static CurvesBatchCache &curves_batch_cache_get(Curves &curves) { - DRW_curves_batch_cache_validate(curves); - return static_cast(curves->batch_cache); + DRW_curves_batch_cache_validate(&curves); + return *static_cast(curves.batch_cache); } void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode) { - HairBatchCache *cache = static_cast(curves->batch_cache); + CurvesBatchCache *cache = static_cast(curves->batch_cache); if (cache == nullptr) { return; } @@ -99,52 +105,42 @@ void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode) } } -static void curves_batch_cache_clear(Curves *curves) -{ - HairBatchCache *cache = static_cast(curves->batch_cache); - if (!cache) { - return; - } - - particle_batch_cache_clear_hair(&cache->hair); -} - void DRW_curves_batch_cache_free(Curves *curves) { - curves_batch_cache_clear(curves); + curves_batch_cache_clear(*curves); MEM_SAFE_FREE(curves->batch_cache); } -static void ensure_seg_pt_count(Curves *curves, ParticleHairCache *curves_cache) +static void ensure_seg_pt_count(const Curves &curves, ParticleHairCache &curves_cache) { - if ((curves_cache->pos != nullptr && curves_cache->indices != nullptr) || - (curves_cache->proc_point_buf != nullptr)) { + if ((curves_cache.pos != nullptr && curves_cache.indices != nullptr) || + (curves_cache.proc_point_buf != nullptr)) { return; } - curves_cache->strands_len = curves->geometry.curve_size; - curves_cache->elems_len = curves->geometry.point_size + curves->geometry.curve_size; - curves_cache->point_len = curves->geometry.point_size; + curves_cache.strands_len = curves.geometry.curve_size; + curves_cache.elems_len = curves.geometry.point_size + curves.geometry.curve_size; + curves_cache.point_len = curves.geometry.point_size; } -static void curves_batch_cache_fill_segments_proc_pos(Curves *curves, - GPUVertBufRaw *attr_step, - GPUVertBufRaw *length_step) +static void curves_batch_cache_fill_segments_proc_pos(const Curves &curves_id, + GPUVertBufRaw &attr_step, + GPUVertBufRaw &length_step) { /* TODO: use hair radius layer if available. */ - const int curve_size = curves->geometry.curve_size; - const blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap( - curves->geometry); - Span positions = geometry.positions(); + const int curve_size = curves_id.geometry.curve_size; + const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( + curves_id.geometry); + Span positions = curves.positions(); for (const int i : IndexRange(curve_size)) { - const IndexRange curve_range = geometry.points_for_curve(i); + const IndexRange curve_range = curves.points_for_curve(i); Span curve_positions = positions.slice(curve_range); float total_len = 0.0f; float *seg_data_first; for (const int i_curve : curve_positions.index_range()) { - float *seg_data = (float *)GPU_vertbuf_raw_step(attr_step); + float *seg_data = (float *)GPU_vertbuf_raw_step(&attr_step); copy_v3_v3(seg_data, curve_positions[i_curve]); if (i_curve == 0) { seg_data_first = seg_data; @@ -156,7 +152,7 @@ static void curves_batch_cache_fill_segments_proc_pos(Curves *curves, seg_data[3] = total_len; } /* Assign length value. */ - *(float *)GPU_vertbuf_raw_step(length_step) = total_len; + *(float *)GPU_vertbuf_raw_step(&length_step) = total_len; if (total_len > 0.0f) { /* Divide by total length to have a [0-1] number. */ for ([[maybe_unused]] const int i_curve : curve_positions.index_range()) { @@ -167,67 +163,67 @@ static void curves_batch_cache_fill_segments_proc_pos(Curves *curves, } } -static void curves_batch_cache_ensure_procedural_pos(Curves *curves, - ParticleHairCache *cache, +static void curves_batch_cache_ensure_procedural_pos(Curves &curves, + ParticleHairCache &cache, GPUMaterial *gpu_material) { - if (cache->proc_point_buf == nullptr) { - /* initialize vertex format */ + if (cache.proc_point_buf == nullptr) { + /* Initialize vertex format. */ GPUVertFormat format = {0}; uint pos_id = GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - cache->proc_point_buf = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(cache->proc_point_buf, cache->point_len); + cache.proc_point_buf = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(cache.proc_point_buf, cache.point_len); GPUVertBufRaw point_step; - GPU_vertbuf_attr_get_raw_data(cache->proc_point_buf, pos_id, &point_step); + GPU_vertbuf_attr_get_raw_data(cache.proc_point_buf, pos_id, &point_step); GPUVertFormat length_format = {0}; uint length_id = GPU_vertformat_attr_add( &length_format, "hairLength", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - cache->proc_length_buf = GPU_vertbuf_create_with_format(&length_format); - GPU_vertbuf_data_alloc(cache->proc_length_buf, cache->strands_len); + cache.proc_length_buf = GPU_vertbuf_create_with_format(&length_format); + GPU_vertbuf_data_alloc(cache.proc_length_buf, cache.strands_len); GPUVertBufRaw length_step; - GPU_vertbuf_attr_get_raw_data(cache->proc_length_buf, length_id, &length_step); + GPU_vertbuf_attr_get_raw_data(cache.proc_length_buf, length_id, &length_step); - curves_batch_cache_fill_segments_proc_pos(curves, &point_step, &length_step); + curves_batch_cache_fill_segments_proc_pos(curves, point_step, length_step); /* Create vbo immediately to bind to texture buffer. */ - GPU_vertbuf_use(cache->proc_point_buf); - cache->point_tex = GPU_texture_create_from_vertbuf("hair_point", cache->proc_point_buf); + GPU_vertbuf_use(cache.proc_point_buf); + cache.point_tex = GPU_texture_create_from_vertbuf("hair_point", cache.proc_point_buf); } - if (gpu_material && cache->proc_length_buf != nullptr && cache->length_tex) { + if (gpu_material && cache.proc_length_buf != nullptr && cache.length_tex) { ListBase gpu_attrs = GPU_material_attributes(gpu_material); LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &gpu_attrs) { if (attr->type == CD_HAIRLENGTH) { - GPU_vertbuf_use(cache->proc_length_buf); - cache->length_tex = GPU_texture_create_from_vertbuf("hair_length", 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); break; } } } } -static void curves_batch_cache_fill_strands_data(Curves *curves, - GPUVertBufRaw *data_step, - GPUVertBufRaw *seg_step) +static void curves_batch_cache_fill_strands_data(const Curves &curves_id, + GPUVertBufRaw &data_step, + GPUVertBufRaw &seg_step) { - const blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap( - curves->geometry); + const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( + curves_id.geometry); - for (const int i : IndexRange(geometry.curves_num())) { - const IndexRange curve_range = geometry.points_for_curve(i); + for (const int i : IndexRange(curves.curves_num())) { + const IndexRange curve_range = curves.points_for_curve(i); - *(uint *)GPU_vertbuf_raw_step(data_step) = curve_range.start(); - *(ushort *)GPU_vertbuf_raw_step(seg_step) = curve_range.size() - 1; + *(uint *)GPU_vertbuf_raw_step(&data_step) = curve_range.start(); + *(ushort *)GPU_vertbuf_raw_step(&seg_step) = curve_range.size() - 1; } } -static void curves_batch_cache_ensure_procedural_strand_data(Curves *curves, - ParticleHairCache *cache) +static void curves_batch_cache_ensure_procedural_strand_data(Curves &curves, + ParticleHairCache &cache) { GPUVertBufRaw data_step, seg_step; @@ -237,77 +233,76 @@ static void curves_batch_cache_ensure_procedural_strand_data(Curves *curves, GPUVertFormat format_seg = {0}; uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U16, 1, GPU_FETCH_INT); - /* Strand Data */ - cache->proc_strand_buf = GPU_vertbuf_create_with_format(&format_data); - GPU_vertbuf_data_alloc(cache->proc_strand_buf, cache->strands_len); - GPU_vertbuf_attr_get_raw_data(cache->proc_strand_buf, data_id, &data_step); + /* Curve Data. */ + cache.proc_strand_buf = GPU_vertbuf_create_with_format(&format_data); + GPU_vertbuf_data_alloc(cache.proc_strand_buf, cache.strands_len); + GPU_vertbuf_attr_get_raw_data(cache.proc_strand_buf, data_id, &data_step); - cache->proc_strand_seg_buf = GPU_vertbuf_create_with_format(&format_seg); - GPU_vertbuf_data_alloc(cache->proc_strand_seg_buf, cache->strands_len); - GPU_vertbuf_attr_get_raw_data(cache->proc_strand_seg_buf, seg_id, &seg_step); + cache.proc_strand_seg_buf = GPU_vertbuf_create_with_format(&format_seg); + GPU_vertbuf_data_alloc(cache.proc_strand_seg_buf, cache.strands_len); + GPU_vertbuf_attr_get_raw_data(cache.proc_strand_seg_buf, seg_id, &seg_step); - curves_batch_cache_fill_strands_data(curves, &data_step, &seg_step); + curves_batch_cache_fill_strands_data(curves, data_step, seg_step); /* Create vbo immediately to bind to texture buffer. */ - GPU_vertbuf_use(cache->proc_strand_buf); - cache->strand_tex = GPU_texture_create_from_vertbuf("curves_strand", cache->proc_strand_buf); + GPU_vertbuf_use(cache.proc_strand_buf); + cache.strand_tex = GPU_texture_create_from_vertbuf("curves_strand", cache.proc_strand_buf); - GPU_vertbuf_use(cache->proc_strand_seg_buf); - cache->strand_seg_tex = GPU_texture_create_from_vertbuf("curves_strand_seg", - cache->proc_strand_seg_buf); + GPU_vertbuf_use(cache.proc_strand_seg_buf); + cache.strand_seg_tex = GPU_texture_create_from_vertbuf("curves_strand_seg", + cache.proc_strand_seg_buf); } -static void curves_batch_cache_ensure_procedural_final_points(ParticleHairCache *cache, int subdiv) +static void curves_batch_cache_ensure_procedural_final_points(ParticleHairCache &cache, int subdiv) { /* Same format as point_tex. */ GPUVertFormat format = {0}; GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - cache->final[subdiv].proc_buf = GPU_vertbuf_create_with_format_ex(&format, - GPU_USAGE_DEVICE_ONLY); + cache.final[subdiv].proc_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DEVICE_ONLY); /* Create a destination buffer for the transform feedback. Sized appropriately */ /* Those are points! not line segments. */ - GPU_vertbuf_data_alloc(cache->final[subdiv].proc_buf, - cache->final[subdiv].strands_res * cache->strands_len); + GPU_vertbuf_data_alloc(cache.final[subdiv].proc_buf, + cache.final[subdiv].strands_res * cache.strands_len); /* Create vbo immediately to bind to texture buffer. */ - GPU_vertbuf_use(cache->final[subdiv].proc_buf); + GPU_vertbuf_use(cache.final[subdiv].proc_buf); - cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf("hair_proc", - cache->final[subdiv].proc_buf); + cache.final[subdiv].proc_tex = GPU_texture_create_from_vertbuf("hair_proc", + cache.final[subdiv].proc_buf); } -static void curves_batch_cache_fill_segments_indices(Curves *curves, +static void curves_batch_cache_fill_segments_indices(const Curves &curves, const int res, - GPUIndexBufBuilder *elb) + GPUIndexBufBuilder &elb) { - const int curve_size = curves->geometry.curve_size; + const int curves_num = curves.geometry.curve_size; uint curr_point = 0; - for ([[maybe_unused]] const int i : IndexRange(curve_size)) { + for ([[maybe_unused]] const int i : IndexRange(curves_num)) { for (int k = 0; k < res; k++) { - GPU_indexbuf_add_generic_vert(elb, curr_point++); + GPU_indexbuf_add_generic_vert(&elb, curr_point++); } - GPU_indexbuf_add_primitive_restart(elb); + GPU_indexbuf_add_primitive_restart(&elb); } } -static void curves_batch_cache_ensure_procedural_indices(Curves *curves, - ParticleHairCache *cache, - int thickness_res, - int subdiv) +static void curves_batch_cache_ensure_procedural_indices(Curves &curves, + ParticleHairCache &cache, + const int thickness_res, + const int subdiv) { BLI_assert(thickness_res <= MAX_THICKRES); /* Cylinder strip not currently supported. */ - if (cache->final[subdiv].proc_hairs[thickness_res - 1] != nullptr) { + if (cache.final[subdiv].proc_hairs[thickness_res - 1] != nullptr) { return; } - int verts_per_hair = cache->final[subdiv].strands_res * thickness_res; + int verts_per_curve = cache.final[subdiv].strands_res * thickness_res; /* +1 for primitive restart */ - int element_count = (verts_per_hair + 1) * cache->strands_len; + int element_count = (verts_per_curve + 1) * cache.strands_len; GPUPrimType prim_type = (thickness_res == 1) ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP; static GPUVertFormat format = {0}; @@ -322,46 +317,46 @@ static void curves_batch_cache_ensure_procedural_indices(Curves *curves, GPUIndexBufBuilder elb; GPU_indexbuf_init_ex(&elb, prim_type, element_count, element_count); - curves_batch_cache_fill_segments_indices(curves, verts_per_hair, &elb); + curves_batch_cache_fill_segments_indices(curves, verts_per_curve, elb); - cache->final[subdiv].proc_hairs[thickness_res - 1] = GPU_batch_create_ex( + cache.final[subdiv].proc_hairs[thickness_res - 1] = GPU_batch_create_ex( prim_type, vbo, GPU_indexbuf_build(&elb), GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); } -bool hair_ensure_procedural_data(Object *object, - ParticleHairCache **r_hair_cache, - GPUMaterial *gpu_material, - int subdiv, - int thickness_res) +bool curves_ensure_procedural_data(Object *object, + ParticleHairCache **r_hair_cache, + GPUMaterial *gpu_material, + const int subdiv, + const int thickness_res) { bool need_ft_update = false; - Curves *curves = static_cast(object->data); + Curves &curves = *static_cast(object->data); - HairBatchCache *cache = curves_batch_cache_get(curves); - *r_hair_cache = &cache->hair; + CurvesBatchCache &cache = curves_batch_cache_get(curves); + *r_hair_cache = &cache.hair; const int steps = 3; /* TODO: don't hard-code? */ (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv); /* Refreshed on combing and simulation. */ if ((*r_hair_cache)->proc_point_buf == nullptr) { - ensure_seg_pt_count(curves, &cache->hair); - curves_batch_cache_ensure_procedural_pos(curves, &cache->hair, gpu_material); + ensure_seg_pt_count(curves, cache.hair); + curves_batch_cache_ensure_procedural_pos(curves, cache.hair, gpu_material); need_ft_update = true; } /* Refreshed if active layer or custom data changes. */ if ((*r_hair_cache)->strand_tex == nullptr) { - curves_batch_cache_ensure_procedural_strand_data(curves, &cache->hair); + curves_batch_cache_ensure_procedural_strand_data(curves, cache.hair); } /* Refreshed only on subdiv count change. */ if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) { - curves_batch_cache_ensure_procedural_final_points(&cache->hair, subdiv); + curves_batch_cache_ensure_procedural_final_points(cache.hair, subdiv); need_ft_update = true; } if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { - curves_batch_cache_ensure_procedural_indices(curves, &cache->hair, thickness_res, subdiv); + curves_batch_cache_ensure_procedural_indices(curves, cache.hair, thickness_res, subdiv); } return need_ft_update; diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c index 7e2ab2c6193..8c185a963e0 100644 --- a/source/blender/draw/intern/draw_hair.c +++ b/source/blender/draw/intern/draw_hair.c @@ -172,8 +172,8 @@ static ParticleHairCache *drw_hair_particle_cache_get(Object *object, object, psys, md, &cache, gpu_material, subdiv, thickness_res); } else { - /* New hair object. */ - update = hair_ensure_procedural_data(object, &cache, gpu_material, subdiv, thickness_res); + /* New curves object. */ + update = curves_ensure_procedural_data(object, &cache, gpu_material, subdiv, thickness_res); } if (update) { @@ -230,7 +230,7 @@ void DRW_hair_duplimat_get(Object *object, } } else { - /* New hair object. */ + /* New curves object. */ copy_m4_m4(dupli_mat, object->obmat); } } @@ -291,7 +291,7 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object, hair_close_tip = (part->shape_flag & PART_SHAPE_CLOSE_TIP) != 0; } else { - /* TODO: implement for new hair object. */ + /* TODO: implement for new curves object. */ hair_rad_shape = 1.0f; hair_rad_root = 0.005f; hair_rad_tip = 0.0f; diff --git a/source/blender/draw/intern/draw_hair_private.h b/source/blender/draw/intern/draw_hair_private.h index 98a55d76373..58e8609106b 100644 --- a/source/blender/draw/intern/draw_hair_private.h +++ b/source/blender/draw/intern/draw_hair_private.h @@ -91,11 +91,11 @@ bool particles_ensure_procedural_data(struct Object *object, /** * Ensure all textures and buffers needed for GPU accelerated drawing. */ -bool hair_ensure_procedural_data(struct Object *object, - struct ParticleHairCache **r_hair_cache, - struct GPUMaterial *gpu_material, - int subdiv, - int thickness_res); +bool curves_ensure_procedural_data(struct Object *object, + struct ParticleHairCache **r_hair_cache, + struct GPUMaterial *gpu_material, + int subdiv, + int thickness_res); #ifdef __cplusplus } -- cgit v1.2.3