game_toolkit_gfx/frame.rs
1use crate::graphics::Graphics;
2use crate::painter::Painter;
3
4pub struct Frame {
5 pub(crate) encoder: Option<wgpu::CommandEncoder>,
6 pub(crate) view: wgpu::TextureView,
7 pub(crate) surface_texture: Option<wgpu::SurfaceTexture>,
8 /// The virtual-resolution canvas the painter draws into, if any.
9 pub(crate) canvas: Option<wgpu::TextureView>,
10 /// Size of `canvas`, and whether it is a virtual-resolution canvas (else window-sized).
11 pub(crate) canvas_size: [u32; 2],
12 pub(crate) canvas_virtual: bool,
13 pub clear_color: [f32; 4],
14 pub(crate) flushed: bool,
15 /// Whether the canvas has been scaled onto the window this frame.
16 pub(crate) composited: bool,
17 /// Whether indexed colour was on when the frame began (the canvas holds indices).
18 pub(crate) indexed: bool,
19}
20
21impl Frame {
22 /// Begin a 2D rendering pass. Returns a [`Painter`] that flushes on drop.
23 pub fn painter<'a>(&'a mut self, gfx: &'a mut Graphics) -> Painter<'a> {
24 Painter::new(self, gfx)
25 }
26
27 pub fn encoder_mut(&mut self) -> Option<&mut wgpu::CommandEncoder> {
28 self.encoder.as_mut()
29 }
30
31 /// The window's (surface's) view. With a virtual resolution the painter draws into the
32 /// canvas instead ([`Self::target_view`]), which is scaled onto this view by
33 /// [`Graphics::flush_pending`] or at the end of the frame.
34 pub fn view(&self) -> &wgpu::TextureView {
35 &self.view
36 }
37
38 /// The view the painter draws into: the virtual-resolution canvas when one is set, else
39 /// the window's view.
40 ///
41 /// With indexed colour on ([`Self::target_is_indexed`]) this is the index canvas: it holds
42 /// palette indices, not colours. Write them with `index_out` from
43 /// `INDEX_WGSL` (feature `indexed`); an RGBA pass would write meaningless indices. Colour
44 /// effects belong in a [`PostEffect`](crate::PostEffect), which sees the resolved colours.
45 pub fn target_view(&self) -> &wgpu::TextureView {
46 self.canvas.as_ref().unwrap_or(&self.view)
47 }
48
49 /// Whether [`Self::target_view`] holds palette indices (indexed colour was on when the
50 /// frame began) rather than colours. Always `false` without the `indexed` feature.
51 pub fn target_is_indexed(&self) -> bool {
52 self.indexed
53 }
54
55 /// Split borrow of the view and encoder so overlays (egui, custom passes) can record
56 /// into the same frame without fighting the borrow checker.
57 pub fn view_and_encoder(&mut self) -> (&wgpu::TextureView, &mut wgpu::CommandEncoder) {
58 (
59 &self.view,
60 self.encoder
61 .as_mut()
62 .expect("frame encoder taken/dropped before view_and_encoder"),
63 )
64 }
65}