diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2018-04-28 03:51:27 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2018-04-28 17:54:57 +0300 |
commit | 9b0ea92be75c67567e05a091d0593b87564e0ad1 (patch) | |
tree | 7e350eb0097468d4d0c424ee11abf7ac1a43996d | |
parent | c06bfe9d09c33cebdffd2c840252d4863fd8ca33 (diff) |
UI: Number slider uniform filling
Now we always fill the slider with a vertical boundary. A bit hard to explain,
but very easy to see the difference.
I split the widget in three parts and used fragment shader discard to remove the
undesired bits. That means all the widget program is doing a bit extra
calculation.
Reviewers: fclem
Subscribers: billreynish
Differential Revision: https://developer.blender.org/D3186
4 files changed, 93 insertions, 46 deletions
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 6082b3ab7b0..a0515d7d4f0 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -717,7 +717,11 @@ typedef struct uiWidgetBaseParameters { float color_tria[4]; float tria1_center[2], tria2_center[2]; float tria1_size, tria2_size; - float shade_dir, do_alpha_check; + float shade_dir; + /* We pack alpha check and discard factor in alpha_discard. + * If the value is negative then we do alpha check. + * The absolute value itself is the discard factor. */ + float alpha_discard; } uiWidgetBaseParameters; enum { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 0a1c35961fd..6b50279d6d3 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -579,6 +579,7 @@ static void widget_init(uiWidgetBase *wtb) wtb->draw_emboss = true; wtb->uniform_params.shade_dir = 1.0f; + wtb->uniform_params.alpha_discard = 1.0f; } /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */ @@ -1014,6 +1015,35 @@ static void widgetbase_outline(uiWidgetBase *wtb, unsigned int pos) widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2); } +static void widgetbase_set_uniform_alpha_discard( + uiWidgetBase *wtb, + const bool alpha_check, + const float discard_factor) +{ + if (alpha_check) { + wtb->uniform_params.alpha_discard = -discard_factor; + } + else { + wtb->uniform_params.alpha_discard = discard_factor; + } +} + +static void widgetbase_set_uniform_alpha_check( + uiWidgetBase *wtb, + const bool alpha_check) +{ + const float discard_factor = fabs(wtb->uniform_params.alpha_discard); + widgetbase_set_uniform_alpha_discard(wtb, alpha_check, discard_factor); +} + +static void widgetbase_set_uniform_discard_factor( + uiWidgetBase *wtb, + const float discard_factor) +{ + bool alpha_check = wtb->uniform_params.alpha_discard < 0.0f; + widgetbase_set_uniform_alpha_discard(wtb, alpha_check, discard_factor); +} + static void widgetbase_set_uniform_colors_ubv( uiWidgetBase *wtb, const unsigned char *col1, const unsigned char *col2, @@ -1022,7 +1052,7 @@ static void widgetbase_set_uniform_colors_ubv( const unsigned char *tria, const bool alpha_check) { - wtb->uniform_params.do_alpha_check = (float)alpha_check; + widgetbase_set_uniform_alpha_check(wtb, alpha_check); rgba_float_args_set_ch(wtb->uniform_params.color_inner1, col1[0], col1[1], col1[2], col1[3]); rgba_float_args_set_ch(wtb->uniform_params.color_inner2, col2[0], col2[1], col2[2], col2[3]); rgba_float_args_set_ch(wtb->uniform_params.color_outline, outline[0], outline[1], outline[2], outline[3]); @@ -3544,74 +3574,74 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s { uiWidgetBase wtb, wtb1; rcti rect1; - double value; - float offs, toffs, fac = 0; + float offs, toffs; char outline[3]; widget_init(&wtb); widget_init(&wtb1); - - /* backdrop first */ - + + /* Backdrop first. */ offs = wcol->roundness * BLI_rcti_size_y(rect); toffs = offs * 0.75f; round_box_edges(&wtb, roundboxalign, rect, offs); wtb.draw_outline = false; widgetbase_draw(&wtb, wcol); - - /* draw left/right parts only when not in text editing */ + + /* Draw slider part only when not in text editing. */ if (!(state & UI_STATE_TEXT_INPUT)) { - int roundboxalign_slider; - - /* slider part */ + int roundboxalign_slider = roundboxalign; + copy_v3_v3_char(outline, wcol->outline); copy_v3_v3_char(wcol->outline, wcol->item); copy_v3_v3_char(wcol->inner, wcol->item); - if (!(state & UI_SELECT)) + if (!(state & UI_SELECT)) { SWAP(short, wcol->shadetop, wcol->shadedown); - + } + rect1 = *rect; - - value = ui_but_value_get(but); - if ((but->softmax - but->softmin) > 0) { - fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin); + float factor, factor_ui; + float factor_discard = 1.0f; /* No discard. */ + float value = (float)ui_but_value_get(but); + + factor = (value - but->softmin) / (but->softmax - but->softmin); + factor_ui = factor * (float)BLI_rcti_size_x(rect); + + if (factor_ui <= offs) { + /* Left part only. */ + roundboxalign_slider &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); + rect1.xmax = rect1.xmin + offs; + factor_discard = factor_ui / offs; } - - /* left part of slider, always rounded */ - rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize); - round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs); - wtb1.draw_outline = false; - widgetbase_draw(&wtb1, wcol); - - /* right part of slider, interpolate roundness */ - rect1.xmax = rect1.xmin + fac + offs; - rect1.xmin += floor(offs - U.pixelsize); - - if (rect1.xmax + offs > rect->xmax) { - roundboxalign_slider = roundboxalign & ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); - offs *= (rect1.xmax + offs - rect->xmax) / offs; + else if (factor_ui <= rect->xmax - offs) { + /* Left part + middle part. */ + roundboxalign_slider &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); + rect1.xmax = rect1.xmin + factor_ui; } else { - roundboxalign_slider = 0; - offs = 0.0f; + /* Left part + middle part + right part. */ + factor_discard = factor; } + round_box_edges(&wtb1, roundboxalign_slider, &rect1, offs); - + wtb1.draw_outline = false; + widgetbase_set_uniform_discard_factor(&wtb1, factor_discard); widgetbase_draw(&wtb1, wcol); + copy_v3_v3_char(wcol->outline, outline); - - if (!(state & UI_SELECT)) + + if (!(state & UI_SELECT)) { SWAP(short, wcol->shadetop, wcol->shadedown); + } } - - /* outline */ + + /* Outline. */ wtb.draw_outline = true; wtb.draw_inner = false; widgetbase_draw(&wtb, wcol); - /* add space at either side of the button so text aligns with numbuttons (which have arrow icons) */ + /* Add space at either side of the button so text aligns with numbuttons (which have arrow icons). */ if (!(state & UI_STATE_TEXT_INPUT)) { rect->xmax -= toffs; rect->xmin += toffs; diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl index 286a5373554..a356014d025 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl @@ -2,6 +2,7 @@ uniform vec3 checkerColorAndSize; noperspective in vec4 finalColor; noperspective in float butCo; +flat in float discardFac; out vec4 fragColor; @@ -22,6 +23,10 @@ vec4 do_checkerboard() void main() { + if (min(1.0, -butCo) > discardFac) { + discard; + } + fragColor = finalColor; if (butCo > 0.5) { diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl index 9d0bacde1ff..dcd23413c77 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl @@ -103,12 +103,17 @@ uniform vec4 parameters[MAX_PARAM]; #define tria1Size parameters[gl_InstanceID * MAX_PARAM + 10].x #define tria2Size parameters[gl_InstanceID * MAX_PARAM + 10].y #define shadeDir parameters[gl_InstanceID * MAX_PARAM + 10].z -#define doAlphaCheck parameters[gl_InstanceID * MAX_PARAM + 10].w +#define alphaDiscard parameters[gl_InstanceID * MAX_PARAM + 10].w + +/* We encode alpha check and discard factor together. */ +#define doAlphaCheck (alphaDiscard < 0.0) +#define discardFactor abs(alphaDiscard) in uint vflag; noperspective out vec4 finalColor; noperspective out float butCo; +flat out float discardFac; vec2 do_widget(void) { @@ -133,27 +138,29 @@ vec2 do_widget(void) else /* (cflag == TOP_LEFT) */ v += rct.xw; + vec2 uv = faci * (v - recti.xz); + /* compute uv and color gradient */ uint color_id = (vflag >> COLOR_OFS) & COLOR_RANGE; if (color_id == COLOR_INNER) { - vec2 uv = faci * (v - recti.xz); float fac = clamp((shadeDir > 0.0) ? uv.y : uv.x, 0.0, 1.0); - if (doAlphaCheck != 0.0) { + + if (doAlphaCheck) { finalColor = colorInner1; butCo = uv.x; } else { finalColor = mix(colorInner2, colorInner1, fac); - butCo = -1.0; + butCo = -abs(uv.x); } } else if (color_id == COLOR_EDGE) { finalColor = colorEdge; - butCo = -1.0; + butCo = -abs(uv.x); } else /* (color_id == COLOR_EMBOSS) */ { finalColor = colorEmboss; - butCo = -1.0; + butCo = -abs(uv.x); } bool is_emboss = (vflag & EMBOSS_FLAG) != 0u; @@ -183,6 +190,7 @@ vec2 do_tria() void main() { + discardFac = discardFactor; bool is_tria = (vflag & TRIA_FLAG) != 0u; vec2 v = (is_tria) ? do_tria() : do_widget(); |