master
mitchellhansen 4 years ago
parent 77dcf1faf9
commit 9ebaece426

File diff suppressed because it is too large Load Diff

@ -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

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 {

@ -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 {

Loading…
Cancel
Save