mirror of
https://github.com/godotengine/godot.git
synced 2024-12-09 10:09:20 +08:00
Merge pull request #32170 from puthre/ninepatch-fix
GLES2 & GLES3 Fixes ninepatch margins for high resolution textures.
This commit is contained in:
commit
a39aeade5b
@ -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 ] *
|
||||
@ -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;
|
||||
@ -798,25 +806,25 @@ 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;
|
||||
@ -824,25 +832,25 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||
// 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;
|
||||
@ -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;
|
||||
|
@ -380,14 +380,16 @@ 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--;
|
||||
@ -395,22 +397,22 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo
|
||||
|
||||
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;
|
||||
}
|
||||
@ -432,9 +434,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;
|
||||
|
Loading…
Reference in New Issue
Block a user