mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 04:14:00 +00:00
Fix 'gfx_display_draw_texture_slice()' (i.e. prevent glitches when rendering Ozone's selection cursor)
This commit is contained in:
parent
9f7e55e59d
commit
1440b46eb0
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user