rendered a model!! wow

This commit is contained in:
aiden 2023-06-21 15:26:05 +01:00
parent 8481f8d529
commit 7b38c71ceb
Signed by: aiden
GPG Key ID: EFA9C74AEBF806E0
3 changed files with 58 additions and 77 deletions

@ -40,6 +40,8 @@ var inches_per_1dg = inches_per_360dg / 360;
var dots_per_1dg = inches_per_1dg * dpi;
*/
#![feature(slice_as_chunks)]
use {
std::{process::ExitCode, time::Instant},
winit::{

@ -1,4 +1,4 @@
use std::{io::{Cursor, BufReader}, path::Path};
use std::{path::Path, assert_eq};
use crate::texture;
use image;
@ -7,10 +7,6 @@ use wgpu::util::DeviceExt;
fn load_bytes<T: AsRef<Path>>(file_name: T) -> Vec<u8> {
return std::fs::read(file_name.as_ref()).unwrap();
}
fn load_string<T: AsRef<Path>>(file_name: T) -> String {
return std::fs::read_to_string(file_name.as_ref()).unwrap();
}
fn load_texture(
file_name: &str,
device: &wgpu::Device,
@ -22,29 +18,28 @@ fn load_texture(
#[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],
pub struct Vertex {
pub position: [f32; 3],
pub tex_coords: [f32; 2],
}
pub struct Material {
pub name: String,
pub diffuse_texture: texture::Texture,
pub bind_group: wgpu::BindGroup,
pub name: String,
pub diffuse_texture: texture::Texture,
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,
pub material: usize,
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>,
pub meshes: Vec<Mesh>,
pub materials: Vec<Material>,
}
pub fn load_obj(
@ -53,22 +48,9 @@ pub fn load_obj(
queue: &wgpu::Queue,
layout: &wgpu::BindGroupLayout,
) -> Model {
let obj_text = load_string(file_name);
let obj_cursor = Cursor::new(obj_text);
let mut obj_reader = BufReader::new(obj_cursor);
let (models, obj_materials) = tobj::load_obj_buf(
&mut(obj_reader),
&(tobj::LoadOptions {
triangulate: true,
single_index: true,
..Default::default()
}),
|p| {
let p = format!("models/{}", p.to_str().unwrap()); // fixme
let mat_text = load_string(p);
tobj::load_mtl_buf(&mut(BufReader::new(Cursor::new(mat_text))))
}
let (models, obj_materials) = tobj::load_obj(
file_name,
&(tobj::GPU_LOAD_OPTIONS)
).unwrap();
let mut materials = Vec::new();
@ -97,45 +79,42 @@ pub fn load_obj(
})
}
let meshes = models
.into_iter()
.map(|m| {
let vertices = (0..m.mesh.positions.len() / 3)
.map(|i| ModelVertex {
position: [
m.mesh.positions[i * 3],
m.mesh.positions[i * 3 + 1],
m.mesh.positions[i * 3 + 2],
],
tex_coords: [m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1]],
normal: [
m.mesh.normals[i * 3],
m.mesh.normals[i * 3 + 1],
m.mesh.normals[i * 3 + 2],
],
})
.collect::<Vec<_>>();
// models is a Vec of struct { mesh: Mesh, name: String }
let mut meshes = Vec::<Mesh>::new();
for model in models {
let mesh = model.mesh;
let vertex_buffer = device.create_buffer_init(&(wgpu::util::BufferInitDescriptor {
label: Some(&(format!("{:?} Vertex Buffer", file_name))),
contents: bytemuck::cast_slice(&(vertices)),
usage: wgpu::BufferUsages::VERTEX,
}));
let index_buffer = device.create_buffer_init(&(wgpu::util::BufferInitDescriptor {
label: Some(&(format!("{:?} Index Buffer", file_name))),
contents: bytemuck::cast_slice(&(m.mesh.indices)),
usage: wgpu::BufferUsages::INDEX,
}));
let (positions, _) = mesh.positions.as_chunks::<3>();
let (texcoords, _) = mesh.texcoords.as_chunks::<2>();
assert_eq!(positions.len(), texcoords.len());
Mesh {
name: file_name.to_string(),
vertex_buffer,
index_buffer,
num_elements: m.mesh.indices.len() as u32,
material: m.mesh.material_id.unwrap_or(0),
}
})
.collect::<Vec<_>>();
let mut vertices = Vec::<Vertex>::new();
for index in 0..positions.len() {
vertices.push(Vertex {
position: positions[index],
tex_coords: [texcoords[index][0], 1.0 - texcoords[index][1]],
});
}
let vertex_buffer = device.create_buffer_init(&(wgpu::util::BufferInitDescriptor {
label: Some(&(format!("{:?} Vertex Buffer", file_name))),
contents: bytemuck::cast_slice(&(vertices)),
usage: wgpu::BufferUsages::VERTEX,
}));
let index_buffer = device.create_buffer_init(&(wgpu::util::BufferInitDescriptor {
label: Some(&(format!("{:?} Index Buffer", file_name))),
contents: bytemuck::cast_slice(&(mesh.indices)),
usage: wgpu::BufferUsages::INDEX,
}));
meshes.push(Mesh {
name: "x".to_string(),
vertex_buffer,
index_buffer,
num_elements: mesh.indices.len() as u32,
material: mesh.material_id.unwrap(),
});
}
Model { meshes, materials }
}
}

@ -1,7 +1,7 @@
use cgmath::{Deg, Rad, Point3};
use winit::window::Window;
use crate::{camera::*, Input, player::Player, obj::{self, ModelVertex}};
use crate::{camera::*, Input, player::Player, obj::{self, Vertex}};
pub struct State {
pub input: Input,
@ -196,9 +196,9 @@ impl State {
buffers: &[
// index 0
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<ModelVertex>() as wgpu::BufferAddress,
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &(wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x2, 2 => Float32x3]),
attributes: &(wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x2]),
},
],
},
@ -216,7 +216,7 @@ impl State {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None, // should use Some(wgpu::Face::Back) once i have 3d objects (rather than 2d ones) in space
cull_mode: Some(wgpu::Face::Back),
polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,