-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e29bce5
commit 819ed63
Showing
12 changed files
with
1,181 additions
and
88 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod model; | ||
mod texture; | ||
pub mod vertex; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
// code from: https://github.com/sotrh/learn-wgpu | ||
|
||
use std::{collections::HashMap, io::BufReader}; | ||
|
||
use wgpu::{util::DeviceExt, BindGroupDescriptor, BindGroupEntry, BindingResource}; | ||
|
||
use super::{texture, vertex::ModelVertex}; | ||
|
||
pub struct Model { | ||
pub mesh: Mesh, | ||
pub material: Material, | ||
} | ||
|
||
pub struct Material { | ||
pub name: String, | ||
pub diffuse_texture: texture::TextureSet, | ||
pub bind_group: wgpu::BindGroup, | ||
} | ||
|
||
pub struct Mesh { | ||
pub name: String, | ||
pub vertex_buffer: wgpu::Buffer, | ||
pub index_buffer: wgpu::Buffer, | ||
pub num_elements: u32, | ||
} | ||
|
||
impl Model { | ||
pub fn create( | ||
device: &wgpu::Device, | ||
queue: &wgpu::Queue, | ||
obj_src: &[u8], | ||
texture_diffuse_src: &[u8], | ||
texture_bind_group_layout: &wgpu::BindGroupLayout, | ||
) -> anyhow::Result<Self> { | ||
let mut bufreader = BufReader::new(obj_src); | ||
|
||
let (raw_models, _) = tobj::load_obj_buf( | ||
&mut bufreader, | ||
&tobj::LoadOptions { | ||
single_index: true, | ||
triangulate: true, | ||
..Default::default() | ||
}, | ||
|_| tobj::MTLLoadResult::Ok((vec![], HashMap::new())), | ||
)?; | ||
|
||
let raw_model = &raw_models.get(0).expect("No model loaded"); | ||
let raw_mesh = &raw_model.mesh; | ||
let mut vertices = Vec::new(); | ||
for i in 0..raw_mesh.positions.len() / 3 { | ||
vertices.push(ModelVertex { | ||
position: [ | ||
raw_mesh.positions[i * 3], | ||
raw_mesh.positions[i * 3 + 1], | ||
raw_mesh.positions[i * 3 + 2], | ||
], | ||
tex_coords: [ | ||
raw_mesh.texcoords[i * 2], | ||
1.0 - raw_mesh.texcoords[i * 2 + 1], | ||
], | ||
normal: [ | ||
raw_mesh.normals[i * 3], | ||
raw_mesh.normals[i * 3 + 1], | ||
raw_mesh.normals[i * 3 + 2], | ||
], | ||
}); | ||
} | ||
|
||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { | ||
label: Some("vertex buffer"), | ||
contents: bytemuck::cast_slice(&vertices), | ||
usage: wgpu::BufferUsages::VERTEX, | ||
}); | ||
|
||
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { | ||
label: Some("index buffer"), | ||
contents: bytemuck::cast_slice(&raw_mesh.indices), | ||
usage: wgpu::BufferUsages::INDEX, | ||
}); | ||
|
||
let mesh = Mesh { | ||
name: "mesh".to_string(), | ||
vertex_buffer, | ||
index_buffer, | ||
num_elements: raw_mesh.indices.len() as u32, | ||
}; | ||
|
||
let texture = | ||
texture::TextureSet::from_bytes(device, queue, texture_diffuse_src, "texture")?; | ||
|
||
let texture_bind_group = device.create_bind_group(&BindGroupDescriptor { | ||
label: Some("material_bind_group"), | ||
layout: texture_bind_group_layout, | ||
entries: &[ | ||
BindGroupEntry { | ||
binding: 0, | ||
resource: BindingResource::TextureView(&texture.view()), | ||
}, | ||
BindGroupEntry { | ||
binding: 1, | ||
resource: BindingResource::Sampler(&texture.sampler()), | ||
}, | ||
], | ||
}); | ||
|
||
let material = Material { | ||
name: "Material".to_string(), | ||
diffuse_texture: texture, | ||
bind_group: texture_bind_group, | ||
}; | ||
|
||
Ok(Self { mesh, material }) | ||
} | ||
} | ||
|
||
pub trait DrawModel<'a> { | ||
fn draw_mesh( | ||
&mut self, | ||
mesh: &'a Mesh, | ||
material: &'a Material, | ||
camera_bind_group: &'a wgpu::BindGroup, | ||
); | ||
|
||
fn draw_model(&mut self, model: &'a Model, camera_bind_group: &'a wgpu::BindGroup); | ||
} | ||
|
||
impl<'a> DrawModel<'a> for wgpu::RenderPass<'a> { | ||
fn draw_mesh( | ||
&mut self, | ||
mesh: &'a Mesh, | ||
material: &'a Material, | ||
camera_bind_group: &'a wgpu::BindGroup, | ||
) { | ||
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..)); | ||
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32); | ||
self.set_bind_group(0, camera_bind_group, &[]); | ||
self.set_bind_group(1, &material.bind_group, &[]); | ||
self.draw_indexed(0..mesh.num_elements, 0, 0..1); | ||
} | ||
|
||
fn draw_model(&mut self, model: &'a Model, camera_bind_group: &'a wgpu::BindGroup) { | ||
self.draw_mesh(&model.mesh, &model.material, camera_bind_group) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// code from: https://github.com/sotrh/learn-wgpu | ||
|
||
use image::GenericImageView; | ||
|
||
pub struct TextureSet { | ||
texture: wgpu::Texture, | ||
view: wgpu::TextureView, | ||
sampler: wgpu::Sampler, | ||
} | ||
|
||
impl TextureSet { | ||
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; | ||
|
||
pub fn create_depth_texture( | ||
device: &wgpu::Device, | ||
config: &wgpu::SurfaceConfiguration, | ||
label: &str, | ||
) -> Self { | ||
let size = wgpu::Extent3d { | ||
width: config.width, | ||
height: config.height, | ||
depth_or_array_layers: 1, | ||
}; | ||
let desc = wgpu::TextureDescriptor { | ||
label: Some(label), | ||
size, | ||
mip_level_count: 1, | ||
sample_count: 1, | ||
dimension: wgpu::TextureDimension::D2, | ||
format: Self::DEPTH_FORMAT, | ||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, | ||
view_formats: &[], | ||
}; | ||
let texture = device.create_texture(&desc); | ||
|
||
let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); | ||
let sampler = device.create_sampler(&wgpu::SamplerDescriptor { | ||
address_mode_u: wgpu::AddressMode::ClampToEdge, | ||
address_mode_v: wgpu::AddressMode::ClampToEdge, | ||
address_mode_w: wgpu::AddressMode::ClampToEdge, | ||
mag_filter: wgpu::FilterMode::Linear, | ||
min_filter: wgpu::FilterMode::Linear, | ||
mipmap_filter: wgpu::FilterMode::Nearest, | ||
compare: Some(wgpu::CompareFunction::LessEqual), | ||
lod_min_clamp: 0.0, | ||
lod_max_clamp: 100.0, | ||
..Default::default() | ||
}); | ||
|
||
Self { | ||
texture, | ||
view, | ||
sampler, | ||
} | ||
} | ||
|
||
pub fn from_bytes( | ||
device: &wgpu::Device, | ||
queue: &wgpu::Queue, | ||
bytes: &[u8], | ||
label: &str, | ||
) -> anyhow::Result<Self> { | ||
let img = image::load_from_memory(bytes)?; | ||
Self::from_image(device, queue, &img, Some(label)) | ||
} | ||
|
||
pub fn from_image( | ||
device: &wgpu::Device, | ||
queue: &wgpu::Queue, | ||
img: &image::DynamicImage, | ||
label: Option<&str>, | ||
) -> anyhow::Result<Self> { | ||
let dimensions = img.dimensions(); | ||
let rgba = img.to_rgba8(); | ||
|
||
let size = wgpu::Extent3d { | ||
width: dimensions.0, | ||
height: dimensions.1, | ||
depth_or_array_layers: 1, | ||
}; | ||
let format = wgpu::TextureFormat::Rgba8UnormSrgb; | ||
let texture = device.create_texture(&wgpu::TextureDescriptor { | ||
label, | ||
size, | ||
mip_level_count: 1, | ||
sample_count: 1, | ||
dimension: wgpu::TextureDimension::D2, | ||
format, | ||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, | ||
view_formats: &[], | ||
}); | ||
|
||
queue.write_texture( | ||
wgpu::ImageCopyTexture { | ||
aspect: wgpu::TextureAspect::All, | ||
texture: &texture, | ||
mip_level: 0, | ||
origin: wgpu::Origin3d::ZERO, | ||
}, | ||
&rgba, | ||
wgpu::ImageDataLayout { | ||
offset: 0, | ||
bytes_per_row: Some(4 * dimensions.0), | ||
rows_per_image: Some(dimensions.1), | ||
}, | ||
size, | ||
); | ||
|
||
let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); | ||
let sampler = device.create_sampler(&wgpu::SamplerDescriptor { | ||
address_mode_u: wgpu::AddressMode::ClampToEdge, | ||
address_mode_v: wgpu::AddressMode::ClampToEdge, | ||
address_mode_w: wgpu::AddressMode::ClampToEdge, | ||
mag_filter: wgpu::FilterMode::Linear, | ||
min_filter: wgpu::FilterMode::Nearest, | ||
mipmap_filter: wgpu::FilterMode::Nearest, | ||
..Default::default() | ||
}); | ||
|
||
Ok(Self { | ||
texture, | ||
view, | ||
sampler, | ||
}) | ||
} | ||
|
||
pub fn view(&self) -> &wgpu::TextureView { | ||
&self.view | ||
} | ||
|
||
pub fn sampler(&self) -> &wgpu::Sampler { | ||
&self.sampler | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use std::mem; | ||
|
||
#[repr(C)] | ||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] | ||
pub struct ModelVertex { | ||
pub position: [f32; 3], | ||
pub tex_coords: [f32; 2], | ||
pub normal: [f32; 3], | ||
} | ||
|
||
impl ModelVertex { | ||
pub fn desc() -> wgpu::VertexBufferLayout<'static> { | ||
wgpu::VertexBufferLayout { | ||
array_stride: mem::size_of::<ModelVertex>() as wgpu::BufferAddress, | ||
step_mode: wgpu::VertexStepMode::Vertex, | ||
attributes: &[ | ||
wgpu::VertexAttribute { | ||
offset: 0, | ||
shader_location: 0, | ||
format: wgpu::VertexFormat::Float32x3, | ||
}, | ||
wgpu::VertexAttribute { | ||
offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, | ||
shader_location: 1, | ||
format: wgpu::VertexFormat::Float32x2, | ||
}, | ||
wgpu::VertexAttribute { | ||
offset: mem::size_of::<[f32; 5]>() as wgpu::BufferAddress, | ||
shader_location: 2, | ||
format: wgpu::VertexFormat::Float32x3, | ||
}, | ||
], | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.