debug rendering
This commit is contained in:
@@ -1,16 +1,18 @@
|
||||
mod bind_group;
|
||||
mod debug_overlay;
|
||||
mod pipeline;
|
||||
mod shadow;
|
||||
mod types;
|
||||
|
||||
pub use types::{DrawCall, Pipeline, Spotlight, SpotlightRaw, Uniforms, MAX_SPOTLIGHTS};
|
||||
|
||||
use crate::debug::DebugMode;
|
||||
use crate::postprocess::{create_blit_pipeline, create_fullscreen_quad, LowResFramebuffer};
|
||||
use crate::texture::{DitherTextures, FlowmapTexture};
|
||||
use pipeline::{create_debug_lines_pipeline, create_main_pipeline, create_snow_clipmap_pipeline,
|
||||
create_wireframe_pipeline};
|
||||
use std::cell::RefCell;
|
||||
|
||||
use pipeline::{create_main_pipeline, create_snow_clipmap_pipeline};
|
||||
|
||||
pub struct Renderer
|
||||
{
|
||||
pub device: wgpu::Device,
|
||||
@@ -22,6 +24,10 @@ pub struct Renderer
|
||||
|
||||
standard_pipeline: wgpu::RenderPipeline,
|
||||
snow_clipmap_pipeline: wgpu::RenderPipeline,
|
||||
wireframe_pipeline: Option<wgpu::RenderPipeline>,
|
||||
debug_lines_pipeline: Option<wgpu::RenderPipeline>,
|
||||
debug_overlay: Option<debug_overlay::DebugOverlay>,
|
||||
wireframe_supported: bool,
|
||||
|
||||
uniform_buffer: wgpu::Buffer,
|
||||
bind_group_layout: wgpu::BindGroupLayout,
|
||||
@@ -84,8 +90,21 @@ impl Renderer
|
||||
.await
|
||||
.map_err(|_| "Failed to find adapter")?;
|
||||
|
||||
let wireframe_supported =
|
||||
adapter.features().contains(wgpu::Features::POLYGON_MODE_LINE);
|
||||
let required_features = if wireframe_supported
|
||||
{
|
||||
wgpu::Features::POLYGON_MODE_LINE
|
||||
}
|
||||
else
|
||||
{
|
||||
wgpu::Features::empty()
|
||||
};
|
||||
let (device, queue) = adapter
|
||||
.request_device(&wgpu::DeviceDescriptor::default())
|
||||
.request_device(&wgpu::DeviceDescriptor {
|
||||
required_features,
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
let size = window.size();
|
||||
@@ -442,6 +461,20 @@ impl Renderer
|
||||
|
||||
let blit_pipeline = create_blit_pipeline(&device, config.format, &blit_bind_group_layout);
|
||||
|
||||
let wireframe_pipeline = if wireframe_supported
|
||||
{
|
||||
Some(create_wireframe_pipeline(&device, config.format, &bind_group_layout))
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
};
|
||||
|
||||
let debug_lines_pipeline =
|
||||
Some(create_debug_lines_pipeline(&device, config.format, &bind_group_layout));
|
||||
|
||||
let debug_overlay = Some(debug_overlay::DebugOverlay::new(&device, config.format));
|
||||
|
||||
let shadow_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Shadow Bind Group Layout"),
|
||||
@@ -465,6 +498,10 @@ impl Renderer
|
||||
framebuffer,
|
||||
standard_pipeline,
|
||||
snow_clipmap_pipeline,
|
||||
wireframe_pipeline,
|
||||
debug_lines_pipeline,
|
||||
debug_overlay,
|
||||
wireframe_supported,
|
||||
uniform_buffer,
|
||||
bind_group_layout,
|
||||
bind_group,
|
||||
@@ -508,6 +545,7 @@ impl Renderer
|
||||
draw_calls: &[DrawCall],
|
||||
time: f32,
|
||||
delta_time: f32,
|
||||
debug_mode: DebugMode,
|
||||
)
|
||||
{
|
||||
let light_view_projections = self.calculate_light_view_projections();
|
||||
@@ -563,6 +601,7 @@ impl Renderer
|
||||
draw_call.enable_dissolve,
|
||||
draw_call.enable_snow_light,
|
||||
&self.spotlights,
|
||||
debug_mode.as_u32(),
|
||||
);
|
||||
self.queue
|
||||
.write_buffer(&self.uniform_buffer, 0, bytemuck::cast_slice(&[uniforms]));
|
||||
@@ -614,6 +653,10 @@ impl Renderer
|
||||
{
|
||||
Pipeline::Standard => &self.standard_pipeline,
|
||||
Pipeline::SnowClipmap => &self.snow_clipmap_pipeline,
|
||||
Pipeline::DebugLines => self
|
||||
.debug_lines_pipeline
|
||||
.as_ref()
|
||||
.unwrap_or(&self.standard_pipeline),
|
||||
};
|
||||
render_pass.set_pipeline(pipeline);
|
||||
render_pass.set_bind_group(0, &self.bind_group, &[]);
|
||||
@@ -636,6 +679,138 @@ impl Renderer
|
||||
}
|
||||
}
|
||||
|
||||
if debug_mode == DebugMode::Wireframe
|
||||
{
|
||||
if let Some(ref wireframe_pipeline) = self.wireframe_pipeline
|
||||
{
|
||||
for draw_call in draw_calls.iter()
|
||||
{
|
||||
if matches!(draw_call.pipeline, Pipeline::SnowClipmap | Pipeline::DebugLines)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let uniforms = Uniforms::new(
|
||||
draw_call.model,
|
||||
*view,
|
||||
*projection,
|
||||
&light_view_projections,
|
||||
camera_position,
|
||||
player_position,
|
||||
self.terrain_height_scale,
|
||||
time,
|
||||
self.shadow_bias,
|
||||
draw_call.tile_scale,
|
||||
draw_call.enable_dissolve,
|
||||
draw_call.enable_snow_light,
|
||||
&self.spotlights,
|
||||
4,
|
||||
);
|
||||
self.queue.write_buffer(
|
||||
&self.uniform_buffer,
|
||||
0,
|
||||
bytemuck::cast_slice(&[uniforms]),
|
||||
);
|
||||
|
||||
{
|
||||
let mut wire_pass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Wireframe Pass"),
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &self.framebuffer.view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
depth_slice: None,
|
||||
})],
|
||||
depth_stencil_attachment: Some(
|
||||
wgpu::RenderPassDepthStencilAttachment {
|
||||
view: &self.framebuffer.depth_view,
|
||||
depth_ops: Some(wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: wgpu::StoreOp::Store,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
},
|
||||
),
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
|
||||
wire_pass.set_pipeline(wireframe_pipeline);
|
||||
wire_pass.set_bind_group(0, &self.bind_group, &[]);
|
||||
wire_pass.set_vertex_buffer(0, draw_call.vertex_buffer.slice(..));
|
||||
|
||||
if let Some(ref instance_buffer) = draw_call.instance_buffer
|
||||
{
|
||||
wire_pass.set_vertex_buffer(1, instance_buffer.slice(..));
|
||||
}
|
||||
|
||||
wire_pass.set_index_buffer(
|
||||
draw_call.index_buffer.slice(..),
|
||||
wgpu::IndexFormat::Uint32,
|
||||
);
|
||||
wire_pass.draw_indexed(
|
||||
0..draw_call.num_indices,
|
||||
0,
|
||||
0..draw_call.num_instances,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if debug_mode == DebugMode::ShadowMap
|
||||
{
|
||||
if let Some(ref overlay) = self.debug_overlay
|
||||
{
|
||||
let shadow_view = &self.shadow_map_view;
|
||||
let framebuffer_view = &self.framebuffer.view;
|
||||
let quad_vb = &self.quad_vb;
|
||||
let quad_ib = &self.quad_ib;
|
||||
let quad_num = self.quad_num_indices;
|
||||
let device = &self.device;
|
||||
overlay.render_shadow_map(
|
||||
&mut encoder,
|
||||
framebuffer_view,
|
||||
shadow_view,
|
||||
quad_vb,
|
||||
quad_ib,
|
||||
quad_num,
|
||||
device,
|
||||
);
|
||||
}
|
||||
}
|
||||
else if debug_mode == DebugMode::SnowLight
|
||||
{
|
||||
if let Some(ref overlay) = self.debug_overlay
|
||||
{
|
||||
let snow_light_view = self
|
||||
.snow_light_accumulation
|
||||
.as_ref()
|
||||
.map(|s| s.read_view())
|
||||
.unwrap_or(&self.dummy_snow_light_view);
|
||||
let framebuffer_view = &self.framebuffer.view;
|
||||
let quad_vb = &self.quad_vb;
|
||||
let quad_ib = &self.quad_ib;
|
||||
let quad_num = self.quad_num_indices;
|
||||
let device = &self.device;
|
||||
let sampler = &self.dummy_snow_light_sampler;
|
||||
overlay.render_snow_light(
|
||||
&mut encoder,
|
||||
framebuffer_view,
|
||||
snow_light_view,
|
||||
sampler,
|
||||
quad_vb,
|
||||
quad_ib,
|
||||
quad_num,
|
||||
device,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.queue.submit(std::iter::once(encoder.finish()));
|
||||
|
||||
let frame = match self.surface.get_current_texture()
|
||||
@@ -849,6 +1024,7 @@ pub fn render(
|
||||
draw_calls: &[DrawCall],
|
||||
time: f32,
|
||||
delta_time: f32,
|
||||
debug_mode: DebugMode,
|
||||
)
|
||||
{
|
||||
GLOBAL_RENDERER.with(|r| {
|
||||
@@ -862,6 +1038,7 @@ pub fn render(
|
||||
draw_calls,
|
||||
time,
|
||||
delta_time,
|
||||
debug_mode,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user