Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLES2 & GLES3 Fixes ninepatch margins for high resolution textures. #32170

Merged
merged 2 commits into from
Oct 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions drivers/gles2/rasterizer_canvas_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,14 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
source.size.y = tex->height;
}

float screen_scale = 1.0;

if (source.size.x != 0 && source.size.y != 0) {

screen_scale = MIN(np->rect.size.x / source.size.x, np->rect.size.y / source.size.y);
screen_scale = MIN(1.0, screen_scale);
}

// prepare vertex buffer

// this buffer contains [ POS POS UV UV ] *
Expand All @@ -777,13 +785,13 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
buffer[(0 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
buffer[(0 * 4 * 4) + 3] = source.position.y * texpixel_size.y;

buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale;
buffer[(0 * 4 * 4) + 5] = np->rect.position.y;

buffer[(0 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
buffer[(0 * 4 * 4) + 7] = source.position.y * texpixel_size.y;

buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale;
buffer[(0 * 4 * 4) + 9] = np->rect.position.y;

buffer[(0 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
Expand All @@ -798,51 +806,51 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
// second row

buffer[(1 * 4 * 4) + 0] = np->rect.position.x;
buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[MARGIN_TOP];
buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale;

buffer[(1 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
buffer[(1 * 4 * 4) + 3] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;

buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[MARGIN_TOP];
buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale;
buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale;

buffer[(1 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
buffer[(1 * 4 * 4) + 7] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;

buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[MARGIN_TOP];
buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale;
buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale;

buffer[(1 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
buffer[(1 * 4 * 4) + 11] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;

buffer[(1 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[MARGIN_TOP];
buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale;

buffer[(1 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
buffer[(1 * 4 * 4) + 15] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;

// third row

buffer[(2 * 4 * 4) + 0] = np->rect.position.x;
buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale;

buffer[(2 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
buffer[(2 * 4 * 4) + 3] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;

buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale;
buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale;

buffer[(2 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
buffer[(2 * 4 * 4) + 7] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;

buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale;
buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale;

buffer[(2 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
buffer[(2 * 4 * 4) + 11] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;

buffer[(2 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale;

buffer[(2 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
buffer[(2 * 4 * 4) + 15] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
Expand All @@ -855,13 +863,13 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
buffer[(3 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
buffer[(3 * 4 * 4) + 3] = (source.position.y + source.size.y) * texpixel_size.y;

buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale;
buffer[(3 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y;

buffer[(3 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
buffer[(3 * 4 * 4) + 7] = (source.position.y + source.size.y) * texpixel_size.y;

buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale;
buffer[(3 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y;

buffer[(3 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
Expand Down
26 changes: 15 additions & 11 deletions drivers/gles3/shaders/canvas.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -379,37 +379,39 @@ uniform bool np_draw_center;
// left top right bottom in pixel coordinates
uniform vec4 np_margins;

float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) {
float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, float s_ratio, int np_repeat, inout int draw_center) {

float tex_size = 1.0 / tex_pixel_size;

if (pixel < margin_begin) {
return pixel * tex_pixel_size;
} else if (pixel >= draw_size - margin_end) {
return (tex_size - (draw_size - pixel)) * tex_pixel_size;
float screen_margin_begin = margin_begin / s_ratio;
float screen_margin_end = margin_end / s_ratio;
if (pixel < screen_margin_begin) {
return pixel * s_ratio * tex_pixel_size;
} else if (pixel >= draw_size - screen_margin_end) {
return (tex_size - (draw_size - pixel) * s_ratio) * tex_pixel_size;
} else {
if (!np_draw_center) {
draw_center--;
}

if (np_repeat == 0) { //stretch
//convert to ratio
float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end);
float ratio = (pixel - screen_margin_begin) / (draw_size - screen_margin_begin - screen_margin_end);
//scale to source texture
return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size;
} else if (np_repeat == 1) { //tile
//convert to ratio
float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end);
float ofs = mod((pixel - screen_margin_begin), tex_size - margin_begin - margin_end);
//scale to source texture
return (margin_begin + ofs) * tex_pixel_size;
} else if (np_repeat == 2) { //tile fit
//convert to ratio
float src_area = draw_size - margin_begin - margin_end;
float src_area = draw_size - screen_margin_begin - screen_margin_end;
float dst_area = tex_size - margin_begin - margin_end;
float scale = max(1.0, floor(src_area / max(dst_area, 0.0000001) + 0.5));

//convert to ratio
float ratio = (pixel - margin_begin) / src_area;
float ratio = (pixel - screen_margin_begin) / src_area;
ratio = mod(ratio * scale, 1.0);
return (margin_begin + ratio * dst_area) * tex_pixel_size;
}
Expand All @@ -431,9 +433,11 @@ void main() {
#ifdef USE_NINEPATCH

int draw_center = 2;
float s_ratio = max((1.0 / color_texpixel_size.x) / abs(dst_rect.z), (1.0 / color_texpixel_size.y) / abs(dst_rect.w));
s_ratio = max(1.0, s_ratio);
uv = vec2(
map_ninepatch_axis(pixel_size_interp.x, abs(dst_rect.z), color_texpixel_size.x, np_margins.x, np_margins.z, np_repeat_h, draw_center),
map_ninepatch_axis(pixel_size_interp.y, abs(dst_rect.w), color_texpixel_size.y, np_margins.y, np_margins.w, np_repeat_v, draw_center));
map_ninepatch_axis(pixel_size_interp.x, abs(dst_rect.z), color_texpixel_size.x, np_margins.x, np_margins.z, s_ratio, np_repeat_h, draw_center),
map_ninepatch_axis(pixel_size_interp.y, abs(dst_rect.w), color_texpixel_size.y, np_margins.y, np_margins.w, s_ratio, np_repeat_v, draw_center));

if (draw_center == 0) {
color.a = 0.0;
Expand Down