2020-09-14 18:53:22 +00:00
|
|
|
use anyhow::*;
|
2021-08-15 16:44:57 +00:00
|
|
|
use cgmath::InnerSpace;
|
2020-04-29 18:30:27 +00:00
|
|
|
use std::ops::Range;
|
|
|
|
use std::path::Path;
|
2021-08-04 11:20:15 +00:00
|
|
|
use tobj::LoadOptions;
|
2020-09-14 18:53:22 +00:00
|
|
|
use wgpu::util::DeviceExt;
|
2020-04-29 18:30:27 +00:00
|
|
|
|
|
|
|
use crate::texture;
|
|
|
|
|
|
|
|
pub trait Vertex {
|
2021-02-12 06:29:40 +00:00
|
|
|
fn desc<'a>() -> wgpu::VertexBufferLayout<'a>;
|
2020-04-29 18:30:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
2020-11-14 21:57:39 +00:00
|
|
|
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
2020-04-29 18:30:27 +00:00
|
|
|
pub struct ModelVertex {
|
2020-11-14 21:57:39 +00:00
|
|
|
position: [f32; 3],
|
|
|
|
tex_coords: [f32; 2],
|
|
|
|
normal: [f32; 3],
|
|
|
|
tangent: [f32; 3],
|
|
|
|
bitangent: [f32; 3],
|
2020-04-29 18:30:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Vertex for ModelVertex {
|
2021-02-12 06:29:40 +00:00
|
|
|
fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
|
2020-04-29 18:30:27 +00:00
|
|
|
use std::mem;
|
2021-02-12 06:29:40 +00:00
|
|
|
wgpu::VertexBufferLayout {
|
|
|
|
array_stride: mem::size_of::<ModelVertex>() as wgpu::BufferAddress,
|
2020-04-29 18:30:27 +00:00
|
|
|
step_mode: wgpu::InputStepMode::Vertex,
|
|
|
|
attributes: &[
|
2021-02-12 06:29:40 +00:00
|
|
|
wgpu::VertexAttribute {
|
2020-04-29 18:30:27 +00:00
|
|
|
offset: 0,
|
|
|
|
shader_location: 0,
|
2021-05-01 21:55:26 +00:00
|
|
|
format: wgpu::VertexFormat::Float32x3,
|
2020-04-29 18:30:27 +00:00
|
|
|
},
|
2021-02-12 06:29:40 +00:00
|
|
|
wgpu::VertexAttribute {
|
2020-04-29 18:30:27 +00:00
|
|
|
offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
|
|
|
shader_location: 1,
|
2021-05-01 21:55:26 +00:00
|
|
|
format: wgpu::VertexFormat::Float32x2,
|
2020-04-29 18:30:27 +00:00
|
|
|
},
|
2021-02-12 06:29:40 +00:00
|
|
|
wgpu::VertexAttribute {
|
2020-04-29 18:30:27 +00:00
|
|
|
offset: mem::size_of::<[f32; 5]>() as wgpu::BufferAddress,
|
|
|
|
shader_location: 2,
|
2021-05-01 21:55:26 +00:00
|
|
|
format: wgpu::VertexFormat::Float32x3,
|
2020-04-29 18:30:27 +00:00
|
|
|
},
|
|
|
|
// Tangent and bitangent
|
2021-02-12 06:29:40 +00:00
|
|
|
wgpu::VertexAttribute {
|
2020-04-29 18:30:27 +00:00
|
|
|
offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
|
|
|
|
shader_location: 3,
|
2021-05-01 21:55:26 +00:00
|
|
|
format: wgpu::VertexFormat::Float32x3,
|
2020-04-29 18:30:27 +00:00
|
|
|
},
|
2021-02-12 06:29:40 +00:00
|
|
|
wgpu::VertexAttribute {
|
2020-04-29 18:30:27 +00:00
|
|
|
offset: mem::size_of::<[f32; 11]>() as wgpu::BufferAddress,
|
|
|
|
shader_location: 4,
|
2021-05-01 21:55:26 +00:00
|
|
|
format: wgpu::VertexFormat::Float32x3,
|
2020-04-29 18:30:27 +00:00
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Material {
|
|
|
|
pub name: String,
|
|
|
|
pub diffuse_texture: texture::Texture,
|
|
|
|
pub normal_texture: texture::Texture,
|
|
|
|
pub bind_group: wgpu::BindGroup,
|
|
|
|
}
|
|
|
|
|
2020-05-01 20:14:10 +00:00
|
|
|
impl Material {
|
|
|
|
pub fn new(
|
2020-09-28 05:24:43 +00:00
|
|
|
device: &wgpu::Device,
|
|
|
|
name: &str,
|
2020-09-14 18:53:22 +00:00
|
|
|
diffuse_texture: texture::Texture,
|
2020-05-01 20:14:10 +00:00
|
|
|
normal_texture: texture::Texture,
|
|
|
|
layout: &wgpu::BindGroupLayout,
|
|
|
|
) -> Self {
|
|
|
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
|
|
layout,
|
2020-09-14 18:53:22 +00:00
|
|
|
entries: &[
|
|
|
|
wgpu::BindGroupEntry {
|
2020-05-01 20:14:10 +00:00
|
|
|
binding: 0,
|
|
|
|
resource: wgpu::BindingResource::TextureView(&diffuse_texture.view),
|
|
|
|
},
|
2020-09-14 18:53:22 +00:00
|
|
|
wgpu::BindGroupEntry {
|
2020-05-01 20:14:10 +00:00
|
|
|
binding: 1,
|
|
|
|
resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler),
|
|
|
|
},
|
2020-09-14 18:53:22 +00:00
|
|
|
wgpu::BindGroupEntry {
|
2020-05-01 20:14:10 +00:00
|
|
|
binding: 2,
|
|
|
|
resource: wgpu::BindingResource::TextureView(&normal_texture.view),
|
|
|
|
},
|
2020-09-14 18:53:22 +00:00
|
|
|
wgpu::BindGroupEntry {
|
2020-05-01 20:14:10 +00:00
|
|
|
binding: 3,
|
|
|
|
resource: wgpu::BindingResource::Sampler(&normal_texture.sampler),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
label: Some(name),
|
|
|
|
});
|
|
|
|
|
2020-09-28 05:24:43 +00:00
|
|
|
Self {
|
2020-05-01 20:14:10 +00:00
|
|
|
name: String::from(name),
|
|
|
|
diffuse_texture,
|
|
|
|
normal_texture,
|
|
|
|
bind_group,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-29 18:30:27 +00:00
|
|
|
pub struct Mesh {
|
|
|
|
pub name: String,
|
|
|
|
pub vertex_buffer: wgpu::Buffer,
|
|
|
|
pub index_buffer: wgpu::Buffer,
|
|
|
|
pub num_elements: u32,
|
|
|
|
pub material: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Model {
|
|
|
|
pub meshes: Vec<Mesh>,
|
|
|
|
pub materials: Vec<Material>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Model {
|
|
|
|
pub fn load<P: AsRef<Path>>(
|
|
|
|
device: &wgpu::Device,
|
2020-09-14 18:53:22 +00:00
|
|
|
queue: &wgpu::Queue,
|
2020-04-29 18:30:27 +00:00
|
|
|
layout: &wgpu::BindGroupLayout,
|
|
|
|
path: P,
|
2020-09-14 18:53:22 +00:00
|
|
|
) -> Result<Self> {
|
2021-08-04 11:20:15 +00:00
|
|
|
let (obj_models, obj_materials) = tobj::load_obj(
|
|
|
|
path.as_ref(),
|
|
|
|
&LoadOptions {
|
2021-06-01 13:27:13 +00:00
|
|
|
triangulate: true,
|
|
|
|
single_index: true,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
)?;
|
|
|
|
|
|
|
|
let obj_materials = obj_materials?;
|
2020-04-29 18:30:27 +00:00
|
|
|
|
|
|
|
// We're assuming that the texture files are stored with the obj file
|
2020-09-28 05:24:43 +00:00
|
|
|
let containing_folder = path.as_ref().parent().context("Directory has no parent")?;
|
2020-04-29 18:30:27 +00:00
|
|
|
|
|
|
|
let mut materials = Vec::new();
|
|
|
|
for mat in obj_materials {
|
|
|
|
let diffuse_path = mat.diffuse_texture;
|
2020-09-28 05:24:43 +00:00
|
|
|
let diffuse_texture =
|
|
|
|
texture::Texture::load(device, queue, containing_folder.join(diffuse_path), false)?;
|
|
|
|
|
2020-09-14 18:53:22 +00:00
|
|
|
let normal_path = mat.normal_texture;
|
2020-09-28 05:24:43 +00:00
|
|
|
let normal_texture =
|
|
|
|
texture::Texture::load(device, queue, containing_folder.join(normal_path), true)?;
|
2020-04-29 18:30:27 +00:00
|
|
|
|
2020-05-01 20:14:10 +00:00
|
|
|
materials.push(Material::new(
|
|
|
|
device,
|
|
|
|
&mat.name,
|
2020-04-29 18:30:27 +00:00
|
|
|
diffuse_texture,
|
|
|
|
normal_texture,
|
2020-05-01 20:14:10 +00:00
|
|
|
layout,
|
|
|
|
));
|
2020-04-29 18:30:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut meshes = Vec::new();
|
|
|
|
for m in obj_models {
|
|
|
|
let mut vertices = Vec::new();
|
|
|
|
for i in 0..m.mesh.positions.len() / 3 {
|
|
|
|
vertices.push(ModelVertex {
|
|
|
|
position: [
|
|
|
|
m.mesh.positions[i * 3],
|
|
|
|
m.mesh.positions[i * 3 + 1],
|
|
|
|
m.mesh.positions[i * 3 + 2],
|
2020-09-28 05:24:43 +00:00
|
|
|
]
|
|
|
|
.into(),
|
|
|
|
tex_coords: [m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1]].into(),
|
2020-04-29 18:30:27 +00:00
|
|
|
normal: [
|
|
|
|
m.mesh.normals[i * 3],
|
|
|
|
m.mesh.normals[i * 3 + 1],
|
|
|
|
m.mesh.normals[i * 3 + 2],
|
2020-09-28 05:24:43 +00:00
|
|
|
]
|
|
|
|
.into(),
|
2020-04-29 18:30:27 +00:00
|
|
|
// We'll calculate these later
|
|
|
|
tangent: [0.0; 3].into(),
|
|
|
|
bitangent: [0.0; 3].into(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
let indices = &m.mesh.indices;
|
2021-08-15 16:44:57 +00:00
|
|
|
let mut triangles_included = (0..vertices.len()).collect::<Vec<_>>();
|
2020-04-29 18:30:27 +00:00
|
|
|
|
2020-05-04 04:45:42 +00:00
|
|
|
// Calculate tangents and bitangets. We're going to
|
|
|
|
// use the triangles, so we need to loop through the
|
|
|
|
// indices in chunks of 3
|
2020-04-29 18:30:27 +00:00
|
|
|
for c in indices.chunks(3) {
|
|
|
|
let v0 = vertices[c[0] as usize];
|
|
|
|
let v1 = vertices[c[1] as usize];
|
|
|
|
let v2 = vertices[c[2] as usize];
|
|
|
|
|
2020-11-14 21:57:39 +00:00
|
|
|
let pos0: cgmath::Vector3<_> = v0.position.into();
|
|
|
|
let pos1: cgmath::Vector3<_> = v1.position.into();
|
|
|
|
let pos2: cgmath::Vector3<_> = v2.position.into();
|
2020-04-29 18:30:27 +00:00
|
|
|
|
2020-11-14 21:57:39 +00:00
|
|
|
let uv0: cgmath::Vector2<_> = v0.tex_coords.into();
|
|
|
|
let uv1: cgmath::Vector2<_> = v1.tex_coords.into();
|
|
|
|
let uv2: cgmath::Vector2<_> = v2.tex_coords.into();
|
2020-04-29 18:30:27 +00:00
|
|
|
|
|
|
|
// Calculate the edges of the triangle
|
|
|
|
let delta_pos1 = pos1 - pos0;
|
|
|
|
let delta_pos2 = pos2 - pos0;
|
|
|
|
|
|
|
|
// This will give us a direction to calculate the
|
|
|
|
// tangent and bitangent
|
|
|
|
let delta_uv1 = uv1 - uv0;
|
|
|
|
let delta_uv2 = uv2 - uv0;
|
|
|
|
|
|
|
|
// Solving the following system of equations will
|
|
|
|
// give us the tangent and bitangent.
|
|
|
|
// delta_pos1 = delta_uv1.x * T + delta_u.y * B
|
|
|
|
// delta_pos2 = delta_uv2.x * T + delta_uv2.y * B
|
2020-09-28 05:24:43 +00:00
|
|
|
// Luckily, the place I found this equation provided
|
2020-04-29 18:30:27 +00:00
|
|
|
// the solution!
|
2020-09-28 05:24:43 +00:00
|
|
|
let r = 1.0 / (delta_uv1.x * delta_uv2.y - delta_uv1.y * delta_uv2.x);
|
2020-04-29 18:30:27 +00:00
|
|
|
let tangent = (delta_pos1 * delta_uv2.y - delta_pos2 * delta_uv1.y) * r;
|
|
|
|
let bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x) * r;
|
2020-09-28 05:24:43 +00:00
|
|
|
|
2020-04-29 18:30:27 +00:00
|
|
|
// We'll use the same tangent/bitangent for each vertex in the triangle
|
2021-08-15 16:44:57 +00:00
|
|
|
vertices[c[0] as usize].tangent =
|
|
|
|
(tangent + cgmath::Vector3::from(vertices[c[0] as usize].tangent)).into();
|
|
|
|
vertices[c[1] as usize].tangent =
|
|
|
|
(tangent + cgmath::Vector3::from(vertices[c[1] as usize].tangent)).into();
|
|
|
|
vertices[c[2] as usize].tangent =
|
|
|
|
(tangent + cgmath::Vector3::from(vertices[c[2] as usize].tangent)).into();
|
|
|
|
vertices[c[0] as usize].bitangent =
|
|
|
|
(bitangent + cgmath::Vector3::from(vertices[c[0] as usize].bitangent)).into();
|
|
|
|
vertices[c[1] as usize].bitangent =
|
|
|
|
(bitangent + cgmath::Vector3::from(vertices[c[1] as usize].bitangent)).into();
|
|
|
|
vertices[c[2] as usize].bitangent =
|
|
|
|
(bitangent + cgmath::Vector3::from(vertices[c[2] as usize].bitangent)).into();
|
2020-04-29 18:30:27 +00:00
|
|
|
|
2021-08-15 16:44:57 +00:00
|
|
|
// Used to average the tangents/bitangents
|
|
|
|
triangles_included[c[0] as usize] += 1;
|
|
|
|
triangles_included[c[1] as usize] += 1;
|
|
|
|
triangles_included[c[2] as usize] += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Average the tangents/bitangents
|
|
|
|
for (i, n) in triangles_included.into_iter().enumerate() {
|
|
|
|
let denom = 1.0 / n as f32;
|
|
|
|
let mut v = &mut vertices[i];
|
|
|
|
v.tangent = (cgmath::Vector3::from(v.tangent) * denom)
|
|
|
|
.normalize()
|
|
|
|
.into();
|
|
|
|
v.bitangent = (cgmath::Vector3::from(v.bitangent) * denom)
|
|
|
|
.normalize()
|
|
|
|
.into();
|
2020-04-29 18:30:27 +00:00
|
|
|
}
|
|
|
|
|
2020-09-28 05:24:43 +00:00
|
|
|
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
|
|
label: Some(&format!("{:?} Vertex Buffer", path.as_ref())),
|
|
|
|
contents: bytemuck::cast_slice(&vertices),
|
|
|
|
usage: wgpu::BufferUsage::VERTEX,
|
|
|
|
});
|
|
|
|
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
|
|
label: Some(&format!("{:?} Index Buffer", path.as_ref())),
|
|
|
|
contents: bytemuck::cast_slice(&m.mesh.indices),
|
|
|
|
usage: wgpu::BufferUsage::INDEX,
|
|
|
|
});
|
2020-04-29 18:30:27 +00:00
|
|
|
|
|
|
|
meshes.push(Mesh {
|
|
|
|
name: m.name,
|
|
|
|
vertex_buffer,
|
|
|
|
index_buffer,
|
|
|
|
num_elements: m.mesh.indices.len() as u32,
|
|
|
|
material: m.mesh.material_id.unwrap_or(0),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-09-14 18:53:22 +00:00
|
|
|
Ok(Self { meshes, materials })
|
2020-04-29 18:30:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-04 11:20:15 +00:00
|
|
|
pub trait DrawModel<'a> {
|
2020-04-29 18:30:27 +00:00
|
|
|
fn draw_mesh(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
mesh: &'a Mesh,
|
|
|
|
material: &'a Material,
|
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-04-29 18:30:27 +00:00
|
|
|
);
|
|
|
|
fn draw_mesh_instanced(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
mesh: &'a Mesh,
|
|
|
|
material: &'a Material,
|
2020-04-29 18:30:27 +00:00
|
|
|
instances: Range<u32>,
|
2021-08-04 11:20:15 +00:00
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-04-29 18:30:27 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
fn draw_model(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
model: &'a Model,
|
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-04-29 18:30:27 +00:00
|
|
|
);
|
|
|
|
fn draw_model_instanced(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
model: &'a Model,
|
2020-04-29 18:30:27 +00:00
|
|
|
instances: Range<u32>,
|
2021-08-04 11:20:15 +00:00
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-04-29 18:30:27 +00:00
|
|
|
);
|
2020-05-01 20:14:10 +00:00
|
|
|
fn draw_model_instanced_with_material(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
model: &'a Model,
|
|
|
|
material: &'a Material,
|
2020-05-01 20:14:10 +00:00
|
|
|
instances: Range<u32>,
|
2021-08-04 11:20:15 +00:00
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-05-01 20:14:10 +00:00
|
|
|
);
|
2020-04-29 18:30:27 +00:00
|
|
|
}
|
|
|
|
|
2021-08-04 11:20:15 +00:00
|
|
|
impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a>
|
2020-04-29 18:30:27 +00:00
|
|
|
where
|
|
|
|
'b: 'a,
|
|
|
|
{
|
|
|
|
fn draw_mesh(
|
|
|
|
&mut self,
|
|
|
|
mesh: &'b Mesh,
|
|
|
|
material: &'b Material,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
|
|
|
self.draw_mesh_instanced(mesh, material, 0..1, uniforms, light);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw_mesh_instanced(
|
|
|
|
&mut self,
|
|
|
|
mesh: &'b Mesh,
|
|
|
|
material: &'b Material,
|
|
|
|
instances: Range<u32>,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
2020-09-14 18:53:22 +00:00
|
|
|
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
2021-02-12 07:18:27 +00:00
|
|
|
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
|
2020-04-29 18:30:27 +00:00
|
|
|
self.set_bind_group(0, &material.bind_group, &[]);
|
2021-08-04 13:06:53 +00:00
|
|
|
self.set_bind_group(1, uniforms, &[]);
|
|
|
|
self.set_bind_group(2, light, &[]);
|
2020-04-29 18:30:27 +00:00
|
|
|
self.draw_indexed(0..mesh.num_elements, 0, instances);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw_model(
|
|
|
|
&mut self,
|
|
|
|
model: &'b Model,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
|
|
|
self.draw_model_instanced(model, 0..1, uniforms, light);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw_model_instanced(
|
|
|
|
&mut self,
|
|
|
|
model: &'b Model,
|
|
|
|
instances: Range<u32>,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
|
|
|
for mesh in &model.meshes {
|
|
|
|
let material = &model.materials[mesh.material];
|
|
|
|
self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms, light);
|
|
|
|
}
|
|
|
|
}
|
2020-05-01 20:14:10 +00:00
|
|
|
|
|
|
|
fn draw_model_instanced_with_material(
|
|
|
|
&mut self,
|
|
|
|
model: &'b Model,
|
|
|
|
material: &'b Material,
|
|
|
|
instances: Range<u32>,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
|
|
|
for mesh in &model.meshes {
|
|
|
|
self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms, light);
|
|
|
|
}
|
|
|
|
}
|
2020-04-29 18:30:27 +00:00
|
|
|
}
|
|
|
|
|
2021-08-04 11:20:15 +00:00
|
|
|
pub trait DrawLight<'a> {
|
2020-04-29 18:30:27 +00:00
|
|
|
fn draw_light_mesh(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
mesh: &'a Mesh,
|
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-04-29 18:30:27 +00:00
|
|
|
);
|
|
|
|
fn draw_light_mesh_instanced(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
mesh: &'a Mesh,
|
2020-04-29 18:30:27 +00:00
|
|
|
instances: Range<u32>,
|
2021-08-04 11:20:15 +00:00
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
|
|
|
);
|
2020-04-29 18:30:27 +00:00
|
|
|
|
|
|
|
fn draw_light_model(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
model: &'a Model,
|
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-04-29 18:30:27 +00:00
|
|
|
);
|
|
|
|
fn draw_light_model_instanced(
|
|
|
|
&mut self,
|
2021-08-04 11:20:15 +00:00
|
|
|
model: &'a Model,
|
2020-04-29 18:30:27 +00:00
|
|
|
instances: Range<u32>,
|
2021-08-04 11:20:15 +00:00
|
|
|
uniforms: &'a wgpu::BindGroup,
|
|
|
|
light: &'a wgpu::BindGroup,
|
2020-04-29 18:30:27 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-08-04 11:20:15 +00:00
|
|
|
impl<'a, 'b> DrawLight<'b> for wgpu::RenderPass<'a>
|
2020-04-29 18:30:27 +00:00
|
|
|
where
|
|
|
|
'b: 'a,
|
|
|
|
{
|
|
|
|
fn draw_light_mesh(
|
|
|
|
&mut self,
|
|
|
|
mesh: &'b Mesh,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
|
|
|
self.draw_light_mesh_instanced(mesh, 0..1, uniforms, light);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw_light_mesh_instanced(
|
|
|
|
&mut self,
|
|
|
|
mesh: &'b Mesh,
|
|
|
|
instances: Range<u32>,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
2020-09-14 18:53:22 +00:00
|
|
|
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
2021-02-12 07:18:27 +00:00
|
|
|
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
|
2020-04-29 18:30:27 +00:00
|
|
|
self.set_bind_group(0, uniforms, &[]);
|
|
|
|
self.set_bind_group(1, light, &[]);
|
|
|
|
self.draw_indexed(0..mesh.num_elements, 0, instances);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw_light_model(
|
|
|
|
&mut self,
|
|
|
|
model: &'b Model,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
|
|
|
self.draw_light_model_instanced(model, 0..1, uniforms, light);
|
|
|
|
}
|
|
|
|
fn draw_light_model_instanced(
|
|
|
|
&mut self,
|
|
|
|
model: &'b Model,
|
|
|
|
instances: Range<u32>,
|
|
|
|
uniforms: &'b wgpu::BindGroup,
|
|
|
|
light: &'b wgpu::BindGroup,
|
|
|
|
) {
|
|
|
|
for mesh in &model.meshes {
|
|
|
|
self.draw_light_mesh_instanced(mesh, instances.clone(), uniforms, light);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|