Fix 'gfx_display_draw_texture_slice()' (i.e. prevent glitches when rendering Ozone's selection cursor)

This commit is contained in:
jdgleaver 2020-03-26 11:38:30 +00:00
parent 9f7e55e59d
commit 1440b46eb0
5 changed files with 64 additions and 23 deletions

View File

@ -1000,6 +1000,45 @@ void gfx_display_draw_texture_slice(
math_matrix_4x4 mymat;
unsigned i;
float V_BL[2], V_BR[2], V_TL[2], V_TR[2], T_BL[2], T_BR[2], T_TL[2], T_TR[2];
/* To prevent visible seams between the corners and
* middle segments of the sliced texture, the texture
* must be scaled such that its effective size (before
* expansion of the middle segments) is no greater than
* the requested display size.
* > This is consequence of the way textures are rendered
* in hardware...
* > Whenever an image is scaled, the colours at the
* transparent edges get interpolated, which means
* the colours of the transparent pixels themselves bleed
* into the visible area.
* > This effectively 'blurs' anything that gets scaled
* [SIDE NOTE: this causes additional issues if the transparent
* pixels have the wrong colour - i.e. if they are black,
* every edge gets a nasty dark border...]
* > This burring is a problem because (by design) the corners
* of the sliced texture are drawn at native resolution,
* whereas the middle segments are stretched to fit the
* requested dimensions. Consequently, the corners are sharp
* while the middle segments are blurred.
* > When *upscaling* the middle segments (i.e. display size
* greater than texture size), the visible effects of this
* are mostly imperceptible.
* > When *downscaling* them, however, the interpolation effects
* completely dominate the output image - creating an ugly
* transition between the corners and middle parts.
* > Since this is a property of hardware rendering, it is not
* practical to fix this 'properly'...
* > However: An effective workaround is to force downscaling of
* the entire texture (including corners) whenever the
* requested display size is less than the texture dimensions.
* > This blurs the corners enough that the corner/middle
* transitions are essentially invisible. */
float max_scale_w = (float)new_w / (float)w;
float max_scale_h = (float)new_h / (float)h;
/* Find the minimum of scale_factor, max_scale_w, max_scale_h */
float slice_scale = (scale_factor < max_scale_w) ?
(scale_factor < max_scale_h) ? scale_factor : max_scale_h :
(max_scale_w < max_scale_h) ? max_scale_w : max_scale_h;
/* need space for the coordinates of two triangles in a strip,
* so 8 vertices */
@ -1009,15 +1048,15 @@ void gfx_display_draw_texture_slice(
/* normalized width/height of the amount to offset from the corners,
* for both the vertex and texture coordinates */
float vert_woff = (offset * scale_factor) / (float)width;
float vert_hoff = (offset * scale_factor) / (float)height;
float vert_woff = (offset * slice_scale) / (float)width;
float vert_hoff = (offset * slice_scale) / (float)height;
float tex_woff = offset / (float)w;
float tex_hoff = offset / (float)h;
/* the width/height of the middle sections of both the scaled and original image */
float vert_scaled_mid_width = (new_w - (offset * scale_factor * 2))
float vert_scaled_mid_width = (new_w - (offset * slice_scale * 2))
/ (float)width;
float vert_scaled_mid_height = (new_h - (offset * scale_factor * 2))
float vert_scaled_mid_height = (new_h - (offset * slice_scale * 2))
/ (float)height;
float tex_mid_width = (w - (offset * 2)) / (float)w;
float tex_mid_height = (h - (offset * 2)) / (float)h;

View File

@ -120,9 +120,9 @@ static void ozone_draw_cursor_slice(
size_t y, float alpha)
{
float scale_factor = ozone->last_scale_factor;
int slice_x = x_offset - 14 * scale_factor;
int slice_x = x_offset - 12 * scale_factor;
int slice_y = (int)y + 8 * scale_factor;
unsigned slice_new_w = width + (3 + 28 - 4) * scale_factor;
unsigned slice_new_w = width + (24 + 1) * scale_factor;
unsigned slice_new_h = height + 20 * scale_factor;
gfx_display_set_alpha(ozone->theme_dynamic.cursor_alpha, alpha);
@ -185,7 +185,7 @@ static void ozone_draw_cursor_fallback(
x_offset,
(int)y,
width,
height - ozone->dimensions.spacer_5px,
height - ozone->dimensions.spacer_3px,
video_width,
video_height,
ozone->theme_dynamic.selection);
@ -211,7 +211,7 @@ static void ozone_draw_cursor_fallback(
video_width,
video_height,
x_offset - ozone->dimensions.spacer_3px,
(int)(y + height - ozone->dimensions.spacer_5px),
(int)(y + height - ozone->dimensions.spacer_3px),
width + ozone->dimensions.spacer_3px * 2,
ozone->dimensions.spacer_3px,
video_width,
@ -226,7 +226,7 @@ static void ozone_draw_cursor_fallback(
(int)(x_offset - ozone->dimensions.spacer_3px),
(int)y,
ozone->dimensions.spacer_3px,
height - ozone->dimensions.spacer_5px,
height - ozone->dimensions.spacer_3px,
video_width,
video_height,
ozone->theme_dynamic.selection_border);
@ -239,7 +239,7 @@ static void ozone_draw_cursor_fallback(
x_offset + width,
(int)y,
ozone->dimensions.spacer_3px,
height - ozone->dimensions.spacer_5px,
height - ozone->dimensions.spacer_3px,
video_width,
video_height,
ozone->theme_dynamic.selection_border);
@ -545,6 +545,7 @@ void ozone_draw_messagebox(
if (ozone->has_all_assets) /* avoid drawing a black box if there's no assets */
{
int slice_x = x - longest_width/2 - 48 * scale_factor;
int slice_y = (list->size > 1) ? y : y - (ozone->footer_font_glyph_height / 2);
unsigned slice_new_w = longest_width + 48 * 2 * scale_factor;
unsigned slice_new_h = ozone->footer_font_glyph_height * (list->size + 2);
@ -553,7 +554,7 @@ void ozone_draw_messagebox(
video_width,
video_height,
slice_x,
y,
slice_y,
256, 256,
slice_new_w,
slice_new_h,

View File

@ -502,8 +502,8 @@ border_iterate:
video_height,
(unsigned) ozone->dimensions.sidebar_width + x_offset + entry_padding + ozone->dimensions.spacer_3px,
entry_width - ozone->dimensions.spacer_5px,
button_height + ozone->dimensions.spacer_2px,
selection_y + scroll_y + ozone->dimensions.spacer_1px,
button_height + ozone->dimensions.spacer_1px,
selection_y + scroll_y,
ozone->animations.cursor_alpha * alpha);
/* Old*/
@ -519,8 +519,8 @@ border_iterate:
of type 'unsigned int'
* */
entry_width - ozone->dimensions.spacer_5px,
button_height + ozone->dimensions.spacer_2px,
old_selection_y + scroll_y + ozone->dimensions.spacer_1px,
button_height + ozone->dimensions.spacer_1px,
old_selection_y + scroll_y,
(1-ozone->animations.cursor_alpha) * alpha);
/* Icons + text */

View File

@ -235,8 +235,8 @@ void ozone_draw_sidebar(
video_height,
ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.spacer_3px,
entry_width - ozone->dimensions.spacer_5px,
ozone->dimensions.sidebar_entry_height + ozone->dimensions.spacer_2px,
selection_y + ozone->dimensions.spacer_2px + ozone->animations.scroll_y_sidebar,
ozone->dimensions.sidebar_entry_height + ozone->dimensions.spacer_1px,
selection_y + ozone->animations.scroll_y_sidebar,
ozone->animations.cursor_alpha);
if (ozone->cursor_in_sidebar_old)
@ -246,9 +246,10 @@ void ozone_draw_sidebar(
video_width,
video_height,
ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.spacer_3px,
entry_width - ozone->dimensions.spacer_5px,
ozone->dimensions.sidebar_entry_height + ozone->dimensions.spacer_2px, selection_old_y + ozone->dimensions.spacer_2px + ozone->animations.scroll_y_sidebar,
1-ozone->animations.cursor_alpha);
entry_width - ozone->dimensions.spacer_5px,
ozone->dimensions.sidebar_entry_height + ozone->dimensions.spacer_1px,
selection_old_y + ozone->animations.scroll_y_sidebar,
1-ozone->animations.cursor_alpha);
/* Menu tabs */
y = ozone->dimensions.header_height + ozone->dimensions.spacer_1px + ozone->dimensions.sidebar_padding_vertical;

View File

@ -930,7 +930,7 @@ static void xmb_render_messagebox_internal(
line_height * list->size + xmb->margins_dialog * 2,
video_width, video_height,
NULL,
xmb->margins_slice, 1.0,
xmb->margins_slice, xmb->last_scale_factor,
xmb->textures.list[XMB_TEXTURE_DIALOG_SLICE]);
for (i = 0; i < list->size; i++)
@ -5050,7 +5050,7 @@ static void xmb_layout_ps3(xmb_handle_t *xmb, int width)
xmb->margins_setting_left = 600.0 * scale_factor * scale_mod[6];
xmb->margins_dialog = 48 * scale_factor;
xmb->margins_slice = 16;
xmb->margins_slice = 16 * scale_factor;
xmb->icon_size = 128.0 * scale_factor;
xmb->font_size = new_font_size;
@ -5098,7 +5098,7 @@ static void xmb_layout_psp(xmb_handle_t *xmb, int width)
xmb->margins_label_top = new_font_size / 3.0;
xmb->margins_setting_left = 600.0 * scale_factor;
xmb->margins_dialog = 48 * scale_factor;
xmb->margins_slice = 16;
xmb->margins_slice = 16 * scale_factor;
xmb->icon_size = 128.0 * scale_factor;
xmb->font_size = new_font_size;