"easy to use" texture manager
Discussed in https://github.com/emilk/egui/discussions/1513
Is your feature request related to a problem? Please describe. There is currently no easy way to load textures without having to manually cache them.
Describe the solution you'd like An easy interface to load textures. For example:
let text = text_man.load("https://en.wikipedia.org/wiki/Scalable_Vector_Graphics#/media/File:SVG_Logo.svg");
Proposed interface
@emilk Should I work on implementing the following interface, or would you like adjustments?
trait ChachingStrategy: Sync {
fn should_unload(&self, /* not sure about the arguments yet */) -> bool;
}
trait BytesLoader: Sync {
fn load(&self, url: &str) -> LoaderResult;
}
trait BytesParser: Sync {
fn parse(&self, bytes: &[u8], size: &TextSize) -> ColorImage;
}
trait ETextMan: Sync {
fn load(&mut self, url: &str) -> TextureId;
fn load_sized(&mut self, url: &str, size: &TextureSize) -> TextureId;
fn unload(&mut self, url: &str);
fn unload_sized(&mut self, url: &str, size: &TextureSize);
}
I think the trait can be simplified with a single load and unload function, with several params, like size: Option<[usize; 2]> and then helper functions that are always implementead.
I don't see why unload would need to know the size. Are you thinking multiple textures of different sizes?
There is also the question of what to do with texture filtering.
But by all means, create a draft!
I already have a relatively fleshed out draft. I need to work out some details (and questions :D), and will then demonstrate the code using a small example I made. Here some things regarding your most recent message:
- Simplifying the trait: I personally think two methods are better, as the user only has to be concerned with the parameters they use. In the current draft it is implemented with a single method, but the trait "hides" that, and splits up the functionality. Should be easy enough to change in the future though.
[usize; 2]instead of(usize, usize)?: I'm actually not sure what type to use for the texture size. I did see that most of your existing code uses(f32, f32)/[f32; 2]. I've tried to convert to that at one point (specificallyVec2), but ran into issues due to hashing.- Loading different sizes: That mostly comes from vector images, that can be rasterized at different sizes. I imagine that most users will not use the
load_sizedmethods, except when rasterizing something (Currently the parsers, eg. png-parser, are also explicitly allowed to ignore the specified size, in case the documents have a fixed one). Back to vector images, I think it would be rather inefficient to not cache the individual rasterized versions, but that's just a theory. - Texture filtering: I have not covered that yet. Given that the system is quite modular, it should be no issue to add additional methods in the future, and require the parsers to take that additional argument.
Sorry, I forgot to answer this!
I think [usize; 2] makes most sense for sizes (compared to Vec2), since the textures need to be integer sized. I am a bit inconsistent with [usize; 2] vs (usize, usize) in egui, and the difference is mostly a matter of taste. But I think [usize; 2] is better, partially because it acts more like a Vec2, i.e. it can be indexed, but also because tuples are made for heterogeneous types ((f32, u32)), while sizes will always be homogeneous.
I'd love to see a draft PR with a texture manager than can be shared.
One use case I'm interested in is having a Markdown viewer that can take a shared reference to a TextureManager which then can load images from URL:s, so that one can embed images in markdown using  or 
A detailed design has emerged in:
- https://github.com/emilk/egui/issues/3291