egui icon indicating copy to clipboard operation
egui copied to clipboard

"easy to use" texture manager

Open Elias-Graf opened this issue 3 years ago • 3 comments

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);
}

Elias-Graf avatar Jul 02 '22 20:07 Elias-Graf

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!

emilk avatar Jul 21 '22 18:07 emilk

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 (specifically Vec2), 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_sized methods, 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.

Elias-Graf avatar Jul 21 '22 20:07 Elias-Graf

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 ![alt text](./image.png) or ![alt text](www.example.com/image.jpg)

emilk avatar Aug 10 '22 17:08 emilk

A detailed design has emerged in:

  • https://github.com/emilk/egui/issues/3291

emilk avatar Sep 01 '23 14:09 emilk