Refactor obj loading
This commit is contained in:
parent
b108e7f80f
commit
c94f7b4bdc
105
src/main.rs
105
src/main.rs
|
@ -8,89 +8,16 @@ mod camera;
|
||||||
mod commands;
|
mod commands;
|
||||||
mod handle;
|
mod handle;
|
||||||
mod mesh;
|
mod mesh;
|
||||||
|
mod model;
|
||||||
mod pool;
|
mod pool;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod scene;
|
mod scene;
|
||||||
|
|
||||||
use camera::*;
|
use camera::*;
|
||||||
use handle::*;
|
use model::*;
|
||||||
use mesh::*;
|
use renderer::Renderer;
|
||||||
use pool::*;
|
|
||||||
use renderer::*;
|
|
||||||
use scene::*;
|
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 {
|
trait WorldState {
|
||||||
fn update(&mut self);
|
fn update(&mut self);
|
||||||
fn render(&self) -> Vec<MeshInstance>;
|
fn render(&self) -> Vec<MeshInstance>;
|
||||||
|
@ -102,17 +29,13 @@ struct Grid {
|
||||||
|
|
||||||
impl Grid {
|
impl Grid {
|
||||||
fn new(ren: &mut Renderer) -> Self {
|
fn new(ren: &mut Renderer) -> Self {
|
||||||
let (mesh, material) = load_model(ren);
|
let model = ObjModel::load(ren);
|
||||||
let mut meshes = Vec::new();
|
let mut meshes = Vec::new();
|
||||||
for x in -5..5 {
|
for x in -5..5 {
|
||||||
for y in -5..5 {
|
for y in -5..5 {
|
||||||
let translation = glam::Vec3::new(x as f32, 0.0, y as f32) * 3.0;
|
let translation = glam::Vec3::new(x as f32, 0.0, y as f32) * 3.0;
|
||||||
let transform = glam::Mat4::from_translation(translation);
|
let transform = glam::Mat4::from_translation(translation);
|
||||||
meshes.push(MeshInstance {
|
model.draw(&mut meshes, transform);
|
||||||
mesh,
|
|
||||||
material,
|
|
||||||
transform,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,14 +61,13 @@ struct Planet {
|
||||||
struct Planets {
|
struct Planets {
|
||||||
start: std::time::Instant,
|
start: std::time::Instant,
|
||||||
planets: Vec<Planet>,
|
planets: Vec<Planet>,
|
||||||
mesh: MeshHandle,
|
model: ObjModel,
|
||||||
material: MaterialHandle,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Planets {
|
impl Planets {
|
||||||
fn new(ren: &mut Renderer) -> Self {
|
fn new(ren: &mut Renderer) -> Self {
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
let (mesh, material) = load_model(ren);
|
let model = ObjModel::load(ren);
|
||||||
|
|
||||||
let mut planets = Vec::new();
|
let mut planets = Vec::new();
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
|
@ -161,8 +83,7 @@ impl Planets {
|
||||||
Self {
|
Self {
|
||||||
start,
|
start,
|
||||||
planets,
|
planets,
|
||||||
mesh,
|
model,
|
||||||
material,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,11 +100,7 @@ impl WorldState for Planets {
|
||||||
let translation = glam::Mat4::from_translation(translation);
|
let translation = glam::Mat4::from_translation(translation);
|
||||||
let theta = planet.speed * elapsed + planet.offset;
|
let theta = planet.speed * elapsed + planet.offset;
|
||||||
let rotation = glam::Mat4::from_rotation_y(theta);
|
let rotation = glam::Mat4::from_rotation_y(theta);
|
||||||
meshes.push(MeshInstance {
|
self.model.draw(&mut meshes, rotation * translation);
|
||||||
mesh: self.mesh,
|
|
||||||
material: self.material,
|
|
||||||
transform: rotation * translation,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meshes
|
meshes
|
||||||
|
@ -234,8 +151,8 @@ fn main() {
|
||||||
let mut camera = Flycam::new(10.0, 0.002);
|
let mut camera = Flycam::new(10.0, 0.002);
|
||||||
let mut is_grabbed = false;
|
let mut is_grabbed = false;
|
||||||
let mut ren = pollster::block_on(make_window_renderer(&window));
|
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(Planets::new(&mut ren));
|
||||||
let mut state: Box<dyn WorldState> = Box::new(Grid::new(&mut ren));
|
// let mut state: Box<dyn WorldState> = Box::new(Grid::new(&mut ren));
|
||||||
|
|
||||||
let lights = vec![
|
let lights = vec![
|
||||||
PointLight {
|
PointLight {
|
||||||
|
|
|
@ -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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue