From c94f7b4bdc4c77f7d90fb4aaa9f3ca5708a1db8d Mon Sep 17 00:00:00 2001 From: marceline-cramer Date: Sat, 12 Feb 2022 01:40:27 -0700 Subject: [PATCH] Refactor obj loading --- src/main.rs | 105 ++++++--------------------------------------------- src/model.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 94 deletions(-) create mode 100644 src/model.rs diff --git a/src/main.rs b/src/main.rs index 1ad0587..814ec85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,89 +8,16 @@ mod camera; mod commands; mod handle; mod mesh; +mod model; mod pool; mod renderer; mod scene; use camera::*; -use handle::*; -use mesh::*; -use pool::*; -use renderer::*; +use model::*; +use renderer::Renderer; use scene::*; -fn load_model(ren: &mut Renderer) -> (MeshHandle, MaterialHandle) { - use tobj::*; - - let model_data = include_bytes!("assets/viking_room/model.obj").to_vec(); - let model_data = &mut model_data.as_slice(); - - let load_options = LoadOptions { - triangulate: true, - single_index: true, - ..Default::default() - }; - - let (models, _mats) = load_obj_buf(model_data, &load_options, |_| unimplemented!()).unwrap(); - - let mut vertices = Vec::new(); - let mut indices = Vec::new(); - - let m = models.first().unwrap(); - let index_base = vertices.len() as u32; - for i in 0..m.mesh.positions.len() / 3 { - let t = i * 3; - vertices.push(Vertex { - position: [ - m.mesh.positions[t], - m.mesh.positions[t + 2], - -m.mesh.positions[t + 1], - ], - normal: [ - m.mesh.normals[t], - m.mesh.normals[t + 2], - -m.mesh.normals[t + 1], - ], - tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]], - }); - } - - indices.extend(m.mesh.indices.iter().map(|i| i + index_base)); - - let mesh_data = MeshData { vertices, indices }; - let mesh_handle = ren.mesh_pool.allocate(&ren.device, &mesh_data); - - let albedo_data = include_bytes!("assets/viking_room/albedo.png"); - let albedo = image::load_from_memory(albedo_data).unwrap(); - - use image::GenericImageView; - let dimensions = albedo.dimensions(); - - let albedo_rgb = albedo.as_rgb8().unwrap().to_vec(); - let mut albedo_rgba = Vec::::new(); - for rgb in albedo_rgb.chunks(3) { - albedo_rgba.extend_from_slice(rgb); - albedo_rgba.push(0xff); - } - - let albedo_data = TextureData { - width: dimensions.0, - height: dimensions.1, - data: albedo_rgba, - }; - - let albedo = ren - .texture_pool - .allocate(&ren.device, &ren.queue, &albedo_data); - - let material_data = MaterialData { albedo }; - let material_handle = - ren.material_pool - .allocate(&ren.device, &ren.texture_pool, &material_data); - - (mesh_handle, material_handle) -} - trait WorldState { fn update(&mut self); fn render(&self) -> Vec; @@ -102,17 +29,13 @@ struct Grid { impl Grid { fn new(ren: &mut Renderer) -> Self { - let (mesh, material) = load_model(ren); + let model = ObjModel::load(ren); let mut meshes = Vec::new(); for x in -5..5 { for y in -5..5 { let translation = glam::Vec3::new(x as f32, 0.0, y as f32) * 3.0; let transform = glam::Mat4::from_translation(translation); - meshes.push(MeshInstance { - mesh, - material, - transform, - }); + model.draw(&mut meshes, transform); } } @@ -138,14 +61,13 @@ struct Planet { struct Planets { start: std::time::Instant, planets: Vec, - mesh: MeshHandle, - material: MaterialHandle, + model: ObjModel, } impl Planets { fn new(ren: &mut Renderer) -> Self { let start = std::time::Instant::now(); - let (mesh, material) = load_model(ren); + let model = ObjModel::load(ren); let mut planets = Vec::new(); for i in 0..10 { @@ -161,8 +83,7 @@ impl Planets { Self { start, planets, - mesh, - material, + model, } } } @@ -179,11 +100,7 @@ impl WorldState for Planets { let translation = glam::Mat4::from_translation(translation); let theta = planet.speed * elapsed + planet.offset; let rotation = glam::Mat4::from_rotation_y(theta); - meshes.push(MeshInstance { - mesh: self.mesh, - material: self.material, - transform: rotation * translation, - }); + self.model.draw(&mut meshes, rotation * translation); } meshes @@ -234,8 +151,8 @@ fn main() { let mut camera = Flycam::new(10.0, 0.002); let mut is_grabbed = false; let mut ren = pollster::block_on(make_window_renderer(&window)); - // let mut state: Box = Box::new(Planets::new(&mut ren)); - let mut state: Box = Box::new(Grid::new(&mut ren)); + let mut state: Box = Box::new(Planets::new(&mut ren)); + // let mut state: Box = Box::new(Grid::new(&mut ren)); let lights = vec![ PointLight { diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 0000000..710a421 --- /dev/null +++ b/src/model.rs @@ -0,0 +1,96 @@ +use crate::handle::*; +use crate::mesh::*; +use crate::pool::{MaterialData, TextureData}; +use crate::renderer::Renderer; +use crate::scene::MeshInstance; + +pub struct ObjModel { + pub mesh_handle: MeshHandle, + pub material_handle: MaterialHandle, +} + +impl ObjModel { + pub fn load(ren: &mut Renderer) -> Self { + use tobj::*; + + let model_data = include_bytes!("assets/viking_room/model.obj").to_vec(); + let model_data = &mut model_data.as_slice(); + + let load_options = LoadOptions { + triangulate: true, + single_index: true, + ..Default::default() + }; + + let (models, _mats) = + load_obj_buf(model_data, &load_options, |_| unimplemented!()).unwrap(); + + let mut vertices = Vec::new(); + let mut indices = Vec::new(); + + let m = models.first().unwrap(); + let index_base = vertices.len() as u32; + for i in 0..m.mesh.positions.len() / 3 { + let t = i * 3; + vertices.push(Vertex { + position: [ + m.mesh.positions[t], + m.mesh.positions[t + 2], + -m.mesh.positions[t + 1], + ], + normal: [ + m.mesh.normals[t], + m.mesh.normals[t + 2], + -m.mesh.normals[t + 1], + ], + tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]], + }); + } + + indices.extend(m.mesh.indices.iter().map(|i| i + index_base)); + + let mesh_data = MeshData { vertices, indices }; + let mesh_handle = ren.mesh_pool.allocate(&ren.device, &mesh_data); + + let albedo_data = include_bytes!("assets/viking_room/albedo.png"); + let albedo = image::load_from_memory(albedo_data).unwrap(); + + use image::GenericImageView; + let dimensions = albedo.dimensions(); + + let albedo_rgb = albedo.as_rgb8().unwrap().to_vec(); + let mut albedo_rgba = Vec::::new(); + for rgb in albedo_rgb.chunks(3) { + albedo_rgba.extend_from_slice(rgb); + albedo_rgba.push(0xff); + } + + let albedo_data = TextureData { + width: dimensions.0, + height: dimensions.1, + data: albedo_rgba, + }; + + let albedo = ren + .texture_pool + .allocate(&ren.device, &ren.queue, &albedo_data); + + let material_data = MaterialData { albedo }; + let material_handle = + ren.material_pool + .allocate(&ren.device, &ren.texture_pool, &material_data); + + Self { + mesh_handle, + material_handle, + } + } + + pub fn draw(&self, meshes: &mut Vec, transform: glam::Mat4) { + meshes.push(MeshInstance { + mesh: self.mesh_handle, + material: self.material_handle, + transform, + }); + } +}