Page MenuHome
Paste P1331

Shader based rounded corners for splash screen (no AA)
ActivePublic

Authored by Julian Eisel (Severin) on Apr 7 2020, 6:07 PM.
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index eb134646649..3ab76f16133 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -268,6 +268,9 @@ enum {
UI_BUT_ALIGN_STITCH_LEFT = 1 << 19,
UI_BUT_ALIGN_ALL = UI_BUT_ALIGN | UI_BUT_ALIGN_STITCH_TOP | UI_BUT_ALIGN_STITCH_LEFT,
+ /** Don't let the layout code change the alignment flags. */
+ UI_BUT_ALIGN_OVERRIDE = 1 << 27,
+
/** This but is "inside" a box item (currently used to change theme colors). */
UI_BUT_BOX_ITEM = 1 << 20,
diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c
index 09811fab52d..5f94fface00 100644
--- a/source/blender/editors/interface/interface_align.c
+++ b/source/blender/editors/interface/interface_align.c
@@ -413,8 +413,14 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region)
* and clear their align flag.
* Tabs get some special treatment here, they get aligned to region border. */
for (but = block->buttons.first; but; but = but->next) {
+ if (but->drawflag & UI_BUT_ALIGN_OVERRIDE) {
+ but->alignnr = 0;
+ continue;
+ }
+
/* special case: tabs need to be aligned to a region border, drawflag tells which one */
if (but->type == UI_BTYPE_TAB) {
+ /* Could probably also use UI_BUT_ALIGN_OVERRIDE now. */
ui_block_align_but_to_region(but, region);
}
else {
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 499d2f7f1fa..bc8330719b5 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -53,6 +53,7 @@
#include "GPU_batch.h"
#include "GPU_batch_presets.h"
+#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -694,12 +695,11 @@ void ui_draw_but_TAB_outline(const rcti *rect,
void ui_draw_but_IMAGE(ARegion *UNUSED(region),
uiBut *but,
- const uiWidgetColors *UNUSED(wcol),
+ const uiWidgetColors *wcol,
const rcti *rect)
{
#ifdef WITH_HEADLESS
- (void)rect;
- (void)but;
+ UNUSED_VARS(rect, wcol, but);
#else
ImBuf *ibuf = (ImBuf *)but->poin;
@@ -710,17 +710,10 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
int w = BLI_rcti_size_x(rect);
int h = BLI_rcti_size_y(rect);
- /* scissor doesn't seem to be doing the right thing...? */
-# if 0
- /* prevent drawing outside widget area */
- int scissor[4];
- GPU_scissor_get_i(scissor);
- GPU_scissor(rect->xmin, rect->ymin, w, h);
-# endif
-
GPU_blend(true);
/* Combine with premultiplied alpha. */
- GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
if (w != ibuf->x || h != ibuf->y) {
/* We scale the bitmap, rather than have OGL do a worse job. */
@@ -733,30 +726,53 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
rgba_uchar_to_float(col, but->col);
}
- IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(&state,
- (float)rect->xmin,
- (float)rect->ymin,
- ibuf->x,
- ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- ibuf->rect,
- 1.0f,
- 1.0f,
- col);
+ uiWidgetBaseParameters widget_params = {
+ .radi = wcol->roundness * U.widget_unit,
+ .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
+ .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
+ .color_inner1[0] = col[0],
+ .color_inner2[0] = col[0],
+ .color_inner1[1] = col[1],
+ .color_inner2[1] = col[1],
+ .color_inner1[2] = col[2],
+ .color_inner2[2] = col[2],
+ .color_inner1[3] = col[3],
+ .color_inner2[3] = col[3],
+ .alpha_discard = 1.0f,
+ };
+ const float checker_params[3] = {
+ UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f};
+ // widget_params.color_inner1[3] *= 0.125f;
+ // widget_params.color_inner2[3] *= 0.125f;
+
+ BLI_rctf_rcti_copy(&widget_params.recti, rect);
+
+ uint gl_texture;
+
+ GPU_create_gl_tex(&gl_texture,
+ ibuf->rect,
+ NULL,
+ ibuf->x,
+ ibuf->y,
+ GL_TEXTURE_2D,
+ false,
+ (ibuf->flags & IB_halffloat) != 0,
+ false,
+ NULL);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, gl_texture);
+
+ GPUBatch *batch = ui_batch_roundbox_get(true, true);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_IMAGE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
+ GPU_batch_uniform_1i(batch, "image", 0);
+ GPU_batch_draw(batch);
+ glBindTexture(GL_TEXTURE_2D, 0);
GPU_blend(false);
- /* Reset default. */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
-# if 0
- // restore scissortest
- GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
-# endif
-
#endif
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index fa4a0a1e07d..7b3cd0e9c7d 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -4797,7 +4797,14 @@ void ui_draw_but(const bContext *C, ARegion *region, uiStyle *style, uiBut *but,
break;
case UI_BTYPE_IMAGE:
- ui_draw_but_IMAGE(region, but, &tui->wcol_regular, rect);
+ UI_draw_roundbox_corner_set(widget_roundbox_set(but, rect));
+ ui_draw_but_IMAGE(region,
+ but,
+ /* XXX Probably not a good way to do this */
+ (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) ?
+ &tui->wcol_menu_back :
+ &tui->wcol_regular,
+ rect);
break;
case UI_BTYPE_HISTOGRAM:
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index a8a0288f895..54483a98a51 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -154,6 +154,7 @@ data_to_c_simple(shaders/gpu_shader_2D_area_borders_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_area_borders_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_widget_base_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_widget_base_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_2D_widget_base_image_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_widget_shadow_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_widget_shadow_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_nodelink_frag.glsl SRC)
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index bb26f5d41a3..57a4aedfffe 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -296,6 +296,7 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_2D_AREA_EDGES,
GPU_SHADER_2D_WIDGET_BASE,
GPU_SHADER_2D_WIDGET_BASE_INST,
+ GPU_SHADER_2D_WIDGET_BASE_IMAGE,
GPU_SHADER_2D_WIDGET_SHADOW,
GPU_SHADER_2D_NODELINK,
GPU_SHADER_2D_NODELINK_INST,
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 1a0daf4ac41..0ce844a1a0c 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -69,6 +69,7 @@ extern char datatoc_gpu_shader_2D_image_rect_vert_glsl[];
extern char datatoc_gpu_shader_2D_image_multi_rect_vert_glsl[];
extern char datatoc_gpu_shader_2D_widget_base_vert_glsl[];
extern char datatoc_gpu_shader_2D_widget_base_frag_glsl[];
+extern char datatoc_gpu_shader_2D_widget_base_image_frag_glsl[];
extern char datatoc_gpu_shader_2D_widget_shadow_vert_glsl[];
extern char datatoc_gpu_shader_2D_widget_shadow_frag_glsl[];
extern char datatoc_gpu_shader_2D_nodelink_frag_glsl[];
@@ -1075,6 +1076,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.frag = datatoc_gpu_shader_2D_widget_base_frag_glsl,
.defs = "#define USE_INSTANCE\n",
},
+ [GPU_SHADER_2D_WIDGET_BASE_IMAGE] =
+ {
+ .vert = datatoc_gpu_shader_2D_widget_base_vert_glsl,
+ .frag = datatoc_gpu_shader_2D_widget_base_image_frag_glsl,
+ },
[GPU_SHADER_2D_WIDGET_SHADOW] =
{
.vert = datatoc_gpu_shader_2D_widget_shadow_vert_glsl,
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_image_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_image_frag.glsl
new file mode 100644
index 00000000000..add8df86869
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_image_frag.glsl
@@ -0,0 +1,41 @@
+uniform vec3 checkerColorAndSize;
+
+noperspective in vec4 finalColor;
+noperspective in float butCo;
+flat in float discardFac;
+
+uniform sampler2D image;
+
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+vec4 do_checkerboard()
+{
+ float size = checkerColorAndSize.z;
+ vec2 phase = mod(gl_FragCoord.xy, size * 2.0);
+
+ if ((phase.x > size && phase.y < size) || (phase.x < size && phase.y > size)) {
+ return vec4(checkerColorAndSize.xxx, 1.0);
+ }
+ else {
+ return vec4(checkerColorAndSize.yyy, 1.0);
+ }
+}
+
+void main()
+{
+ if (min(1.0, -butCo) > discardFac) {
+ discard;
+ }
+
+ fragColor = texture(image, texCoord_interp) * finalColor;
+
+ if (butCo > 0.5) {
+ vec4 checker = do_checkerboard();
+ fragColor = mix(checker, fragColor, fragColor.a);
+ }
+
+ if (butCo > 0.0) {
+ fragColor.a = 1.0;
+ }
+}
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 0b2bc08944e..003b68dcec3 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
@@ -184,6 +184,7 @@ in uint vflag;
noperspective out vec4 finalColor;
noperspective out float butCo;
flat out float discardFac;
+out vec2 texCoord_interp;
vec2 do_widget(void)
{
@@ -275,4 +276,7 @@ void main()
v += jit[(vflag >> JIT_OFS) & JIT_RANGE];
gl_Position = ModelViewProjectionMatrix * vec4(v, 0.0, 1.0);
+ bool is_inner = (vflag & INNER_FLAG) != 0u;
+ vec4 rct = (is_inner) ? recti : rect;
+ texCoord_interp = (v - rct.xz) / (rct.yw - rct.xz);
}
diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c
index 0a1553cb3e1..8d8d959a2de 100644
--- a/source/blender/windowmanager/intern/wm_splash_screen.c
+++ b/source/blender/windowmanager/intern/wm_splash_screen.c
@@ -280,6 +280,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSE
U.dpi_fac * ibuf_unit_size[1],
NULL);
UI_but_func_set(but, wm_block_splash_close, block, NULL);
+ UI_but_drawflag_enable(but, UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_OVERRIDE);
UI_block_func_set(block, wm_block_splash_refreshmenu, block, NULL);
int x = U.dpi_fac * (ibuf_unit_size[0] + 1);