diff options
author | Christofer Nolander <christofer@nolander.me> | 2024-09-22 19:16:16 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-22 19:16:16 +0200 |
commit | 6f7b9b9b8759ea3c9dea3ca5b0a17768b3731c95 (patch) | |
tree | 211fe87f9679a35fed8e2dc468d3da9a23956cb1 | |
parent | 07ccf41bf9ba25c63b24bd062221ea4f0b976e68 (diff) |
Add support for mipmap textures. (#5146)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md)
before opening a Pull Request!
* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.
Please be patient! I will review your PR, but my time is limited!
-->
* [x] I have followed the instructions in the PR template
Adds support for mipmaps in the `glow` backend.
Should be possible to implement for `wgpu` in the future as well, but
requires a custom compute kernel.
-rw-r--r-- | crates/egui_glow/src/painter.rs | 23 | ||||
-rw-r--r-- | crates/epaint/src/textures.rs | 23 |
2 files changed, 39 insertions, 7 deletions
diff --git a/crates/egui_glow/src/painter.rs b/crates/egui_glow/src/painter.rs index db2ff76d..f8f6145c 100644 --- a/crates/egui_glow/src/painter.rs +++ b/crates/egui_glow/src/painter.rs @@ -22,14 +22,18 @@ const VERT_SRC: &str = include_str!("shader/vertex.glsl"); const FRAG_SRC: &str = include_str!("shader/fragment.glsl"); trait TextureFilterExt { - fn glow_code(&self) -> u32; + fn glow_code(&self, mipmap: Option<egui::TextureFilter>) -> u32; } impl TextureFilterExt for egui::TextureFilter { - fn glow_code(&self) -> u32 { - match self { - Self::Linear => glow::LINEAR, - Self::Nearest => glow::NEAREST, + fn glow_code(&self, mipmap: Option<egui::TextureFilter>) -> u32 { + match (self, mipmap) { + (Self::Linear, None) => glow::LINEAR, + (Self::Nearest, None) => glow::NEAREST, + (Self::Linear, Some(Self::Linear)) => glow::LINEAR_MIPMAP_LINEAR, + (Self::Nearest, Some(Self::Linear)) => glow::NEAREST_MIPMAP_LINEAR, + (Self::Linear, Some(Self::Nearest)) => glow::LINEAR_MIPMAP_NEAREST, + (Self::Nearest, Some(Self::Nearest)) => glow::NEAREST_MIPMAP_NEAREST, } } } @@ -569,12 +573,12 @@ impl Painter { self.gl.tex_parameter_i32( glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, - options.magnification.glow_code() as i32, + options.magnification.glow_code(None) as i32, ); self.gl.tex_parameter_i32( glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, - options.minification.glow_code() as i32, + options.minification.glow_code(options.mipmap_mode) as i32, ); self.gl.tex_parameter_i32( @@ -635,6 +639,11 @@ impl Painter { ); check_for_gl_error!(&self.gl, "tex_image_2d"); } + + if options.mipmap_mode.is_some() { + self.gl.generate_mipmap(glow::TEXTURE_2D); + check_for_gl_error!(&self.gl, "generate_mipmap"); + } } } diff --git a/crates/epaint/src/textures.rs b/crates/epaint/src/textures.rs index 4244c687..cc191a75 100644 --- a/crates/epaint/src/textures.rs +++ b/crates/epaint/src/textures.rs @@ -159,6 +159,16 @@ pub struct TextureOptions { /// How to wrap the texture when the texture coordinates are outside the [0, 1] range. pub wrap_mode: TextureWrapMode, + + /// How to filter between texture mipmaps. + /// + /// Mipmaps ensures textures look smooth even when the texture is very small and pixels are much + /// larger than individual texels. + /// + /// # Notes + /// + /// - This may not be available on all backends (currently only `egui_glow`). + pub mipmap_mode: Option<TextureFilter>, } impl TextureOptions { @@ -167,6 +177,7 @@ impl TextureOptions { magnification: TextureFilter::Linear, minification: TextureFilter::Linear, wrap_mode: TextureWrapMode::ClampToEdge, + mipmap_mode: None, }; /// Nearest magnification and minification. @@ -174,6 +185,7 @@ impl TextureOptions { magnification: TextureFilter::Nearest, minification: TextureFilter::Nearest, wrap_mode: TextureWrapMode::ClampToEdge, + mipmap_mode: None, }; /// Linear magnification and minification, but with the texture repeated. @@ -181,6 +193,7 @@ impl TextureOptions { magnification: TextureFilter::Linear, minification: TextureFilter::Linear, wrap_mode: TextureWrapMode::Repeat, + mipmap_mode: None, }; /// Linear magnification and minification, but with the texture mirrored and repeated. @@ -188,6 +201,7 @@ impl TextureOptions { magnification: TextureFilter::Linear, minification: TextureFilter::Linear, wrap_mode: TextureWrapMode::MirroredRepeat, + mipmap_mode: None, }; /// Nearest magnification and minification, but with the texture repeated. @@ -195,6 +209,7 @@ impl TextureOptions { magnification: TextureFilter::Nearest, minification: TextureFilter::Nearest, wrap_mode: TextureWrapMode::Repeat, + mipmap_mode: None, }; /// Nearest magnification and minification, but with the texture mirrored and repeated. @@ -202,7 +217,15 @@ impl TextureOptions { magnification: TextureFilter::Nearest, minification: TextureFilter::Nearest, wrap_mode: TextureWrapMode::MirroredRepeat, + mipmap_mode: None, }; + + pub const fn with_mipmap_mode(self, mipmap_mode: Option<TextureFilter>) -> Self { + Self { + mipmap_mode, + ..self + } + } } impl Default for TextureOptions { |