[Bf-blender-cvs] [9b0ea92be75] blender2.8: UI: Number slider uniform filling

Dalai Felinto noreply at git.blender.org
Sat Apr 28 16:57:25 CEST 2018


Commit: 9b0ea92be75c67567e05a091d0593b87564e0ad1
Author: Dalai Felinto
Date:   Sat Apr 28 02:51:27 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB9b0ea92be75c67567e05a091d0593b87564e0ad1

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

===================================================================

M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl
M	source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl

===================================================================

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();



More information about the Bf-blender-cvs mailing list