Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-07-14 17:18:24 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-07-14 17:47:45 +0300
commit102f66c0a4b1f1013aa6bb061c9a2627f4252031 (patch)
tree4cf86c4a777034b7c2715605565f4fe2fccc942c /source/blender/draw/intern
parent5e1212368510e97e519d151ce19d77ed56f1a565 (diff)
PointCloud: Initial rendering support for Workbench
Also includes outline overlays. Removes the temp overlay drawing
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/draw_cache.c4
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h3
-rw-r--r--source/blender/draw/intern/draw_cache_impl_pointcloud.c46
-rw-r--r--source/blender/draw/intern/draw_manager_data.c2
-rw-r--r--source/blender/draw/intern/shaders/common_pointcloud_lib.glsl138
5 files changed, 61 insertions, 132 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 0a2cd106fd2..20e346375a7 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -829,7 +829,7 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob)
case OB_HAIR:
return NULL;
case OB_POINTCLOUD:
- return NULL;
+ return DRW_pointcloud_batch_cache_get_dots(ob);
case OB_VOLUME:
return DRW_cache_volume_face_wireframe_get(ob);
case OB_GPENCIL: {
@@ -958,7 +958,7 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
case OB_HAIR:
return NULL;
case OB_POINTCLOUD:
- return NULL;
+ return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
case OB_VOLUME:
return NULL;
default:
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 6279d6d8ea0..96d351794e6 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -145,6 +145,9 @@ int DRW_pointcloud_material_count_get(struct PointCloud *pointcloud);
struct GPUBatch *DRW_pointcloud_batch_cache_get_dots(struct Object *ob);
struct GPUBatch *DRW_pointcloud_batch_cache_get_surface(struct Object *ob);
+struct GPUBatch **DRW_cache_pointcloud_surface_shaded_get(struct Object *ob,
+ struct GPUMaterial **gpumat_array,
+ uint gpumat_array_len);
/* Volume */
int DRW_volume_material_count_get(struct Volume *volume);
diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.c b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
index 897703c71ec..78d67a772bf 100644
--- a/source/blender/draw/intern/draw_cache_impl_pointcloud.c
+++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
@@ -52,9 +52,12 @@ typedef struct PointCloudBatchCache {
GPUBatch *dots;
GPUBatch *surface;
+ GPUBatch **surface_per_mat;
/* settings to determine if cache is invalid */
bool is_dirty;
+
+ int mat_len;
} PointCloudBatchCache;
/* GPUBatch cache management. */
@@ -62,7 +65,14 @@ typedef struct PointCloudBatchCache {
static bool pointcloud_batch_cache_valid(PointCloud *pointcloud)
{
PointCloudBatchCache *cache = pointcloud->batch_cache;
- return (cache && cache->is_dirty == false);
+
+ if (cache == NULL) {
+ return false;
+ }
+ if (cache->mat_len != DRW_pointcloud_material_count_get(pointcloud)) {
+ return false;
+ }
+ return cache->is_dirty == false;
}
static void pointcloud_batch_cache_init(PointCloud *pointcloud)
@@ -76,6 +86,10 @@ static void pointcloud_batch_cache_init(PointCloud *pointcloud)
memset(cache, 0, sizeof(*cache));
}
+ cache->mat_len = DRW_pointcloud_material_count_get(pointcloud);
+ cache->surface_per_mat = MEM_callocN(sizeof(GPUBatch *) * cache->mat_len,
+ "pointcloud suface_per_mat");
+
cache->is_dirty = false;
}
@@ -119,6 +133,13 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud)
GPU_VERTBUF_DISCARD_SAFE(cache->pos);
GPU_VERTBUF_DISCARD_SAFE(cache->geom);
GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices);
+
+ if (cache->surface_per_mat) {
+ for (int i = 0; i < cache->mat_len; i++) {
+ GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]);
+ }
+ }
+ MEM_SAFE_FREE(cache->surface_per_mat);
}
void DRW_pointcloud_batch_cache_free(PointCloud *pointcloud)
@@ -138,7 +159,7 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache *
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
/* initialize vertex format */
- GPU_vertformat_attr_add(&format, "ptcloud", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
}
cache->pos = GPU_vertbuf_create_with_format(&format);
@@ -198,7 +219,7 @@ static void pointcloud_batch_cache_ensure_geom(Object *UNUSED(ob), PointCloudBat
static uint pos;
if (format.attr_len == 0) {
/* initialize vertex format */
- pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(&format, "pos_inst", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
GPU_vertformat_alias_add(&format, "nor");
}
@@ -249,6 +270,25 @@ GPUBatch *DRW_pointcloud_batch_cache_get_surface(Object *ob)
return cache->surface;
}
+GPUBatch **DRW_cache_pointcloud_surface_shaded_get(Object *ob,
+ struct GPUMaterial **UNUSED(gpumat_array),
+ uint gpumat_array_len)
+{
+ PointCloud *pointcloud = ob->data;
+ PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
+ BLI_assert(cache->mat_len == gpumat_array_len);
+
+ if (cache->surface_per_mat[0] == NULL) {
+ pointcloud_batch_cache_ensure_pos(ob, cache);
+ pointcloud_batch_cache_ensure_geom(ob, cache);
+
+ cache->surface_per_mat[0] = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices);
+ GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false);
+ }
+
+ return cache->surface_per_mat;
+}
+
int DRW_pointcloud_material_count_get(PointCloud *pointcloud)
{
return max_ii(1, pointcloud->totcol);
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 3d83b918757..14d77ab1b21 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -793,10 +793,10 @@ void DRW_shgroup_call_range(
drw_command_draw_range(shgroup, geom, handle, v_sta, v_ct);
}
+/* A count of 0 instance will use the default number of instance in the batch. */
void DRW_shgroup_call_instance_range(
DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_ct)
{
- BLI_assert(i_ct > 0);
BLI_assert(geom != NULL);
if (G.f & G_FLAG_PICKSEL) {
drw_command_set_select_id(shgroup, NULL, DST.select_id);
diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
index 9636495a539..7545d7c89f3 100644
--- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
@@ -1,136 +1,22 @@
-/**
- * Library to create hairs dynamically from control points.
- * This is less bandwidth intensive than fetching the vertex attributes
- * but does more ALU work per vertex. This also reduces the amount
- * of data the CPU has to precompute and transfer for each update.
- */
-/**
- * hairStrandsRes: Number of points per hair strand.
- * 2 - no subdivision
- * 3+ - 1 or more interpolated points per hair.
- */
-uniform int hairStrandsRes = 8;
+/* NOTE: To be used with UNIFORM_RESOURCE_ID and INSTANCED_ATTR as define. */
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
-/**
- * hairThicknessRes : Subdiv around the hair.
- * 1 - Wire Hair: Only one pixel thick, independent of view distance.
- * 2 - Polystrip Hair: Correct width, flat if camera is parallel.
- * 3+ - Cylinder Hair: Massive calculation but potentially perfect. Still need proper support.
- */
-uniform int hairThicknessRes = 1;
+in vec4 pos; /* Position and radius. */
-/* Hair thickness shape. */
-uniform float hairRadRoot = 0.01;
-uniform float hairRadTip = 0.0;
-uniform float hairRadShape = 0.5;
-uniform bool hairCloseTip = true;
+/* ---- Instanced attribs ---- */
-uniform vec4 hairDupliMatrix[4];
+in vec3 pos_inst;
+in vec3 nor;
-/* -- Per control points -- */
-uniform samplerBuffer hairPointBuffer; /* RGBA32F */
-#define point_position xyz
-#define point_time w /* Position along the hair length */
-
-/* -- Per strands data -- */
-uniform usamplerBuffer hairStrandBuffer; /* R32UI */
-uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */
-
-/* Not used, use one buffer per uv layer */
-// uniform samplerBuffer hairUVBuffer; /* RG32F */
-// uniform samplerBuffer hairColBuffer; /* RGBA16 linear color */
-
-/* -- Subdivision stage -- */
-/**
- * We use a transform feedback to preprocess the strands and add more subdivision to it.
- * For the moment these are simple smooth interpolation but one could hope to see the full
- * children particle modifiers being evaluated at this stage.
- *
- * If no more subdivision is needed, we can skip this step.
- */
-
-#ifdef HAIR_PHASE_SUBDIV
-int hair_get_base_id(float local_time, int strand_segments, out float interp_time)
+/* Return object position. */
+vec3 pointcloud_get_pos(void)
{
- float time_per_strand_seg = 1.0 / float(strand_segments);
-
- float ratio = local_time / time_per_strand_seg;
- interp_time = fract(ratio);
-
- return int(ratio);
+ return pos.xyz + pos_inst * pos.w;
}
-void hair_get_interp_attrs(
- out vec4 data0, out vec4 data1, out vec4 data2, out vec4 data3, out float interp_time)
-{
- float local_time = float(gl_VertexID % hairStrandsRes) / float(hairStrandsRes - 1);
-
- int hair_id = gl_VertexID / hairStrandsRes;
- int strand_offset = int(texelFetch(hairStrandBuffer, hair_id).x);
- int strand_segments = int(texelFetch(hairStrandSegBuffer, hair_id).x);
-
- int id = hair_get_base_id(local_time, strand_segments, interp_time);
-
- int ofs_id = id + strand_offset;
-
- data0 = texelFetch(hairPointBuffer, ofs_id - 1);
- data1 = texelFetch(hairPointBuffer, ofs_id);
- data2 = texelFetch(hairPointBuffer, ofs_id + 1);
- data3 = texelFetch(hairPointBuffer, ofs_id + 2);
-
- if (id <= 0) {
- /* root points. Need to reconstruct previous data. */
- data0 = data1 * 2.0 - data2;
- }
- if (id + 1 >= strand_segments) {
- /* tip points. Need to reconstruct next data. */
- data3 = data2 * 2.0 - data1;
- }
-}
-#endif
-
-/* -- Drawing stage -- */
-/**
- * For final drawing, the vertex index and the number of vertex per segment
- */
-
-#ifndef HAIR_PHASE_SUBDIV
-int hair_get_strand_id(void)
+/* Return object Normal. */
+vec3 pointcloud_get_nor(void)
{
- return gl_VertexID / (hairStrandsRes * hairThicknessRes);
+ return nor;
}
-
-int hair_get_base_id(void)
-{
- return gl_VertexID / hairThicknessRes;
-}
-
-/* Copied from cycles. */
-float hair_shaperadius(float shape, float root, float tip, float time)
-{
- float radius = 1.0 - time;
-
- if (shape < 0.0) {
- radius = pow(radius, 1.0 + shape);
- }
- else {
- radius = pow(radius, 1.0 / (1.0 - shape));
- }
-
- if (hairCloseTip && (time > 0.99)) {
- return 0.0;
- }
-
- return (radius * (root - tip)) + tip;
-}
-
-# ifdef OS_MAC
-in float dummy;
-# endif
-
-vec3 pointcloud_get_pos()
-{
-}
-
-#endif