diff options
-rw-r--r-- | source/blender/draw/intern/draw_common.c | 16 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 192 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl | 7 |
4 files changed, 184 insertions, 32 deletions
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 8d23688959c..68a82d017cf 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -332,6 +332,22 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Gwn_Batch *geom) return grp; } +DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct Gwn_Batch *geom, int *baseid) +{ + GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_ID_VARIYING_SIZE); + + DRW_shgroup_instance_format(g_formats.instance_sized, { + {"callId" , DRW_ATTRIB_INT, 1}, + {"size" , DRW_ATTRIB_FLOAT, 1}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized); + DRW_shgroup_uniform_int(grp, "baseId", baseid, 1); + + return grp; +} + DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Gwn_Batch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA); diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index ec646693207..c70a1a38e62 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -114,6 +114,7 @@ struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct struct DRWShadingGroup *shgroup_instance_image_plane(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Gwn_Batch *geom); +struct DRWShadingGroup *shgroup_instance_outline(struct DRWPass *pass, struct Gwn_Batch *geom, int *baseid); struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Gwn_Batch *geom); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index efbd43f6aac..c9ef8640031 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -86,6 +86,7 @@ extern char datatoc_object_particle_dot_frag_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_common_fxaa_lib_glsl[]; extern char datatoc_gpu_shader_flat_color_frag_glsl[]; +extern char datatoc_gpu_shader_flat_id_frag_glsl[]; extern char datatoc_common_fullscreen_vert_glsl[]; extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; @@ -208,8 +209,17 @@ typedef struct OBJECT_PrivateData { DRWShadingGroup *outlines_transform; /* Lightprobes */ - DRWShadingGroup *lightprobes_cube; - DRWShadingGroup *lightprobes_planar; + DRWShadingGroup *lightprobes_cube_select; + DRWShadingGroup *lightprobes_cube_select_group; + DRWShadingGroup *lightprobes_cube_active; + DRWShadingGroup *lightprobes_cube_active_group; + DRWShadingGroup *lightprobes_cube_transform; + + DRWShadingGroup *lightprobes_planar_select; + DRWShadingGroup *lightprobes_planar_select_group; + DRWShadingGroup *lightprobes_planar_active; + DRWShadingGroup *lightprobes_planar_active_group; + DRWShadingGroup *lightprobes_planar_transform; /* Wire */ DRWShadingGroup *wire; @@ -233,6 +243,11 @@ typedef struct OBJECT_PrivateData { int id_ofs_select; int id_ofs_select_group; int id_ofs_transform; + int id_ofs_prb_active; + int id_ofs_prb_active_group; + int id_ofs_prb_select; + int id_ofs_prb_select_group; + int id_ofs_prb_transform; } OBJECT_PrivateData; /* Transient data */ static struct { @@ -381,7 +396,7 @@ static void OBJECT_engine_init(void *vedata) /* Lightprobes */ e_data.lightprobe_grid_sh = DRW_shader_create( - datatoc_object_lightprobe_grid_vert_glsl, NULL, datatoc_gpu_shader_uniform_color_frag_glsl, NULL); + datatoc_object_lightprobe_grid_vert_glsl, NULL, datatoc_gpu_shader_flat_id_frag_glsl, NULL); } { @@ -608,24 +623,96 @@ static DRWShadingGroup *shgroup_points(DRWPass *pass, const float col[4], GPUSha return grp; } +static int *shgroup_theme_id_to_probe_outline_counter( + OBJECT_StorageList *stl, int theme_id) +{ + switch (theme_id) { + case TH_ACTIVE: + return &stl->g_data->id_ofs_prb_active; + case TH_SELECT: + return &stl->g_data->id_ofs_prb_select; + case TH_GROUP: + return &stl->g_data->id_ofs_prb_select_group; + case TH_GROUP_ACTIVE: + return &stl->g_data->id_ofs_prb_active_group; + case TH_TRANSFORM: + default: + return &stl->g_data->id_ofs_prb_transform; + } +} + +static int *shgroup_theme_id_to_outline_counter( + OBJECT_StorageList *stl, int theme_id) +{ + switch (theme_id) { + case TH_ACTIVE: + return &stl->g_data->id_ofs_active; + case TH_SELECT: + return &stl->g_data->id_ofs_select; + case TH_GROUP: + return &stl->g_data->id_ofs_select_group; + case TH_GROUP_ACTIVE: + return &stl->g_data->id_ofs_active_group; + case TH_TRANSFORM: + default: + return &stl->g_data->id_ofs_transform; + } +} + +static DRWShadingGroup *shgroup_theme_id_to_probe_planar_outline_shgrp( + OBJECT_StorageList *stl, int theme_id) +{ + /* does not increment counter */ + switch (theme_id) { + case TH_ACTIVE: + return stl->g_data->lightprobes_planar_active; + case TH_SELECT: + return stl->g_data->lightprobes_planar_select; + case TH_GROUP: + return stl->g_data->lightprobes_planar_select_group; + case TH_GROUP_ACTIVE: + return stl->g_data->lightprobes_planar_active_group; + case TH_TRANSFORM: + default: + return stl->g_data->lightprobes_planar_transform; + } +} + +static DRWShadingGroup *shgroup_theme_id_to_probe_cube_outline_shgrp( + OBJECT_StorageList *stl, int theme_id) +{ + /* does not increment counter */ + switch (theme_id) { + case TH_ACTIVE: + return stl->g_data->lightprobes_cube_active; + case TH_SELECT: + return stl->g_data->lightprobes_cube_select; + case TH_GROUP: + return stl->g_data->lightprobes_cube_select_group; + case TH_GROUP_ACTIVE: + return stl->g_data->lightprobes_cube_active_group; + case TH_TRANSFORM: + default: + return stl->g_data->lightprobes_cube_transform; + } +} + static DRWShadingGroup *shgroup_theme_id_to_outline_or( OBJECT_StorageList *stl, int theme_id, DRWShadingGroup *fallback) { + int *counter = shgroup_theme_id_to_outline_counter(stl, theme_id); + *counter += 1; + switch (theme_id) { case TH_ACTIVE: - stl->g_data->id_ofs_active++; return stl->g_data->outlines_active; case TH_SELECT: - stl->g_data->id_ofs_select++; return stl->g_data->outlines_select; case TH_GROUP: - stl->g_data->id_ofs_select_group++; return stl->g_data->outlines_select_group; case TH_GROUP_ACTIVE: - stl->g_data->id_ofs_active_group++; return stl->g_data->outlines_active_group; case TH_TRANSFORM: - stl->g_data->id_ofs_transform++; return stl->g_data->outlines_transform; default: return fallback; @@ -798,12 +885,15 @@ static void OBJECT_cache_init(void *vedata) OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl; OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + OBJECT_PrivateData *g_data; if (!stl->g_data) { /* Alloc transient pointers */ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); } + g_data = stl->g_data; + { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE; psl->outlines = DRW_pass_create("Outlines Depth Pass", state); @@ -811,32 +901,48 @@ static void OBJECT_cache_init(void *vedata) GPUShader *sh = e_data.outline_prepass_sh; /* Select */ - stl->g_data->outlines_select = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_select, sh); - stl->g_data->outlines_select_group = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_select_group, sh); + g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh); + g_data->outlines_select_group = shgroup_outline(psl->outlines, &g_data->id_ofs_select_group, sh); /* Transform */ - stl->g_data->outlines_transform = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_transform, sh); + g_data->outlines_transform = shgroup_outline(psl->outlines, &g_data->id_ofs_transform, sh); /* Active */ - stl->g_data->outlines_active = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_active, sh); - stl->g_data->outlines_active_group = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_active_group, sh); + g_data->outlines_active = shgroup_outline(psl->outlines, &g_data->id_ofs_active, sh); + g_data->outlines_active_group = shgroup_outline(psl->outlines, &g_data->id_ofs_active_group, sh); - stl->g_data->id_ofs_select = 0; - stl->g_data->id_ofs_select_group = 0; - stl->g_data->id_ofs_active = 0; - stl->g_data->id_ofs_active_group = 0; - stl->g_data->id_ofs_transform = 0; + g_data->id_ofs_select = 0; + g_data->id_ofs_select_group = 0; + g_data->id_ofs_active = 0; + g_data->id_ofs_active_group = 0; + g_data->id_ofs_transform = 0; } { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; - psl->lightprobes = DRW_pass_create("Object Probe Pass", state); + DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state); + struct Gwn_Batch *sphere = DRW_cache_sphere_get(); + struct Gwn_Batch *quad = DRW_cache_quad_get(); /* Cubemap */ - stl->g_data->lightprobes_cube = shgroup_instance(psl->lightprobes, DRW_cache_sphere_get()); + g_data->lightprobes_cube_select = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_select); + g_data->lightprobes_cube_select_group = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_select_group); + g_data->lightprobes_cube_active = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_active); + g_data->lightprobes_cube_active_group = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_active_group); + g_data->lightprobes_cube_transform = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_transform); /* Planar */ - stl->g_data->lightprobes_planar = shgroup_instance(psl->lightprobes, DRW_cache_quad_get()); + g_data->lightprobes_planar_select = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_select); + g_data->lightprobes_planar_select_group = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_select_group); + g_data->lightprobes_planar_active = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_active); + g_data->lightprobes_planar_active_group = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_active_group); + g_data->lightprobes_planar_transform = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_transform); + + g_data->id_ofs_prb_select = 0; + g_data->id_ofs_prb_select_group = 0; + g_data->id_ofs_prb_active = 0; + g_data->id_ofs_prb_active_group = 0; + g_data->id_ofs_prb_transform = 0; } { @@ -1596,7 +1702,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl static float one = 1.0f; LightProbe *prb = (LightProbe *)ob->data; bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0); - DRW_object_wire_theme_get(ob, view_layer, &color); + int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color); OBJECT_LightProbeEngineData *prb_data = (OBJECT_LightProbeEngineData *)DRW_object_engine_data_ensure( @@ -1607,6 +1713,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl NULL); if ((DRW_state_is_select() || do_outlines) && ((prb->flag & LIGHTPROBE_FLAG_SHOW_DATA) != 0)) { + int *call_id = shgroup_theme_id_to_probe_outline_counter(stl, theme_id); if (prb->type == LIGHTPROBE_TYPE_GRID) { /* Update transforms */ @@ -1643,7 +1750,8 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl prb_data->cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z; DRWShadingGroup *grp = DRW_shgroup_create(e_data.lightprobe_grid_sh, psl->lightprobes); - DRW_shgroup_uniform_vec4(grp, "color", color, 1); + DRW_shgroup_uniform_int_copy(grp, "call_id", *call_id); + DRW_shgroup_uniform_int(grp, "baseId", call_id, 1); /* that's correct */ DRW_shgroup_uniform_vec3(grp, "corner", prb_data->corner, 1); DRW_shgroup_uniform_vec3(grp, "increment_x", prb_data->increment_x, 1); DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1); @@ -1656,12 +1764,18 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl prb_data->draw_size = prb->data_draw_size * 0.1f; unit_m4(prb_data->probe_cube_mat); copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]); - DRW_shgroup_call_dynamic_add(stl->g_data->lightprobes_cube, color, &prb_data->draw_size, prb_data->probe_cube_mat); + + DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id); + DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, prb_data->probe_cube_mat); } else { prb_data->draw_size = 1.0f; - DRW_shgroup_call_dynamic_add(stl->g_data->lightprobes_planar, color, &prb_data->draw_size, ob->obmat); + + DRWShadingGroup *grp = shgroup_theme_id_to_probe_planar_outline_shgrp(stl, theme_id); + DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, ob->obmat); } + + *call_id += 1; } switch (prb->type) { @@ -2072,12 +2186,20 @@ static void OBJECT_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - int id_ct_select = g_data->id_ofs_select; + int id_ct_select = g_data->id_ofs_select; int id_ct_select_group = g_data->id_ofs_select_group; - int id_ct_active = g_data->id_ofs_active; + int id_ct_active = g_data->id_ofs_active; int id_ct_active_group = g_data->id_ofs_active_group; - int id_ct_transform = g_data->id_ofs_transform; + int id_ct_transform = g_data->id_ofs_transform; + + int id_ct_prb_select = g_data->id_ofs_prb_select; + int id_ct_prb_select_group = g_data->id_ofs_prb_select_group; + int id_ct_prb_active = g_data->id_ofs_prb_active; + int id_ct_prb_active_group = g_data->id_ofs_prb_active_group; + int id_ct_prb_transform = g_data->id_ofs_prb_transform; + int outline_calls = id_ct_select + id_ct_select_group + id_ct_active + id_ct_active_group + id_ct_transform; + outline_calls += id_ct_prb_select + id_ct_prb_select_group + id_ct_prb_active + id_ct_prb_active_group + id_ct_prb_transform; float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -2085,10 +2207,16 @@ static void OBJECT_draw_scene(void *vedata) DRW_stats_group_start("Outlines"); g_data->id_ofs_active = 1; - g_data->id_ofs_active_group = g_data->id_ofs_active + id_ct_active + 1; - g_data->id_ofs_select = g_data->id_ofs_active_group + id_ct_active_group + 1; - g_data->id_ofs_select_group = g_data->id_ofs_select + id_ct_select + 1; - g_data->id_ofs_transform = g_data->id_ofs_select_group + id_ct_select_group + 1; + g_data->id_ofs_active_group = g_data->id_ofs_active + id_ct_active + id_ct_prb_active + 1; + g_data->id_ofs_select = g_data->id_ofs_active_group + id_ct_active_group + id_ct_prb_active_group + 1; + g_data->id_ofs_select_group = g_data->id_ofs_select + id_ct_select + id_ct_prb_select + 1; + g_data->id_ofs_transform = g_data->id_ofs_select_group + id_ct_select_group + id_ct_prb_select_group + 1; + + g_data->id_ofs_prb_active = g_data->id_ofs_active + id_ct_active; + g_data->id_ofs_prb_active_group = g_data->id_ofs_active_group + id_ct_active_group; + g_data->id_ofs_prb_select = g_data->id_ofs_select + id_ct_select; + g_data->id_ofs_prb_select_group = g_data->id_ofs_select_group + id_ct_select_group; + g_data->id_ofs_prb_transform = g_data->id_ofs_transform + id_ct_transform; /* Render filled polygon on a separate framebuffer */ GPU_framebuffer_bind(fbl->outlines_fb); diff --git a/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl index b47b3ee1cf4..85a656df906 100644 --- a/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl +++ b/source/blender/draw/modes/shaders/object_lightprobe_grid_vert.glsl @@ -11,6 +11,11 @@ uniform vec3 increment_x; uniform vec3 increment_y; uniform vec3 increment_z; +uniform int call_id; /* we don't want the builtin callId which would be 0. */ +uniform int baseId; + +flat out uint finalId; + void main() { vec3 ls_cell_location; @@ -25,4 +30,6 @@ void main() increment_z * ls_cell_location.z); gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 * sphere_size + ws_cell_location, 1.0); + + finalId = uint(baseId + call_id); }
\ No newline at end of file |