From f3f6946eb23379327965059235b14e6a02182827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kr=C3=A1l?= Date: Thu, 25 Aug 2022 08:05:58 +0200 Subject: [PATCH] `egui_glium` correct texture filtering (#1962) * correct texture filter in egui_glium * update example * cargo fmt * rename UserTexture --- crates/egui_glium/examples/native_texture.rs | 4 +- crates/egui_glium/src/painter.rs | 63 +++++++++++++++----- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/crates/egui_glium/examples/native_texture.rs b/crates/egui_glium/examples/native_texture.rs index e63327fe..9521976e 100644 --- a/crates/egui_glium/examples/native_texture.rs +++ b/crates/egui_glium/examples/native_texture.rs @@ -16,7 +16,9 @@ fn main() { // Allow us to share the texture with egui: let glium_texture = std::rc::Rc::new(glium_texture); // Allocate egui's texture id for GL texture - let texture_id = egui_glium.painter.register_native_texture(glium_texture); + let texture_id = egui_glium + .painter + .register_native_texture(glium_texture, egui::TextureFilter::Linear); // Setup button image size for reasonable image size for button container. let button_image_size = egui::vec2(32_f32, 32_f32); diff --git a/crates/egui_glium/src/painter.rs b/crates/egui_glium/src/painter.rs index 6615457f..4f02aca1 100644 --- a/crates/egui_glium/src/painter.rs +++ b/crates/egui_glium/src/painter.rs @@ -1,7 +1,7 @@ #![allow(deprecated)] // legacy implement_vertex macro #![allow(semicolon_in_expressions_from_macros)] // glium::program! macro -use egui::epaint::Primitive; +use egui::{epaint::Primitive, TextureFilter}; use { egui::{emath::Rect, epaint::Mesh}, @@ -20,7 +20,7 @@ pub struct Painter { max_texture_side: usize, program: glium::Program, - textures: ahash::HashMap>, + textures: ahash::HashMap, /// [`egui::TextureId::User`] index next_native_tex_id: u64, @@ -146,12 +146,14 @@ impl Painter { if let Some(texture) = self.texture(mesh.texture_id) { // The texture coordinates for text are so that both nearest and linear should work with the egui font texture. - // For user textures linear sampling is more likely to be the right choice. - let filter = MagnifySamplerFilter::Linear; + let filter = match texture.filter { + TextureFilter::Nearest => MagnifySamplerFilter::Nearest, + TextureFilter::Linear => MagnifySamplerFilter::Linear, + }; let uniforms = uniform! { u_screen_size: [width_in_points, height_in_points], - u_sampler: texture.sampled().magnify_filter(filter).wrap_function(SamplerWrapFunction::Clamp), + u_sampler: texture.glium_texture.sampled().magnify_filter(filter).wrap_function(SamplerWrapFunction::Clamp), }; // egui outputs colors with premultiplied alpha: @@ -253,19 +255,26 @@ impl Painter { if let Some(pos) = delta.pos { // update a sub-region - if let Some(gl_texture) = self.textures.get(&tex_id) { + if let Some(user_texture) = self.textures.get_mut(&tex_id) { let rect = glium::Rect { left: pos[0] as _, bottom: pos[1] as _, width: glium_image.width, height: glium_image.height, }; - gl_texture.main_level().write(rect, glium_image); + user_texture + .glium_texture + .main_level() + .write(rect, glium_image); + + user_texture.filter = delta.filter; } } else { let gl_texture = SrgbTexture2d::with_format(facade, glium_image, format, mipmaps).unwrap(); - self.textures.insert(tex_id, gl_texture.into()); + + let user_texture = EguiTexture::new(gl_texture.into(), delta.filter); + self.textures.insert(tex_id, user_texture); } } @@ -273,18 +282,44 @@ impl Painter { self.textures.remove(&tex_id); } - fn texture(&self, texture_id: egui::TextureId) -> Option<&SrgbTexture2d> { - self.textures.get(&texture_id).map(|rc| rc.as_ref()) + fn texture(&self, texture_id: egui::TextureId) -> Option<&EguiTexture> { + self.textures.get(&texture_id) } - pub fn register_native_texture(&mut self, native: Rc) -> egui::TextureId { + pub fn register_native_texture( + &mut self, + native: Rc, + filter: TextureFilter, + ) -> egui::TextureId { let id = egui::TextureId::User(self.next_native_tex_id); self.next_native_tex_id += 1; - self.textures.insert(id, native); + + let texture = EguiTexture::new(native, filter); + self.textures.insert(id, texture); id } - pub fn replace_native_texture(&mut self, id: egui::TextureId, replacing: Rc) { - self.textures.insert(id, replacing); + pub fn replace_native_texture( + &mut self, + id: egui::TextureId, + replacing: Rc, + filter: TextureFilter, + ) { + let texture = EguiTexture::new(replacing, filter); + self.textures.insert(id, texture); + } +} + +struct EguiTexture { + glium_texture: Rc, + filter: TextureFilter, +} + +impl EguiTexture { + fn new(glium_texture: Rc, filter: TextureFilter) -> Self { + Self { + glium_texture, + filter, + } } }