1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
use super::*; pub struct TextureAtlas { texture: ugli::Texture, uvs: Vec<AABB<f32>>, } impl TextureAtlas { pub fn new(ugli: &Rc<Ugli>, textures: &[&ugli::Texture]) -> Self { let mut width = 0; let mut height = 0; for texture in textures { width += texture.size().x; height = height.max(texture.size().y); } let mut atlas_texture = ugli::Texture::new_uninitialized(ugli, vec2(width, height)); let mut uvs = Vec::with_capacity(textures.len()); let mut x = 0; for texture in textures { let framebuffer = ugli::FramebufferRead::new( ugli, ugli::ColorAttachmentRead::Texture(texture), ugli::DepthAttachmentRead::None, ); framebuffer.copy_to_texture( &mut atlas_texture, AABB::pos_size(vec2(0, 0), texture.size()), vec2(x, 0), ); uvs.push(AABB::pos_size( vec2(x as f32 / width as f32, 0.0), vec2( texture.size().x as f32 / width as f32, texture.size().y as f32 / height as f32, ), )); x += texture.size().x; } Self { texture: atlas_texture, uvs, } } pub fn uv(&self, texture_index: usize) -> AABB<f32> { self.uvs[texture_index] } pub fn texture(&self) -> &ugli::Texture { &self.texture } pub fn set_filter(&mut self, filter: ugli::Filter) { self.texture.set_filter(filter); } }