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)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct Vertex {
|
||||
pub struct Vertex {
|
||||
_pos: [f32; 4],
|
||||
_normal: [f32; 4],
|
||||
}
|
||||
@@ -11,14 +11,14 @@ unsafe impl Pod 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 {
|
||||
_pos: [pos[0], pos[1], pos[2], 1.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 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");
|
||||
@@ -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 = [
|
||||
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::{Zeroable, Pod};
|
||||
use crate::OPENGL_TO_WGPU_MATRIX;
|
||||
|
||||
struct Light {
|
||||
pub struct Light {
|
||||
pos: cgmath::Point3<f32>,
|
||||
color: wgpu::Color,
|
||||
fov: f32,
|
||||
@@ -11,7 +12,7 @@ struct Light {
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct LightRaw {
|
||||
pub struct LightRaw {
|
||||
proj: [[f32; 4]; 4],
|
||||
pos: [f32; 4],
|
||||
color: [f32; 4],
|
||||
@@ -32,7 +33,7 @@ impl Light {
|
||||
near: self.depth.start,
|
||||
far: self.depth.end,
|
||||
};
|
||||
let mx_correction = framework::OPENGL_TO_WGPU_MATRIX;
|
||||
let mx_correction = OPENGL_TO_WGPU_MATRIX;
|
||||
let mx_view_proj =
|
||||
mx_correction * cgmath::Matrix4::from(projection.to_perspective()) * mx_view;
|
||||
LightRaw {
|
||||
|
||||
18
src/main.rs
18
src/main.rs
@@ -13,6 +13,7 @@ use winit::{
|
||||
event::{self, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
};
|
||||
use crate::render::Renderer;
|
||||
|
||||
mod framework;
|
||||
mod geometry;
|
||||
@@ -130,8 +131,9 @@ fn main() {
|
||||
.await
|
||||
.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();
|
||||
assert!(
|
||||
adapter_features.contains(required_features),
|
||||
@@ -139,7 +141,7 @@ fn main() {
|
||||
required_features - adapter_features
|
||||
);
|
||||
|
||||
let needed_limits = E::required_limits();
|
||||
let needed_limits = wgpu::Limits::default();//Renderer::required_limits();
|
||||
|
||||
// Maybe for debug tracing???
|
||||
let trace_dir = std::env::var("WGPU_TRACE");
|
||||
@@ -196,7 +198,7 @@ fn main() {
|
||||
WebSpawner {}
|
||||
};*/
|
||||
|
||||
// Swapchain has a prototype dealio
|
||||
|
||||
let mut sc_desc = wgpu::SwapChainDescriptor {
|
||||
// Allows a texture to be a output attachment of a renderpass.
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
@@ -224,6 +226,8 @@ fn main() {
|
||||
|
||||
log::info!("Entering render loop...");
|
||||
|
||||
let mut renderer = render::Renderer::init();
|
||||
|
||||
|
||||
// This is just an winit event loop
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
@@ -271,7 +275,7 @@ fn main() {
|
||||
sc_desc.width = size.width;
|
||||
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);
|
||||
}
|
||||
@@ -289,7 +293,7 @@ fn main() {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {
|
||||
example.update(event);
|
||||
renderer.update(event);
|
||||
}
|
||||
},
|
||||
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::__core::mem;
|
||||
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)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct ForwardUniforms {
|
||||
pub struct ForwardUniforms {
|
||||
proj: [[f32; 4]; 4],
|
||||
num_lights: [u32; 4],
|
||||
}
|
||||
@@ -17,7 +20,7 @@ unsafe impl Zeroable for ForwardUniforms {}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct EntityUniforms {
|
||||
pub struct EntityUniforms {
|
||||
model: [[f32; 4]; 4],
|
||||
color: [f32; 4],
|
||||
}
|
||||
@@ -27,17 +30,16 @@ unsafe impl Pod for EntityUniforms {}
|
||||
unsafe impl Zeroable for EntityUniforms {}
|
||||
|
||||
#[repr(C)]
|
||||
struct ShadowUniforms {
|
||||
pub struct ShadowUniforms {
|
||||
proj: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
struct Pass {
|
||||
pub struct Pass {
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
bind_group: wgpu::BindGroup,
|
||||
uniform_buf: wgpu::Buffer,
|
||||
}
|
||||
|
||||
|
||||
pub struct Renderer {
|
||||
lights_are_dirty: bool,
|
||||
shadow_pass: Pass,
|
||||
@@ -63,7 +65,7 @@ impl Renderer {
|
||||
cgmath::Point3::new(0f32, 0.0, 0.0),
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
let light_uniform_size =
|
||||
@@ -133,6 +135,7 @@ impl Renderer {
|
||||
// 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
|
||||
// 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 vb_desc = wgpu::VertexBufferDescriptor {
|
||||
stride: vertex_size as wgpu::BufferAddress,
|
||||
@@ -140,6 +143,24 @@ impl Renderer {
|
||||
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
|
||||
Need to open this up in renderdoc and see what it's actually doing
|
||||
@@ -147,7 +168,8 @@ impl Renderer {
|
||||
|
||||
let shadow_pass = {
|
||||
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 =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
@@ -161,12 +183,15 @@ impl Renderer {
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
|
||||
// Pipeline is similar between passes, but with a different label
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("shadow"),
|
||||
bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
// Holds the shadow uniforms, which is just a 4 vec of quaternians
|
||||
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: uniform_size,
|
||||
@@ -276,6 +301,7 @@ impl Renderer {
|
||||
],
|
||||
label: None,
|
||||
});
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("main"),
|
||||
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 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 {
|
||||
mx_world: cgmath::Matrix4<f32>,
|
||||
rotation_speed: f32,
|
||||
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_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,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -27,8 +37,31 @@ impl Runtime {
|
||||
{
|
||||
|
||||
// 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
|
||||
let local_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
||||
Reference in New Issue
Block a user