Particles compiles and runs (no visuals yet)

This commit is contained in:
Imbris 2020-12-05 17:04:29 -05:00 committed by Avi Weinstock
parent b4df7e63e8
commit 0b9e1fdf6c
11 changed files with 98 additions and 147 deletions

View File

@ -40,7 +40,13 @@ pub use self::{
},
GlobalModel, Globals, GlobalsBindGroup, GlobalsLayouts, Light, Shadow,
},
renderer::{ColLightInfo, Drawer, Renderer, UiDrawer},
renderer::{
drawer::{
Drawer, FirstPassDrawer, ParticleDrawer, PreparedUiDrawer, SecondPassDrawer,
ThirdPassDrawer, UiDrawer,
},
ColLightInfo, Renderer,
},
texture::Texture,
};
pub use wgpu::{AddressMode, FilterMode};

View File

@ -25,45 +25,6 @@ impl Locals {
}
}
/*#[repr(C)]
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
pub struct Vertex {
pos: [f32; 2],
}
impl Vertex {
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
use std::mem;
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 1] =
wgpu::vertex_attr_array![0 => Float2];
wgpu::VertexBufferDescriptor {
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
}
pub fn create_mesh() -> Mesh<Vertex> {
let mut mesh = Mesh::new();
#[rustfmt::skip]
mesh.push_tri(Tri::new(
Vertex { pos: [ 1.0, -1.0] },
Vertex { pos: [-1.0, 1.0] },
Vertex { pos: [-1.0, -1.0] },
));
#[rustfmt::skip]
mesh.push_tri(Tri::new(
Vertex { pos: [1.0, -1.0] },
Vertex { pos: [1.0, 1.0] },
Vertex { pos: [-1.0, 1.0] },
));
mesh
}*/
pub struct BindGroup {
pub(in super::super) bind_group: wgpu::BindGroup,
}
@ -92,7 +53,10 @@ impl CloudsLayout {
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { filtering: true, comparison: false },
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
count: None,
},
// Depth source
@ -109,7 +73,10 @@ impl CloudsLayout {
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { filtering: true, comparison: false },
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
count: None,
},
// Locals

View File

@ -349,7 +349,7 @@ impl GlobalsLayouts {
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
view_dimension: wgpu::TextureViewDimension::Cube,
multisampled: false,
},
count: None,

View File

@ -174,7 +174,6 @@ impl ParticlePipeline {
device: &wgpu::Device,
vs_module: &wgpu::ShaderModule,
fs_module: &wgpu::ShaderModule,
sc_desc: &wgpu::SwapChainDescriptor,
global_layout: &GlobalsLayouts,
aa_mode: AaMode,
) -> Self {
@ -216,7 +215,8 @@ impl ParticlePipeline {
}),
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[wgpu::ColorStateDescriptor {
format: sc_desc.format,
// TODO pass this format in or make it a const
format: wgpu::TextureFormat::Rgba8UnormSrgb,
color_blend: wgpu::BlendDescriptor {
src_factor: wgpu::BlendFactor::SrcAlpha,
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,

View File

@ -22,45 +22,6 @@ impl Locals {
}
}
/*#[repr(C)]
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
pub struct Vertex {
pub pos: [f32; 2],
}
impl Vertex {
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
use std::mem;
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 1] =
wgpu::vertex_attr_array![0 => Float2];
wgpu::VertexBufferDescriptor {
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
}
pub fn create_mesh() -> Mesh<Vertex> {
let mut mesh = Mesh::new();
#[rustfmt::skip]
mesh.push_tri(Tri::new(
Vertex { pos: [ 1.0, -1.0] },
Vertex { pos: [-1.0, 1.0] },
Vertex { pos: [-1.0, -1.0] },
));
#[rustfmt::skip]
mesh.push_tri(Tri::new(
Vertex { pos: [1.0, -1.0] },
Vertex { pos: [1.0, 1.0] },
Vertex { pos: [-1.0, 1.0] },
));
mesh
}*/
pub struct BindGroup {
pub(in super::super) bind_group: wgpu::BindGroup,
}
@ -89,7 +50,10 @@ impl PostProcessLayout {
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { filtering: true, comparison: false },
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
count: None,
},
// Locals

View File

@ -1,7 +1,5 @@
mod binding;
mod drawer;
pub use drawer::{Drawer, UiDrawer};
pub(super) mod drawer;
use super::{
consts::Consts,
@ -172,12 +170,10 @@ impl Locals {
sampler,
&clouds_locals,
);
let postprocess_bind = layouts.postprocess.bind(
device,
tgt_color_pp_view,
sampler,
&postprocess_locals,
);
let postprocess_bind =
layouts
.postprocess
.bind(device, tgt_color_pp_view, sampler, &postprocess_locals);
Self {
clouds: clouds_locals,
@ -203,12 +199,10 @@ impl Locals {
sampler,
&self.clouds,
);
self.postprocess_bind = layouts.postprocess.bind(
device,
tgt_color_pp_view,
sampler,
&self.postprocess,
);
self.postprocess_bind =
layouts
.postprocess
.bind(device, tgt_color_pp_view, sampler, &self.postprocess);
}
}
@ -920,7 +914,7 @@ impl Renderer {
pub fn start_recording_frame<'a>(
&'a mut self,
globals: &'a GlobalsBindGroup,
) -> Result<Option<Drawer<'a>>, RenderError> {
) -> Result<Option<drawer::Drawer<'a>>, RenderError> {
span!(
_guard,
"start_recording_frame",
@ -958,7 +952,7 @@ impl Renderer {
label: Some("A render encoder"),
});
Ok(Some(Drawer::new(encoder, self, tex, globals)))
Ok(Some(drawer::Drawer::new(encoder, self, tex, globals)))
}
/// Recreate the pipelines
@ -2134,7 +2128,6 @@ fn create_pipelines(
device,
&create_shader("particle-vert", ShaderKind::Vertex)?,
&create_shader("particle-frag", ShaderKind::Fragment)?,
sc_desc,
&layouts.global,
mode.aa,
);

