Merge pull request #46865 from lawnjelly/ninepatch_shader_option

Support ninepatch mode in GLES3 shader
This commit is contained in:
Rémi Verschelde 2021-03-12 10:05:44 +01:00 committed by GitHub
commit a550260404
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 1 deletions

View file

@ -2337,6 +2337,12 @@ void RasterizerCanvasGLES3::initialize() {
glBindVertexArray(0);
} // for vao
// deal with ninepatch mode option
if (bdata.settings_ninepatch_mode == 1) {
state.canvas_shader.add_custom_define("#define USE_NINEPATCH_SCALING\n");
}
gl_checkerror();
}

View file

@ -462,6 +462,47 @@ uniform bool np_draw_center;
// left top right bottom in pixel coordinates
uniform vec4 np_margins;
// there are two ninepatch modes, and we don't want to waste a conditional
#if defined USE_NINEPATCH_SCALING
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;
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 - 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 - 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 - 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 - screen_margin_begin) / src_area;
ratio = mod(ratio * scale, 1.0);
return (margin_begin + ratio * dst_area) * tex_pixel_size;
}
}
}
#else
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 tex_size = 1.0 / tex_pixel_size;
@ -501,6 +542,7 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo
}
}
}
#endif
#endif
#endif
@ -517,6 +559,17 @@ void main() {
#ifdef USE_NINEPATCH
int draw_center = 2;
#if defined USE_NINEPATCH_SCALING
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, 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;
}
#else
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));
@ -524,7 +577,7 @@ void main() {
if (draw_center == 0) {
color.a = 0.0;
}
#endif
uv = uv * src_rect.zw + src_rect.xy; //apply region if needed
#endif