notan_graphics/
renderer.rs

1use crate::buffer::*;
2use crate::commands::*;
3
4use crate::pipeline::*;
5use crate::texture::*;
6
7#[derive(Default, Clone)]
8pub struct Renderer {
9    commands: Vec<Commands>,
10    size: (u32, u32),
11    primitive: DrawPrimitive,
12    slot_count: u32,
13}
14
15impl Renderer {
16    pub fn new(width: u32, height: u32) -> Self {
17        Self {
18            size: (width, height),
19            commands: vec![Commands::Size { width, height }],
20            primitive: DrawPrimitive::Triangles,
21            slot_count: 0,
22        }
23    }
24
25    pub fn begin(&mut self, options: Option<ClearOptions>) {
26        let (color, stencil, depth) = match options {
27            Some(opts) => (opts.color, opts.stencil, opts.depth),
28            _ => (None, None, None),
29        };
30
31        self.commands.push(Commands::Begin {
32            color,
33            stencil,
34            depth,
35        });
36    }
37
38    pub fn set_primitive(&mut self, primitive: DrawPrimitive) {
39        self.primitive = primitive;
40    }
41
42    pub fn end(&mut self) {
43        self.commands.push(Commands::End);
44        self.unbind_textures();
45    }
46
47    pub fn set_size(&mut self, width: u32, height: u32) {
48        self.size = (width, height);
49        self.commands.push(Commands::Size { width, height });
50    }
51
52    pub fn size(&self) -> (u32, u32) {
53        self.size
54    }
55
56    pub fn width(&self) -> u32 {
57        self.size.0
58    }
59
60    pub fn height(&self) -> u32 {
61        self.size.1
62    }
63
64    pub fn set_viewport(&mut self, x: f32, y: f32, width: f32, height: f32) {
65        self.commands.push(Commands::Viewport {
66            x,
67            y,
68            width,
69            height,
70        });
71    }
72
73    pub fn set_scissors(&mut self, x: f32, y: f32, width: f32, height: f32) {
74        self.commands.push(Commands::Scissors {
75            x,
76            y,
77            width,
78            height,
79        });
80    }
81
82    pub fn set_pipeline(&mut self, pipeline: &Pipeline) {
83        self.commands.push(Commands::Pipeline {
84            id: pipeline.id(),
85            options: pipeline.options,
86        });
87    }
88
89    pub fn bind_buffer(&mut self, buffer: &Buffer) {
90        self.commands.push(Commands::BindBuffer { id: buffer.id() });
91    }
92
93    pub fn bind_buffers(&mut self, buffers: &[&Buffer]) {
94        self.commands
95            .extend(buffers.iter().map(|b| Commands::BindBuffer { id: b.id() }));
96    }
97
98    pub fn draw(&mut self, offset: i32, count: i32) {
99        self.commands.push(Commands::Draw {
100            primitive: self.primitive,
101            offset,
102            count,
103        })
104    }
105
106    pub fn draw_instanced(&mut self, offset: i32, count: i32, length: i32) {
107        self.commands.push(Commands::DrawInstanced {
108            primitive: self.primitive,
109            offset,
110            count,
111            length,
112        })
113    }
114
115    pub fn bind_texture(&mut self, location: u32, texture: &Texture) {
116        self.bind_texture_slot(self.slot_count, location, texture);
117        self.slot_count += 1;
118    }
119
120    pub fn bind_texture_slot(&mut self, slot: u32, location: u32, texture: &Texture) {
121        self.commands.push(Commands::BindTexture {
122            slot,
123            location,
124            id: texture.id(),
125        })
126    }
127
128    pub fn unbind_textures(&mut self) {
129        self.slot_count = 0;
130    }
131
132    pub fn clear(&mut self) {
133        self.unbind_textures();
134        self.commands.clear();
135    }
136
137    pub fn commands(&self) -> &[Commands] {
138        &self.commands
139    }
140}