1use crate::{
11 backend::{framebuffer::Framebuffer, texture::Texture as TextureBackend},
12 context::GraphicsContext,
13 framebuffer::FramebufferError,
14 texture::{TexelUpload, Texture},
15};
16use crate::{
17 pixel::{ColorPixel, PixelFormat, RenderablePixel},
18 texture::{Dimensionable, Sampler},
19};
20
21pub trait ColorSlot<B, D>
38where
39 B: ?Sized + Framebuffer<D>,
40 D: Dimensionable,
41 D::Size: Copy,
42{
43 type ColorTextures;
49
50 fn color_formats() -> Vec<PixelFormat>;
54
55 fn reify_color_textures<C>(
59 ctx: &mut C,
60 size: D::Size,
61 mipmaps: usize,
62 sampler: &Sampler,
63 framebuffer: &mut B::FramebufferRepr,
64 attachment_index: usize,
65 ) -> Result<Self::ColorTextures, FramebufferError>
66 where
67 C: GraphicsContext<Backend = B>;
68}
69
70impl<B, D> ColorSlot<B, D> for ()
71where
72 B: ?Sized + Framebuffer<D>,
73 D: Dimensionable,
74 D::Size: Copy,
75{
76 type ColorTextures = ();
77
78 fn color_formats() -> Vec<PixelFormat> {
79 Vec::new()
80 }
81
82 fn reify_color_textures<C>(
83 _: &mut C,
84 _: D::Size,
85 _: usize,
86 _: &Sampler,
87 _: &mut B::FramebufferRepr,
88 _: usize,
89 ) -> Result<Self::ColorTextures, FramebufferError>
90 where
91 C: GraphicsContext<Backend = B>,
92 {
93 Ok(())
94 }
95}
96
97impl<B, D, P> ColorSlot<B, D> for P
98where
99 B: ?Sized + Framebuffer<D> + TextureBackend<D, P>,
100 D: Dimensionable,
101 D::Size: Copy,
102 Self: ColorPixel + RenderablePixel,
103{
104 type ColorTextures = Texture<B, D, P>;
105
106 fn color_formats() -> Vec<PixelFormat> {
107 vec![P::pixel_format()]
108 }
109
110 fn reify_color_textures<C>(
111 ctx: &mut C,
112 size: D::Size,
113 mipmaps: usize,
114 sampler: &Sampler,
115 framebuffer: &mut B::FramebufferRepr,
116 attachment_index: usize,
117 ) -> Result<Self::ColorTextures, FramebufferError>
118 where
119 C: GraphicsContext<Backend = B>,
120 {
121 let texture = Texture::new(ctx, size, sampler.clone(), TexelUpload::reserve(mipmaps))?;
122
123 unsafe { B::attach_color_texture(framebuffer, &texture.repr, attachment_index)? };
124
125 Ok(texture)
126 }
127}
128
129macro_rules! impl_color_slot_tuple {
130 ($($pf:ident),*) => {
131 impl<B, D, $($pf),*> ColorSlot<B, D> for ($($pf),*)
132 where
133 B: ?Sized + Framebuffer<D> + $(TextureBackend<D, $pf> +)*,
134 D: Dimensionable,
135 D::Size: Copy,
136 $(
137 $pf: ColorPixel + RenderablePixel
138 ),*
139 {
140 type ColorTextures = ($(Texture<B, D, $pf>),*);
141
142 fn color_formats() -> Vec<PixelFormat> {
143 vec![$($pf::pixel_format()),*]
144
145 }
146
147 impl_reify_color_textures!{ $($pf),* }
148 }
149 }
150}
151
152macro_rules! impl_reify_color_textures {
157 ($pf:ident , $($pfr:ident),*) => {
158 fn reify_color_textures<C>(
159 ctx: &mut C,
160 size: D::Size,
161 mipmaps: usize,
162 sampler: &Sampler,
163 framebuffer: &mut B::FramebufferRepr,
164 mut attachment_index: usize,
165 ) -> Result<Self::ColorTextures, FramebufferError>
166 where
167 C: GraphicsContext<Backend = B>,
168 {
169 let textures = (
170 <$pf as ColorSlot<B, D>>::reify_color_textures(
172 ctx,
173 size,
174 mipmaps,
175 sampler,
176 framebuffer,
177 attachment_index,
178 )?,
179 $({
181 attachment_index += 1;
182 let texture = <$pfr as ColorSlot<B, D>>::reify_color_textures(
183 ctx,
184 size,
185 mipmaps,
186 sampler,
187 framebuffer,
188 attachment_index,
189 )?;
190
191 texture
192 }),*
193 );
194
195 Ok(textures)
196 }
197 }
198}
199
200macro_rules! impl_color_slot_tuples {
201 ($first:ident , $second:ident) => {
202 impl_color_slot_tuple!($first, $second);
204 };
205
206 ($first:ident , $($pf:ident),*) => {
207 impl_color_slot_tuples!($($pf),*);
209 impl_color_slot_tuple!($first, $($pf),*);
211 };
212}
213
214impl_color_slot_tuples!(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11);