diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index b4a6cd38c6c..4d3f7d55c42 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -6376,6 +6376,9 @@ class VIEW3D_PT_overlay_object(Panel): sub = split.column(align=True) sub.prop(overlay, "show_extras", text="Extras") + subsub = sub.column() + subsub.active = overlay.show_extras + subsub.prop(overlay, "show_light_colors") sub.prop(overlay, "show_relationship_lines") sub.prop(overlay, "show_outline_selected") diff --git a/source/blender/draw/engines/overlay/overlay_extra.cc b/source/blender/draw/engines/overlay/overlay_extra.cc index 88978750766..6f32c3ae6ac 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.cc +++ b/source/blender/draw/engines/overlay/overlay_extra.cc @@ -123,6 +123,9 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata) cb->field_tube_limit = BUF_INSTANCE(grp_sub, format, DRW_cache_field_tube_limit_get()); cb->field_vortex = BUF_INSTANCE(grp_sub, format, DRW_cache_field_vortex_get()); cb->field_wind = BUF_INSTANCE(grp_sub, format, DRW_cache_field_wind_get()); + cb->light_icon_inner = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_inner_lines_get()); + cb->light_icon_outer = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_outer_lines_get()); + cb->light_icon_sun_rays = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_sun_rays_get()); cb->light_area[0] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_disk_lines_get()); cb->light_area[1] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_square_lines_get()); cb->light_point = BUF_INSTANCE(grp_sub, format, DRW_cache_light_point_lines_get()); @@ -605,8 +608,9 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) Light *la = static_cast(ob->data); float *color_p; DRW_object_wire_theme_get(ob, view_layer, &color_p); + /* Remove the alpha. */ - float color[4] = {UNPACK3(color_p), 1.0f}; + float theme_color[4] = {UNPACK3(color_p), 1.0f}; /* Pack render data into object matrix. */ union { float mat[4][4]; @@ -636,12 +640,25 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) DRW_buffer_add_entry(cb->groundline, instdata.pos); + float light_color[4] = {1.0f}; + const bool show_light_colors = vedata->stl->pd->overlay.flag & V3D_OVERLAY_SHOW_LIGHT_COLORS; + if (show_light_colors) { + copy_v3_v3(light_color, &la->r); + } + + /* Draw the outer ring of the light icon and the sun rays in `light_color`, if required. */ + DRW_buffer_add_entry( + cb->light_icon_outer, show_light_colors ? light_color : theme_color, &instdata); + DRW_buffer_add_entry(cb->light_icon_inner, theme_color, &instdata); + if (la->type == LA_LOCAL) { instdata.area_size_x = instdata.area_size_y = la->radius; - DRW_buffer_add_entry(cb->light_point, color, &instdata); + DRW_buffer_add_entry(cb->light_point, theme_color, &instdata); } else if (la->type == LA_SUN) { - DRW_buffer_add_entry(cb->light_sun, color, &instdata); + DRW_buffer_add_entry(cb->light_sun, theme_color, &instdata); + DRW_buffer_add_entry( + cb->light_icon_sun_rays, show_light_colors ? light_color : theme_color, &instdata); } else if (la->type == LA_SPOT) { /* Previous implementation was using the clip-end distance as cone size. @@ -664,8 +681,8 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) instdata.spot_blend = sqrtf((a2 - a2 * c2) / (c2 - a2 * c2)); instdata.spot_cosine = a; /* HACK: We pack the area size in alpha color. This is decoded by the shader. */ - color[3] = -max_ff(la->radius, FLT_MIN); - DRW_buffer_add_entry(cb->light_spot, color, &instdata); + theme_color[3] = -max_ff(la->radius, FLT_MIN); + DRW_buffer_add_entry(cb->light_spot, theme_color, &instdata); if ((la->mode & LA_SHOW_CONE) && !DRW_state_is_select()) { const float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f}; @@ -679,7 +696,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) int sqr = ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_RECT); instdata.area_size_x = la->area_size; instdata.area_size_y = uniform_scale ? la->area_size : la->area_sizey; - DRW_buffer_add_entry(cb->light_area[sqr], color, &instdata); + DRW_buffer_add_entry(cb->light_area[sqr], theme_color, &instdata); } } diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index b4b1867a08f..6c6e5cc7fbd 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -178,6 +178,9 @@ typedef struct OVERLAY_ExtraCallBuffers { DRWCallBuffer *groundline; + DRWCallBuffer *light_icon_inner; + DRWCallBuffer *light_icon_outer; + DRWCallBuffer *light_icon_sun_rays; DRWCallBuffer *light_point; DRWCallBuffer *light_sun; DRWCallBuffer *light_spot; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index abe3283bab7..0d346d56de6 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -116,6 +116,9 @@ static struct DRWShapeCache { GPUBatch *drw_field_cone_limit; GPUBatch *drw_field_sphere_limit; GPUBatch *drw_ground_line; + GPUBatch *drw_light_icon_inner_lines; + GPUBatch *drw_light_icon_outer_lines; + GPUBatch *drw_light_icon_sun_rays; GPUBatch *drw_light_point_lines; GPUBatch *drw_light_sun_lines; GPUBatch *drw_light_spot_lines; @@ -1461,21 +1464,90 @@ GPUBatch *DRW_cache_groundline_get(void) return SHC.drw_ground_line; } -GPUBatch *DRW_cache_light_point_lines_get(void) +GPUBatch *DRW_cache_light_icon_inner_lines_get(void) { - if (!SHC.drw_light_point_lines) { + if (!SHC.drw_light_icon_inner_lines) { GPUVertFormat format = extra_vert_format(); - int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS); + int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS); GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, v_len); const float r = 9.0f; int v = 0; - /* Light Icon */ + circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE); circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE); + + SHC.drw_light_icon_inner_lines = GPU_batch_create_ex( + GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_light_icon_inner_lines; +} + +GPUBatch *DRW_cache_light_icon_outer_lines_get(void) +{ + if (!SHC.drw_light_icon_outer_lines) { + GPUVertFormat format = extra_vert_format(); + + int v_len = 2 * OUTER_NSEGMENTS; + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, v_len); + + const float r = 9.0f; + int v = 0; + circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE); + + SHC.drw_light_icon_outer_lines = GPU_batch_create_ex( + GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_light_icon_outer_lines; +} + +GPUBatch *DRW_cache_light_icon_sun_rays_get(void) +{ + if (!SHC.drw_light_icon_sun_rays) { + GPUVertFormat format = extra_vert_format(); + + const int num_rays = 8; + int v_len = 4 * num_rays; + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, v_len); + + const float r = 9.0f; + + int v = 0; + + /* Sun Rays */ + for (int a = 0; a < num_rays; a++) { + float angle = (2.0f * M_PI * a) / (float)num_rays; + float s = sinf(angle) * r; + float c = cosf(angle) * r; + GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE}); + GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE}); + GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE}); + GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE}); + } + + SHC.drw_light_icon_sun_rays = GPU_batch_create_ex( + GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_light_icon_sun_rays; +} + +GPUBatch *DRW_cache_light_point_lines_get(void) +{ + if (!SHC.drw_light_point_lines) { + GPUVertFormat format = extra_vert_format(); + + int v_len = 2 * CIRCLE_NSEGMENTS; + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, v_len); + + int v = 0; + /* Light area */ int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE; circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag); @@ -1490,26 +1562,12 @@ GPUBatch *DRW_cache_light_sun_lines_get(void) if (!SHC.drw_light_sun_lines) { GPUVertFormat format = extra_vert_format(); - int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + 8 * 2 + 1); + int v_len = 2; GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, v_len); - const float r = 9.0f; int v = 0; - /* Light Icon */ - circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE); - /* Sun Rays */ - for (int a = 0; a < 8; a++) { - float angle = (2.0f * M_PI * a) / 8.0f; - float s = sinf(angle) * r; - float c = cosf(angle) * r; - GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE}); - GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE}); - GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE}); - GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE}); - } + /* Direction Line */ GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0, 0.0, 0.0}, 0}); GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0, 0.0, -20.0}, 0}); /* Good default. */ @@ -1524,17 +1582,12 @@ GPUBatch *DRW_cache_light_spot_lines_get(void) if (!SHC.drw_light_spot_lines) { GPUVertFormat format = extra_vert_format(); - int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + - CIRCLE_NSEGMENTS * 4 + 1); + int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS * 4 + 1); GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, v_len); - const float r = 9.0f; int v = 0; - /* Light Icon */ - circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE); + /* Light area */ int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE; circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag); @@ -1597,17 +1650,12 @@ GPUBatch *DRW_cache_light_area_disk_lines_get(void) if (!SHC.drw_light_area_disk_lines) { GPUVertFormat format = extra_vert_format(); - int v_len = 2 * - (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS + 1); + int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS + 1); GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, v_len); - const float r = 9.0f; int v = 0; - /* Light Icon */ - circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE); + /* Light area */ circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 0.5f, 0.0f, VCLASS_LIGHT_AREA_SHAPE); /* Direction Line */ @@ -1630,15 +1678,11 @@ GPUBatch *DRW_cache_light_area_square_lines_get(void) GPUVertFormat format = extra_vert_format(); GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + 4 + 1); + int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + 4 + 1); GPU_vertbuf_data_alloc(vbo, v_len); - const float r = 9.0f; int v = 0; - /* Light Icon */ - circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE); - circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE); + /* Light area */ int flag = VCLASS_LIGHT_AREA_SHAPE; for (int a = 0; a < 4; a++) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 772cf3b12a5..d1f09d235b1 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -106,6 +106,9 @@ struct GPUBatch *DRW_cache_field_sphere_limit_get(void); /* Lights */ +struct GPUBatch *DRW_cache_light_icon_inner_lines_get(void); +struct GPUBatch *DRW_cache_light_icon_outer_lines_get(void); +struct GPUBatch *DRW_cache_light_icon_sun_rays_get(void); struct GPUBatch *DRW_cache_light_point_lines_get(void); struct GPUBatch *DRW_cache_light_sun_lines_get(void); struct GPUBatch *DRW_cache_light_spot_lines_get(void); diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index d01e8158ce0..ff82cd2183f 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -552,6 +552,7 @@ enum { V3D_OVERLAY_SCULPT_SHOW_MASK = (1 << 14), V3D_OVERLAY_SCULPT_SHOW_FACE_SETS = (1 << 15), V3D_OVERLAY_SCULPT_CURVES_CAGE = (1 << 16), + V3D_OVERLAY_SHOW_LIGHT_COLORS = (1 << 17), }; /** #View3DOverlay.edit_flag */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 7cd68e475b4..1aea7338283 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -4407,6 +4407,11 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna) prop, "Extras", "Object details, including empty wire, cameras and other visual guides"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_light_colors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_SHOW_LIGHT_COLORS); + RNA_def_property_ui_text(prop, "Light Colors", "Show light colors"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_bones", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_HIDE_BONES); RNA_def_property_ui_text(