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:
Diffstat (limited to 'source/blender/draw/intern/draw_hair.c')
-rw-r--r--source/blender/draw/intern/draw_hair.c157
1 files changed, 92 insertions, 65 deletions
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 2fdaf0d5345..6cfba0e2a78 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -124,32 +124,109 @@ void DRW_hair_init(void)
}
}
-DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
- ParticleSystem *psys,
- ModifierData *md,
- DRWShadingGroup *shgrp_parent)
+static ParticleHairCache *drw_hair_particle_cache_get(
+ Object *object, ParticleSystem *psys, ModifierData *md, int subdiv, int thickness_res)
+{
+ bool update;
+ ParticleHairCache *cache;
+ if (psys) {
+ /* Old particle hair. */
+ update = particles_ensure_procedural_data(object, psys, md, &cache, subdiv, thickness_res);
+ }
+ else {
+ /* New hair object. */
+ update = hair_ensure_procedural_data(object, &cache, subdiv, thickness_res);
+ }
+
+ if (update) {
+ int final_points_len = cache->final[subdiv].strands_res * cache->strands_len;
+ if (final_points_len > 0) {
+ GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
+
+#ifdef USE_TRANSFORM_FEEDBACK
+ DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
+ tf_shader, g_tf_pass, cache->final[subdiv].proc_buf);
+#else
+ DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
+
+ ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
+ pr_call->next = g_tf_calls;
+ pr_call->vbo = cache->final[subdiv].proc_buf;
+ pr_call->shgrp = tf_shgrp;
+ pr_call->vert_len = final_points_len;
+ g_tf_calls = pr_call;
+ DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
+ DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
+ DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
+#endif
+
+ DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", cache->point_tex);
+ DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", cache->strand_tex);
+ DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", cache->strand_seg_tex);
+ DRW_shgroup_uniform_int(tf_shgrp, "hairStrandsRes", &cache->final[subdiv].strands_res, 1);
+ DRW_shgroup_call_procedural_points(tf_shgrp, NULL, final_points_len);
+ }
+ }
+ return cache;
+}
+
+/* Note: Only valid after DRW_hair_update(). */
+GPUVertBuf *DRW_hair_pos_buffer_get(Object *object, ParticleSystem *psys, ModifierData *md)
{
- /* TODO(fclem): Pass the scene as parameter */
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
- float dupli_mat[4][4];
- Object *dupli_parent = DRW_object_get_dupli_parent(object);
- DupliObject *dupli_object = DRW_object_get_dupli(object);
int subdiv = scene->r.hair_subdiv;
int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2;
- ParticleHairCache *hair_cache;
- bool need_ft_update;
+ ParticleHairCache *cache = drw_hair_particle_cache_get(object, psys, md, subdiv, thickness_res);
+
+ return cache->final[subdiv].proc_buf;
+}
+
+void DRW_hair_duplimat_get(Object *object,
+ ParticleSystem *psys,
+ ModifierData *UNUSED(md),
+ float (*dupli_mat)[4])
+{
+ Object *dupli_parent = DRW_object_get_dupli_parent(object);
+ DupliObject *dupli_object = DRW_object_get_dupli(object);
+
if (psys) {
- /* Old particle hair. */
- need_ft_update = particles_ensure_procedural_data(
- object, psys, md, &hair_cache, subdiv, thickness_res);
+ if ((dupli_parent != NULL) && (dupli_object != NULL)) {
+ if (dupli_object->type & OB_DUPLICOLLECTION) {
+ copy_m4_m4(dupli_mat, dupli_parent->obmat);
+ }
+ else {
+ copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
+ invert_m4(dupli_mat);
+ mul_m4_m4m4(dupli_mat, object->obmat, dupli_mat);
+ }
+ }
+ else {
+ unit_m4(dupli_mat);
+ }
}
else {
/* New hair object. */
- need_ft_update = hair_ensure_procedural_data(object, &hair_cache, subdiv, thickness_res);
+ copy_m4_m4(dupli_mat, object->obmat);
}
+}
+
+DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
+ ParticleSystem *psys,
+ ModifierData *md,
+ DRWShadingGroup *shgrp_parent)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ float dupli_mat[4][4];
+
+ int subdiv = scene->r.hair_subdiv;
+ int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2;
+
+ ParticleHairCache *hair_cache = drw_hair_particle_cache_get(
+ object, psys, md, subdiv, thickness_res);
DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent);
@@ -177,25 +254,7 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture);
}
- if (psys) {
- if ((dupli_parent != NULL) && (dupli_object != NULL)) {
- if (dupli_object->type & OB_DUPLICOLLECTION) {
- copy_m4_m4(dupli_mat, dupli_parent->obmat);
- }
- else {
- copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
- invert_m4(dupli_mat);
- mul_m4_m4m4(dupli_mat, object->obmat, dupli_mat);
- }
- }
- else {
- unit_m4(dupli_mat);
- }
- }
- else {
- /* New hair object. */
- copy_m4_m4(dupli_mat, object->obmat);
- }
+ DRW_hair_duplimat_get(object, psys, md, dupli_mat);
/* Get hair shape parameters. */
float hair_rad_shape, hair_rad_root, hair_rad_tip;
@@ -229,38 +288,6 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object,
GPUBatch *geom = hair_cache->final[subdiv].proc_hairs[thickness_res - 1];
DRW_shgroup_call_no_cull(shgrp, geom, object);
- /* Transform Feedback subdiv. */
- if (need_ft_update) {
- int final_points_len = hair_cache->final[subdiv].strands_res * hair_cache->strands_len;
- if (final_points_len) {
- GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
-
-#ifdef USE_TRANSFORM_FEEDBACK
- DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
- tf_shader, g_tf_pass, hair_cache->final[subdiv].proc_buf);
-#else
- DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
-
- ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
- pr_call->next = g_tf_calls;
- pr_call->vbo = hair_cache->final[subdiv].proc_buf;
- pr_call->shgrp = tf_shgrp;
- pr_call->vert_len = final_points_len;
- g_tf_calls = pr_call;
- DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
- DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
- DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
-#endif
-
- DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", hair_cache->point_tex);
- DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex);
- DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", hair_cache->strand_seg_tex);
- DRW_shgroup_uniform_int(
- tf_shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
- DRW_shgroup_call_procedural_points(tf_shgrp, NULL, final_points_len);
- }
- }
-
return shgrp;
}