notan_graphics/
render_texture.rs

1use crate::texture::*;
2use crate::{Device, DropManager, Renderer, ResourceId};
3use std::ops::Deref;
4use std::sync::Arc;
5
6#[derive(Debug)]
7struct RenderTextureIdRef {
8    id: u64,
9    drop_manager: Arc<DropManager>,
10}
11
12impl Drop for RenderTextureIdRef {
13    fn drop(&mut self) {
14        self.drop_manager.push(ResourceId::RenderTexture(self.id));
15    }
16}
17
18#[derive(Debug, Clone)]
19pub struct RenderTexture {
20    id: u64,
21    _id_ref: Arc<RenderTextureIdRef>,
22    texture: Texture,
23}
24
25impl RenderTexture {
26    pub(crate) fn new(id: u64, texture: Texture, drop_manager: Arc<DropManager>) -> Self {
27        let id_ref = Arc::new(RenderTextureIdRef { id, drop_manager });
28
29        Self {
30            id,
31            _id_ref: id_ref,
32            texture,
33        }
34    }
35
36    #[inline(always)]
37    pub fn id(&self) -> u64 {
38        self.id
39    }
40
41    /// Returns a reference to the inner texture
42    #[inline(always)]
43    pub fn texture(&self) -> &Texture {
44        &self.texture
45    }
46
47    /// Consume the Render Texture and return the inner texture
48    #[inline(always)]
49    pub fn take_inner(self) -> Texture {
50        let Self { texture, .. } = self;
51
52        texture
53    }
54
55    pub fn create_renderer(&mut self) -> Renderer {
56        Renderer::new(self.width() as _, self.height() as _)
57    }
58
59    #[cfg(feature = "texture_to_file")]
60    pub fn to_file<P: AsRef<std::path::Path>>(
61        &self,
62        gfx: &mut Device,
63        path: P,
64    ) -> Result<(), String> {
65        crate::to_file::save_to_png_file(gfx, self.texture(), true, path)
66    }
67}
68
69impl Deref for RenderTexture {
70    type Target = Texture;
71
72    fn deref(&self) -> &Self::Target {
73        &self.texture
74    }
75}
76
77pub struct RenderTextureBuilder<'a> {
78    device: &'a mut Device,
79    info: TextureInfo,
80}
81
82impl<'a> RenderTextureBuilder<'a> {
83    pub fn new(device: &'a mut Device, width: u32, height: u32) -> Self {
84        let info = TextureInfo {
85            width,
86            height,
87            ..Default::default()
88        };
89
90        Self { device, info }
91    }
92
93    /// Enable depth
94    pub fn with_depth(mut self) -> Self {
95        self.info.depth = true;
96        self
97    }
98
99    /// Set the Texture format
100    pub fn with_format(mut self, format: TextureFormat) -> Self {
101        self.info.format = format;
102        self
103    }
104
105    /// Set the Texture filter modes
106    pub fn with_filter(mut self, min: TextureFilter, mag: TextureFilter) -> Self {
107        self.info.min_filter = min;
108        self.info.mag_filter = mag;
109        self
110    }
111
112    /// Set the texture wrap modes (x -> s, y -> t)
113    pub fn with_wrap(mut self, x: TextureWrap, y: TextureWrap) -> Self {
114        self.info.wrap_x = x;
115        self.info.wrap_y = y;
116        self
117    }
118
119    /// Toggle mipmap generation (with Linear filter if enabled)
120    pub fn with_mipmaps(mut self, enable: bool) -> Self {
121        if enable {
122            self.info.mipmap_filter = Some(TextureFilter::Linear);
123        } else {
124            self.info.mipmap_filter = None;
125        }
126        self
127    }
128
129    /// Set mipmap filtering function
130    pub fn with_mipmap_filter(mut self, filter: TextureFilter) -> Self {
131        self.info.mipmap_filter = Some(filter);
132        self
133    }
134
135    pub fn build(self) -> Result<RenderTexture, String> {
136        let Self { device, info } = self;
137
138        device.inner_create_render_texture(info)
139    }
140}