View File

@ -5,8 +5,8 @@ use super::{
instances::Instances,
model::{DynamicModel, Model},
pipelines::{
clouds, figure, fluid, postprocess, sprite, terrain, ui, GlobalsBindGroup, Light,
Shadow,
clouds, figure, fluid, particle, postprocess, sprite, terrain, ui, GlobalsBindGroup,
Light, Shadow,
},
},
Renderer,
@ -19,7 +19,6 @@ pub struct Drawer<'a> {
renderer: &'a mut Renderer,
tex: wgpu::SwapChainTexture,
globals: &'a GlobalsBindGroup,
//pub(super) postprocess_locals: wgpu::BindGroup,
}
impl<'a> Drawer<'a> {
@ -111,7 +110,7 @@ impl<'a> Drawer<'a> {
},
}],
// TODO: do we need this?
depth_stencil_attachment: None
depth_stencil_attachment: None,
});
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
@ -231,6 +230,36 @@ impl<'a> FirstPassDrawer<'a> {
self.render_pass.set_vertex_buffer(1, &instances.ibuf, 0, 0);
self.render_pass.draw(verts, 0..instances.count() as u32);
}*/
pub fn draw_particles<'c>(&'c mut self) -> ParticleDrawer<'c, 'a> {
self.render_pass
.set_pipeline(&self.renderer.particle_pipeline.pipeline);
ParticleDrawer {
render_pass: &mut self.render_pass,
}
}
}
pub struct ParticleDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
}
impl<'pass_ref, 'pass: 'pass_ref> ParticleDrawer<'pass_ref, 'pass> {
// Note: if we ever need to draw less than the whole model, this api can be
// changed
pub fn draw<'data: 'pass>(
&mut self,
model: &'data Model<particle::Vertex>,
instances: &'data Instances<particle::Instance>,
) {
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
self.render_pass
.set_vertex_buffer(1, instances.buf().slice(..));
self.render_pass
// TODO: since we cast to u32 maybe this should returned by the len/count functions?
.draw(0..model.len() as u32, 0..instances.count() as u32);
}
}
pub struct SecondPassDrawer<'a> {
@ -262,7 +291,7 @@ impl<'a> ThirdPassDrawer<'a> {
self.render_pass.draw(0..3, 0..1);
}
pub fn draw_ui<'c>(&'c mut self) -> UiDrawer<'c, 'a> {
pub fn draw_ui(&mut self) -> UiDrawer<'_, 'a> {
self.render_pass
.set_pipeline(&self.renderer.ui_pipeline.pipeline);

View File

@ -136,7 +136,7 @@ impl Camera {
self.dependents.view_mat_inv = self.dependents.view_mat.inverted();
self.dependents.proj_mat =
Mat4::perspective_rh_no(self.fov, self.aspect, NEAR_PLANE, FAR_PLANE);
Mat4::perspective_rh_zo(self.fov, self.aspect, NEAR_PLANE, FAR_PLANE);
self.dependents.proj_mat_inv = self.dependents.proj_mat.inverted();
// TODO: Make this more efficient.

View File

@ -16,8 +16,9 @@ pub use self::{
use crate::{
audio::{ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend},
render::{
create_skybox_mesh, CloudsLocals, Consts, GlobalModel, Globals, GlobalsBindGroup, Light,
Model, PostProcessLocals, Renderer, Shadow, ShadowLocals, SkyboxVertex,
create_skybox_mesh, CloudsLocals, Consts, FirstPassDrawer, GlobalModel, Globals,
GlobalsBindGroup, Light, Model, PostProcessLocals, Renderer, Shadow, ShadowLocals,
SkyboxVertex,
},
settings::Settings,
window::{AnalogGameInput, Event},
@ -976,9 +977,9 @@ impl Scene {
pub fn global_bind_group(&self) -> &GlobalsBindGroup { &self.globals_bind_group }
/// Render the scene using the provided `Renderer`.
pub fn render(
&mut self,
renderer: &mut Renderer,
pub fn render<'a>(
&'a self,
drawer: &mut FirstPassDrawer<'a>,
state: &State,
player_entity: EcsEntity,
tick: u64,
@ -995,7 +996,7 @@ impl Scene {
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
// would instead have this as an extension.
if renderer.render_mode().shadow.is_map() && (is_daylight || !light_data.1.is_empty()) {
/*if renderer.render_mode().shadow.is_map() && (is_daylight || !light_data.1.is_empty()) {
// if is_daylight {
// // Set up shadow mapping.
// renderer.start_shadows();
@ -1013,10 +1014,10 @@ impl Scene {
// // Flush shadows.
// renderer.flush_shadows();
// }
}
}*/
let lod = self.lod.get_data();
self.figure_mgr.render_player(
/*self.figure_mgr.render_player(
renderer,
state,
player_entity,
@ -1024,10 +1025,10 @@ impl Scene {
global,
lod,
camera_data,
);
);*/
// Render terrain and figures.
self.terrain.render(renderer, global, lod, focus_pos);
/*self.terrain.render(renderer, global, lod, focus_pos);
self.figure_mgr.render(
renderer,
@ -1038,21 +1039,22 @@ impl Scene {
lod,
camera_data,
);
self.lod.render(renderer, global);
self.lod.render(renderer, global);*/
// Render the skybox.
// TODO: renderer.render_skybox(&self.skybox.model, global, lod);
self.terrain.render_translucent(
/*self.terrain.render_translucent(
renderer,
global,
lod,
focus_pos,
cam_pos,
scene_data.sprite_render_distance,
);
);*/
// Render particle effects.
self.particle_mgr.render(renderer, scene_data, global, lod);
self.particle_mgr
.render(&mut drawer.draw_particles(), scene_data);
}
}

View File

@ -3,7 +3,7 @@ use crate::{
mesh::{greedy::GreedyMesh, segment::generate_mesh_base_vol_particle},
render::{
pipelines::particle::ParticleMode, GlobalModel, Instances, Light, LodData, Model,
ParticleInstance, ParticleVertex, Renderer,
ParticleDrawer, ParticleInstance, ParticleVertex, Renderer,
},
};
use common::{
@ -1178,13 +1178,7 @@ impl ParticleMgr {
self.instances = gpu_instances;
}
pub fn render(
&self,
renderer: &mut Renderer,
scene_data: &SceneData,
global: &GlobalModel,
lod: &LodData,
) {
pub fn render<'a>(&'a self, drawer: &mut ParticleDrawer<'_, 'a>, scene_data: &SceneData) {
span!(_guard, "render", "ParticleMgr::render");
if scene_data.particles_enabled {
let model = &self
@ -1192,8 +1186,7 @@ impl ParticleMgr {
.get(DEFAULT_MODEL_KEY)
.expect("Expected particle model in cache");
/* renderer.render_particles(model, global, &self.instances,
* lod); */
drawer.draw(model, &self.instances);
}
}

View File

@ -1387,7 +1387,16 @@ impl PlayState for SessionState {
/// This method should be called once per frame.
fn render(&mut self, renderer: &mut Renderer, settings: &Settings) {
span!(_guard, "render", "<Session as PlayState>::render");
// Render the screen using the global renderer
let mut drawer = match renderer
.start_recording_frame(self.scene.global_bind_group())
.unwrap()
{
Some(d) => d,
// Couldn't get swap chain texture this frame
None => return,
};
// Render world
{
let client = self.client.borrow();
@ -1410,7 +1419,7 @@ impl PlayState for SessionState {
is_aiming: self.is_aiming,
};
self.scene.render(
renderer,
&mut drawer.first_pass(),
client.state(),
client.entity(),
client.get_tick(),
@ -1418,18 +1427,6 @@ impl PlayState for SessionState {
);
}
let mut drawer = match renderer
.start_recording_frame(self.scene.global_bind_group())
.unwrap()
{
Some(d) => d,
// Couldn't get swap chain texture this frame
None => return,
};
// Render world
/* let mut first_pass = */
drawer.first_pass();
// Clouds
drawer.second_pass().draw_clouds();
// PostProcess and UI