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