Decouple model handles from Renderer
This commit is contained in:
parent
7329e39970
commit
36fa7a9dea
49
src/model.rs
49
src/model.rs
|
@ -4,6 +4,12 @@ use crate::pool::{MaterialData, TextureData};
|
|||
use crate::renderer::Renderer;
|
||||
use crate::scene::MeshInstance;
|
||||
|
||||
pub trait OnLoad {
|
||||
fn load_mesh(&mut self, mesh_data: &MeshData) -> MeshHandle;
|
||||
fn load_texture(&mut self, texture_data: &TextureData) -> TextureHandle;
|
||||
fn load_material(&mut self, material_data: &MaterialData) -> MaterialHandle;
|
||||
}
|
||||
|
||||
pub struct BasicMesh {
|
||||
pub mesh_handle: MeshHandle,
|
||||
pub material_handle: MaterialHandle,
|
||||
|
@ -24,7 +30,7 @@ pub struct ObjModel {
|
|||
}
|
||||
|
||||
impl ObjModel {
|
||||
pub fn load(ren: &mut Renderer) -> Self {
|
||||
pub fn load(mut on_load: impl OnLoad) -> Self {
|
||||
use tobj::*;
|
||||
|
||||
let model_data = include_bytes!("assets/viking_room/model.obj").to_vec();
|
||||
|
@ -64,7 +70,7 @@ impl ObjModel {
|
|||
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 mesh_handle = on_load.load_mesh(&mesh_data);
|
||||
|
||||
let albedo_data = include_bytes!("assets/viking_room/albedo.png");
|
||||
let albedo = image::load_from_memory(albedo_data).unwrap();
|
||||
|
@ -85,14 +91,10 @@ impl ObjModel {
|
|||
data: albedo_rgba,
|
||||
};
|
||||
|
||||
let albedo = ren
|
||||
.texture_pool
|
||||
.allocate(&ren.device, &ren.queue, &albedo_data);
|
||||
let albedo = on_load.load_texture(&albedo_data);
|
||||
|
||||
let material_data = MaterialData { albedo };
|
||||
let material_handle =
|
||||
ren.material_pool
|
||||
.allocate(&ren.device, &ren.texture_pool, &material_data);
|
||||
let material_handle = on_load.load_material(&material_data);
|
||||
|
||||
let mesh = BasicMesh {
|
||||
mesh_handle,
|
||||
|
@ -111,12 +113,12 @@ pub struct GltfModel {
|
|||
}
|
||||
|
||||
impl GltfModel {
|
||||
pub fn load(ren: &mut Renderer) -> Self {
|
||||
pub fn load(on_load: impl OnLoad) -> Self {
|
||||
use gltf::*;
|
||||
|
||||
let model_data = include_bytes!("assets/DamagedHelmet.glb");
|
||||
let model = Gltf::from_slice(model_data.as_slice()).unwrap();
|
||||
let loader = GltfLoader::load(&model, ren);
|
||||
let loader = GltfLoader::load(&model, on_load);
|
||||
|
||||
Self {
|
||||
meshes: loader.meshes,
|
||||
|
@ -130,21 +132,21 @@ impl GltfModel {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct GltfLoader<'a> {
|
||||
pub struct GltfLoader<'a, T: OnLoad> {
|
||||
pub model: &'a gltf::Gltf,
|
||||
pub buffers: Vec<Vec<u8>>,
|
||||
pub ren: &'a mut Renderer,
|
||||
pub on_load: T,
|
||||
pub meshes: Vec<BasicMesh>,
|
||||
}
|
||||
|
||||
impl<'a> GltfLoader<'a> {
|
||||
pub fn load(model: &'a gltf::Gltf, ren: &'a mut Renderer) -> Self {
|
||||
impl<'a, T: OnLoad> GltfLoader<'a, T> {
|
||||
pub fn load(model: &'a gltf::Gltf, on_load: T) -> Self {
|
||||
let buffers = Self::load_buffers(model);
|
||||
|
||||
let mut loader = Self {
|
||||
model,
|
||||
buffers,
|
||||
ren,
|
||||
on_load,
|
||||
meshes: Default::default(),
|
||||
};
|
||||
|
||||
|
@ -199,11 +201,7 @@ impl<'a> GltfLoader<'a> {
|
|||
let base_color = pbr.base_color_texture().unwrap().texture();
|
||||
let albedo = self.load_texture(base_color);
|
||||
|
||||
let material_data = MaterialData { albedo };
|
||||
|
||||
self.ren
|
||||
.material_pool
|
||||
.allocate(&self.ren.device, &self.ren.texture_pool, &material_data)
|
||||
self.on_load.load_material(&MaterialData { albedo })
|
||||
}
|
||||
|
||||
pub fn load_texture(&mut self, texture: gltf::Texture) -> TextureHandle {
|
||||
|
@ -234,15 +232,11 @@ impl<'a> GltfLoader<'a> {
|
|||
rgba
|
||||
};
|
||||
|
||||
let data = TextureData {
|
||||
self.on_load.load_texture(&TextureData {
|
||||
width: dimensions.0,
|
||||
height: dimensions.1,
|
||||
data: rgba,
|
||||
};
|
||||
|
||||
self.ren
|
||||
.texture_pool
|
||||
.allocate(&self.ren.device, &self.ren.queue, &data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load_primitive_mesh(&mut self, primitive: gltf::Primitive) -> MeshHandle {
|
||||
|
@ -281,8 +275,7 @@ impl<'a> GltfLoader<'a> {
|
|||
ReadIndices::U8(indices) => indices.map(|i| i as u32).collect(),
|
||||
};
|
||||
|
||||
let mesh_data = MeshData { vertices, indices };
|
||||
self.ren.mesh_pool.allocate(&self.ren.device, &mesh_data)
|
||||
self.on_load.load_mesh(&MeshData { vertices, indices })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use super::camera::Camera;
|
||||
use super::commands::{Command, CommandSet};
|
||||
use super::mesh::Vertex;
|
||||
use super::pool::{MaterialPool, MeshGroup, MeshPool, TexturePool};
|
||||
use super::scene::{Scene, PointLight};
|
||||
use super::mesh::{MeshData, Vertex};
|
||||
use super::pool::*;
|
||||
use super::scene::{PointLight, Scene};
|
||||
use crate::handle::*;
|
||||
use crate::model::OnLoad;
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
pub struct Renderer {
|
||||
|
@ -255,7 +257,10 @@ impl Renderer {
|
|||
bytemuck::cast_slice(&[self.camera_uniform]),
|
||||
);
|
||||
|
||||
let Scene { meshes, point_lights } = scene;
|
||||
let Scene {
|
||||
meshes,
|
||||
point_lights,
|
||||
} = scene;
|
||||
let mesh_commands = CommandSet::build(meshes);
|
||||
|
||||
// TODO persistent staging buffer (write_buffer creates a new one per call)
|
||||
|
@ -349,6 +354,22 @@ impl Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
impl OnLoad for &mut Renderer {
|
||||
fn load_mesh(&mut self, mesh_data: &MeshData) -> MeshHandle {
|
||||
self.mesh_pool.allocate(&self.device, mesh_data)
|
||||
}
|
||||
|
||||
fn load_texture(&mut self, texture_data: &TextureData) -> TextureHandle {
|
||||
self.texture_pool
|
||||
.allocate(&self.device, &self.queue, texture_data)
|
||||
}
|
||||
|
||||
fn load_material(&mut self, material_data: &MaterialData) -> MaterialHandle {
|
||||
self.material_pool
|
||||
.allocate(&self.device, &self.texture_pool, material_data)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct CameraUniform {
|
||||
|
|
Loading…
Reference in New Issue