Rework the dynamic texture system to be less stupid
This commit is contained in:
parent
78aafb460e
commit
93bcd1e083
|
@ -731,8 +731,8 @@ pub struct TextureManager {
|
|||
animated_textures: Vec<AnimatedTexture>,
|
||||
pending_uploads: Vec<(i32, atlas::Rect, Vec<u8>)>,
|
||||
|
||||
dynamic_textures: HashMap<String, (i32, atlas::Rect), BuildHasherDefault<FNVHash>>,
|
||||
free_dynamics: Vec<(i32, atlas::Rect)>,
|
||||
dynamic_textures: HashMap<String, (Texture, image::DynamicImage), BuildHasherDefault<FNVHash>>,
|
||||
free_dynamics: Vec<Texture>,
|
||||
}
|
||||
|
||||
impl TextureManager {
|
||||
|
@ -773,8 +773,6 @@ impl TextureManager {
|
|||
}
|
||||
|
||||
fn update_textures(&mut self, version: usize) {
|
||||
self.dynamic_textures.clear();
|
||||
self.free_dynamics.clear();
|
||||
self.pending_uploads.clear();
|
||||
self.atlases.clear();
|
||||
self.animated_textures.clear();
|
||||
|
@ -782,10 +780,27 @@ impl TextureManager {
|
|||
let map = self.textures.clone();
|
||||
self.textures.clear();
|
||||
|
||||
self.free_dynamics.clear();
|
||||
|
||||
self.add_defaults();
|
||||
|
||||
for name in map.keys() {
|
||||
self.load_texture(name);
|
||||
if name.starts_with("steven-dynamic:") {
|
||||
let n = &name["steven-dynamic:".len()..];
|
||||
let (width, height, data) = {
|
||||
let dyn = match self.dynamic_textures.get(n) {
|
||||
Some(val) => val,
|
||||
None => continue,
|
||||
};
|
||||
let img = &dyn.1;
|
||||
let (width, height) = img.dimensions();
|
||||
(width, height, img.to_rgba().into_vec())
|
||||
};
|
||||
let new_tex = self.put_texture("steven-dynamic", n, width as u32, height as u32, data);
|
||||
self.dynamic_textures.get_mut(n).unwrap().0 = new_tex;
|
||||
} else {
|
||||
self.load_texture(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,79 +972,45 @@ impl TextureManager {
|
|||
t
|
||||
}
|
||||
|
||||
pub fn put_dynamic(&mut self, plugin: &str, name: &str, img: image::DynamicImage) -> Texture {
|
||||
pub fn put_dynamic(&mut self, name: &str, img: image::DynamicImage) -> Texture {
|
||||
let (width, height) = img.dimensions();
|
||||
let (width, height) = (width as usize, height as usize);
|
||||
let mut rect = None;
|
||||
let mut rect_pos = 0;
|
||||
for (i, r) in self.free_dynamics.iter().enumerate() {
|
||||
let (atlas, r) = *r;
|
||||
if r.width == width && r.height == height {
|
||||
rect_pos = i;
|
||||
rect = Some((atlas, r));
|
||||
rect = Some(r.clone());
|
||||
break;
|
||||
} else if r.width >= width && r.height >= height {
|
||||
rect_pos = i;
|
||||
rect = Some((atlas, r));
|
||||
rect = Some(r.clone());
|
||||
}
|
||||
}
|
||||
let data = img.to_rgba().into_vec();
|
||||
let mut new = false;
|
||||
let (atlas, rect) = if let Some(r) = rect {
|
||||
|
||||
if let Some(tex) = rect {
|
||||
self.free_dynamics.remove(rect_pos);
|
||||
r
|
||||
} else {
|
||||
new = true;
|
||||
self.find_free(width as usize, height as usize)
|
||||
};
|
||||
|
||||
let mut full_name = String::new();
|
||||
if plugin != "minecraft" {
|
||||
full_name.push_str(plugin);
|
||||
full_name.push_str(":");
|
||||
}
|
||||
full_name.push_str(name);
|
||||
|
||||
self.dynamic_textures.insert(full_name.clone(), (atlas, rect));
|
||||
if new {
|
||||
self.put_texture(plugin, name, width as u32, height as u32, data)
|
||||
} else {
|
||||
let t = Texture {
|
||||
name: full_name.clone(),
|
||||
version: self.version,
|
||||
atlas: atlas,
|
||||
x: rect.x,
|
||||
y: rect.y,
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
rel_x: 0.0,
|
||||
rel_y: 0.0,
|
||||
rel_width: 1.0,
|
||||
rel_height: 1.0,
|
||||
is_rel: false,
|
||||
};
|
||||
let rect = atlas::Rect {
|
||||
x: rect.x,
|
||||
y: rect.y,
|
||||
x: tex.x,
|
||||
y: tex.y,
|
||||
width: width,
|
||||
height: height,
|
||||
};
|
||||
self.pending_uploads.push((atlas, rect, data));
|
||||
self.textures.insert(full_name.to_owned(), t.clone());
|
||||
self.pending_uploads.push((tex.atlas, rect, data));
|
||||
let t = tex.relative(0.0, 0.0, (width as f32) / (tex.width as f32), (height as f32) / (tex.height as f32));
|
||||
self.dynamic_textures.insert(name.to_owned(), (tex, img));
|
||||
t
|
||||
} else {
|
||||
let tex = self.put_texture("steven-dynamic", name, width as u32, height as u32, data);
|
||||
self.dynamic_textures.insert(name.to_owned(), (tex.clone(), img));
|
||||
tex
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_dynamic(&mut self, plugin: &str, name: &str) {
|
||||
let mut full_name = String::new();
|
||||
if plugin != "minecraft" {
|
||||
full_name.push_str(plugin);
|
||||
full_name.push_str(":");
|
||||
}
|
||||
full_name.push_str(name);
|
||||
|
||||
let desc = self.dynamic_textures.remove(&full_name).unwrap();
|
||||
self.free_dynamics.push(desc);
|
||||
pub fn remove_dynamic(&mut self, name: &str) {
|
||||
let desc = self.dynamic_textures.remove(name).unwrap();
|
||||
self.free_dynamics.push(desc.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ impl ServerList {
|
|||
for server in &mut elements.servers {
|
||||
server.collection.remove_all(ui_container);
|
||||
if let Some(ref icon) = server.icon_texture {
|
||||
tex.remove_dynamic("steven_icon", &icon);
|
||||
tex.remove_dynamic(&icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -442,13 +442,17 @@ impl super::Screen for ServerList {
|
|||
});
|
||||
self.reload_server_list(renderer, ui_container);
|
||||
}
|
||||
fn on_deactive(&mut self, _renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
fn on_deactive(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
// Clean up
|
||||
{
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
elements.logo.remove(ui_container);
|
||||
elements.elements.remove_all(ui_container);
|
||||
let mut tex = renderer.get_textures_ref().write().unwrap();
|
||||
for server in &mut elements.servers {
|
||||
if let Some(ref icon) = server.icon_texture {
|
||||
tex.remove_dynamic(&icon);
|
||||
}
|
||||
server.collection.remove_all(ui_container);
|
||||
}
|
||||
elements.servers.clear();
|
||||
|
@ -535,7 +539,7 @@ impl super::Screen for ServerList {
|
|||
s.icon_texture = Some(name.clone());
|
||||
let icon_tex = tex.write()
|
||||
.unwrap()
|
||||
.put_dynamic("steven_icon", &name, favicon);
|
||||
.put_dynamic(&name, favicon);
|
||||
let icon = ui_container.get_mut(&s.icon);
|
||||
icon.set_texture(icon_tex);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue