Skip to main content

astrelis_render/
target.rs

1//! Render target abstraction for unified surface/framebuffer rendering.
2
3use crate::framebuffer::Framebuffer;
4
5/// A render target that can be either a window surface or an offscreen framebuffer.
6///
7/// This enum simplifies render pass setup by providing a unified interface
8/// for different rendering destinations.
9#[derive(Debug, Clone, Copy)]
10#[derive(Default)]
11pub enum RenderTarget<'a> {
12    /// Render to the window surface.
13    ///
14    /// The surface view is obtained from the FrameContext during render pass creation.
15    #[default]
16    Surface,
17
18    /// Render to an offscreen framebuffer.
19    ///
20    /// The framebuffer manages its own color, depth, and MSAA textures.
21    Framebuffer(&'a Framebuffer),
22}
23
24impl<'a> RenderTarget<'a> {
25    /// Check if this target is a surface.
26    pub fn is_surface(&self) -> bool {
27        matches!(self, RenderTarget::Surface)
28    }
29
30    /// Check if this target is a framebuffer.
31    pub fn is_framebuffer(&self) -> bool {
32        matches!(self, RenderTarget::Framebuffer(_))
33    }
34
35    /// Get the framebuffer if this is a framebuffer target.
36    pub fn framebuffer(&self) -> Option<&'a Framebuffer> {
37        match self {
38            RenderTarget::Framebuffer(fb) => Some(fb),
39            _ => None,
40        }
41    }
42
43    /// Get the texture format for this target.
44    ///
45    /// For framebuffers, returns the framebuffer's format.
46    /// For surfaces, returns None (format must be obtained from surface config).
47    pub fn format(&self) -> Option<wgpu::TextureFormat> {
48        match self {
49            RenderTarget::Surface => None,
50            RenderTarget::Framebuffer(fb) => Some(fb.format()),
51        }
52    }
53
54    /// Get the sample count for this target.
55    ///
56    /// For framebuffers, returns the framebuffer's sample count.
57    /// For surfaces, returns 1 (surfaces don't support MSAA directly).
58    pub fn sample_count(&self) -> u32 {
59        match self {
60            RenderTarget::Surface => 1,
61            RenderTarget::Framebuffer(fb) => fb.sample_count(),
62        }
63    }
64
65    /// Check if this target has MSAA enabled.
66    pub fn has_msaa(&self) -> bool {
67        self.sample_count() > 1
68    }
69
70    /// Check if this target has a depth buffer.
71    pub fn has_depth(&self) -> bool {
72        match self {
73            RenderTarget::Surface => false,
74            RenderTarget::Framebuffer(fb) => fb.has_depth(),
75        }
76    }
77
78    /// Get the depth view if available.
79    pub fn depth_view(&self) -> Option<&wgpu::TextureView> {
80        match self {
81            RenderTarget::Surface => None,
82            RenderTarget::Framebuffer(fb) => fb.depth_view(),
83        }
84    }
85}
86
87
88impl<'a> From<&'a Framebuffer> for RenderTarget<'a> {
89    fn from(fb: &'a Framebuffer) -> Self {
90        RenderTarget::Framebuffer(fb)
91    }
92}