peacock/graphics/
sprite_batch.rs1use 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 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}