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}