1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00

Specify deifferent minification and magnification filters (#2224)

* Specify deifferent minification and magnification filters

* Fixes

* Update changelogs

* Doctest fixes

* Add deprecation notice for RetainedImage::with_texture_filter
This commit is contained in:
Emil Ernerfeldt
2022-11-02 17:54:06 +01:00
committed by GitHub
parent 8e79a5a8ae
commit 34e6e12f00
19 changed files with 147 additions and 97 deletions

View File

@@ -13,6 +13,7 @@ All notable changes to the epaint crate will be documented in this file.
* Added `epaint::hex_color!` to create `Color32`'s from hex strings under the `color-hex` feature ([#1596](https://github.com/emilk/egui/pull/1596)).
* Optimize tessellation of filled circles by 10x or more ([#1616](https://github.com/emilk/egui/pull/1616)).
* Added opt-in feature `deadlock_detection` to detect double-lock of mutexes on the same thread ([#1619](https://github.com/emilk/egui/pull/1619)).
* Texture loading now takes a `TexureOptions` with minification and magnification filters ([#2224](https://github.com/emilk/egui/pull/2224)).
## 0.18.1 - 2022-05-01

View File

@@ -1,4 +1,4 @@
use crate::{textures::TextureFilter, Color32};
use crate::{textures::TextureOptions, Color32};
/// An image stored in RAM.
///
@@ -291,7 +291,7 @@ pub struct ImageDelta {
/// If [`Self::pos`] is `Some`, this describes a patch of the whole image starting at [`Self::pos`].
pub image: ImageData,
pub filter: TextureFilter,
pub options: TextureOptions,
/// If `None`, set the whole texture to [`Self::image`].
///
@@ -301,19 +301,19 @@ pub struct ImageDelta {
impl ImageDelta {
/// Update the whole texture.
pub fn full(image: impl Into<ImageData>, filter: TextureFilter) -> Self {
pub fn full(image: impl Into<ImageData>, options: TextureOptions) -> Self {
Self {
image: image.into(),
filter,
options,
pos: None,
}
}
/// Update a sub-region of an existing texture.
pub fn partial(pos: [usize; 2], image: impl Into<ImageData>, filter: TextureFilter) -> Self {
pub fn partial(pos: [usize; 2], image: impl Into<ImageData>, options: TextureOptions) -> Self {
Self {
image: image.into(),
filter,
options,
pos: Some(pos),
}
}

View File

@@ -1,6 +1,6 @@
use emath::{remap_clamp, Rect};
use crate::{textures::TextureFilter, FontImage, ImageDelta};
use crate::{FontImage, ImageDelta};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct Rectu {
@@ -174,16 +174,18 @@ impl TextureAtlas {
/// Call to get the change to the image since last call.
pub fn take_delta(&mut self) -> Option<ImageDelta> {
let texture_options = crate::textures::TextureOptions::LINEAR;
let dirty = std::mem::replace(&mut self.dirty, Rectu::NOTHING);
if dirty == Rectu::NOTHING {
None
} else if dirty == Rectu::EVERYTHING {
Some(ImageDelta::full(self.image.clone(), TextureFilter::Linear))
Some(ImageDelta::full(self.image.clone(), texture_options))
} else {
let pos = [dirty.min_x, dirty.min_y];
let size = [dirty.max_x - dirty.min_x, dirty.max_y - dirty.min_y];
let region = self.image.region(pos, size);
Some(ImageDelta::partial(pos, region, TextureFilter::Linear))
Some(ImageDelta::partial(pos, region, texture_options))
}
}

View File

@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::{
emath::NumExt, mutex::RwLock, textures::TextureFilter, ImageData, ImageDelta, TextureId,
emath::NumExt, mutex::RwLock, textures::TextureOptions, ImageData, ImageDelta, TextureId,
TextureManager,
};
@@ -66,10 +66,10 @@ impl TextureHandle {
}
/// Assign a new image to an existing texture.
pub fn set(&mut self, image: impl Into<ImageData>, filter: TextureFilter) {
pub fn set(&mut self, image: impl Into<ImageData>, options: TextureOptions) {
self.tex_mngr
.write()
.set(self.id, ImageDelta::full(image.into(), filter));
.set(self.id, ImageDelta::full(image.into(), options));
}
/// Assign a new image to a subregion of the whole texture.
@@ -77,11 +77,11 @@ impl TextureHandle {
&mut self,
pos: [usize; 2],
image: impl Into<ImageData>,
filter: TextureFilter,
options: TextureOptions,
) {
self.tex_mngr
.write()
.set(self.id, ImageDelta::partial(pos, image.into(), filter));
.set(self.id, ImageDelta::partial(pos, image.into(), options));
}
/// width x height

View File

@@ -26,7 +26,7 @@ impl TextureManager {
/// MUST have a white pixel at (0,0) ([`crate::WHITE_UV`]).
///
/// The texture is given a retain-count of `1`, requiring one call to [`Self::free`] to free it.
pub fn alloc(&mut self, name: String, image: ImageData, filter: TextureFilter) -> TextureId {
pub fn alloc(&mut self, name: String, image: ImageData, options: TextureOptions) -> TextureId {
let id = TextureId::Managed(self.next_id);
self.next_id += 1;
@@ -35,10 +35,10 @@ impl TextureManager {
size: image.size(),
bytes_per_pixel: image.bytes_per_pixel(),
retain_count: 1,
filter,
options,
});
self.delta.set.push((id, ImageDelta::full(image, filter)));
self.delta.set.push((id, ImageDelta::full(image, options)));
id
}
@@ -131,8 +131,50 @@ pub struct TextureMeta {
/// Free when this reaches zero.
pub retain_count: usize,
/// The texture filtering mode to use when rendering
pub filter: TextureFilter,
/// The texture filtering mode to use when rendering.
pub options: TextureOptions,
}
impl TextureMeta {
/// Size in bytes.
/// width x height x [`Self::bytes_per_pixel`].
pub fn bytes_used(&self) -> usize {
self.size[0] * self.size[1] * self.bytes_per_pixel
}
}
// ----------------------------------------------------------------------------
/// How the texture texels are filtered.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TextureOptions {
/// How to filter when magnifying (when texels are larger than pixels).
pub magnification: TextureFilter,
/// How to filter when minifying (when texels are smaller than pixels).
pub minification: TextureFilter,
}
impl TextureOptions {
/// Linear magnification and minification.
pub const LINEAR: Self = Self {
magnification: TextureFilter::Linear,
minification: TextureFilter::Linear,
};
/// Nearest magnification and minification.
pub const NEAREST: Self = Self {
magnification: TextureFilter::Nearest,
minification: TextureFilter::Nearest,
};
}
impl Default for TextureOptions {
/// The default is linear for both magnification and minification.
fn default() -> Self {
Self::LINEAR
}
}
/// How the texture texels are filtered.
@@ -146,25 +188,9 @@ pub enum TextureFilter {
Nearest,
/// Linearly interpolate the nearest neighbors, creating a smoother look when zooming in and out.
///
/// This is the default.
Linear,
}
impl Default for TextureFilter {
fn default() -> Self {
Self::Linear
}
}
impl TextureMeta {
/// Size in bytes.
/// width x height x [`Self::bytes_per_pixel`].
pub fn bytes_used(&self) -> usize {
self.size[0] * self.size[1] * self.bytes_per_pixel
}
}
// ----------------------------------------------------------------------------
/// What has been allocated and freed during the last period.