Add `TextureOptions::wrap_mode` (#3954)
Exposes support in both glow and wgpu for texture wrap modes This would be breaking for manual creations of TextureOptions but would work with the current TextureOptions::NEAREST and LINEAR without change, keeping those clamp to edge I wasn't sure how best to expose the options to the user and added consts for LINEAR_REPEAT LINEAR_MIRRORED_REPEAT NEAREST_REPEAT NEAREST_MIRRORED_REPEAT This does not include wrap mode clamp to border as it worked fine with glow but with wgpu it panics due to Features Features(ADDRESS_MODE_CLAMP_TO_BORDER) are required but not enabled on the device, and I thought it was probably best not to try to enable that feature, but happy to include that functionality also if that is okay to be toggled  --------- Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
parent
a41a04d635
commit
a5973e5cac
|
|
@ -923,12 +923,19 @@ fn create_sampler(
|
||||||
epaint::textures::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
|
epaint::textures::TextureFilter::Nearest => wgpu::FilterMode::Nearest,
|
||||||
epaint::textures::TextureFilter::Linear => wgpu::FilterMode::Linear,
|
epaint::textures::TextureFilter::Linear => wgpu::FilterMode::Linear,
|
||||||
};
|
};
|
||||||
|
let address_mode = match options.wrap_mode {
|
||||||
|
epaint::textures::TextureWrapMode::ClampToEdge => wgpu::AddressMode::ClampToEdge,
|
||||||
|
epaint::textures::TextureWrapMode::Repeat => wgpu::AddressMode::Repeat,
|
||||||
|
epaint::textures::TextureWrapMode::MirroredRepeat => wgpu::AddressMode::MirrorRepeat,
|
||||||
|
};
|
||||||
device.create_sampler(&wgpu::SamplerDescriptor {
|
device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
label: Some(&format!(
|
label: Some(&format!(
|
||||||
"egui sampler (mag: {mag_filter:?}, min {min_filter:?})"
|
"egui sampler (mag: {mag_filter:?}, min {min_filter:?})"
|
||||||
)),
|
)),
|
||||||
mag_filter,
|
mag_filter,
|
||||||
min_filter,
|
min_filter,
|
||||||
|
address_mode_u: address_mode,
|
||||||
|
address_mode_v: address_mode,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,7 @@ pub use emath::{
|
||||||
pub use epaint::{
|
pub use epaint::{
|
||||||
mutex,
|
mutex,
|
||||||
text::{FontData, FontDefinitions, FontFamily, FontId, FontTweak},
|
text::{FontData, FontDefinitions, FontFamily, FontId, FontTweak},
|
||||||
textures::{TextureFilter, TextureOptions, TexturesDelta},
|
textures::{TextureFilter, TextureOptions, TextureWrapMode, TexturesDelta},
|
||||||
ClippedPrimitive, ColorImage, FontImage, ImageData, Mesh, PaintCallback, PaintCallbackInfo,
|
ClippedPrimitive, ColorImage, FontImage, ImageData, Mesh, PaintCallback, PaintCallbackInfo,
|
||||||
Rounding, Shape, Stroke, TextureHandle, TextureId,
|
Rounding, Shape, Stroke, TextureHandle, TextureId,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,20 @@ impl TextureFilterExt for egui::TextureFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait TextureWrapModeExt {
|
||||||
|
fn glow_code(&self) -> u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextureWrapModeExt for egui::TextureWrapMode {
|
||||||
|
fn glow_code(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
Self::ClampToEdge => glow::CLAMP_TO_EDGE,
|
||||||
|
Self::Repeat => glow::REPEAT,
|
||||||
|
Self::MirroredRepeat => glow::MIRRORED_REPEAT,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PainterError(String);
|
pub struct PainterError(String);
|
||||||
|
|
||||||
|
|
@ -555,12 +569,12 @@ impl Painter {
|
||||||
self.gl.tex_parameter_i32(
|
self.gl.tex_parameter_i32(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
glow::TEXTURE_WRAP_S,
|
glow::TEXTURE_WRAP_S,
|
||||||
glow::CLAMP_TO_EDGE as i32,
|
options.wrap_mode.glow_code() as i32,
|
||||||
);
|
);
|
||||||
self.gl.tex_parameter_i32(
|
self.gl.tex_parameter_i32(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
glow::TEXTURE_WRAP_T,
|
glow::TEXTURE_WRAP_T,
|
||||||
glow::CLAMP_TO_EDGE as i32,
|
options.wrap_mode.glow_code() as i32,
|
||||||
);
|
);
|
||||||
check_for_gl_error!(&self.gl, "tex_parameter");
|
check_for_gl_error!(&self.gl, "tex_parameter");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,9 @@ pub struct TextureOptions {
|
||||||
|
|
||||||
/// How to filter when minifying (when texels are smaller than pixels).
|
/// How to filter when minifying (when texels are smaller than pixels).
|
||||||
pub minification: TextureFilter,
|
pub minification: TextureFilter,
|
||||||
|
|
||||||
|
/// How to wrap the texture when the texture coordinates are outside the [0, 1] range.
|
||||||
|
pub wrap_mode: TextureWrapMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureOptions {
|
impl TextureOptions {
|
||||||
|
|
@ -163,12 +166,42 @@ impl TextureOptions {
|
||||||
pub const LINEAR: Self = Self {
|
pub const LINEAR: Self = Self {
|
||||||
magnification: TextureFilter::Linear,
|
magnification: TextureFilter::Linear,
|
||||||
minification: TextureFilter::Linear,
|
minification: TextureFilter::Linear,
|
||||||
|
wrap_mode: TextureWrapMode::ClampToEdge,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Nearest magnification and minification.
|
/// Nearest magnification and minification.
|
||||||
pub const NEAREST: Self = Self {
|
pub const NEAREST: Self = Self {
|
||||||
magnification: TextureFilter::Nearest,
|
magnification: TextureFilter::Nearest,
|
||||||
minification: TextureFilter::Nearest,
|
minification: TextureFilter::Nearest,
|
||||||
|
wrap_mode: TextureWrapMode::ClampToEdge,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Linear magnification and minification, but with the texture repeated.
|
||||||
|
pub const LINEAR_REPEAT: Self = Self {
|
||||||
|
magnification: TextureFilter::Linear,
|
||||||
|
minification: TextureFilter::Linear,
|
||||||
|
wrap_mode: TextureWrapMode::Repeat,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Linear magnification and minification, but with the texture mirrored and repeated.
|
||||||
|
pub const LINEAR_MIRRORED_REPEAT: Self = Self {
|
||||||
|
magnification: TextureFilter::Linear,
|
||||||
|
minification: TextureFilter::Linear,
|
||||||
|
wrap_mode: TextureWrapMode::MirroredRepeat,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Nearest magnification and minification, but with the texture repeated.
|
||||||
|
pub const NEAREST_REPEAT: Self = Self {
|
||||||
|
magnification: TextureFilter::Nearest,
|
||||||
|
minification: TextureFilter::Nearest,
|
||||||
|
wrap_mode: TextureWrapMode::Repeat,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Nearest magnification and minification, but with the texture mirrored and repeated.
|
||||||
|
pub const NEAREST_MIRRORED_REPEAT: Self = Self {
|
||||||
|
magnification: TextureFilter::Nearest,
|
||||||
|
minification: TextureFilter::Nearest,
|
||||||
|
wrap_mode: TextureWrapMode::MirroredRepeat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,6 +226,23 @@ pub enum TextureFilter {
|
||||||
Linear,
|
Linear,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Defines how textures are wrapped around objects when texture coordinates fall outside the [0, 1] range.
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
|
pub enum TextureWrapMode {
|
||||||
|
/// Stretches the edge pixels to fill beyond the texture's bounds.
|
||||||
|
///
|
||||||
|
/// This is what you want to use for a normal image in a GUI.
|
||||||
|
#[default]
|
||||||
|
ClampToEdge,
|
||||||
|
|
||||||
|
/// Tiles the texture across the surface, repeating it horizontally and vertically.
|
||||||
|
Repeat,
|
||||||
|
|
||||||
|
/// Mirrors the texture with each repetition, creating symmetrical tiling.
|
||||||
|
MirroredRepeat,
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// What has been allocated and freed during the last period.
|
/// What has been allocated and freed during the last period.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue