feo_oop_engine/graphics/
draw_pass_manager.rs1use std::{iter, sync::{Arc, RwLock}};
2use vulkano::{buffer::{BufferUsage, CpuAccessibleBuffer, CpuBufferPool}, command_buffer::AutoCommandBufferBuilder, command_buffer::{AutoCommandBuffer, DynamicState}, descriptor::{DescriptorSet, descriptor_set::PersistentDescriptorSet}, device::Queue, framebuffer::{RenderPassAbstract, Subpass}, pipeline::{GraphicsPipeline, GraphicsPipelineAbstract}};
3use crate::{components::{Normal, TextureIndex, Vertex}, scene::game_object::camera::Camera, shaders::{fs_draw, vs_draw}};
4use vulkano::pipeline::viewport::Viewport;
5use super::three_vertex_buffers_definition::ThreeBuffersDefinition;
6
7pub struct DrawPassManager {
9 gfx_queue: Arc<Queue>,
10 pub(crate) pipeline: Arc<dyn GraphicsPipelineAbstract + Send + Sync>,
11
12 pub(crate) vertex_buffers: Vec<Arc<CpuAccessibleBuffer<[Vertex]>>>,
13 pub(crate) normal_buffers: Vec<Arc<CpuAccessibleBuffer<[Normal]>>>,
14 pub(crate) texture_index_buffers: Vec<Arc<CpuAccessibleBuffer<[TextureIndex]>>>,
15
16 pub(crate) scene_buffer: CpuBufferPool<vs_draw::ty::Camera>,
17 pub(crate) scene_set: Option<Arc<dyn DescriptorSet + Send + Sync>>,
18
19 pub(crate) world_buffers: CpuBufferPool<vs_draw::ty::World>,
20 pub(crate) world_sets: Vec<Arc<dyn DescriptorSet + Send + Sync>>,
21
22 pub(crate) material_buffers: CpuBufferPool<fs_draw::ty::Material>,
23 pub(crate) material_sets: Vec<Arc<dyn DescriptorSet + Send + Sync>>,
24}
25
26impl DrawPassManager {
27 pub fn new<R>(gfx_queue: Arc<Queue>, subpass: Subpass<R>, viewport_dimensions: [u32; 2]) -> DrawPassManager
29 where R: RenderPassAbstract + Send + Sync + 'static {
30 let scene_buffer = CpuBufferPool::<vs_draw::ty::Camera>::new(gfx_queue.device().clone(), BufferUsage::all());
31 let world_buffers = CpuBufferPool::<vs_draw::ty::World>::new(gfx_queue.device().clone(), BufferUsage::all());
32 let material_buffers = CpuBufferPool::<fs_draw::ty::Material>::new(gfx_queue.device().clone(), BufferUsage::all());
33
34 let vs = vs_draw::Shader::load(gfx_queue.device().clone()).unwrap();
35 let fs = fs_draw::Shader::load(gfx_queue.device().clone()).unwrap();
36
37 let pipeline = Arc::new(
38 GraphicsPipeline::start()
39 .vertex_input(ThreeBuffersDefinition::<Vertex, Normal, TextureIndex>::new()) .vertex_shader(vs.main_entry_point(), ())
41 .triangle_list()
42 .viewports_dynamic_scissors_irrelevant(1)
43 .viewports(iter::once(Viewport {
44 origin: [0.0, 0.0],
45 dimensions: [viewport_dimensions[0] as f32, viewport_dimensions[1] as f32],
46 depth_range: 0.0..1.0,
47 }))
48 .fragment_shader(fs.main_entry_point(), ())
49 .depth_write(true)
50 .depth_stencil_simple_depth()
51 .render_pass(subpass)
52 .build(gfx_queue.device().clone()).unwrap()
53 );
54
55 DrawPassManager {
56 gfx_queue,
57 pipeline: pipeline as Arc<_>,
58
59 vertex_buffers: Vec::new(),
60 normal_buffers: Vec::new(),
61 texture_index_buffers: Vec::new(),
62
63 scene_buffer,
64 scene_set: None,
65
66 world_buffers,
67 world_sets: Vec::new(),
68
69 material_buffers,
70 material_sets: Vec::new(),
71 }
72 }
73
74 pub fn recreate_camera_set(&mut self, camera: Arc<RwLock<dyn Camera>>){
76 self.scene_set = Some({
77 let uniform_buffer_subbuffer = {
78 let camera = camera.clone();
79 let camera = camera.read().expect("Unable to acquire read lock on main camera"); let uniform_data: vs_draw::ty::Camera = camera.create_uniforms(); self.scene_buffer.next(uniform_data).unwrap()
83 };
84
85 let layout = self.pipeline.descriptor_set_layout(0).unwrap();
86
87 Arc::new(
88 PersistentDescriptorSet::start(layout.clone())
89 .add_buffer(uniform_buffer_subbuffer).unwrap()
90 .build().unwrap()
91 )
92 });
93 }
94
95 #[inline]
97 pub fn clear(&mut self){
98 self.vertex_buffers = Vec::new();
99 self.normal_buffers = Vec::new();
100 self.texture_index_buffers = Vec::new();
101
102 self.world_sets = Vec::new();
103 self.material_sets = Vec::new();
104
105 self.scene_set = None;
106 }
107
108 pub fn draw(&self) -> AutoCommandBuffer {
145 let mut builder = AutoCommandBufferBuilder::secondary_graphics(
146 self.gfx_queue.device().clone(),
147 self.gfx_queue.family(),
148 self.pipeline.clone().subpass().clone(),
149 ).unwrap();
150
151 (0..self.vertex_buffers.len()).for_each(|i| {
152 builder.draw(
153 self.pipeline.clone(),
154 &DynamicState::none(),
155 vec![
156 self.vertex_buffers[i].clone(),
157 self.normal_buffers[i].clone(),
158 self.texture_index_buffers[i].clone()
159 ],
160 vec![
161 self.scene_set.clone().unwrap(),
162 self.world_sets[i].clone(),
163 self.material_sets[i].clone(),
164 ],
165 (),
166 vec![],
167 ).unwrap();
168 });
169
170 builder.build().unwrap()
171 }
172
173 pub fn rebuild(
175 &mut self,
176 dimensions: &[u32; 2],
177 render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) {
178 let vs = vs_draw::Shader::load(self.gfx_queue.device().clone()).unwrap();
179 let fs = fs_draw::Shader::load(self.gfx_queue.device().clone()).unwrap();
180
181 self.pipeline = Arc::new(
182 GraphicsPipeline::start()
183 .vertex_input(ThreeBuffersDefinition::<Vertex, Normal, TextureIndex>::new()) .vertex_shader(vs.main_entry_point(), ())
185 .triangle_list()
186 .viewports_dynamic_scissors_irrelevant(1)
187 .viewports(iter::once(Viewport {
188 origin: [0.0, 0.0],
189 dimensions: [dimensions[0] as f32, dimensions[1] as f32],
190 depth_range: 0.0..1.0,
191 }))
192 .fragment_shader(fs.main_entry_point(), ())
193 .depth_write(true)
194 .depth_stencil_simple_depth()
195 .render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
196 .build(self.gfx_queue.device().clone())
197 .unwrap()
198 );
199 }
200}