From 49285a71ce2e2eb52009b6a2905910d940bdd71c Mon Sep 17 00:00:00 2001 From: Till Date: Mon, 29 Jul 2019 02:31:46 +0200 Subject: [PATCH] yay cubes --- config/input.toml | 5 +++++ src/main.rs | 11 ++++++--- src/vulkan.rs | 57 ++++++++++++++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/config/input.toml b/config/input.toml index e9cff7b..e815e48 100644 --- a/config/input.toml +++ b/config/input.toml @@ -27,6 +27,11 @@ scan_code = 30 name = "d" scan_code = 32 +[[button]] +name = "test" +scan_code = 20 +ctrl = true + [[axis]] name = "move_forward" positive_button = "w" diff --git a/src/main.rs b/src/main.rs index 009e8c2..0c8fb6f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ use winit::{Event}; -use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation}; +use cgmath::{Matrix4, Rad, Vector3, Deg, Quaternion, Rotation3, One, Rotation, SquareMatrix}; mod vulkan; -use crate::vulkan::{GameData, Game, LinePoint}; +use crate::vulkan::{GameData, Game, LinePoint, GameObject}; mod input; use crate::input::{InputState}; @@ -40,6 +40,11 @@ impl Game for TestGame<'_> { println!("{:.0} ms / {:.0} FPS", frame_time * 1000.0, 1.0 / frame_time); } + if self.input.button_just_pressed("test") { + println!("test"); + game_data.game_objects.push(GameObject { mesh_index: 0, model_matrix: Matrix4::identity() }); + } + self.cam_rotation = self.cam_rotation * Quaternion::from_angle_z(Deg(self.input.get_axis("look_horizontal") * 0.05)); self.cam_rotation = Quaternion::from_angle_x(Deg(self.input.get_axis("look_vertical") * 0.05)) * self.cam_rotation; self.cam_position += self.cam_rotation.invert().rotate_vector(Vector3::new( @@ -87,7 +92,7 @@ fn main() { let line_count = 30; vulkan::init( - "models/iski51.obj", + vec!["models/box.obj", "models/iski51.obj"], (-line_count..=line_count) .flat_map(|it| vec![ LinePoint { position: [it as f32, -line_count as f32, 0.] }, diff --git a/src/vulkan.rs b/src/vulkan.rs index 9d14d00..9952d73 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -35,7 +35,6 @@ use vs::ty::PushConstants; use line_vs::ty::LinePushConstants; use tobj::{load_obj}; -use vulkano::pipeline::depth_stencil::DepthStencil; const VALIDATION_LAYERS: &[&str] = &[ "VK_LAYER_LUNARG_standard_validation" @@ -64,6 +63,16 @@ pub trait Game { fn on_window_event(self: &mut Self, event: &Event); } +pub struct Mesh { + vertex_buffer: Arc>, + index_buffer: Arc>, +} + +pub struct GameObject { + pub mesh_index: usize, + pub model_matrix: Matrix4, +} + pub struct GameData { pub start_time: SystemTime, pub line_vertices: Vec, @@ -72,11 +81,11 @@ pub struct GameData { pub recreate_pipeline: bool, pub dimensions: [u32; 2], pub shutdown: bool, - mesh_vertex_buffer: Option>>, - mesh_index_buffer: Option>>, + pub game_objects: Vec, + pub meshes: Vec, } -pub fn init(mesh_path: &str, line_vertices: Vec, game: &mut dyn Game) { +pub fn init(mesh_paths: Vec<&str>, line_vertices: Vec, game: &mut dyn Game) { let mut data = GameData { push_constants: PushConstants { time: 0.0, @@ -95,8 +104,8 @@ pub fn init(mesh_path: &str, line_vertices: Vec, game: &mut dyn Game) shutdown: false, line_vertices, dimensions: [0, 0], - mesh_vertex_buffer: None, - mesh_index_buffer: None, + meshes: vec![], + game_objects: vec![], }; if game.validation_layers_enabled() { @@ -209,9 +218,8 @@ pub fn init(mesh_path: &str, line_vertices: Vec, game: &mut dyn Game) PresentMode::Fifo, true, None).unwrap() }; - let (mesh_vertices, mesh_indices) = load_mesh(mesh_path); - data.mesh_vertex_buffer = Some(CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::vertex_buffer(), mesh_vertices.into_iter()).unwrap()); - data.mesh_index_buffer = Some(CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::index_buffer(), mesh_indices.into_iter()).unwrap()); + mesh_paths.iter().for_each(|path| data.meshes.push(load_mesh(device.clone(), path))); + let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::vertex_buffer(), data.line_vertices.iter().cloned()).unwrap(); let render_pass = Arc::new(vulkano::single_pass_renderpass!( @@ -321,23 +329,29 @@ pub fn init(mesh_path: &str, line_vertices: Vec, game: &mut dyn Game) game.update(&mut data); - let command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap() + let mut cbb = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap() // Before we can draw, we have to *enter a render pass*. There are two methods to do // this: `draw_inline` and `draw_secondary`. The latter is a bit more advanced and is // not covered here. - .begin_render_pass(framebuffers[image_num].clone(), false, vec![[0.0, 0.0, 0.0, 1.0].into(), ClearValue::Depth(1.0)]).unwrap() + .begin_render_pass(framebuffers[image_num].clone(), false, vec![[0.0, 0.0, 0.0, 1.0].into(), ClearValue::Depth(1.0)]).unwrap(); - // We are now inside the first subpass of the render pass. We add a draw command. - .draw_indexed(pipeline.clone(), &dynamic_state, data.mesh_vertex_buffer.clone().unwrap(), data.mesh_index_buffer.clone().unwrap(), (), data.push_constants.clone()).unwrap() - .draw(line_pipeline.clone(), &dynamic_state, line_vertex_buffer.clone(), (), data.line_push_constants.clone()).unwrap() + + // We are now inside the first subpass of the render pass + for i in 0..data.game_objects.len() { + cbb = cbb.draw_indexed(pipeline.clone(), &dynamic_state, + data.meshes[data.game_objects[i].mesh_index].vertex_buffer.clone(), + data.meshes[data.game_objects[i].mesh_index].index_buffer.clone(), + (), data.push_constants.clone()).unwrap(); + } + + cbb = cbb.draw(line_pipeline.clone(), &dynamic_state, line_vertex_buffer.clone(), (), data.line_push_constants.clone()).unwrap() // We leave the render pass by calling `draw_end`. Note that if we had multiple // subpasses we could have called `next_inline` (or `next_secondary`) to jump to the // next subpass. - .end_render_pass().unwrap() + .end_render_pass().unwrap(); - // Finish building the command buffer by calling `build`. - .build().unwrap(); + let command_buffer = cbb.build().unwrap(); let future = previous_frame_end.join(acquire_future) .then_execute(queue.clone(), command_buffer).unwrap() @@ -458,7 +472,7 @@ fn create_pipeline( .vertex_shader(vertex_shader_entry.clone(), ()) .line_list() .viewports_dynamic_scissors_irrelevant(1) - .depth_stencil(DepthStencil::simple_depth_test()) + .depth_stencil_simple_depth() .fragment_shader(fragment_shader_entry.clone(), ()) .render_pass(sub_pass.clone()) .build(device.clone()) @@ -470,6 +484,7 @@ fn create_pipeline( .triangle_list() .viewports_dynamic_scissors_irrelevant(1) .depth_stencil_simple_depth() + .cull_mode_back() .fragment_shader(fragment_shader_entry.clone(), ()) .render_pass(sub_pass.clone()) .build(device.clone()) @@ -508,7 +523,7 @@ fn read_shader(vert_path_relative: &str, frag_path_relative: &str) -> Option<(Co } } -fn load_mesh(mesh_path: &str) -> (Vec, Vec) { +fn load_mesh(device: Arc, mesh_path: &str) -> Mesh { let mut vertices = Vec::new(); let mut indices = Vec::new(); @@ -543,5 +558,7 @@ fn load_mesh(mesh_path: &str) -> (Vec, Vec) { } } - (vertices, indices) + let vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::vertex_buffer(), vertices.into_iter()).unwrap(); + let index_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::index_buffer(), indices.into_iter()).unwrap(); + Mesh { vertex_buffer, index_buffer } } \ No newline at end of file