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_cache_impl_particles.c')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c89
1 files changed, 61 insertions, 28 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index 5c51f24a435..96bdca7d935 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -46,6 +46,7 @@
#include "ED_particle.h"
#include "GPU_batch.h"
+#include "GPU_material.h"
#include "DEG_depsgraph_query.h"
@@ -183,7 +184,9 @@ void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache)
{
/* TODO: more granular update tagging. */
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_point_buf);
+ GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_length_buf);
DRW_TEXTURE_FREE_SAFE(hair_cache->point_tex);
+ DRW_TEXTURE_FREE_SAFE(hair_cache->length_tex);
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_buf);
GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_seg_buf);
@@ -609,7 +612,8 @@ static int particle_batch_cache_fill_segments(ParticleSystem *psys,
static void particle_batch_cache_fill_segments_proc_pos(ParticleCacheKey **path_cache,
const int num_path_keys,
- GPUVertBufRaw *attr_step)
+ GPUVertBufRaw *attr_step,
+ GPUVertBufRaw *length_step)
{
for (int i = 0; i < num_path_keys; i++) {
ParticleCacheKey *path = path_cache[i];
@@ -630,6 +634,8 @@ static void particle_batch_cache_fill_segments_proc_pos(ParticleCacheKey **path_
seg_data[3] = total_len;
co_prev = path[j].co;
}
+ /* Assign length value*/
+ *(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 (int j = 0; j <= path->segments; j++, seg_data_first += 4) {
@@ -1079,40 +1085,64 @@ static void particle_batch_cache_ensure_procedural_indices(PTCacheEdit *edit,
static void particle_batch_cache_ensure_procedural_pos(PTCacheEdit *edit,
ParticleSystem *psys,
- ParticleHairCache *cache)
+ ParticleHairCache *cache,
+ GPUMaterial *gpu_material)
{
- if (cache->proc_point_buf != NULL) {
- return;
- }
+ if (cache->proc_point_buf == NULL) {
+ /* initialize vertex format */
+ GPUVertFormat pos_format = {0};
+ uint pos_id = GPU_vertformat_attr_add(
+ &pos_format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- /* 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(&pos_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 pos_step;
+ GPU_vertbuf_attr_get_raw_data(cache->proc_point_buf, pos_id, &pos_step);
- GPUVertBufRaw pos_step;
- GPU_vertbuf_attr_get_raw_data(cache->proc_point_buf, pos_id, &pos_step);
+ GPUVertFormat length_format = {0};
+ uint length_id = GPU_vertformat_attr_add(
+ &length_format, "hairLength", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- if (edit != NULL && edit->pathcache != NULL) {
- particle_batch_cache_fill_segments_proc_pos(edit->pathcache, edit->totcached, &pos_step);
- }
- else {
- if ((psys->pathcache != NULL) &&
- (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) {
- particle_batch_cache_fill_segments_proc_pos(psys->pathcache, psys->totpart, &pos_step);
+ 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);
+
+ if (edit != NULL && edit->pathcache != NULL) {
+ particle_batch_cache_fill_segments_proc_pos(
+ edit->pathcache, edit->totcached, &pos_step, &length_step);
}
- if (psys->childcache) {
- const int child_count = psys->totchild * psys->part->disp / 100;
- particle_batch_cache_fill_segments_proc_pos(psys->childcache, child_count, &pos_step);
+ else {
+ if ((psys->pathcache != NULL) &&
+ (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) {
+ particle_batch_cache_fill_segments_proc_pos(
+ psys->pathcache, psys->totpart, &pos_step, &length_step);
+ }
+ if (psys->childcache) {
+ const int child_count = psys->totchild * psys->part->disp / 100;
+ particle_batch_cache_fill_segments_proc_pos(
+ psys->childcache, child_count, &pos_step, &length_step);
+ }
}
- }
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(cache->proc_point_buf);
+ /* Create vbo immediately to bind to texture buffer. */
+ GPU_vertbuf_use(cache->proc_point_buf);
+ cache->point_tex = GPU_texture_create_from_vertbuf("part_point", cache->proc_point_buf);
+ }
- cache->point_tex = GPU_texture_create_from_vertbuf("part_point", cache->proc_point_buf);
+ /* Checking hair length separately, only allocating gpu memory when needed. */
+ if (gpu_material && cache->proc_length_buf != NULL && cache->length_tex == NULL) {
+ 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);
+ break;
+ }
+ }
+ }
}
static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
@@ -1649,6 +1679,7 @@ bool particles_ensure_procedural_data(Object *object,
ParticleSystem *psys,
ModifierData *md,
ParticleHairCache **r_hair_cache,
+ GPUMaterial *gpu_material,
int subdiv,
int thickness_res)
{
@@ -1666,9 +1697,11 @@ bool particles_ensure_procedural_data(Object *object,
(*r_hair_cache)->final[subdiv].strands_res = 1 << (part->draw_step + subdiv);
/* Refreshed on combing and simulation. */
- if ((*r_hair_cache)->proc_point_buf == NULL) {
+ if ((*r_hair_cache)->proc_point_buf == NULL ||
+ (gpu_material && (*r_hair_cache)->length_tex == NULL)) {
ensure_seg_pt_count(source.edit, source.psys, &cache->hair);
- particle_batch_cache_ensure_procedural_pos(source.edit, source.psys, &cache->hair);
+ particle_batch_cache_ensure_procedural_pos(
+ source.edit, source.psys, &cache->hair, gpu_material);
need_ft_update = true;
}