diff --git a/src/draw/opengles/lv_draw_opengles.c b/src/draw/opengles/lv_draw_opengles.c index 72ded26d0f..a334fb22a8 100644 --- a/src/draw/opengles/lv_draw_opengles.c +++ b/src/draw/opengles/lv_draw_opengles.c @@ -626,7 +626,12 @@ static unsigned int create_texture(int32_t w, int32_t h, const void * data) #if 0 GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); + /* GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); + * Alternatively, the above form can be used in some cases for slightly faster performance, but + * visual quality when using image scales that are not exactly 1:1 (or 2:1 or some other increment) + * will be not as good. + */ #endif GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); @@ -658,8 +663,8 @@ static void lv_draw_opengles_3d(lv_draw_task_t * t, const lv_draw_3d_dsc_t * dsc lv_area_t clip_area = t->clip_area; lv_area_move(&clip_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); - lv_opengles_render_texture(dsc->tex_id, coords, dsc->opa, targ_tex_w, targ_tex_h, &clip_area, dsc->h_flip, - !dsc->v_flip); + lv_opengles_render(dsc->tex_id, coords, dsc->opa, targ_tex_w, targ_tex_h, &clip_area, dsc->h_flip, !dsc->v_flip, + lv_color_black(), true); if(target_texture) { GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); diff --git a/src/drivers/opengles/assets/lv_opengles_shader.c b/src/drivers/opengles/assets/lv_opengles_shader.c index 107f1dddf7..ae377b6ea7 100644 --- a/src/drivers/opengles/assets/lv_opengles_shader.c +++ b/src/drivers/opengles/assets/lv_opengles_shader.c @@ -100,7 +100,7 @@ static const char *src_fragment_shader_v100 = R"( } if (abs(u_ColorDepth - 8.0) < 0.1) { float gray = texColor.r; - gl_FragColor = vec4(gray, gray, gray, u_Opa); + gl_FragColor = vec4(vec3(gray * u_Opa), u_Opa); } else { float combinedAlpha = texColor.a * u_Opa; gl_FragColor = vec4(texColor.rgb * combinedAlpha, combinedAlpha); @@ -203,12 +203,16 @@ static const char *src_fragment_shader_v300es = R"( if (u_IsFill) { texColor = vec4(u_FillColor, 1.0); } else { - //texColor = texture(u_Texture, v_TexCoord); - texColor = textureLod(u_Texture, v_TexCoord, 0.0); // If the vertices have been transformed, and mipmaps have not been generated, some rotation angles (notably 90 and 270) require using textureLod() to mitigate derivative calculation errors from increments flipping direction + texColor = texture(u_Texture, v_TexCoord); + /* If the vertices have been transformed, and mipmaps have not been generated, + * some rotation angles (notably 90 and 270) require using textureLod() to mitigate + * derivative calculation errors from interpolator increments flipping direction. + * texColor = textureLod(u_Texture, v_TexCoord, u_LodLevel); + */ } if (abs(u_ColorDepth - 8.0) < 0.1) { float gray = texColor.r; - color = vec4(gray, gray, gray, u_Opa); + color = vec4(vec3(gray * u_Opa), u_Opa); } else { float combinedAlpha = texColor.a * u_Opa; color = vec4(texColor.rgb * combinedAlpha, combinedAlpha); diff --git a/src/drivers/opengles/lv_opengles_driver.c b/src/drivers/opengles/lv_opengles_driver.c index 90a4ee60c8..81669c264c 100644 --- a/src/drivers/opengles/lv_opengles_driver.c +++ b/src/drivers/opengles/lv_opengles_driver.c @@ -33,10 +33,9 @@ /********************** * STATIC PROTOTYPES **********************/ -static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, - int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, - bool h_flip, bool v_flip, lv_color_t fill_color); -static void lv_opengles_enable_blending(void); + +static void lv_opengles_enable_blending(bool blend_opt); +static void lv_opengles_disable_blending(void); static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size); static void lv_opengles_vertex_buffer_deinit(void); static void lv_opengles_vertex_buffer_bind(void); @@ -102,7 +101,7 @@ void lv_opengles_init(void) { if(is_init) return; - lv_opengles_enable_blending(); + lv_opengles_enable_blending(false); unsigned int indices[] = { 0, 1, 2, @@ -146,15 +145,15 @@ void lv_opengles_render_texture(unsigned int texture, const lv_area_t * texture_ int32_t disp_h, const lv_area_t * texture_clip_area, bool h_flip, bool v_flip) { LV_PROFILER_DRAW_BEGIN; - lv_opengles_render_internal(texture, texture_area, opa, disp_w, disp_h, texture_clip_area, h_flip, v_flip, - lv_color_black()); + lv_opengles_render(texture, texture_area, opa, disp_w, disp_h, texture_clip_area, h_flip, v_flip, + lv_color_black(), false); LV_PROFILER_DRAW_END; } void lv_opengles_render_fill(lv_color_t color, const lv_area_t * area, lv_opa_t opa, int32_t disp_w, int32_t disp_h) { LV_PROFILER_DRAW_BEGIN; - lv_opengles_render_internal(0, area, opa, disp_w, disp_h, area, false, false, color); + lv_opengles_render(0, area, opa, disp_w, disp_h, area, false, false, color, false); LV_PROFILER_DRAW_END; } @@ -210,12 +209,9 @@ void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h) LV_PROFILER_DRAW_END; } -/********************** - * STATIC FUNCTIONS - **********************/ - -static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, - int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, bool h_flip, bool v_flip, lv_color_t fill_color) +void lv_opengles_render(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, + int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, + bool h_flip, bool v_flip, lv_color_t fill_color, bool blend_opt) { LV_PROFILER_DRAW_BEGIN; lv_area_t intersection; @@ -263,6 +259,7 @@ static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * }; lv_opengles_shader_bind(); + lv_opengles_enable_blending(blend_opt); lv_opengles_shader_set_uniform1f("u_ColorDepth", LV_COLOR_DEPTH); lv_opengles_shader_set_uniform1i("u_Texture", 0); lv_opengles_shader_set_uniformmatrix3fv("u_VertexTransform", 1, transposed_matrix); @@ -271,13 +268,23 @@ static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * lv_opengles_shader_set_uniform3f("u_FillColor", (float)fill_color.red / 255.0f, (float)fill_color.green / 255.0f, (float)fill_color.blue / 255.0f); lv_opengles_render_draw(); + lv_opengles_disable_blending(); LV_PROFILER_DRAW_END; } -static void lv_opengles_enable_blending(void) +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_opengles_enable_blending(bool blend_opt) { GL_CALL(glEnable(GL_BLEND)); - GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + GL_CALL(glBlendFunc(blend_opt ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); +} + +static void lv_opengles_disable_blending(void) +{ + GL_CALL(glDisable(GL_BLEND)); } static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size) diff --git a/src/drivers/opengles/lv_opengles_driver.h b/src/drivers/opengles/lv_opengles_driver.h index 67dcf5d270..de075cc5f0 100644 --- a/src/drivers/opengles/lv_opengles_driver.h +++ b/src/drivers/opengles/lv_opengles_driver.h @@ -45,7 +45,7 @@ void lv_opengles_init(void); void lv_opengles_deinit(void); /** - * Render a texture + * Render a texture using alternate blending mode for smoother translucent materials and correct anti-aliasing of glTF elements when using transparent background * @param texture OpenGL texture ID * @param texture_area the area in the window to render the texture in * @param opa opacity to blend the texture with existing contents diff --git a/src/drivers/opengles/lv_opengles_private.h b/src/drivers/opengles/lv_opengles_private.h index 6e98997dbf..e81e839da7 100644 --- a/src/drivers/opengles/lv_opengles_private.h +++ b/src/drivers/opengles/lv_opengles_private.h @@ -17,6 +17,9 @@ extern "C" { #include "../../lv_conf_internal.h" #if LV_USE_OPENGLES +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" + #if LV_USE_EGL #include "glad/include/glad/gles2.h" #include "glad/include/glad/egl.h" @@ -100,6 +103,10 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ +void lv_opengles_render(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, + int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, + bool h_flip, bool v_flip, lv_color_t fill_color, bool blend_opt); + /********************** * MACROS **********************/