refactor
This commit is contained in:
9965
resources/teapot.obj
Normal file
9965
resources/teapot.obj
Normal file
File diff suppressed because it is too large
Load Diff
10
resources/untitled.mtl
Normal file
10
resources/untitled.mtl
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
newmtl None
|
||||||
|
Ns 0
|
||||||
|
Ka 0.000000 0.000000 0.000000
|
||||||
|
Kd 0.8 0.8 0.8
|
||||||
|
Ks 0.8 0.8 0.8
|
||||||
|
d 1
|
||||||
|
illum 2
|
||||||
2423
resources/untitled.obj
Normal file
2423
resources/untitled.obj
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ use bytemuck::{Pod, Zeroable};
|
|||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct Vertex {
|
pub struct Vertex {
|
||||||
_pos: [f32; 4],
|
_pos: [f32; 4],
|
||||||
_normal: [f32; 4],
|
_normal: [f32; 4],
|
||||||
}
|
}
|
||||||
@@ -11,14 +11,14 @@ unsafe impl Pod for Vertex {}
|
|||||||
|
|
||||||
unsafe impl Zeroable for Vertex {}
|
unsafe impl Zeroable for Vertex {}
|
||||||
|
|
||||||
fn vertex(pos: [f32; 3], nor: [f32; 3]) -> Vertex {
|
pub fn vertex(pos: [f32; 3], nor: [f32; 3]) -> Vertex {
|
||||||
Vertex {
|
Vertex {
|
||||||
_pos: [pos[0], pos[1], pos[2], 1.0],
|
_pos: [pos[0], pos[1], pos[2], 1.0],
|
||||||
_normal: [nor[0], nor[1], nor[2], 0.0],
|
_normal: [nor[0], nor[1], nor[2], 0.0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_mesh(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
|
pub fn import_mesh(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
|
||||||
//let obj_file = "/home/mrh/source/3d-min-viable-eng/resources/Tree_01.obj";
|
//let obj_file = "/home/mrh/source/3d-min-viable-eng/resources/Tree_01.obj";
|
||||||
//let mtl_file = "/home/mrh/source/3d-min-viable-eng/resources/Tree_01.mtl";
|
//let mtl_file = "/home/mrh/source/3d-min-viable-eng/resources/Tree_01.mtl";
|
||||||
let (models, materials) = tobj::load_obj(mesh_path, false).expect("Failed to load file");
|
let (models, materials) = tobj::load_obj(mesh_path, false).expect("Failed to load file");
|
||||||
@@ -73,7 +73,7 @@ fn import_mesh(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_plane(size: f32) -> (Vec<Vertex>, Vec<u32>) {
|
pub fn create_plane(size: f32) -> (Vec<Vertex>, Vec<u32>) {
|
||||||
let vertex_data = [
|
let vertex_data = [
|
||||||
vertex([size, -size, 0.0], [0.0, 0.0, 1.0]),
|
vertex([size, -size, 0.0], [0.0, 0.0, 1.0]),
|
||||||
vertex([size, size, 0.0], [0.0, 0.0, 1.0]),
|
vertex([size, size, 0.0], [0.0, 0.0, 1.0]),
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use bytemuck::__core::ops::Range;
|
use bytemuck::__core::ops::Range;
|
||||||
use bytemuck::{Zeroable, Pod};
|
use bytemuck::{Zeroable, Pod};
|
||||||
|
use crate::OPENGL_TO_WGPU_MATRIX;
|
||||||
|
|
||||||
struct Light {
|
pub struct Light {
|
||||||
pos: cgmath::Point3<f32>,
|
pos: cgmath::Point3<f32>,
|
||||||
color: wgpu::Color,
|
color: wgpu::Color,
|
||||||
fov: f32,
|
fov: f32,
|
||||||
@@ -11,7 +12,7 @@ struct Light {
|
|||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct LightRaw {
|
pub struct LightRaw {
|
||||||
proj: [[f32; 4]; 4],
|
proj: [[f32; 4]; 4],
|
||||||
pos: [f32; 4],
|
pos: [f32; 4],
|
||||||
color: [f32; 4],
|
color: [f32; 4],
|
||||||
@@ -32,7 +33,7 @@ impl Light {
|
|||||||
near: self.depth.start,
|
near: self.depth.start,
|
||||||
far: self.depth.end,
|
far: self.depth.end,
|
||||||
};
|
};
|
||||||
let mx_correction = framework::OPENGL_TO_WGPU_MATRIX;
|
let mx_correction = OPENGL_TO_WGPU_MATRIX;
|
||||||
let mx_view_proj =
|
let mx_view_proj =
|
||||||
mx_correction * cgmath::Matrix4::from(projection.to_perspective()) * mx_view;
|
mx_correction * cgmath::Matrix4::from(projection.to_perspective()) * mx_view;
|
||||||
LightRaw {
|
LightRaw {
|
||||||
|
|||||||
18
src/main.rs
18
src/main.rs
@@ -13,6 +13,7 @@ use winit::{
|
|||||||
event::{self, WindowEvent},
|
event::{self, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
};
|
};
|
||||||
|
use crate::render::Renderer;
|
||||||
|
|
||||||
mod framework;
|
mod framework;
|
||||||
mod geometry;
|
mod geometry;
|
||||||
@@ -130,8 +131,9 @@ fn main() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let optional_features = E::optional_features();
|
|
||||||
let required_features = E::required_features();
|
let optional_features = Renderer::optional_features();
|
||||||
|
let required_features = Renderer::required_features();
|
||||||
let adapter_features = adapter.features();
|
let adapter_features = adapter.features();
|
||||||
assert!(
|
assert!(
|
||||||
adapter_features.contains(required_features),
|
adapter_features.contains(required_features),
|
||||||
@@ -139,7 +141,7 @@ fn main() {
|
|||||||
required_features - adapter_features
|
required_features - adapter_features
|
||||||
);
|
);
|
||||||
|
|
||||||
let needed_limits = E::required_limits();
|
let needed_limits = wgpu::Limits::default();//Renderer::required_limits();
|
||||||
|
|
||||||
// Maybe for debug tracing???
|
// Maybe for debug tracing???
|
||||||
let trace_dir = std::env::var("WGPU_TRACE");
|
let trace_dir = std::env::var("WGPU_TRACE");
|
||||||
@@ -196,7 +198,7 @@ fn main() {
|
|||||||
WebSpawner {}
|
WebSpawner {}
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
// Swapchain has a prototype dealio
|
|
||||||
let mut sc_desc = wgpu::SwapChainDescriptor {
|
let mut sc_desc = wgpu::SwapChainDescriptor {
|
||||||
// Allows a texture to be a output attachment of a renderpass.
|
// Allows a texture to be a output attachment of a renderpass.
|
||||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
@@ -224,6 +226,8 @@ fn main() {
|
|||||||
|
|
||||||
log::info!("Entering render loop...");
|
log::info!("Entering render loop...");
|
||||||
|
|
||||||
|
let mut renderer = render::Renderer::init();
|
||||||
|
|
||||||
|
|
||||||
// This is just an winit event loop
|
// This is just an winit event loop
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
@@ -271,7 +275,7 @@ fn main() {
|
|||||||
sc_desc.width = size.width;
|
sc_desc.width = size.width;
|
||||||
sc_desc.height = size.height;
|
sc_desc.height = size.height;
|
||||||
|
|
||||||
example.resize(&sc_desc, &device, &queue);
|
renderer.resize(&sc_desc, &device, &queue);
|
||||||
|
|
||||||
swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
||||||
}
|
}
|
||||||
@@ -289,7 +293,7 @@ fn main() {
|
|||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
example.update(event);
|
renderer.update(event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
event::Event::RedrawRequested(_) => {
|
event::Event::RedrawRequested(_) => {
|
||||||
@@ -303,7 +307,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
example.render(&frame.output, &device, &queue, &spawner);
|
renderer.render(&frame.output, &device, &queue, &spawner);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
use crate::{EntityUniforms, Pass};
|
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use bytemuck::__core::mem;
|
use bytemuck::__core::mem;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
use std::rc::Rc;
|
use std::{iter, num::NonZeroU32, ops::Range, rc::Rc};
|
||||||
|
use crate::OPENGL_TO_WGPU_MATRIX;
|
||||||
|
use crate::light::LightRaw;
|
||||||
|
use crate::geometry::{Vertex, import_mesh, create_plane};
|
||||||
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct ForwardUniforms {
|
pub struct ForwardUniforms {
|
||||||
proj: [[f32; 4]; 4],
|
proj: [[f32; 4]; 4],
|
||||||
num_lights: [u32; 4],
|
num_lights: [u32; 4],
|
||||||
}
|
}
|
||||||
@@ -17,7 +20,7 @@ unsafe impl Zeroable for ForwardUniforms {}
|
|||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct EntityUniforms {
|
pub struct EntityUniforms {
|
||||||
model: [[f32; 4]; 4],
|
model: [[f32; 4]; 4],
|
||||||
color: [f32; 4],
|
color: [f32; 4],
|
||||||
}
|
}
|
||||||
@@ -27,17 +30,16 @@ unsafe impl Pod for EntityUniforms {}
|
|||||||
unsafe impl Zeroable for EntityUniforms {}
|
unsafe impl Zeroable for EntityUniforms {}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ShadowUniforms {
|
pub struct ShadowUniforms {
|
||||||
proj: [[f32; 4]; 4],
|
proj: [[f32; 4]; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Pass {
|
pub struct Pass {
|
||||||
pipeline: wgpu::RenderPipeline,
|
pipeline: wgpu::RenderPipeline,
|
||||||
bind_group: wgpu::BindGroup,
|
bind_group: wgpu::BindGroup,
|
||||||
uniform_buf: wgpu::Buffer,
|
uniform_buf: wgpu::Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
lights_are_dirty: bool,
|
lights_are_dirty: bool,
|
||||||
shadow_pass: Pass,
|
shadow_pass: Pass,
|
||||||
@@ -63,7 +65,7 @@ impl Renderer {
|
|||||||
cgmath::Point3::new(0f32, 0.0, 0.0),
|
cgmath::Point3::new(0f32, 0.0, 0.0),
|
||||||
cgmath::Vector3::unit_z(),
|
cgmath::Vector3::unit_z(),
|
||||||
);
|
);
|
||||||
let mx_correction = framework::OPENGL_TO_WGPU_MATRIX;
|
let mx_correction = OPENGL_TO_WGPU_MATRIX;
|
||||||
mx_correction * mx_projection * mx_view
|
mx_correction * mx_projection * mx_view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +117,7 @@ impl Renderer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self) -> Renderer {
|
pub fn init(device: &wgpu::Device) -> Renderer {
|
||||||
|
|
||||||
// Pre init the light uniform, with slots enough for MAX_LIGHTS
|
// Pre init the light uniform, with slots enough for MAX_LIGHTS
|
||||||
let light_uniform_size =
|
let light_uniform_size =
|
||||||
@@ -133,6 +135,7 @@ impl Renderer {
|
|||||||
// This seems way way way way easier than what I was doing in tracer
|
// This seems way way way way easier than what I was doing in tracer
|
||||||
// Though the attr thing is still a macro. Which would cause issues if
|
// Though the attr thing is still a macro. Which would cause issues if
|
||||||
// I wanted to get tricky with the 0,1 types
|
// I wanted to get tricky with the 0,1 types
|
||||||
|
let vertex_size = mem::size_of::<Vertex>();
|
||||||
let vertex_attr = wgpu::vertex_attr_array![0 => Float4, 1 => Float4];
|
let vertex_attr = wgpu::vertex_attr_array![0 => Float4, 1 => Float4];
|
||||||
let vb_desc = wgpu::VertexBufferDescriptor {
|
let vb_desc = wgpu::VertexBufferDescriptor {
|
||||||
stride: vertex_size as wgpu::BufferAddress,
|
stride: vertex_size as wgpu::BufferAddress,
|
||||||
@@ -140,6 +143,24 @@ impl Renderer {
|
|||||||
attributes: &vertex_attr,
|
attributes: &vertex_attr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is also in the runtime which really shouldn't have this
|
||||||
|
let local_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
|
count: None,
|
||||||
|
ty: wgpu::BindingType::UniformBuffer {
|
||||||
|
dynamic: false,
|
||||||
|
min_binding_size: wgpu::BufferSize::new(
|
||||||
|
mem::size_of::<EntityUniforms>() as _
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
There appear to be two passes required for shadows, the shadow pass, and the forward pass
|
There appear to be two passes required for shadows, the shadow pass, and the forward pass
|
||||||
Need to open this up in renderdoc and see what it's actually doing
|
Need to open this up in renderdoc and see what it's actually doing
|
||||||
@@ -147,7 +168,8 @@ impl Renderer {
|
|||||||
|
|
||||||
let shadow_pass = {
|
let shadow_pass = {
|
||||||
let uniform_size = mem::size_of::<ShadowUniforms>() as wgpu::BufferAddress;
|
let uniform_size = mem::size_of::<ShadowUniforms>() as wgpu::BufferAddress;
|
||||||
// Create pipeline layout
|
|
||||||
|
// I believe this is just making a_Pos or u_ViewProj available in the vert shader
|
||||||
let bind_group_layout =
|
let bind_group_layout =
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
@@ -161,12 +183,15 @@ impl Renderer {
|
|||||||
count: None,
|
count: None,
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Pipeline is similar between passes, but with a different label
|
||||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("shadow"),
|
label: Some("shadow"),
|
||||||
bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout],
|
bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Holds the shadow uniforms, which is just a 4 vec of quaternians
|
||||||
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: uniform_size,
|
size: uniform_size,
|
||||||
@@ -276,6 +301,7 @@ impl Renderer {
|
|||||||
],
|
],
|
||||||
label: None,
|
label: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("main"),
|
label: Some("main"),
|
||||||
bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout],
|
bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout],
|
||||||
|
|||||||
@@ -1,21 +1,31 @@
|
|||||||
use crate::ShadowUniforms;
|
|
||||||
use bytemuck::__core::mem;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use bytemuck::__core::mem;
|
||||||
|
use crate::light::Light;
|
||||||
|
use crate::render::EntityUniforms;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This will eventually be within an ECS...
|
||||||
|
|
||||||
|
So I will probably take the same approach that I did for tracer and have meta-data for rendering
|
||||||
|
held by the ECS, and a render system which will cycle through them and render
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
struct Entity {
|
struct Entity {
|
||||||
mx_world: cgmath::Matrix4<f32>,
|
mx_world: cgmath::Matrix4<f32>,
|
||||||
rotation_speed: f32,
|
rotation_speed: f32,
|
||||||
color: wgpu::Color,
|
color: wgpu::Color,
|
||||||
vertex_buf: Rc<wgpu::Buffer>,
|
vertex_buf: Rc<wgpu::Buffer>, // Could probably tie this along with index & count to some resource handle in the renderer
|
||||||
index_buf: Rc<wgpu::Buffer>,
|
index_buf: Rc<wgpu::Buffer>,
|
||||||
index_count: usize,
|
index_count: usize,
|
||||||
bind_group: wgpu::BindGroup,
|
bind_group: wgpu::BindGroup, // This is a little weird to have in the entity isn't it?
|
||||||
uniform_buf: wgpu::Buffer,
|
uniform_buf: wgpu::Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Runtime {
|
pub struct Runtime {
|
||||||
entities: Vec<Entity>, // This is going to be ECS'd
|
entities: Vec<Entity>,
|
||||||
|
// This is going to be ECS'd
|
||||||
lights: Vec<Light>, // ECS
|
lights: Vec<Light>, // ECS
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +37,31 @@ impl Runtime {
|
|||||||
{
|
{
|
||||||
|
|
||||||
// https://sotrh.github.io/learn-wgpu/beginner/tutorial5-textures/#the-bindgroup
|
// https://sotrh.github.io/learn-wgpu/beginner/tutorial5-textures/#the-bindgroup
|
||||||
// It appears like bindgroups are
|
// It appears like bindgroups are the shader input definitions
|
||||||
|
/*
|
||||||
|
But it is defined in multiples places...
|
||||||
|
|
||||||
|
` `
|
||||||
|
|
||||||
|
one of these in each pass
|
||||||
|
let bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The entities have one
|
||||||
|
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout: &local_bind_group_layout,
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::Buffer(plane_uniform_buf.slice(..)),
|
||||||
|
}],
|
||||||
|
label: None,
|
||||||
|
});
|
||||||
|
*/
|
||||||
// Defines the Uniform buffer for the Vertex and Fragment shaders
|
// Defines the Uniform buffer for the Vertex and Fragment shaders
|
||||||
let local_bind_group_layout =
|
let local_bind_group_layout =
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
|||||||
Reference in New Issue
Block a user