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::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 {
|
||||
label: Some(&format!(
|
||||
"egui sampler (mag: {mag_filter:?}, min {min_filter:?})"
|
||||
)),
|
||||
mag_filter,
|
||||
min_filter,
|
||||
address_mode_u: address_mode,
|
||||
address_mode_v: address_mode,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ pub use emath::{
|
|||
pub use epaint::{
|
||||
mutex,
|
||||
text::{FontData, FontDefinitions, FontFamily, FontId, FontTweak},
|
||||
textures::{TextureFilter, TextureOptions, TexturesDelta},
|
||||
textures::{TextureFilter, TextureOptions, TextureWrapMode, TexturesDelta},
|
||||
ClippedPrimitive, ColorImage, FontImage, ImageData, Mesh, PaintCallback, PaintCallbackInfo,
|
||||
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)]
|
||||
pub struct PainterError(String);
|
||||
|
||||
|
|
@ -555,12 +569,12 @@ impl Painter {
|
|||
self.gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_WRAP_S,
|
||||
glow::CLAMP_TO_EDGE as i32,
|
||||
options.wrap_mode.glow_code() as i32,
|
||||
);
|
||||
self.gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
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");
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,9 @@ pub struct TextureOptions {
|
|||
|
||||
/// How to filter when minifying (when texels are smaller than pixels).
|
||||
pub minification: TextureFilter,
|
||||
|
||||
/// How to wrap the texture when the texture coordinates are outside the [0, 1] range.
|
||||
pub wrap_mode: TextureWrapMode,
|
||||
}
|
||||
|
||||
impl TextureOptions {
|
||||
|
|
@ -163,12 +166,42 @@ impl TextureOptions {
|
|||
pub const LINEAR: Self = Self {
|
||||
magnification: TextureFilter::Linear,
|
||||
minification: TextureFilter::Linear,
|
||||
wrap_mode: TextureWrapMode::ClampToEdge,
|
||||
};
|
||||
|
||||
/// Nearest magnification and minification.
|
||||
pub const NEAREST: Self = Self {
|
||||
magnification: 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,
|
||||
}
|
||||
|
||||
/// 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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue