feat(gltf): use alternate blending mode for glTF views (#9115)

This commit is contained in:
Matt
2025-10-30 17:33:24 -04:00
committed by GitHub
parent d82de1ef38
commit e6bd7fcd9b
5 changed files with 47 additions and 24 deletions
+8 -3
View File
@@ -626,7 +626,12 @@ static unsigned int create_texture(int32_t w, int32_t h, const void * data)
#if 0 #if 0
GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); 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_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 #endif
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); 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_t clip_area = t->clip_area;
lv_area_move(&clip_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); 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, lv_opengles_render(dsc->tex_id, coords, dsc->opa, targ_tex_w, targ_tex_h, &clip_area, dsc->h_flip, !dsc->v_flip,
!dsc->v_flip); lv_color_black(), true);
if(target_texture) { if(target_texture) {
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
@@ -100,7 +100,7 @@ static const char *src_fragment_shader_v100 = R"(
} }
if (abs(u_ColorDepth - 8.0) < 0.1) { if (abs(u_ColorDepth - 8.0) < 0.1) {
float gray = texColor.r; float gray = texColor.r;
gl_FragColor = vec4(gray, gray, gray, u_Opa); gl_FragColor = vec4(vec3(gray * u_Opa), u_Opa);
} else { } else {
float combinedAlpha = texColor.a * u_Opa; float combinedAlpha = texColor.a * u_Opa;
gl_FragColor = vec4(texColor.rgb * combinedAlpha, combinedAlpha); gl_FragColor = vec4(texColor.rgb * combinedAlpha, combinedAlpha);
@@ -203,12 +203,16 @@ static const char *src_fragment_shader_v300es = R"(
if (u_IsFill) { if (u_IsFill) {
texColor = vec4(u_FillColor, 1.0); texColor = vec4(u_FillColor, 1.0);
} else { } else {
//texColor = texture(u_Texture, v_TexCoord); 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 /* 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) { if (abs(u_ColorDepth - 8.0) < 0.1) {
float gray = texColor.r; float gray = texColor.r;
color = vec4(gray, gray, gray, u_Opa); color = vec4(vec3(gray * u_Opa), u_Opa);
} else { } else {
float combinedAlpha = texColor.a * u_Opa; float combinedAlpha = texColor.a * u_Opa;
color = vec4(texColor.rgb * combinedAlpha, combinedAlpha); color = vec4(texColor.rgb * combinedAlpha, combinedAlpha);
+23 -16
View File
@@ -33,10 +33,9 @@
/********************** /**********************
* STATIC PROTOTYPES * 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, static void lv_opengles_enable_blending(bool blend_opt);
bool h_flip, bool v_flip, lv_color_t fill_color); static void lv_opengles_disable_blending(void);
static void lv_opengles_enable_blending(void);
static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size); 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_deinit(void);
static void lv_opengles_vertex_buffer_bind(void); static void lv_opengles_vertex_buffer_bind(void);
@@ -102,7 +101,7 @@ void lv_opengles_init(void)
{ {
if(is_init) return; if(is_init) return;
lv_opengles_enable_blending(); lv_opengles_enable_blending(false);
unsigned int indices[] = { unsigned int indices[] = {
0, 1, 2, 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) int32_t disp_h, const lv_area_t * texture_clip_area, bool h_flip, bool v_flip)
{ {
LV_PROFILER_DRAW_BEGIN; LV_PROFILER_DRAW_BEGIN;
lv_opengles_render_internal(texture, texture_area, opa, disp_w, disp_h, texture_clip_area, h_flip, v_flip, lv_opengles_render(texture, texture_area, opa, disp_w, disp_h, texture_clip_area, h_flip, v_flip,
lv_color_black()); lv_color_black(), false);
LV_PROFILER_DRAW_END; 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) 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_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; 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; LV_PROFILER_DRAW_END;
} }
/********************** void lv_opengles_render(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa,
* STATIC FUNCTIONS 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)
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)
{ {
LV_PROFILER_DRAW_BEGIN; LV_PROFILER_DRAW_BEGIN;
lv_area_t intersection; 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_shader_bind();
lv_opengles_enable_blending(blend_opt);
lv_opengles_shader_set_uniform1f("u_ColorDepth", LV_COLOR_DEPTH); lv_opengles_shader_set_uniform1f("u_ColorDepth", LV_COLOR_DEPTH);
lv_opengles_shader_set_uniform1i("u_Texture", 0); lv_opengles_shader_set_uniform1i("u_Texture", 0);
lv_opengles_shader_set_uniformmatrix3fv("u_VertexTransform", 1, transposed_matrix); 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, 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); (float)fill_color.blue / 255.0f);
lv_opengles_render_draw(); lv_opengles_render_draw();
lv_opengles_disable_blending();
LV_PROFILER_DRAW_END; 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(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) static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size)
+1 -1
View File
@@ -45,7 +45,7 @@ void lv_opengles_init(void);
void lv_opengles_deinit(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 OpenGL texture ID
* @param texture_area the area in the window to render the texture in * @param texture_area the area in the window to render the texture in
* @param opa opacity to blend the texture with existing contents * @param opa opacity to blend the texture with existing contents
@@ -17,6 +17,9 @@ extern "C" {
#include "../../lv_conf_internal.h" #include "../../lv_conf_internal.h"
#if LV_USE_OPENGLES #if LV_USE_OPENGLES
#include "../../misc/lv_area.h"
#include "../../misc/lv_color.h"
#if LV_USE_EGL #if LV_USE_EGL
#include "glad/include/glad/gles2.h" #include "glad/include/glad/gles2.h"
#include "glad/include/glad/egl.h" #include "glad/include/glad/egl.h"
@@ -100,6 +103,10 @@ extern "C" {
* GLOBAL PROTOTYPES * 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 * MACROS
**********************/ **********************/