scene_example/
scene_example.rs

1#![allow(deprecated)]
2
3mod scene_loader;
4pub mod util;
5
6use std::{sync::Arc, thread::sleep, time::Duration};
7
8use chaos_vk::{graphics::{buffer::{VkBuffer, VkIterBuffer}, command::{CommandBufferType, VkBuilder}, mesh::mesh::Mesh, presenter::Presenter, utils::{descriptor_set, instancing_pipeline, render_pass_with_depth}, vertex::PosInstanceData, vk::Vk}, imgui_renderer::ImGui};
9use glam::Mat4;
10use scene_loader::{geometry::sphere, loader::Scene, renderer::Renderer, shaders::{self, vs}};
11use util::math::rand_betw;
12use vulkano::{command_buffer::{RenderPassBeginInfo, SubpassBeginInfo, SubpassContents}, descriptor_set::WriteDescriptorSet, pipeline::{graphics::viewport::Viewport, GraphicsPipeline, Pipeline}};
13use winit::{dpi::PhysicalSize, event::{DeviceEvent, Event, MouseScrollDelta, VirtualKeyCode, WindowEvent}, event_loop::EventLoop, window::{Icon, Theme}};
14
15fn main() {
16    example();
17}
18
19fn example() {
20    let el = EventLoop::new();
21    let (vk, window) = Vk::new(&el);
22    window.set_cursor_grab(winit::window::CursorGrabMode::Confined).unwrap();
23    window.set_cursor_visible(false);
24    window.set_title("CHAOS-VK");
25    window.set_window_icon({
26        let w = 8;
27        let h = 8;
28
29        Some(Icon::from_rgba(
30            (0..w*h*4).map(|_| rand_betw(0, 255)).collect(), 
31            w, 
32            h
33        ).unwrap())
34    });
35    window.set_theme(Some(Theme::Dark));
36    window.set_inner_size(PhysicalSize::new(1200, 900));
37    let size = window.inner_size();
38
39    
40    let mut presenter = Presenter::new(vk.clone(), window.clone());
41    let mut renderer = Renderer::new();
42    let mut imgui = ImGui::new(vk.clone(), &presenter);
43
44    renderer.camera.proj = Mat4::perspective_lh(
45        80.0f32.to_radians(), 
46        size.width as f32 / size.height as f32, 0.1, 1000.0
47    );
48
49    let vs = shaders::vs::load(vk.device.clone()).unwrap();
50    let fs = shaders::fs::load(vk.device.clone()).unwrap();
51
52    let rp = render_pass_with_depth(vk.clone(), Some(presenter.swapchain.clone()));
53
54    let pipeline = instancing_pipeline(vk.clone(), vs.clone(), fs.clone(), rp.clone(), Viewport {
55        offset: [0.0, 0.0],
56        extent: size.into(),
57        depth_range: 0.0..=1.0,
58    });
59
60    presenter.window_resized = true;
61    presenter.recreate(vk.clone(), rp.clone(), window.clone());
62
63    let sphere = sphere(5, 1.0);
64    renderer.meshes.push(Mesh::new(vk.clone(), &sphere.vertices, &sphere.indices));
65
66    let mut cursor_x = 0.0;
67    let mut cursor_y = 0.0;
68
69    let data = (0..250).map(|_| { PosInstanceData {
70            ofs: [rand_betw(-100.0, 100.0), rand_betw(-10.0, 10.0), rand_betw(-100.0, 100.0)]
71        }
72    }).collect::<Vec<PosInstanceData>>();
73    renderer.meshes[0].instances = data.clone();
74    let instance_buffer = VkIterBuffer::vertex(vk.allocators.clone(), data);
75    renderer.meshes[0].ibo = instance_buffer;
76
77    let mut dt = 0.0;
78
79    el.run(move |event, _target, control_flow| {
80        control_flow.set_poll();
81
82        match event {
83            Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
84                control_flow.set_exit();
85            },
86            Event::WindowEvent { event, .. } => {
87                renderer.camera.input(&event);
88
89                match event {
90                    WindowEvent::KeyboardInput { input, .. } => {
91                        if input.virtual_keycode == Some(VirtualKeyCode::Escape) {
92                            control_flow.set_exit();
93                        }
94
95                        if input.modifiers.ctrl() && input.virtual_keycode == Some(VirtualKeyCode::S) {
96                            Scene::write("assets/scene.cf", &renderer).expect("Failed to write scene");
97                        }
98
99                        if input.modifiers.ctrl() && input.virtual_keycode == Some(VirtualKeyCode::L) {
100                            Scene::read("assets/scene.cf", &mut renderer, vk.clone()).expect("Failed to load scene");
101                        }
102
103                       window.set_cursor_visible(input.modifiers.alt());
104                    },
105
106                    WindowEvent::CursorMoved { position, .. } => {
107                        imgui.on_mouse_move(position.x as f32, position.y as f32);
108                    }
109
110                    WindowEvent::MouseInput { button, state, .. } => {
111                        imgui.on_mouse_click(button, state);
112                    }
113
114                    WindowEvent::MouseWheel { delta: MouseScrollDelta::PixelDelta(pos), .. } => {
115                        imgui.on_mouse_scroll(pos.x as f32, pos.y as f32);
116                    }
117
118                    _ => ()
119                }
120            }
121
122            Event::DeviceEvent {
123                event: DeviceEvent::Text { codepoint }, ..
124            } => {
125                dbg!(codepoint);
126            }
127
128            Event::DeviceEvent { event: DeviceEvent::MouseMotion { delta },.. } => {
129                cursor_x += delta.0 as f32;
130                cursor_y += delta.1 as f32;
131
132                renderer.camera.mouse_callback(cursor_x, cursor_y);
133            }
134
135            Event::MainEventsCleared => {
136                let now = std::time::Instant::now();
137                
138                let frame = imgui.frame(&window);
139                frame.text("hello, world!");
140                frame.text(format!("dt:{:.1}", dt*1000.0));
141                
142                presenter.recreate(vk.clone(), rp.clone(), window.clone());
143
144                renderer.update(dt);
145                presenter.cmd_bufs = get_cmd_bufs(
146                    vk.clone(), 
147                    &renderer,
148                    &mut imgui,
149                    &presenter, 
150                    pipeline.clone()
151                );
152                
153                presenter.present(vk.clone());
154                
155                sleep(Duration::from_millis(16).saturating_sub(Duration::from_millis((dt * 1000.0) as u64)));
156                dt = now.elapsed().as_secs_f32();
157            }
158
159            Event::LoopDestroyed => {println!("EXIT");}
160            _ => {}
161        }
162    });
163}
164
165pub fn get_cmd_bufs(
166    vk: Arc<Vk>, 
167    renderer: &Renderer,
168    imgui_renderer: &mut ImGui,
169    presenter: &Presenter,
170    pipeline: Arc<GraphicsPipeline>,
171) -> Vec<CommandBufferType> {
172    let mut cmd_bufs: Vec<CommandBufferType> = vec![];
173
174    let ubo = VkBuffer::uniform(vk.allocators.clone(), vs::Camera {
175        view: renderer.camera.get_view(),
176        proj: renderer.camera.get_proj(),
177    });
178
179    let camera_desc_set = descriptor_set(
180        vk.clone(), 
181        0, 
182        pipeline.clone(), 
183        [WriteDescriptorSet::buffer(0, ubo.content.clone())]
184    ).0;
185
186    let render_passes = imgui_renderer.get_renderpasses(
187        presenter.images.clone(),
188        vk.clone()
189    );
190
191    let mut i = 0;
192    for framebuffer in &presenter.framebuffers.clone() {
193        let mut builder = VkBuilder::new_multiple(vk.clone());
194
195        builder.0
196            .begin_render_pass(
197                RenderPassBeginInfo {
198                    clear_values: vec![Some([0.1, 0.2, 0.3, 1.0].into()), Some(1.0.into())],
199                    ..RenderPassBeginInfo::framebuffer(framebuffer.clone())
200                },
201                SubpassBeginInfo {
202                    contents: SubpassContents::Inline,
203                    ..Default::default()
204                },
205            )
206            .unwrap()
207            .bind_pipeline_graphics(pipeline.clone())
208            .unwrap()
209            .bind_descriptor_sets(
210                vulkano::pipeline::PipelineBindPoint::Graphics, 
211                pipeline.layout().clone(), 
212                0, 
213                camera_desc_set.clone(),
214            )
215            .unwrap();
216
217        for mesh in &renderer.meshes {
218            mesh.build_commands(vk.clone(), &mut builder.0, pipeline.clone());
219        }
220
221        builder.0.end_render_pass(Default::default()).unwrap();
222
223        let render_pass = &render_passes[i];
224        builder.0.begin_render_pass(
225            RenderPassBeginInfo {
226                clear_values: vec![None],
227                render_pass: render_pass.rp.clone(),
228                ..RenderPassBeginInfo::framebuffer(render_pass.framebuffer.clone())
229            },
230            SubpassBeginInfo {
231                contents: SubpassContents::SecondaryCommandBuffers,
232                ..Default::default()
233            },
234        ).expect(&format!("failed to start imgui render pass on framebuffer {:?}", framebuffer));
235
236        builder.0.execute_commands(render_pass.cmd_buf.clone()).unwrap();
237        
238        builder.0.end_render_pass(Default::default()).unwrap();
239        
240        
241        cmd_bufs.push(
242            builder.command_buffer()
243        );
244
245        i += 1;
246    }
247
248    cmd_bufs
249}