Commit: 845732652fa7a3d3a053006d30a76ea39fdc3c47
Author: Luca Rood
Date:   Mon May 22 12:14:37 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB845732652fa7a3d3a053006d30a76ea39fdc3c47

Implement UBOs for particles

This fixes the issue where all particles were drawn with the colors and
size of the last psys to be drawn.

===================================================================

M       source/blender/draw/CMakeLists.txt
D       source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl
M       source/blender/draw/modes/object_mode.c
A       source/blender/draw/modes/shaders/particle_dot_frag.glsl
A       source/blender/draw/modes/shaders/particle_dot_vert.glsl
A       source/blender/draw/modes/shaders/particle_prim_frag.glsl
R080    source/blender/draw/engines/clay/shaders/particle_prim_vert.glsl        
source/blender/draw/modes/shaders/particle_prim_vert.glsl

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt 
b/source/blender/draw/CMakeLists.txt
index 3bfa9a15ce3..9bd208b823e 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -111,8 +111,6 @@ data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC)
 data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
 data_to_c_simple(engines/clay/shaders/particle_vert.glsl SRC)
 data_to_c_simple(engines/clay/shaders/particle_strand_frag.glsl SRC)
-data_to_c_simple(engines/clay/shaders/particle_prim_vert.glsl SRC)
-data_to_c_simple(engines/clay/shaders/particle_prim_frag.glsl SRC)
 
 data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
@@ -167,6 +165,10 @@ data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC)
 data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC)
+data_to_c_simple(modes/shaders/particle_prim_vert.glsl SRC)
+data_to_c_simple(modes/shaders/particle_prim_frag.glsl SRC)
+data_to_c_simple(modes/shaders/particle_dot_vert.glsl SRC)
+data_to_c_simple(modes/shaders/particle_dot_frag.glsl SRC)
 
 list(APPEND INC
 )
diff --git a/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl 
b/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl
deleted file mode 100644
index 50572f293d9..00000000000
--- a/source/blender/draw/engines/clay/shaders/particle_prim_frag.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-
-uniform vec4 color;
-
-flat in int finalAxis;
-
-out vec4 fragColor;
-
-void main()
-{
-       if (finalAxis == -1) {
-               fragColor = color;
-       }
-       else {
-               vec4 col = vec4(0.0);
-               col[finalAxis] = 1.0;
-               col.a = 1.0;
-               fragColor = col;
-       }
-}
diff --git a/source/blender/draw/modes/object_mode.c 
b/source/blender/draw/modes/object_mode.c
index 21f5ad97b3d..fb105a8c7e5 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -56,6 +56,8 @@
 #include "draw_manager_text.h"
 #include "draw_common.h"
 
+#define MAX_OBJECT_MAT 512 /* 512 = 9 bit material id */
+
 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
 extern GlobalsUboStorage ts;
 
@@ -68,9 +70,30 @@ extern char datatoc_object_empty_image_frag_glsl[];
 extern char datatoc_object_empty_image_vert_glsl[];
 extern char datatoc_particle_prim_vert_glsl[];
 extern char datatoc_particle_prim_frag_glsl[];
+extern char datatoc_particle_dot_vert_glsl[];
+extern char datatoc_particle_dot_frag_glsl[];
 extern char datatoc_common_globals_lib_glsl[];
 
 /* *********** LISTS *********** */
