diff options
author | Hans Goudey <h.goudey@me.com> | 2022-08-17 17:20:25 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-08-17 17:20:25 +0300 |
commit | eaa87101cd5a20e577748bfff95b7cb06b04dd4b (patch) | |
tree | 8243ee6bd1479299f23819ef2765720fc9a18889 /source/blender/draw | |
parent | 71f091a631c2deae08ff289184f928538b527cb3 (diff) |
Metaball: Evaluate metaball objects as mesh components
With the ultimate goal of simplifying drawing and evaluation,
this patch makes the following changes and removes code:
- Use `Mesh` instead of `DispList` for evaluated basis metaballs.
- Remove all `DispList` drawing code, which is now unused.
- Simplify code that converts evaluated metaballs to meshes.
- Store the evaluated mesh in the evaluated geometry set.
This has the following indirect benefits:
- Evaluated meshes from metaball objects can be used in geometry nodes.
- Renderers can ignore evaluated metaball objects completely
- Cycles rendering no longer has to convert to mesh from `DispList`.
- We get closer to removing `DispList` completely.
- Optimizations to mesh rendering will also apply to metaball objects.
The vertex normals on the evaluated mesh are technically invalid;
the regular calculation wouldn't reproduce them. Metaball objects
don't support modifiers though, so it shouldn't be a problem.
Eventually we can support per-vertex custom normals (T93551).
Differential Revision: https://developer.blender.org/D14593
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_engine.c | 2 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_materials.c | 2 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_render.c | 2 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee_next/eevee_instance.cc | 3 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_engine.c | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_engine.c | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 83 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 9 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 38 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_displist.c | 354 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_metaball.c | 294 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.c | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 3 |
14 files changed, 38 insertions, 758 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 0a62263ce3b..684134609c9 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -71,11 +71,9 @@ set(SRC intern/draw_attributes.cc intern/draw_cache_impl_curve.cc intern/draw_cache_impl_curves.cc - intern/draw_cache_impl_displist.c intern/draw_cache_impl_gpencil.c intern/draw_cache_impl_lattice.c intern/draw_cache_impl_mesh.cc - intern/draw_cache_impl_metaball.c intern/draw_cache_impl_particles.c intern/draw_cache_impl_pointcloud.cc intern/draw_cache_impl_subdivision.cc diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index ffe0863fb9f..cc7d0c6b22e 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -109,7 +109,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob) } if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) { - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) { + if (ELEM(ob->type, OB_MESH, OB_SURF)) { EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow); } else if (ob->type == OB_CURVES) { diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index efd27c19654..94f29d64628 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -806,7 +806,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, !DRW_state_is_image_render(); /* First get materials for this mesh. */ - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) { + if (ELEM(ob->type, OB_MESH, OB_SURF)) { const int materials_len = DRW_cache_object_material_count_get(ob); EeveeMaterialCache *matcache = BLI_array_alloca(matcache, materials_len); diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 82944f237ea..3e268758076 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -224,7 +224,7 @@ void EEVEE_render_cache(void *vedata, } if (ob_visibility & OB_VISIBLE_SELF) { - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) { + if (ELEM(ob->type, OB_MESH, OB_SURF)) { EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow); if (do_cryptomatte) { EEVEE_cryptomatte_cache_populate(data, sldata, ob); diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index 6665b3a7c9b..eb32ebe9555 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -144,8 +144,7 @@ void Instance::object_sync(Object *ob) case OB_MESH: case OB_CURVES_LEGACY: case OB_SURF: - case OB_FONT: - case OB_MBALL: { + case OB_FONT: { sync.sync_mesh(ob, ob_handle); break; } diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index 5edd68bffff..6e2da95e405 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -320,7 +320,6 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) OB_MESH, OB_CURVES_LEGACY, OB_SURF, - OB_MBALL, OB_FONT, OB_GPENCIL, OB_CURVES, diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 9eb35c25bf4..ad32618e636 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -409,7 +409,7 @@ void workbench_cache_populate(void *ved, Object *ob) return; } - if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL, OB_POINTCLOUD)) { + if (ELEM(ob->type, OB_MESH, OB_SURF, OB_POINTCLOUD)) { bool use_sculpt_pbvh, use_texpaint_mode, draw_shadow, has_transp_mat = false; eV3DShadingColorType color_type = workbench_color_type_get( wpd, ob, &use_sculpt_pbvh, &use_texpaint_mode, &draw_shadow); diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 4c0f025e934..275392ec56a 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -780,6 +780,39 @@ GPUBatch *DRW_cache_normal_arrow_get(void) return SHC.drw_normal_arrow; } +void DRW_vertbuf_create_wiredata(GPUVertBuf *vbo, const int vert_len) +{ + static GPUVertFormat format = {0}; + static struct { + uint wd; + } attr_id; + if (format.attr_len == 0) { + /* initialize vertex format */ + if (!GPU_crappy_amd_driver()) { + /* Some AMD drivers strangely crash with a vbo with this format. */ + attr_id.wd = GPU_vertformat_attr_add( + &format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); + } + else { + attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + } + } + + GPU_vertbuf_init_with_format(vbo, &format); + GPU_vertbuf_data_alloc(vbo, vert_len); + + if (GPU_vertbuf_get_format(vbo)->stride == 1) { + memset(GPU_vertbuf_get_data(vbo), 0xFF, (size_t)vert_len); + } + else { + GPUVertBufRaw wd_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step); + for (int i = 0; i < vert_len; i++) { + *((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f; + } + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -836,8 +869,6 @@ GPUBatch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_edge_detection_get(ob, r_is_manifold); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -860,8 +891,6 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_face_wireframe_get(ob); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -887,8 +916,6 @@ GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return NULL; case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -911,8 +938,6 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob) return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_surface_get(ob); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -936,8 +961,6 @@ GPUVertBuf *DRW_cache_object_pos_vertbuf_get(Object *ob) case OB_SURF: case OB_FONT: return NULL; - case OB_MBALL: - return DRW_mball_batch_cache_pos_vertbuf_get(ob); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -968,8 +991,6 @@ int DRW_cache_object_material_count_get(struct Object *ob) case OB_SURF: case OB_FONT: return DRW_curve_material_count_get(ob->data); - case OB_MBALL: - return DRW_metaball_material_count_get(ob->data); case OB_CURVES: return DRW_curves_material_count_get(ob->data); case OB_POINTCLOUD: @@ -997,8 +1018,6 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob, return NULL; case OB_FONT: return NULL; - case OB_MBALL: - return DRW_cache_mball_surface_shaded_get(ob, gpumat_array, gpumat_array_len); case OB_CURVES: return NULL; case OB_POINTCLOUD: @@ -2972,39 +2991,6 @@ GPUBatch *DRW_cache_curve_vert_overlay_get(Object *ob) /** \} */ /* -------------------------------------------------------------------- */ -/** \name MetaBall - * \{ */ - -GPUBatch *DRW_cache_mball_surface_get(Object *ob) -{ - BLI_assert(ob->type == OB_MBALL); - return DRW_metaball_batch_cache_get_triangles_with_normals(ob); -} - -GPUBatch *DRW_cache_mball_edge_detection_get(Object *ob, bool *r_is_manifold) -{ - BLI_assert(ob->type == OB_MBALL); - return DRW_metaball_batch_cache_get_edge_detection(ob, r_is_manifold); -} - -GPUBatch *DRW_cache_mball_face_wireframe_get(Object *ob) -{ - BLI_assert(ob->type == OB_MBALL); - return DRW_metaball_batch_cache_get_wireframes_face(ob); -} - -GPUBatch **DRW_cache_mball_surface_shaded_get(Object *ob, - struct GPUMaterial **gpumat_array, - uint gpumat_array_len) -{ - BLI_assert(ob->type == OB_MBALL); - MetaBall *mb = ob->data; - return DRW_metaball_batch_cache_get_surface_shaded(ob, mb, gpumat_array, gpumat_array_len); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Font * \{ */ @@ -3322,9 +3308,6 @@ void drw_batch_cache_validate(Object *ob) case OB_SURF: DRW_curve_batch_cache_validate((Curve *)ob->data); break; - case OB_MBALL: - DRW_mball_batch_cache_validate((MetaBall *)ob->data); - break; case OB_LATTICE: DRW_lattice_batch_cache_validate((Lattice *)ob->data); break; diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index a107eb7c75c..4e8788ada08 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -213,15 +213,6 @@ struct GPUBatch *DRW_cache_particles_get_edit_tip_points(struct Object *object, struct PTCacheEdit *edit); struct GPUBatch *DRW_cache_particles_get_prim(int type); -/* Metaball */ - -struct GPUBatch *DRW_cache_mball_surface_get(struct Object *ob); -struct GPUBatch **DRW_cache_mball_surface_shaded_get(struct Object *ob, - struct GPUMaterial **gpumat_array, - uint gpumat_array_len); -struct GPUBatch *DRW_cache_mball_face_wireframe_get(struct Object *ob); -struct GPUBatch *DRW_cache_mball_edge_detection_get(struct Object *ob, bool *r_is_manifold); - /* Curves */ struct GPUBatch *DRW_cache_curves_surface_get(struct Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 91dbef8d7b1..7f7d0a7613f 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -36,10 +36,6 @@ extern "C" { /** \name Expose via BKE callbacks * \{ */ -void DRW_mball_batch_cache_dirty_tag(struct MetaBall *mb, int mode); -void DRW_mball_batch_cache_validate(struct MetaBall *mb); -void DRW_mball_batch_cache_free(struct MetaBall *mb); - void DRW_curve_batch_cache_dirty_tag(struct Curve *cu, int mode); void DRW_curve_batch_cache_validate(struct Curve *cu); void DRW_curve_batch_cache_free(struct Curve *cu); @@ -111,39 +107,6 @@ struct GPUBatch *DRW_curve_batch_cache_get_edit_verts(struct Curve *cu); /** \} */ /* -------------------------------------------------------------------- */ -/** \name Metaball - * \{ */ - -int DRW_metaball_material_count_get(struct MetaBall *mb); - -struct GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob); -struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(struct Object *ob, - struct MetaBall *mb, - struct GPUMaterial **gpumat_array, - uint gpumat_array_len); -struct GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(struct Object *ob); -struct GPUBatch *DRW_metaball_batch_cache_get_edge_detection(struct Object *ob, - bool *r_is_manifold); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name DispList - * \{ */ - -void DRW_displist_vertbuf_create_pos_and_nor(struct ListBase *lb, - struct GPUVertBuf *vbo, - const struct Scene *scene); -void DRW_displist_vertbuf_create_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo); -void DRW_displist_indexbuf_create_lines_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo); -void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo); -void DRW_displist_indexbuf_create_edges_adjacency_lines(struct ListBase *lb, - struct GPUIndexBuf *ibo, - bool *r_is_manifold); - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Lattice * \{ */ @@ -309,7 +272,6 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(struct Mesh *me); * \{ */ struct GPUVertBuf *DRW_mesh_batch_cache_pos_vertbuf_get(struct Mesh *me); -struct GPUVertBuf *DRW_mball_batch_cache_pos_vertbuf_get(struct Object *ob); int DRW_mesh_material_count_get(const struct Object *object, const struct Mesh *me); diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c deleted file mode 100644 index 96c088c3ee9..00000000000 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ /dev/null @@ -1,354 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2017 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup draw - * - * \brief DispList API for render engines - * - * \note DispList may be removed soon! This is a utility for object types that use render. - */ - -#include "BLI_edgehash.h" -#include "BLI_listbase.h" -#include "BLI_math_vector.h" -#include "BLI_utildefines.h" - -#include "DNA_curve_types.h" -#include "DNA_scene_types.h" - -#include "BKE_displist.h" - -#include "GPU_batch.h" -#include "GPU_capabilities.h" - -#include "draw_cache_inline.h" - -#include "draw_cache_impl.h" /* own include */ - -static int dl_vert_len(const DispList *dl) -{ - switch (dl->type) { - case DL_INDEX3: - case DL_INDEX4: - return dl->nr; - case DL_SURF: - return dl->parts * dl->nr; - } - return 0; -} - -static int dl_tri_len(const DispList *dl) -{ - switch (dl->type) { - case DL_INDEX3: - return dl->parts; - case DL_INDEX4: - return dl->parts * 2; - case DL_SURF: - return dl->totindex * 2; - } - return 0; -} - -/* see: displist_vert_coords_alloc */ -static int curve_render_surface_vert_len_get(const ListBase *lb) -{ - int vert_len = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - vert_len += dl_vert_len(dl); - } - return vert_len; -} - -static int curve_render_surface_tri_len_get(const ListBase *lb) -{ - int tri_len = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - tri_len += dl_tri_len(dl); - } - return tri_len; -} - -typedef void(SetTriIndicesFn)(void *thunk, uint v1, uint v2, uint v3); - -static void displist_indexbufbuilder_set( - SetTriIndicesFn *set_tri_indices, - SetTriIndicesFn *set_quad_tri_indices, /* meh, find a better solution. */ - void *thunk, - const DispList *dl, - const int ofs) -{ - if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { - const int *idx = dl->index; - if (dl->type == DL_INDEX3) { - const int i_end = dl->parts; - for (int i = 0; i < i_end; i++, idx += 3) { - set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); - } - } - else if (dl->type == DL_SURF) { - const int i_end = dl->totindex; - for (int i = 0; i < i_end; i++, idx += 4) { - set_quad_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); - set_quad_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[3] + ofs); - } - } - else { - BLI_assert(dl->type == DL_INDEX4); - const int i_end = dl->parts; - for (int i = 0; i < i_end; i++, idx += 4) { - if (idx[2] != idx[3]) { - set_quad_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[1] + ofs); - set_quad_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); - } - else { - set_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[1] + ofs); - } - } - } - } -} - -void DRW_displist_vertbuf_create_pos_and_nor(ListBase *lb, GPUVertBuf *vbo, const Scene *scene) -{ - const bool do_hq_normals = (scene->r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 || - GPU_use_hq_normals_workaround(); - - static GPUVertFormat format = {0}; - static GPUVertFormat format_hq = {0}; - static struct { - uint pos, nor; - uint pos_hq, nor_hq; - } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.nor = GPU_vertformat_attr_add( - &format, "nor", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - /* initialize vertex format */ - attr_id.pos_hq = GPU_vertformat_attr_add(&format_hq, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.nor_hq = GPU_vertformat_attr_add( - &format_hq, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - } - - uint pos_id = do_hq_normals ? attr_id.pos_hq : attr_id.pos; - uint nor_id = do_hq_normals ? attr_id.nor_hq : attr_id.nor; - - GPU_vertbuf_init_with_format(vbo, do_hq_normals ? &format_hq : &format); - GPU_vertbuf_data_alloc(vbo, curve_render_surface_vert_len_get(lb)); - - BKE_displist_normals_add(lb); - - int vbo_len_used = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - const bool ndata_is_single = dl->type == DL_INDEX3; - if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { - const float *fp_co = dl->verts; - const float *fp_no = dl->nors; - const int vbo_end = vbo_len_used + dl_vert_len(dl); - while (vbo_len_used < vbo_end) { - GPU_vertbuf_attr_set(vbo, pos_id, vbo_len_used, fp_co); - if (fp_no) { - GPUNormal vnor_pack; - GPU_normal_convert_v3(&vnor_pack, fp_no, do_hq_normals); - GPU_vertbuf_attr_set(vbo, nor_id, vbo_len_used, &vnor_pack); - if (ndata_is_single == false) { - fp_no += 3; - } - } - fp_co += 3; - vbo_len_used += 1; - } - } - } -} - -void DRW_vertbuf_create_wiredata(GPUVertBuf *vbo, const int vert_len) -{ - static GPUVertFormat format = {0}; - static struct { - uint wd; - } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - if (!GPU_crappy_amd_driver()) { - /* Some AMD drivers strangely crash with a vbo with this format. */ - attr_id.wd = GPU_vertformat_attr_add( - &format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); - } - else { - attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - } - } - - GPU_vertbuf_init_with_format(vbo, &format); - GPU_vertbuf_data_alloc(vbo, vert_len); - - if (GPU_vertbuf_get_format(vbo)->stride == 1) { - memset(GPU_vertbuf_get_data(vbo), 0xFF, (size_t)vert_len); - } - else { - GPUVertBufRaw wd_step; - GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step); - for (int i = 0; i < vert_len; i++) { - *((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f; - } - } -} - -void DRW_displist_vertbuf_create_wiredata(ListBase *lb, GPUVertBuf *vbo) -{ - const int vert_len = curve_render_surface_vert_len_get(lb); - DRW_vertbuf_create_wiredata(vbo, vert_len); -} - -void DRW_displist_indexbuf_create_triangles_in_order(ListBase *lb, GPUIndexBuf *ibo) -{ - const int tri_len = curve_render_surface_tri_len_get(lb); - const int vert_len = curve_render_surface_vert_len_get(lb); - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); - - int ofs = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - displist_indexbufbuilder_set((SetTriIndicesFn *)GPU_indexbuf_add_tri_verts, - (SetTriIndicesFn *)GPU_indexbuf_add_tri_verts, - &elb, - dl, - ofs); - ofs += dl_vert_len(dl); - } - - GPU_indexbuf_build_in_place(&elb, ibo); -} - -static void set_overlay_wires_tri_indices(void *thunk, uint v1, uint v2, uint v3) -{ - GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk; - GPU_indexbuf_add_line_verts(eld, v1, v2); - GPU_indexbuf_add_line_verts(eld, v2, v3); - GPU_indexbuf_add_line_verts(eld, v3, v1); -} - -static void set_overlay_wires_quad_tri_indices(void *thunk, uint v1, uint v2, uint v3) -{ - GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk; - GPU_indexbuf_add_line_verts(eld, v1, v3); - GPU_indexbuf_add_line_verts(eld, v3, v2); -} - -void DRW_displist_indexbuf_create_lines_in_order(ListBase *lb, GPUIndexBuf *ibo) -{ - const int tri_len = curve_render_surface_tri_len_get(lb); - const int vert_len = curve_render_surface_vert_len_get(lb); - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_LINES, tri_len * 3, vert_len); - - int ofs = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - displist_indexbufbuilder_set( - set_overlay_wires_tri_indices, set_overlay_wires_quad_tri_indices, &elb, dl, ofs); - ofs += dl_vert_len(dl); - } - - GPU_indexbuf_build_in_place(&elb, ibo); -} - -/* Edge detection/adjacency. */ -#define NO_EDGE INT_MAX -static void set_edge_adjacency_lines_indices( - EdgeHash *eh, GPUIndexBufBuilder *elb, bool *r_is_manifold, uint v1, uint v2, uint v3) -{ - bool inv_indices = (v2 > v3); - void **pval; - bool value_is_init = BLI_edgehash_ensure_p(eh, v2, v3, &pval); - int v_data = POINTER_AS_INT(*pval); - if (!value_is_init || v_data == NO_EDGE) { - /* Save the winding order inside the sign bit. Because the - * edgehash sort the keys and we need to compare winding later. */ - int value = (int)v1 + 1; /* Int 0 bm_looptricannot be signed */ - *pval = POINTER_FROM_INT((inv_indices) ? -value : value); - } - else { - /* HACK Tag as not used. Prevent overhead of BLI_edgehash_remove. */ - *pval = POINTER_FROM_INT(NO_EDGE); - bool inv_opposite = (v_data < 0); - uint v_opposite = (uint)abs(v_data) - 1; - - if (inv_opposite == inv_indices) { - /* Don't share edge if triangles have non matching winding. */ - GPU_indexbuf_add_line_adj_verts(elb, v1, v2, v3, v1); - GPU_indexbuf_add_line_adj_verts(elb, v_opposite, v2, v3, v_opposite); - *r_is_manifold = false; - } - else { - GPU_indexbuf_add_line_adj_verts(elb, v1, v2, v3, v_opposite); - } - } -} - -static void set_edges_adjacency_lines_indices(void *thunk, uint v1, uint v2, uint v3) -{ - void **packed = (void **)thunk; - GPUIndexBufBuilder *elb = (GPUIndexBufBuilder *)packed[0]; - EdgeHash *eh = (EdgeHash *)packed[1]; - bool *r_is_manifold = (bool *)packed[2]; - - set_edge_adjacency_lines_indices(eh, elb, r_is_manifold, v1, v2, v3); - set_edge_adjacency_lines_indices(eh, elb, r_is_manifold, v2, v3, v1); - set_edge_adjacency_lines_indices(eh, elb, r_is_manifold, v3, v1, v2); -} - -void DRW_displist_indexbuf_create_edges_adjacency_lines(struct ListBase *lb, - struct GPUIndexBuf *ibo, - bool *r_is_manifold) -{ - const int tri_len = curve_render_surface_tri_len_get(lb); - const int vert_len = curve_render_surface_vert_len_get(lb); - - *r_is_manifold = true; - - /* Allocate max but only used indices are sent to GPU. */ - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, tri_len * 3, vert_len); - - EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3); - - /* pack values to pass to `set_edges_adjacency_lines_indices` function. */ - void *thunk[3] = {&elb, eh, r_is_manifold}; - int v_idx = 0; - LISTBASE_FOREACH (const DispList *, dl, lb) { - displist_indexbufbuilder_set((SetTriIndicesFn *)set_edges_adjacency_lines_indices, - (SetTriIndicesFn *)set_edges_adjacency_lines_indices, - thunk, - dl, - v_idx); - v_idx += dl_vert_len(dl); - } - - /* Create edges for remaining non manifold edges. */ - EdgeHashIterator *ehi; - for (ehi = BLI_edgehashIterator_new(eh); BLI_edgehashIterator_isDone(ehi) == false; - BLI_edgehashIterator_step(ehi)) { - uint v1, v2; - int v_data = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); - if (v_data == NO_EDGE) { - continue; - } - BLI_edgehashIterator_getKey(ehi, &v1, &v2); - uint v0 = (uint)abs(v_data) - 1; - if (v_data < 0) { /* inv_opposite */ - SWAP(uint, v1, v2); - } - GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0); - *r_is_manifold = false; - } - BLI_edgehashIterator_free(ehi); - BLI_edgehash_free(eh, NULL); - - GPU_indexbuf_build_in_place(&elb, ibo); -} -#undef NO_EDGE diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c deleted file mode 100644 index 1408dc91069..00000000000 --- a/source/blender/draw/intern/draw_cache_impl_metaball.c +++ /dev/null @@ -1,294 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2017 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup draw - * - * \brief MetaBall API for render engines - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_math_base.h" -#include "BLI_utildefines.h" - -#include "DNA_meta_types.h" -#include "DNA_object_types.h" - -#include "BKE_curve.h" -#include "BKE_mball.h" - -#include "GPU_batch.h" - -#include "DRW_render.h" -#include "draw_cache_impl.h" /* own include */ - -static void metaball_batch_cache_clear(MetaBall *mb); - -/* -------------------------------------------------------------------- */ -/** \name MetaBall GPUBatch Cache - * \{ */ - -typedef struct MetaBallBatchCache { - GPUBatch *batch; - GPUBatch **shaded_triangles; - - int mat_len; - - /* Shared */ - GPUVertBuf *pos_nor_in_order; - - /* Wireframe */ - struct { - GPUBatch *batch; - } face_wire; - - /* Edge detection */ - GPUBatch *edge_detection; - GPUIndexBuf *edges_adj_lines; - - /* settings to determine if cache is invalid */ - bool is_dirty; - - /* Valid only if edge_detection is up to date. */ - bool is_manifold; -} MetaBallBatchCache; - -/* GPUBatch cache management. */ - -static bool metaball_batch_cache_valid(MetaBall *mb) -{ - MetaBallBatchCache *cache = mb->batch_cache; - - if (cache == NULL) { - return false; - } - - return cache->is_dirty == false; -} - -static void metaball_batch_cache_init(MetaBall *mb) -{ - MetaBallBatchCache *cache = mb->batch_cache; - - if (!cache) { - cache = mb->batch_cache = MEM_mallocN(sizeof(*cache), __func__); - } - cache->batch = NULL; - cache->mat_len = 0; - cache->shaded_triangles = NULL; - cache->is_dirty = false; - cache->pos_nor_in_order = NULL; - cache->face_wire.batch = NULL; - cache->edge_detection = NULL; - cache->edges_adj_lines = NULL; - cache->is_manifold = false; -} - -void DRW_mball_batch_cache_validate(MetaBall *mb) -{ - if (!metaball_batch_cache_valid(mb)) { - metaball_batch_cache_clear(mb); - metaball_batch_cache_init(mb); - } -} - -static MetaBallBatchCache *metaball_batch_cache_get(MetaBall *mb) -{ - return mb->batch_cache; -} - -void DRW_mball_batch_cache_dirty_tag(MetaBall *mb, int mode) -{ - MetaBallBatchCache *cache = mb->batch_cache; - if (cache == NULL) { - return; - } - switch (mode) { - case BKE_MBALL_BATCH_DIRTY_ALL: - cache->is_dirty = true; - break; - default: - BLI_assert(0); - } -} - -static void metaball_batch_cache_clear(MetaBall *mb) -{ - MetaBallBatchCache *cache = mb->batch_cache; - if (!cache) { - return; - } - - GPU_BATCH_DISCARD_SAFE(cache->face_wire.batch); - GPU_BATCH_DISCARD_SAFE(cache->batch); - GPU_BATCH_DISCARD_SAFE(cache->edge_detection); - GPU_VERTBUF_DISCARD_SAFE(cache->pos_nor_in_order); - GPU_INDEXBUF_DISCARD_SAFE(cache->edges_adj_lines); - /* NOTE: shaded_triangles[0] is already freed by `cache->batch`. */ - MEM_SAFE_FREE(cache->shaded_triangles); - cache->mat_len = 0; - cache->is_manifold = false; -} - -void DRW_mball_batch_cache_free(MetaBall *mb) -{ - metaball_batch_cache_clear(mb); - MEM_SAFE_FREE(mb->batch_cache); -} - -static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, - MetaBallBatchCache *cache, - const struct Scene *scene) -{ - if (cache->pos_nor_in_order == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - cache->pos_nor_in_order = GPU_vertbuf_calloc(); - DRW_displist_vertbuf_create_pos_and_nor(lb, cache->pos_nor_in_order, scene); - } - return cache->pos_nor_in_order; -} - -static GPUIndexBuf *mball_batch_cache_get_edges_adj_lines(Object *ob, MetaBallBatchCache *cache) -{ - if (cache->edges_adj_lines == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - cache->edges_adj_lines = GPU_indexbuf_calloc(); - DRW_displist_indexbuf_create_edges_adjacency_lines( - lb, cache->edges_adj_lines, &cache->is_manifold); - } - return cache->edges_adj_lines; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Public Object/MetaBall API - * \{ */ - -GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - if (cache->batch == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - GPUIndexBuf *ibo = GPU_indexbuf_calloc(); - DRW_displist_indexbuf_create_triangles_in_order(lb, ibo); - cache->batch = GPU_batch_create_ex(GPU_PRIM_TRIS, - mball_batch_cache_get_pos_and_normals(ob, cache, scene), - ibo, - GPU_BATCH_OWNS_INDEX); - } - - return cache->batch; -} - -GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(Object *ob, - MetaBall *mb, - struct GPUMaterial **UNUSED(gpumat_array), - uint gpumat_array_len) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - BLI_assert(gpumat_array_len == DRW_metaball_material_count_get(mb)); - - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - if (cache->shaded_triangles == NULL) { - cache->mat_len = gpumat_array_len; - cache->shaded_triangles = MEM_callocN(sizeof(*cache->shaded_triangles) * cache->mat_len, - __func__); - cache->shaded_triangles[0] = DRW_metaball_batch_cache_get_triangles_with_normals(ob); - for (int i = 1; i < cache->mat_len; i++) { - cache->shaded_triangles[i] = NULL; - } - } - return cache->shaded_triangles; -} - -GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(Object *ob) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - if (cache->face_wire.batch == NULL) { - ListBase *lb = &ob->runtime.curve_cache->disp; - - GPUVertBuf *vbo_wiredata = GPU_vertbuf_calloc(); - DRW_displist_vertbuf_create_wiredata(lb, vbo_wiredata); - - GPUIndexBuf *ibo = GPU_indexbuf_calloc(); - DRW_displist_indexbuf_create_lines_in_order(lb, ibo); - - cache->face_wire.batch = GPU_batch_create_ex( - GPU_PRIM_LINES, - mball_batch_cache_get_pos_and_normals(ob, cache, scene), - ibo, - GPU_BATCH_OWNS_INDEX); - - GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wiredata, true); - } - - return cache->face_wire.batch; -} - -struct GPUBatch *DRW_metaball_batch_cache_get_edge_detection(struct Object *ob, - bool *r_is_manifold) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - if (cache->edge_detection == NULL) { - cache->edge_detection = GPU_batch_create( - GPU_PRIM_LINES_ADJ, - mball_batch_cache_get_pos_and_normals(ob, cache, scene), - mball_batch_cache_get_edges_adj_lines(ob, cache)); - } - - if (r_is_manifold) { - *r_is_manifold = cache->is_manifold; - } - - return cache->edge_detection; -} - -struct GPUVertBuf *DRW_mball_batch_cache_pos_vertbuf_get(Object *ob) -{ - if (!BKE_mball_is_basis(ob)) { - return NULL; - } - - MetaBall *mb = ob->data; - MetaBallBatchCache *cache = metaball_batch_cache_get(mb); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const struct Scene *scene = draw_ctx->scene; - - return mball_batch_cache_get_pos_and_normals(ob, cache, scene); -} - -int DRW_metaball_material_count_get(MetaBall *mb) -{ - return max_ii(1, mb->totcol); -} - -/** \} */ diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 0f330dbb519..de56b34df78 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -417,7 +417,6 @@ bool DRW_object_is_flat(Object *ob, int *r_axis) OB_CURVES_LEGACY, OB_SURF, OB_FONT, - OB_MBALL, OB_CURVES, OB_POINTCLOUD, OB_VOLUME)) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 4693e5f8e20..3be2ddf5173 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2989,9 +2989,6 @@ void DRW_engines_register(void) /* setup callbacks */ { - BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag; - BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; - BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag; BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free; |