diff --git a/models/box.mtl b/models/box.mtl new file mode 100644 index 0000000..8b747fa --- /dev/null +++ b/models/box.mtl @@ -0,0 +1,12 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl Material +Ns 323.999994 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.0 0.0 0.0 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/models/box.obj b/models/box.obj new file mode 100644 index 0000000..24e1463 --- /dev/null +++ b/models/box.obj @@ -0,0 +1,46 @@ +# Blender v2.80 (sub 74) OBJ File: '' +# www.blender.org +mtllib box.mtl +o Cube +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +vt 0.375000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.250000 +vt 0.375000 0.250000 +vt 0.375000 0.250000 +vt 0.625000 0.250000 +vt 0.625000 0.500000 +vt 0.375000 0.500000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.625000 0.750000 +vt 0.625000 1.000000 +vt 0.375000 1.000000 +vt 0.125000 0.500000 +vt 0.375000 0.500000 +vt 0.375000 0.750000 +vt 0.125000 0.750000 +vt 0.625000 0.500000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +usemtl Material +s off +f 1/1/1 5/2/1 7/3/1 3/4/1 +f 4/5/2 3/6/2 7/7/2 8/8/2 +f 8/8/3 7/7/3 5/9/3 6/10/3 +f 6/10/4 2/11/4 4/12/4 8/13/4 +f 2/14/5 1/15/5 3/16/5 4/17/5 +f 6/18/6 5/19/6 1/20/6 2/11/6 diff --git a/src/main.rs b/src/main.rs index 87110ea..341074f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,15 +67,12 @@ impl Game for TestGame { fn main() { let mut game = TestGame {}; - vulkan::init(vec![ - Vertex { position: [0.1, 0.2, 0.2] }, - Vertex { position: [0.2, 0.4, 0.2] }, - Vertex { position: [0.2, 0.2, 0.3] } - ], - vec![ - Vertex { position: [-0.9, 1., 0.] }, - Vertex { position: [0.9, 0., 0.] }, - ], - &mut game + vulkan::init( + "models/box.obj", + vec![ + Vertex { position: [-0.9, 1., 0.] }, + Vertex { position: [0.9, 0., 0.] }, + ], + &mut game ); } \ No newline at end of file diff --git a/src/vulkan.rs b/src/vulkan.rs index e1ddbce..8a4eb63 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -33,6 +33,8 @@ use shaderc; use crate::PushConstants; use vulkano::instance::debug::{DebugCallback, MessageTypes}; +use tobj::{load_obj}; + const VALIDATION_LAYERS: &[&str] = &[ "VK_LAYER_LUNARG_standard_validation" ]; @@ -57,7 +59,6 @@ pub trait Game { pub struct GameData { pub start_time: SystemTime, - pub mesh_vertices: Vec, pub line_vertices: Vec, pub push_constants: PushConstants, pub recreate_pipeline: bool, @@ -65,7 +66,9 @@ pub struct GameData { pub shutdown: bool, } -pub fn init(mesh_vertices: Vec, line_vertices: Vec, game: &mut dyn Game) { + + +pub fn init(mesh_path: &str, line_vertices: Vec, game: &mut dyn Game) { let mut data = GameData { push_constants: PushConstants { time: 0.0, @@ -78,7 +81,6 @@ pub fn init(mesh_vertices: Vec, line_vertices: Vec, game: &mut d recreate_pipeline: false, aspect_ratio: 1.0, shutdown: false, - mesh_vertices, line_vertices, }; @@ -192,8 +194,10 @@ pub fn init(mesh_vertices: Vec, line_vertices: Vec, game: &mut d PresentMode::Fifo, true, None).unwrap() }; - let mesh_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data.mesh_vertices.iter().cloned()).unwrap(); - let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data.line_vertices.iter().cloned()).unwrap(); + let (mesh_vertices, mesh_indices) = load_mesh(mesh_path); + let mesh_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::vertex_buffer(), mesh_vertices.into_iter()).unwrap(); + let mesh_index_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::index_buffer(), mesh_indices.into_iter()).unwrap(); + 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!( device.clone(), @@ -313,7 +317,7 @@ pub fn init(mesh_vertices: Vec, line_vertices: Vec, game: &mut d .begin_render_pass(framebuffers[image_num].clone(), false, clear_values).unwrap() // We are now inside the first subpass of the render pass. We add a draw command. - .draw(pipeline.clone(), &dynamic_state, mesh_vertex_buffer.clone(), (), data.push_constants.clone()).unwrap() + .draw_indexed(pipeline.clone(), &dynamic_state, mesh_vertex_buffer.clone(), mesh_index_buffer.clone(), (), data.push_constants.clone()).unwrap() .draw(line_pipeline.clone(), &dynamic_state, line_vertex_buffer.clone(), (), ()).unwrap() // We leave the render pass by calling `draw_end`. Note that if we had multiple @@ -479,3 +483,37 @@ fn read_shader(vert_path_relative: &str, frag_path_relative: &str) -> Option<(Co } } } + +fn load_mesh(mesh_path: &str) -> (Vec, Vec) { + let mut vertices = Vec::new(); + let mut indices = Vec::new(); + + let (models, _materials) = load_obj(mesh_path.as_ref()).unwrap(); + + for model in models.iter() { + let mesh = &model.mesh; + + for index in &mesh.indices { + let ind_usize = *index as usize; + let position = [ + mesh.positions[ind_usize * 3], + mesh.positions[ind_usize * 3 + 1], + mesh.positions[ind_usize * 3 + 2], + ]; +// +// let color = [1.0, 1.0, 1.0]; +// +// let tex_coord = [ +// mesh.texcoords[ind_usize * 2], +// 1.0 - mesh.texcoords[ind_usize * 2 + 1], +// ]; + + let vertex = Vertex { position }; + vertices.push(vertex); + let index = indices.len() as u32; + indices.push(index); + } + } + + (vertices, indices) +} \ No newline at end of file