diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh index d2de4d3523f..1d28e64454f 100644 --- a/source/blender/editors/include/UI_interface_c.hh +++ b/source/blender/editors/include/UI_interface_c.hh @@ -493,7 +493,8 @@ void UI_draw_roundbox_4fv_ex(const rctf *rect, int UI_draw_roundbox_corner_get(); #endif -void UI_draw_box_shadow(const rctf *rect, unsigned char alpha); +void ui_draw_dropshadow(const rctf *rct, float radius, float width, float aspect, float alpha); + void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4]); /** diff --git a/source/blender/editors/interface/interface_draw.cc b/source/blender/editors/interface/interface_draw.cc index 2ddfdd74a7b..16cad5ef7d9 100644 --- a/source/blender/editors/interface/interface_draw.cc +++ b/source/blender/editors/interface/interface_draw.cc @@ -2178,108 +2178,20 @@ void ui_draw_but_TRACKPREVIEW(ARegion * /*region*/, /* ****************************************************** */ -/* TODO(merwin): high quality UI drop shadows using GLSL shader and single draw call - * would replace / modify the following 3 functions. */ - -static void ui_shadowbox(const rctf *rect, uint pos, uint color, float shadsize, uchar alpha) +void ui_draw_dropshadow( + const rctf *rct, const float radius, const float width, const float aspect, const float alpha) { - /** - *
- * v1-_ - * | -_v2 - * | | - * | | - * | | - * v7_______v3____v4 - * \ | / - * \ | _v5 - * v8______v6_- - *- */ - const float v1[2] = {rect->xmax, rect->ymax - 0.3f * shadsize}; - const float v2[2] = {rect->xmax + shadsize, rect->ymax - 0.75f * shadsize}; - const float v3[2] = {rect->xmax, rect->ymin}; - const float v4[2] = {rect->xmax + shadsize, rect->ymin}; + if (width == 0.0f) { + return; + } - const float v5[2] = {rect->xmax + 0.7f * shadsize, rect->ymin - 0.7f * shadsize}; - - const float v6[2] = {rect->xmax, rect->ymin - shadsize}; - const float v7[2] = {rect->xmin + 0.3f * shadsize, rect->ymin}; - const float v8[2] = {rect->xmin + 0.5f * shadsize, rect->ymin - shadsize}; - - /* right quad */ - immAttr4ub(color, 0, 0, 0, alpha); - immVertex2fv(pos, v3); - immVertex2fv(pos, v1); - immAttr4ub(color, 0, 0, 0, 0); - immVertex2fv(pos, v2); - - immVertex2fv(pos, v2); - immVertex2fv(pos, v4); - immAttr4ub(color, 0, 0, 0, alpha); - immVertex2fv(pos, v3); - - /* corner shape */ - // immAttr4ub(color, 0, 0, 0, alpha); /* Not needed, done above in previous tri. */ - immVertex2fv(pos, v3); - immAttr4ub(color, 0, 0, 0, 0); - immVertex2fv(pos, v4); - immVertex2fv(pos, v5); - - immVertex2fv(pos, v5); - immVertex2fv(pos, v6); - immAttr4ub(color, 0, 0, 0, alpha); - immVertex2fv(pos, v3); - - /* bottom quad */ - // immAttr4ub(color, 0, 0, 0, alpha); /* Not needed, done above in previous tri. */ - immVertex2fv(pos, v3); - immAttr4ub(color, 0, 0, 0, 0); - immVertex2fv(pos, v6); - immVertex2fv(pos, v8); - - immVertex2fv(pos, v8); - immAttr4ub(color, 0, 0, 0, alpha); - immVertex2fv(pos, v7); - immVertex2fv(pos, v3); -} - -void UI_draw_box_shadow(const rctf *rect, uchar alpha) -{ - GPU_blend(GPU_BLEND_ALPHA); - - GPUVertFormat *format = immVertexFormat(); - const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint color = GPU_vertformat_attr_add( - format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); - - immBegin(GPU_PRIM_TRIS, 54); - - /* accumulated outline boxes to make shade not linear, is more pleasant */ - ui_shadowbox(rect, pos, color, 11.0, (20 * alpha) >> 8); - ui_shadowbox(rect, pos, color, 7.0, (40 * alpha) >> 8); - ui_shadowbox(rect, pos, color, 5.0, (80 * alpha) >> 8); - - immEnd(); - - immUnbindProgram(); - - GPU_blend(GPU_BLEND_NONE); -} - -void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int /*select*/) -{ /* This undoes the scale of the view for higher zoom factors to clamp the shadow size. */ const float clamped_aspect = smoothminf(aspect, 1.0f, 0.5f); + const float shadow_width = width * clamped_aspect; + const float shadow_offset = min_ff(shadow_width, BLI_rctf_size_y(rct) - 2.0f * radius); - const float shadow_softness = 0.6f * U.widget_unit * clamped_aspect; - const float shadow_offset = 0.5f * U.widget_unit * clamped_aspect; - const float shadow_alpha = 0.5f * alpha; - - const float max_radius = (BLI_rctf_size_y(rct) - shadow_offset) * 0.5f; - const float rad = min_ff(radius, max_radius); + const float inner_radius = max_ff(radius - U.pixelsize, 0.0); + const float shadow_radius = radius + shadow_width - U.pixelsize; GPU_blend(GPU_BLEND_ALPHA); @@ -2287,13 +2199,13 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha widget_params.recti.xmin = rct->xmin; widget_params.recti.ymin = rct->ymin; widget_params.recti.xmax = rct->xmax; - widget_params.recti.ymax = rct->ymax - shadow_offset; - widget_params.rect.xmin = rct->xmin - shadow_softness; - widget_params.rect.ymin = rct->ymin - shadow_softness; - widget_params.rect.xmax = rct->xmax + shadow_softness; - widget_params.rect.ymax = rct->ymax - shadow_offset + shadow_softness; - widget_params.radi = rad; - widget_params.rad = rad + shadow_softness; + widget_params.recti.ymax = rct->ymax; + widget_params.rect.xmin = rct->xmin - shadow_width; + widget_params.rect.ymin = rct->ymin - shadow_width; + widget_params.rect.xmax = rct->xmax + shadow_width; + widget_params.rect.ymax = rct->ymax + shadow_width - shadow_offset; + widget_params.radi = inner_radius; + widget_params.rad = shadow_radius; widget_params.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f; widget_params.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f; widget_params.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f; @@ -2303,17 +2215,8 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha GPUBatch *batch = ui_batch_roundbox_shadow_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW); GPU_batch_uniform_4fv_array(batch, "parameters", 4, (const float(*)[4]) & widget_params); - GPU_batch_uniform_1f(batch, "alpha", shadow_alpha); + GPU_batch_uniform_1f(batch, "alpha", alpha); GPU_batch_draw(batch); - /* outline emphasis */ - const float color[4] = {0.0f, 0.0f, 0.0f, 0.4f}; - rctf rect{}; - rect.xmin = rct->xmin - 0.5f; - rect.xmax = rct->xmax + 0.5f; - rect.ymin = rct->ymin - 0.5f; - rect.ymax = rct->ymax + 0.5f; - UI_draw_roundbox_4fv(&rect, false, radius + 0.5f, color); - GPU_blend(GPU_BLEND_NONE); } diff --git a/source/blender/editors/interface/interface_intern.hh b/source/blender/editors/interface/interface_intern.hh index abf1facc7ec..4d1e4d6fa8b 100644 --- a/source/blender/editors/interface/interface_intern.hh +++ b/source/blender/editors/interface/interface_intern.hh @@ -1028,10 +1028,6 @@ void ui_draw_aligned_panel(const uiStyle *style, bool region_search_filter_active); void ui_panel_tag_search_filter_match(Panel *panel); -/* interface_draw.cc */ - -void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); - /** * Draws in resolution of 48x4 colors. */ diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 9fdc06f1a3e..31711ecf303 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -599,86 +599,6 @@ static void widget_init(uiWidgetBase *wtb) /** \name Draw Round Box * \{ */ -/* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */ -/* return tot */ -static int round_box_shadow_edges( - float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step) -{ - float vec[WIDGET_CURVE_RESOLU][2]; - int tot = 0; - - rad += step; - - if (2.0f * rad > BLI_rcti_size_y(rect)) { - rad = 0.5f * BLI_rcti_size_y(rect); - } - - const float minx = rect->xmin - step; - const float miny = rect->ymin - step; - const float maxx = rect->xmax + step; - const float maxy = rect->ymax + step; - - /* Multiply. */ - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) { - vec[a][0] = rad * cornervec[a][0]; - vec[a][1] = rad * cornervec[a][1]; - } - - /* start with left-top, anti clockwise */ - if (roundboxalign & UI_CNR_TOP_LEFT) { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = minx + rad - vec[a][0]; - vert[tot][1] = maxy - vec[a][1]; - } - } - else { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = minx; - vert[tot][1] = maxy; - } - } - - if (roundboxalign & UI_CNR_BOTTOM_LEFT) { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = minx + vec[a][1]; - vert[tot][1] = miny + rad - vec[a][0]; - } - } - else { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = minx; - vert[tot][1] = miny; - } - } - - if (roundboxalign & UI_CNR_BOTTOM_RIGHT) { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = maxx - rad + vec[a][0]; - vert[tot][1] = miny + vec[a][1]; - } - } - else { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = maxx; - vert[tot][1] = miny; - } - } - - if (roundboxalign & UI_CNR_TOP_RIGHT) { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = maxx - vec[a][1]; - vert[tot][1] = maxy - rad + vec[a][0]; - } - } - else { - for (int a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) { - vert[tot][0] = maxx; - vert[tot][1] = maxy; - } - } - return tot; -} - /* this call has 1 extra arg to allow mask outline */ static void round_box__edges( uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi) @@ -2828,54 +2748,18 @@ static void widget_state_menu_item(uiWidgetType *wt, /* outside of rect, rad to left/bottom/right */ static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin) { - bTheme *btheme = UI_GetTheme(); - uiWidgetBase wtb; - rcti rect1 = *rect; - float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; - const float radout = UI_ThemeMenuShadowWidth(); + const float outline = U.pixelsize; - /* disabled shadow */ - if (radout == 0.0f) { - return; - } + rctf shadow_rect; + BLI_rctf_rcti_copy(&shadow_rect, rect); + BLI_rctf_pad(&shadow_rect, -outline, -outline); - /* prevent tooltips to not show round shadow */ - if (radout > 0.2f * BLI_rcti_size_y(&rect1)) { - rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1); - } - else { - rect1.ymax -= radout; - } + UI_draw_roundbox_corner_set(roundboxalign); - /* inner part */ - const int totvert = round_box_shadow_edges(wtb.inner_v, - &rect1, - radin, - roundboxalign & - (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), - 0.0f); + const float shadow_alpha = UI_GetTheme()->tui.menu_shadow_fac; + const float shadow_width = UI_ThemeMenuShadowWidth(); - /* we draw a number of increasing size alpha quad strips */ - const float alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout; - - const uint pos = GPU_vertformat_attr_add( - immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - for (int step = 1; step <= int(radout); step++) { - const float expfac = sqrtf(step / radout); - - round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, float(step)); - - immUniformColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac)); - - widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip); - - widget_draw_vertex_buffer(pos, 0, GPU_PRIM_TRI_STRIP, triangle_strip, nullptr, totvert * 2); - } - - immUnbindProgram(); + ui_draw_dropshadow(&shadow_rect, radin, shadow_width, 1.0f, shadow_alpha); } static void widget_menu_back( @@ -5534,9 +5418,7 @@ static void ui_draw_widget_back_color(uiWidgetTypeEnum type, uiWidgetType *wt = widget_type(type); if (use_shadow) { - GPU_blend(GPU_BLEND_ALPHA); widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit); - GPU_blend(GPU_BLEND_NONE); } rcti rect_copy = *rect; diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index aa729e8200b..3167e9af8b6 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -91,8 +91,6 @@ #include "GEO_fillet_curves.hh" -#include "../interface/interface_intern.hh" /* TODO: Remove */ - #include "node_intern.hh" /* own include */ #include