+
+/**
+ * UBOs data needs to be 16 byte aligned (size of vec4)
+ *
+ * Reminder: float, int, bool are 4 bytes
+ *
+ * \note struct is expected to be initialized with all pad-bits zero'd
+ * so we can use 'memcmp' to check for duplicates. Possibly hash data later.
+ */
+typedef struct OBJECT_PARTICLE_UBO_Material {
+       float prim_color[3];
+       float pad1;
+       /* - 16 -*/
+       float sec_color[3];
+       float size;
+       /* - 16 -*/
+} OBJECT_PARTICLE_UBO_Material; /* 32 bytes */
+BLI_STATIC_ASSERT_ALIGN(OBJECT_PARTICLE_UBO_Material, 16)
+
 typedef struct OBJECT_PassList {
        struct DRWPass *non_meshes;
        struct DRWPass *ob_center;
@@ -95,7 +118,19 @@ typedef struct OBJECT_FramebufferList {
        struct GPUFrameBuffer *blur;
 } OBJECT_FramebufferList;
 
+typedef struct OBJECT_Storage {
+       /* Materials Parameter UBO */
+       OBJECT_PARTICLE_UBO_Material materials[MAX_OBJECT_MAT];
+       int particle_ubo_current_id;
+       DRWShadingGroup *part_dot_shgrps[MAX_OBJECT_MAT];
+       DRWShadingGroup *part_cross_shgrps[MAX_OBJECT_MAT];
+       DRWShadingGroup *part_circle_shgrps[MAX_OBJECT_MAT];
+       DRWShadingGroup *part_axis_shgrps[MAX_OBJECT_MAT];
+} OBJECT_Storage;
+
 typedef struct OBJECT_StorageList {
+       struct OBJECT_Storage *storage;
+       struct GPUUniformBuffer *part_mat_ubo;
        struct OBJECT_PrivateData *g_data;
 } OBJECT_StorageList;
 
@@ -186,12 +221,6 @@ typedef struct OBJECT_PrivateData{
        DRWShadingGroup *wire_select;
        DRWShadingGroup *wire_select_group;
        DRWShadingGroup *wire_transform;
-
-       /* Particles */
-       DRWShadingGroup *part_dot_shgrp;
-       DRWShadingGroup *part_cross_shgrp;
-       DRWShadingGroup *part_circle_shgrp;
-       DRWShadingGroup *part_axis_shgrp;
 } OBJECT_PrivateData; /* Transient data */
 
 static struct {
@@ -216,6 +245,8 @@ static struct {
        struct GPUTexture *outlines_depth_tx;
        struct GPUTexture *outlines_color_tx;
        struct GPUTexture *outlines_blur_tx;
+       /* Just a serie of int from 0 to MAX_CLAY_MAT-1 */
+       int ubo_mat_idxs[MAX_OBJECT_MAT];
 } e_data = {NULL}; /* Engine data */
 
 
@@ -235,6 +266,7 @@ enum {
 
 static void OBJECT_engine_init(void *vedata)
 {
+       OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
        OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
 
        const float *viewport_size = DRW_viewport_size_get();
@@ -292,11 +324,26 @@ static void OBJECT_engine_init(void *vedata)
        }
 
        if (!e_data.part_prim_sh) {
-               e_data.part_prim_sh = 
DRW_shader_create(datatoc_particle_prim_vert_glsl, NULL, 
datatoc_particle_prim_frag_glsl, NULL);
+               e_data.part_prim_sh = 
DRW_shader_create(datatoc_particle_prim_vert_glsl, NULL, 
datatoc_particle_prim_frag_glsl, "#define MAX_MATERIAL " 
STRINGIFY(MAX_OBJECT_MAT) "\n");
        }
 
        if (!e_data.part_dot_sh) {
-               e_data.part_dot_sh = 
GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+               e_data.part_dot_sh = 
DRW_shader_create(datatoc_particle_dot_vert_glsl, NULL, 
datatoc_particle_dot_frag_glsl, "#define MAX_MATERIAL " 
STRINGIFY(MAX_OBJECT_MAT) "\n");
+       }
+
+       if (e_data.ubo_mat_idxs[1] == 0) {
+               /* Just int to have pointers to them */
+               for (int i = 0; i < MAX_OBJECT_MAT; ++i) {
+                       e_data.ubo_mat_idxs[i] = i;
+               }
+       }
+
+       if (!stl->storage) {
+               stl->storage = MEM_callocN(sizeof(OBJECT_Storage), 
"OBJECT_Storage");
+       }
+
+       if (!stl->part_mat_ubo) {
+               stl->part_mat_ubo = 
DRW_uniformbuffer_create(sizeof(OBJECT_PARTICLE_UBO_Material) * MAX_OBJECT_MAT, 
NULL);
        }
 
        {
@@ -444,6 +491,7 @@ static void OBJECT_engine_free(void)
        DRW_SHADER_FREE_SAFE(e_data.object_empty_image_wire_sh);
        DRW_SHADER_FREE_SAFE(e_data.grid_sh);
        DRW_SHADER_FREE_SAFE(e_data.part_prim_sh);
+       DRW_SHADER_FREE_SAFE(e_data.part_dot_sh);
 }
 
 static DRWShadingGroup *shgroup_outline(DRWPass *pass, const float col[4], 
GPUShader *sh)
@@ -989,29 +1037,15 @@ static void OBJECT_cache_init(void *vedata)
 
        {
                /* Particle Pass */
-               psl->particle = DRW_pass_create("Particle Pass", 
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | 
DRW_STATE_POINT | DRW_STATE_BLEND);
-
-               static int screen_space[2] = {0, 1};
-
-               stl->g_data->part_dot_shgrp = 
DRW_shgroup_create(e_data.part_dot_sh, psl->particle);
-
-               stl->g_data->part_cross_shgrp = 
DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, 
DRW_cache_particles_get_prim(PART_DRAW_CROSS));
-               DRW_shgroup_uniform_int(stl->g_data->part_cross_shgrp, 
"screen_space", &screen_space[0], 1);
-               DRW_shgroup_uniform_float(stl->g_data->part_cross_shgrp, 
"pixel_size", DRW_viewport_pixelsize_get(), 1);
-               DRW_shgroup_attrib_float(stl->g_data->part_cross_shgrp, "pos", 
3);
-               DRW_shgroup_attrib_float(stl->g_data->part_cross_shgrp, "rot", 
4);
-
-               stl->g_data->part_circle_shgrp = 
DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, 
DRW_cache_particles_get_prim(PART_DRAW_CIRC));
-               DRW_shgroup_uniform_int(stl->g_data->part_circle_shgrp, 
"screen_space", &screen_space[1], 1);
-               DRW_shgroup_uniform_float(stl->g_data->part_circle_shgrp, 
"pixel_size", DRW_viewport_pixelsize_get(), 1);
-               DRW_shgroup_attrib_float(stl->g_data->part_circle_shgrp, "pos", 
3);
-               DRW_shgroup_attrib_float(stl->g_data->part_circle_shgrp, "rot", 
4);
-
-               stl->g_data->part_axis_shgrp = 
DRW_shgroup_instance_create(e_data.part_prim_sh, psl->particle, 
DRW_cache_particles_get_prim(PART_DRAW_AXIS));
-               DRW_shgroup_uniform_int(stl->g_data->part_axis_shgrp, 
"screen_space", &screen_space[0], 1);
-               DRW_shgroup_uniform_float(stl->g_data->part_axis_shgrp, 
"pixel_size", DRW_viewport_pixelsize_get(), 1);
-               DRW_shgroup_attrib_float(stl->g_data->part_axis_shgrp, "pos", 
3);
-               DRW_shgroup_attrib_float(stl->g_data->part_axis_shgrp, "rot", 
4);
+               psl->particle = DRW_pass_create(
+                                    "Particle Pass",
+                                    DRW_STATE_WRITE_COLOR | 
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_POINT | 
DRW_STATE_BLEND);
+
+               stl->storage->particle_ubo_current_id = 0;
+               memset(stl->storage->part_dot_shgrps, 0, sizeof(DRWShadingGroup 
*) * MAX_OBJECT_MAT);
+               memset(stl->storage->part_cross_shgrps, 0, 
sizeof(DRWShadingGroup *) * MAX_OBJECT_MAT);
+               memset(stl->storage->part_circle_shgrps, 0, 
sizeof(DRWShadingGroup *) * MAX_OBJECT_MAT);
+               memset(stl->storage->part_axis_shgrps, 0, 
sizeof(DRWShadingGroup *) * MAX_OBJECT_MAT);
        }
 }
 
