Refactor obj loading

This commit is contained in:
marceline-cramer 2022-02-12 01:40:27 -07:00
parent b108e7f80f
commit c94f7b4bdc
2 changed files with 107 additions and 94 deletions

View File

@ -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::<u8>::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<MeshInstance>;
@ -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<Planet>,
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<dyn WorldState> = Box::new(Planets::new(&mut ren));
let mut state: Box<dyn WorldState> = Box::new(Grid::new(&mut ren));
let mut state: Box<dyn WorldState> = Box::new(Planets::new(&mut ren));
// let mut state: Box<dyn WorldState> = Box::new(Grid::new(&mut ren));
let lights = vec![
PointLight {

96
src/model.rs Normal file
View File

@ -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::<u8>::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<MeshInstance>, transform: glam::Mat4) {
meshes.push(MeshInstance {
mesh: self.mesh_handle,
material: self.material_handle,
transform,
});
}
}