1use std::sync::Arc;
2use vulkano::{command_buffer::{AutoCommandBufferBuilder, SubpassContents}, device::Queue, format::Format, framebuffer::Framebuffer, framebuffer::{FramebufferAbstract, RenderPassAbstract, Subpass}, image::AttachmentImage, image::ImageUsage, image::{ImageViewAbstract, SwapchainImage, view::ImageView}, sync::GpuFuture};
3use feo_math::{linear_algebra::{matrix4::Matrix4}, utils::space::Space};
4use winit::window::Window;
5use super::{draw_pass_manager::DrawPassManager, lighting_pass_manager::LightingPassManager, pass_builder::PassBuilder};
6
7pub struct FrameSystem {
9 pub(crate) gfx_queue: Arc<Queue>,
10
11 render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
12 framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>,
13
14 pub(crate) diffuse_buffer: Arc<ImageView<Arc<AttachmentImage>>>,
15 pub(crate) normals_buffer: Arc<ImageView<Arc<AttachmentImage>>>,
16 pub(crate) ambient_buffer: Arc<ImageView<Arc<AttachmentImage>>>,
17 pub(crate) specular_buffer: Arc<ImageView<Arc<AttachmentImage>>>,
18 pub(crate) depth_buffer: Arc<ImageView<Arc<AttachmentImage>>>,
19
20 pub(crate) lighting_pass_manager: LightingPassManager,
23 pub(crate) draw_pass_manager: DrawPassManager,
24}
25
26impl FrameSystem {
27 pub fn new(gfx_queue: Arc<Queue>, final_output_format: Format, dims: [u32; 2]) -> FrameSystem {
29 let render_pass = Arc::new(
30 vulkano::ordered_passes_renderpass!(gfx_queue.device().clone(),
31 attachments: {
32 final_color: {
34 load: Clear,
35 store: Store,
36 format: final_output_format,
37 samples: 1,
38 },
39 normals: {
41 load: Clear,
42 store: DontCare,
43 format: Format::R16G16B16A16Sfloat,
44 samples: 1,
45 },
46 diffuse: {
48 load: Clear,
49 store: DontCare,
50 format: Format::A2B10G10R10UnormPack32,
51 samples: 1,
52 },
53 ambient: {
55 load: Clear,
56 store: DontCare,
57 format: Format::A2B10G10R10UnormPack32,
58 samples: 1,
59 },
60 specular: {
62 load: Clear,
63 store: DontCare,
64 format: Format::A2B10G10R10UnormPack32,
65 samples: 1,
66 },
67 depth: {
69 load: Clear,
70 store: DontCare,
71 format: Format::D16Unorm,
72 samples: 1,
73 }},
82 passes: [
83 {
85 color: [normals, diffuse, ambient, specular], depth_stencil: {depth},
87 input: []
88 },
89
90 {
99 color: [final_color],
100 depth_stencil: {},
101 input: [normals, diffuse, ambient, specular, depth]
102 }
103 ]
104 ).unwrap(),
105 );
106
107 let atch_usage = ImageUsage {
108 transient_attachment: true,
109 input_attachment: true,
110 ..ImageUsage::none()
111 };
112
113 let depth_buffer = ImageView::new(
114 AttachmentImage::with_usage(
115 gfx_queue.device().clone(),
116 dims,
117 Format::D16Unorm,
118 atch_usage,
119 ).unwrap(),
120 ).unwrap();
121 let normals_buffer = ImageView::new(
130 AttachmentImage::with_usage(
131 gfx_queue.device().clone(),
132 dims,
133 Format::R16G16B16A16Sfloat,
134 atch_usage,
135 ).unwrap(),
136 ).unwrap();
137 let diffuse_buffer = ImageView::new(
138 AttachmentImage::with_usage(
139 gfx_queue.device().clone(),
140 dims,
141 Format::A2B10G10R10UnormPack32,
142 atch_usage,
143 ).unwrap(),
144 ).unwrap();
145 let ambient_buffer = ImageView::new(
146 AttachmentImage::with_usage(
147 gfx_queue.device().clone(),
148 dims,
149 Format::A2B10G10R10UnormPack32,
150 atch_usage,
151 ).unwrap(),
152 ).unwrap();
153 let specular_buffer = ImageView::new(
154 AttachmentImage::with_usage(
155 gfx_queue.device().clone(),
156 dims,
157 Format::A2B10G10R10UnormPack32,
158 atch_usage,
159 ).unwrap(),
160 ).unwrap();
161
162 let draw_pass_manager = DrawPassManager::new(gfx_queue.clone(), Subpass::from(render_pass.clone(), 0).unwrap(), dims);
167 let lighting_pass_manager = LightingPassManager::new(gfx_queue.clone(), Subpass::from(render_pass.clone(), 1).unwrap());
168
169 FrameSystem {
170 gfx_queue,
171 render_pass: render_pass as Arc<_>,
172 framebuffers: Vec::new(),
173 diffuse_buffer,
174 ambient_buffer,
175 specular_buffer,
176 normals_buffer,
177 depth_buffer,
178 lighting_pass_manager,
181 draw_pass_manager,
182 }
183 }
184
185 pub fn pass_builder<F>(
187 &mut self,
188 before_future: F,
189 img_num: usize,
190 screen_to_camera: Matrix4<f32>,
191 to_camera_space: Space) -> PassBuilder
192 where F: GpuFuture + 'static {
193 let framebuffer = self.framebuffers[img_num].clone();
194
195 let mut command_buffer_builder = AutoCommandBufferBuilder::primary_one_time_submit(
197 self.gfx_queue.device().clone(),
198 self.gfx_queue.family(),
199 ).unwrap();
200
201 command_buffer_builder.begin_render_pass(
202 framebuffer.clone(),
203 SubpassContents::SecondaryCommandBuffers,
204 vec![
205 [0.0, 0.0, 0.0, 0.0].into(),
206 [0.0, 0.0, 0.0, 0.0].into(),
207 [0.0, 0.0, 0.0, 0.0].into(),
208 [0.0, 0.0, 0.0, 0.0].into(),
209 [0.0, 0.0, 0.0, 0.0].into(),
210 1.0_f32.into(),
211 ],
212 ).unwrap();
213
214 PassBuilder {
215 system: self,
216 before_main_cb_future: Some(Box::new(before_future)),
217 framebuffer,
218 command_buffer_builder: Some(command_buffer_builder),
219 screen_to_camera,
220 to_camera_space
221 }
222 }
223
224 pub fn rebuild_dims(&mut self, images: &[Arc<ImageView<Arc<SwapchainImage<Window>>>>]){
226 let dimensions = &images[0].clone().image().dimensions().width_height();
227 self.draw_pass_manager.rebuild(dimensions, self.render_pass.clone());
228
229 let atch_usage = ImageUsage {
230 transient_attachment: true,
231 input_attachment: true,
232 ..ImageUsage::none()
233 };
234
235 self.depth_buffer = ImageView::new(
236 AttachmentImage::with_usage(
237 self.gfx_queue.device().clone(),
238 *dimensions,
239 Format::D16Unorm,
240 atch_usage,
241 ).unwrap(),
242 ).unwrap();
243 self.normals_buffer = ImageView::new(
244 AttachmentImage::with_usage(
245 self.gfx_queue.device().clone(),
246 *dimensions,
247 Format::R16G16B16A16Sfloat,
248 atch_usage,
249 ).unwrap(),
250 ).unwrap();
251 self.diffuse_buffer = ImageView::new(
252 AttachmentImage::with_usage(
253 self.gfx_queue.device().clone(),
254 *dimensions,
255 Format::A2B10G10R10UnormPack32,
256 atch_usage,
257 ).unwrap(),
258 ).unwrap();
259 self.ambient_buffer = ImageView::new(
260 AttachmentImage::with_usage(
261 self.gfx_queue.device().clone(),
262 *dimensions,
263 Format::A2B10G10R10UnormPack32,
264 atch_usage,
265 ).unwrap(),
266 ).unwrap();
267 self.specular_buffer = ImageView::new(
268 AttachmentImage::with_usage(
269 self.gfx_queue.device().clone(),
270 *dimensions,
271 Format::A2B10G10R10UnormPack32,
272 atch_usage,
273 ).unwrap(),
274 ).unwrap();
275
276 self.framebuffers = images.iter()
277 .map(|image|
278 Arc::new(
279 Framebuffer::start(self.render_pass.clone())
280 .add(image.clone()).unwrap()
281 .add(self.normals_buffer.clone()).unwrap()
282 .add(self.diffuse_buffer.clone()).unwrap()
283 .add(self.ambient_buffer.clone()).unwrap()
284 .add(self.specular_buffer.clone()).unwrap()
285 .add(self.depth_buffer.clone()).unwrap()
286 .build().unwrap(),
287 ) as Arc<dyn FramebufferAbstract + Send + Sync>
288 ).collect::<Vec<_>>();
289 }
290}