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
This commit is contained in:
parent
c06bfe9d09
commit
9b0ea92be7
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
rect1 = *rect;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue