Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_cache_impl_pointcloud.cc
| Show All 26 Lines | |||||
| #include "draw_cache_impl.h" /* own include */ | #include "draw_cache_impl.h" /* own include */ | ||||
| /* ---------------------------------------------------------------------- */ | /* ---------------------------------------------------------------------- */ | ||||
| /* PointCloud GPUBatch Cache */ | /* PointCloud GPUBatch Cache */ | ||||
| struct PointCloudBatchCache { | struct PointCloudBatchCache { | ||||
| GPUVertBuf *pos; /* Position and radius. */ | GPUVertBuf *pos; /* Position and radius. */ | ||||
| GPUVertBuf *geom; /* Instanced geometry for each point in the cloud (small sphere). */ | GPUVertBuf *geom; /* Instanced geometry for each point in the cloud (small sphere). */ | ||||
| GPUVertBuf *attr_viewer; | |||||
| GPUIndexBuf *geom_indices; | GPUIndexBuf *geom_indices; | ||||
| GPUBatch *dots; | GPUBatch *dots; | ||||
| GPUBatch *surface; | GPUBatch *surface; | ||||
| GPUBatch **surface_per_mat; | GPUBatch **surface_per_mat; | ||||
| GPUBatch *surface_viewer_attribute; | |||||
| /* settings to determine if cache is invalid */ | /* settings to determine if cache is invalid */ | ||||
| bool is_dirty; | bool is_dirty; | ||||
| int mat_len; | int mat_len; | ||||
| }; | }; | ||||
| /* GPUBatch cache management. */ | /* GPUBatch cache management. */ | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | static void pointcloud_batch_cache_clear(PointCloud &pointcloud) | ||||
| if (!cache) { | if (!cache) { | ||||
| return; | return; | ||||
| } | } | ||||
| GPU_BATCH_DISCARD_SAFE(cache->dots); | GPU_BATCH_DISCARD_SAFE(cache->dots); | ||||
| GPU_BATCH_DISCARD_SAFE(cache->surface); | GPU_BATCH_DISCARD_SAFE(cache->surface); | ||||
| GPU_VERTBUF_DISCARD_SAFE(cache->pos); | GPU_VERTBUF_DISCARD_SAFE(cache->pos); | ||||
| GPU_VERTBUF_DISCARD_SAFE(cache->geom); | GPU_VERTBUF_DISCARD_SAFE(cache->geom); | ||||
| GPU_VERTBUF_DISCARD_SAFE(cache->attr_viewer); | |||||
| GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices); | GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices); | ||||
| if (cache->surface_per_mat) { | if (cache->surface_per_mat) { | ||||
| for (int i = 0; i < cache->mat_len; i++) { | for (int i = 0; i < cache->mat_len; i++) { | ||||
| GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]); | GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]); | ||||
| } | } | ||||
| } | } | ||||
| GPU_BATCH_DISCARD_SAFE(cache->surface_viewer_attribute); | |||||
| MEM_SAFE_FREE(cache->surface_per_mat); | MEM_SAFE_FREE(cache->surface_per_mat); | ||||
| } | } | ||||
| void DRW_pointcloud_batch_cache_validate(PointCloud *pointcloud) | void DRW_pointcloud_batch_cache_validate(PointCloud *pointcloud) | ||||
| { | { | ||||
| if (!pointcloud_batch_cache_valid(*pointcloud)) { | if (!pointcloud_batch_cache_valid(*pointcloud)) { | ||||
| pointcloud_batch_cache_clear(*pointcloud); | pointcloud_batch_cache_clear(*pointcloud); | ||||
| pointcloud_batch_cache_init(*pointcloud); | pointcloud_batch_cache_init(*pointcloud); | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | static void pointcloud_batch_cache_ensure_geom(PointCloudBatchCache &cache) | ||||
| for (int i = 0; i < ARRAY_SIZE(half_octahedron_tris); i++) { | for (int i = 0; i < ARRAY_SIZE(half_octahedron_tris); i++) { | ||||
| GPU_indexbuf_add_tri_verts(&builder, UNPACK3(half_octahedron_tris[i])); | GPU_indexbuf_add_tri_verts(&builder, UNPACK3(half_octahedron_tris[i])); | ||||
| } | } | ||||
| cache.geom_indices = GPU_indexbuf_build(&builder); | 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) | GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob) | ||||
| { | { | ||||
| PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data); | PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data); | ||||
| PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud); | PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud); | ||||
| if (cache->dots == nullptr) { | if (cache->dots == nullptr) { | ||||
| pointcloud_batch_cache_ensure_pos(pointcloud, *cache); | pointcloud_batch_cache_ensure_pos(pointcloud, *cache); | ||||
| cache->dots = GPU_batch_create(GPU_PRIM_POINTS, cache->pos, nullptr); | cache->dots = GPU_batch_create(GPU_PRIM_POINTS, cache->pos, nullptr); | ||||
| Show All 13 Lines | if (cache->surface == nullptr) { | ||||
| cache->surface = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices); | cache->surface = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices); | ||||
| GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false); | GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false); | ||||
| } | } | ||||
| return cache->surface; | 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, | GPUBatch **DRW_cache_pointcloud_surface_shaded_get(Object *ob, | ||||
| struct GPUMaterial **UNUSED(gpumat_array), | struct GPUMaterial **UNUSED(gpumat_array), | ||||
| uint gpumat_array_len) | uint gpumat_array_len) | ||||
| { | { | ||||
| PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data); | PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data); | ||||
| PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud); | PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud); | ||||
| BLI_assert(cache->mat_len == gpumat_array_len); | BLI_assert(cache->mat_len == gpumat_array_len); | ||||
| UNUSED_VARS(gpumat_array_len); | UNUSED_VARS(gpumat_array_len); | ||||
| Show All 16 Lines | |||||