Decouple model handles from Renderer

This commit is contained in:
marceline-cramer 2022-02-15 17:13:24 -07:00
parent 7329e39970
commit 36fa7a9dea
2 changed files with 46 additions and 32 deletions

View File

@ -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 })
}
}

View File

@ -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 {