peacock/graphics/
sprite_batch.rs

1use std::ops::Add;
2
3use sfml::graphics::{
4    Drawable, PrimitiveType, RenderStates, RenderTarget, Sprite, Texture, Transformable,
5    VertexArray,
6};
7use sfml::system::Vector2f;
8
9pub struct SpriteBatch<'t> {
10    texture: &'t Texture,
11    vertices: VertexArray,
12    sprite_count: usize,
13}
14
15impl<'t> SpriteBatch<'t> {
16    /// The initial size of the vertex array, in batch units.
17    const INITIAL_VERTEX_ARRAY_SIZE: usize = 256;
18
19    pub fn new(texture: &'t Texture) -> Self {
20        let vertices = VertexArray::new(
21            PrimitiveType::Quads,
22            SpriteBatch::INITIAL_VERTEX_ARRAY_SIZE * 4,
23        );
24
25        Self {
26            texture,
27            vertices,
28            sprite_count: 0,
29        }
30    }
31
32    pub fn draw_sprite(&mut self, sprite: &Sprite) {
33        let index = self.sprite_count * 4;
34
35        if index >= self.vertices.vertex_count() {
36            self.vertices.resize(self.vertices.vertex_count() + 4);
37        }
38
39        self.vertices[index + 0].position = sprite.position();
40        self.vertices[index + 1].position = sprite.position().add(Vector2f::new(8.0, 0.0));
41        self.vertices[index + 2].position = sprite.position().add(Vector2f::new(8.0, 8.0));
42        self.vertices[index + 3].position = sprite.position().add(Vector2f::new(0.0, 8.0));
43
44        let texture_rect = sprite.texture_rect();
45        let position = Vector2f::new(texture_rect.left as f32, texture_rect.top as f32);
46        let size = Vector2f::new(texture_rect.width as f32, texture_rect.height as f32);
47
48        self.vertices[index + 0].tex_coords = position;
49        self.vertices[index + 1].tex_coords = position.add(Vector2f::new(size.x, 0.0));
50        self.vertices[index + 2].tex_coords = position.add(size);
51        self.vertices[index + 3].tex_coords = position.add(Vector2f::new(0.0, size.y));
52
53        self.vertices[index + 0].color = sprite.color();
54        self.vertices[index + 1].color = sprite.color();
55        self.vertices[index + 2].color = sprite.color();
56        self.vertices[index + 3].color = sprite.color();
57
58        self.sprite_count += 1;
59    }
60}
61
62impl<'t> Drawable for SpriteBatch<'t> {
63    fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
64        &'a self,
65        target: &mut RenderTarget,
66        states: RenderStates<'texture, 'shader, 'shader_texture>,
67    ) {
68        let render_states = RenderStates {
69            texture: Some(&self.texture),
70            ..states
71        };
72        target.draw_with_renderstates(&self.vertices, render_states);
73    }
74}