@@ -1382,6 +1416,120 @@ static void 
DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob)
        DRW_shgroup_call_dynamic_add(shgroup, ob->obmat[3]);
 }
 
+static DRWShadingGroup *OBJECT_particle_shgroup_create(DRWPass *pass, int 
*material_id, OBJECT_PassList *psl, int part_type)
+{
+       DRWShadingGroup *grp;
+
+       if (part_type == PART_DRAW_DOT) {
+               grp = DRW_shgroup_create(e_data.part_dot_sh, pass);
+       }
+       else {
+               static int screen_space[2] = {0, 1};
+
+               grp = DRW_shgroup_instance_create(e_data.part_prim_sh, 
psl->particle, DRW_cache_particles_get_prim(part_type));
+               DRW_shgroup_uniform_int(grp, "screen_space", 
&screen_space[part_type == PART_DRAW_CIRC ? 1 : 0], 1);
+               DRW_shgroup_uniform_float(grp, "pixel_size", 
DRW_viewport_pixelsize_get(), 1);
+               DRW_shgroup_attrib_float(grp, "pos", 3);
+               DRW_shgroup_attrib_float(grp, "rot", 4);
+       }
+
+       DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
+
+       return grp;
+}
+
+static int search_particle_mat_to_ubo(OBJECT_Storage *storage, const 
OBJECT_PARTICLE_UBO_Material *particle_mat_ubo_test)
+{
+       for (int i = 0; i < storage->particle_ubo_current_id; i++) {
+               OBJECT_PARTICLE_UBO_Material *ubo = &storage->materials[i];
+               if (memcmp(ubo, particle_mat_ubo_test, 
sizeof(*particle_mat_ubo_test)) == 0) {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+static int push_particle_mat_to_ubo(OBJEC

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to