Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add visual debugging for entities #193

Merged
merged 1 commit into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion korangar/src/graphics/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ struct EngineContext {
#[cfg(feature = "debug")]
forward_circle_drawer: ForwardCircleDrawer,
#[cfg(feature = "debug")]
forward_rectangle_drawer: ForwardRectangleDrawer,
#[cfg(feature = "debug")]
post_processing_buffer_drawer: PostProcessingBufferDrawer,
#[cfg(feature = "debug")]
picker_marker_drawer: PickerMarkerDrawer,
Expand Down Expand Up @@ -288,9 +290,10 @@ impl GraphicsEngine {

#[cfg(feature = "debug")]
forward_aabb_drawer,

#[cfg(feature = "debug")]
forward_circle_drawer,
#[cfg(feature = "debug")]
forward_rectangle_drawer,
} = ForwardResources::create(
&self.capabilities,
&self.device,
Expand Down Expand Up @@ -371,6 +374,8 @@ impl GraphicsEngine {
#[cfg(feature = "debug")]
forward_circle_drawer,
#[cfg(feature = "debug")]
forward_rectangle_drawer,
#[cfg(feature = "debug")]
post_processing_buffer_drawer,
#[cfg(feature = "debug")]
picker_marker_drawer,
Expand Down Expand Up @@ -488,6 +493,8 @@ impl GraphicsEngine {
forward_aabb_drawer,
#[cfg(feature = "debug")]
forward_circle_drawer,
#[cfg(feature = "debug")]
forward_rectangle_drawer,
} = ForwardResources::create(
&self.capabilities,
&self.device,
Expand Down Expand Up @@ -531,6 +538,7 @@ impl GraphicsEngine {
{
engine_context.forward_aabb_drawer = forward_aabb_drawer;
engine_context.forward_circle_drawer = forward_circle_drawer;
engine_context.forward_rectangle_drawer = forward_rectangle_drawer;
engine_context.post_processing_buffer_drawer = post_processing_buffer_drawer;
}
}
Expand Down Expand Up @@ -776,6 +784,7 @@ impl GraphicsEngine {
scope.spawn(|_| {
context.post_processing_buffer_drawer.prepare(&self.device, instruction);
context.forward_circle_drawer.prepare(&self.device, instruction);
context.forward_rectangle_drawer.prepare(&self.device, instruction);
});

context.global_context.prepare(&self.device, instruction);
Expand Down Expand Up @@ -812,6 +821,7 @@ impl GraphicsEngine {
visitor.upload(&mut context.forward_aabb_drawer);
visitor.upload(&mut context.post_processing_buffer_drawer);
visitor.upload(&mut context.forward_circle_drawer);
visitor.upload(&mut context.forward_rectangle_drawer);
visitor.upload(&mut context.picker_marker_drawer);
}

Expand Down Expand Up @@ -1000,6 +1010,7 @@ impl GraphicsEngine {
{
engine_context.forward_aabb_drawer.draw(&mut render_pass, None);
engine_context.forward_circle_drawer.draw(&mut render_pass, None);
engine_context.forward_rectangle_drawer.draw(&mut render_pass, None);
}

if instruction.water.is_some() {
Expand Down Expand Up @@ -1177,6 +1188,8 @@ struct ForwardResources {
forward_aabb_drawer: ForwardAabbDrawer,
#[cfg(feature = "debug")]
forward_circle_drawer: ForwardCircleDrawer,
#[cfg(feature = "debug")]
forward_rectangle_drawer: ForwardRectangleDrawer,
}

impl ForwardResources {
Expand All @@ -1194,6 +1207,8 @@ impl ForwardResources {
let forward_aabb_drawer = ForwardAabbDrawer::new(capabilities, device, queue, global_context, forward_pass_context);
#[cfg(feature = "debug")]
let forward_circle_drawer = ForwardCircleDrawer::new(capabilities, device, queue, global_context, forward_pass_context);
#[cfg(feature = "debug")]
let forward_rectangle_drawer = ForwardRectangleDrawer::new(capabilities, device, queue, global_context, forward_pass_context);

Self {
forward_entity_drawer,
Expand All @@ -1203,6 +1218,8 @@ impl ForwardResources {
forward_aabb_drawer,
#[cfg(feature = "debug")]
forward_circle_drawer,
#[cfg(feature = "debug")]
forward_rectangle_drawer,
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions korangar/src/graphics/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub struct RenderInstruction<'a> {
#[cfg(feature = "debug")]
pub circles: &'a [DebugCircleInstruction],
#[cfg(feature = "debug")]
pub rectangles: &'a [DebugRectangleInstruction],
#[cfg(feature = "debug")]
pub marker: &'a [MarkerInstruction],
}

Expand Down Expand Up @@ -238,3 +240,10 @@ pub struct DebugCircleInstruction {
pub screen_position: ScreenPosition,
pub screen_size: ScreenSize,
}

#[cfg(feature = "debug")]
#[derive(Copy, Clone, Debug)]
pub struct DebugRectangleInstruction {
pub world: Matrix4<f32>,
pub color: Color,
}
2 changes: 1 addition & 1 deletion korangar/src/graphics/passes/forward/aabb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl Prepare for ForwardAabbDrawer {
for instruction in instructions.aabb.iter() {
self.instance_data.push(InstanceData {
world: instruction.world.into(),
color: instruction.color.into(),
color: instruction.color.components_linear(),
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/graphics/passes/forward/circle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl Prepare for ForwardCircleDrawer {
for instruction in instructions.circles.iter() {
self.instance_data.push(InstanceData {
position: instruction.position.to_homogeneous().into(),
color: instruction.color.into(),
color: instruction.color.components_linear(),
screen_position: instruction.screen_position.into(),
screen_size: instruction.screen_size.into(),
});
Expand Down
4 changes: 4 additions & 0 deletions korangar/src/graphics/passes/forward/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ mod circle;
mod entity;
mod indicator;
mod model;
#[cfg(feature = "debug")]
mod rectangle;

#[cfg(feature = "debug")]
pub(crate) use aabb::ForwardAabbDrawer;
Expand All @@ -13,6 +15,8 @@ pub(crate) use circle::ForwardCircleDrawer;
pub(crate) use entity::ForwardEntityDrawer;
pub(crate) use indicator::ForwardIndicatorDrawer;
pub(crate) use model::ForwardModelDrawer;
#[cfg(feature = "debug")]
pub(crate) use rectangle::ForwardRectangleDrawer;
use wgpu::{
BindGroupLayout, Color, CommandEncoder, Device, LoadOp, Operations, Queue, RenderPass, RenderPassColorAttachment,
RenderPassDepthStencilAttachment, RenderPassDescriptor, StoreOp, TextureFormat,
Expand Down
216 changes: 216 additions & 0 deletions korangar/src/graphics/passes/forward/rectangle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
use std::num::NonZeroU64;

use bytemuck::{Pod, Zeroable};
use cgmath::Point3;
use wgpu::util::StagingBelt;
use wgpu::{
include_wgsl, BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
BindingType, BufferBindingType, BufferUsages, ColorTargetState, ColorWrites, CommandEncoder, CompareFunction, DepthBiasState,
DepthStencilState, Device, FragmentState, IndexFormat, MultisampleState, PipelineCompilationOptions, PipelineLayoutDescriptor,
PrimitiveState, PrimitiveTopology, Queue, RenderPass, RenderPipeline, RenderPipelineDescriptor, ShaderModuleDescriptor, ShaderStages,
StencilState, VertexState,
};

use crate::graphics::passes::{
BindGroupCount, ColorAttachmentCount, DepthAttachmentCount, Drawer, ForwardRenderPassContext, RenderPassContext,
};
use crate::graphics::{Capabilities, GlobalContext, Prepare, RenderInstruction, SimpleVertex};
use crate::Buffer;

const SHADER: ShaderModuleDescriptor = include_wgsl!("shader/rectangle.wgsl");
const DRAWER_NAME: &str = "screen rectangle";
const INITIAL_INSTRUCTION_SIZE: usize = 256;
const INDEX_COUNT: usize = 8;

#[derive(Copy, Clone, Pod, Zeroable)]
#[repr(C)]
struct InstanceData {
world: [[f32; 4]; 4],
color: [f32; 4],
}

pub(crate) struct ForwardRectangleDrawer {
vertex_buffer: Buffer<SimpleVertex>,
index_buffer: Buffer<u16>,
instance_data_buffer: Buffer<InstanceData>,
bind_group_layout: BindGroupLayout,
bind_group: BindGroup,
pipeline: RenderPipeline,
draw_count: usize,
instance_data: Vec<InstanceData>,
}

impl Drawer<{ BindGroupCount::Two }, { ColorAttachmentCount::One }, { DepthAttachmentCount::One }> for ForwardRectangleDrawer {
type Context = ForwardRenderPassContext;
type DrawData<'data> = Option<()>;

fn new(
_capabilities: &Capabilities,
device: &Device,
queue: &Queue,
global_context: &GlobalContext,
render_pass_context: &Self::Context,
) -> Self {
let shader_module = device.create_shader_module(SHADER);

// Vertices are defined in world coordinates (Same as WGPU's NDC).
let vertex_data = [
SimpleVertex::new(Point3::new(-1.0, 0.0, 1.0)),
SimpleVertex::new(Point3::new(-1.0, 2.0, 1.0)),
SimpleVertex::new(Point3::new(1.0, 0.0, 1.0)),
SimpleVertex::new(Point3::new(1.0, 2.0, 1.0)),
];

let index_data: [u16; INDEX_COUNT] = [0, 1, 2, 3, 1, 3, 0, 2];

let vertex_buffer = Buffer::with_data(
device,
queue,
format!("{DRAWER_NAME} box vertex"),
BufferUsages::VERTEX | BufferUsages::COPY_DST,
&vertex_data,
);

let index_buffer = Buffer::with_data(
device,
queue,
format!("{DRAWER_NAME} box index"),
BufferUsages::INDEX | BufferUsages::COPY_DST,
&index_data,
);

let instance_data_buffer = Buffer::with_capacity(
device,
format!("{DRAWER_NAME} instance data"),
BufferUsages::COPY_DST | BufferUsages::STORAGE,
(size_of::<InstanceData>() * INITIAL_INSTRUCTION_SIZE) as _,
);

let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
label: Some(DRAWER_NAME),
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStages::VERTEX_FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Storage { read_only: true },
has_dynamic_offset: false,
min_binding_size: NonZeroU64::new(size_of::<InstanceData>() as _),
},
count: None,
}],
});

let bind_group = Self::create_bind_group(device, &bind_group_layout, &instance_data_buffer);

let bind_group_layouts = Self::Context::bind_group_layout(device);

let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
label: Some(DRAWER_NAME),
bind_group_layouts: &[bind_group_layouts[0], bind_group_layouts[1], &bind_group_layout],
push_constant_ranges: &[],
});

let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
label: Some(DRAWER_NAME),
layout: Some(&pipeline_layout),
vertex: VertexState {
module: &shader_module,
entry_point: Some("vs_main"),
compilation_options: PipelineCompilationOptions::default(),
buffers: &[SimpleVertex::buffer_layout()],
},
fragment: Some(FragmentState {
module: &shader_module,
entry_point: Some("fs_main"),
compilation_options: PipelineCompilationOptions::default(),
targets: &[Some(ColorTargetState {
format: render_pass_context.color_attachment_formats()[0],
blend: None,
write_mask: ColorWrites::default(),
})],
}),
multiview: None,
primitive: PrimitiveState {
topology: PrimitiveTopology::LineList,
..Default::default()
},
depth_stencil: Some(DepthStencilState {
format: render_pass_context.depth_attachment_output_format()[0],
depth_write_enabled: false,
depth_compare: CompareFunction::Always,
stencil: StencilState::default(),
bias: DepthBiasState::default(),
}),
multisample: MultisampleState {
count: global_context.msaa.sample_count(),
..Default::default()
},
cache: None,
});

Self {
vertex_buffer,
index_buffer,
instance_data_buffer,
bind_group_layout,
bind_group,
pipeline,
draw_count: 0,
instance_data: Vec::default(),
}
}

fn draw(&mut self, pass: &mut RenderPass<'_>, _draw_data: Self::DrawData<'_>) {
if self.draw_count == 0 {
return;
}

pass.set_pipeline(&self.pipeline);
pass.set_bind_group(2, &self.bind_group, &[]);
pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
pass.set_index_buffer(self.index_buffer.slice(..), IndexFormat::Uint16);
pass.draw_indexed(0..INDEX_COUNT as u32, 0, 0..self.draw_count as u32);
}
}

impl Prepare for ForwardRectangleDrawer {
fn prepare(&mut self, _device: &Device, instructions: &RenderInstruction) {
self.draw_count = instructions.rectangles.len();

if self.draw_count == 0 {
return;
}

self.instance_data.clear();

for instruction in instructions.rectangles.iter() {
self.instance_data.push(InstanceData {
world: instruction.world.into(),
color: instruction.color.components_linear(),
});
}
}

fn upload(&mut self, device: &Device, staging_belt: &mut StagingBelt, command_encoder: &mut CommandEncoder) {
let recreated = self
.instance_data_buffer
.write(device, staging_belt, command_encoder, &self.instance_data);

if recreated {
self.bind_group = Self::create_bind_group(device, &self.bind_group_layout, &self.instance_data_buffer);
}
}
}

impl ForwardRectangleDrawer {
fn create_bind_group(device: &Device, bind_group_layout: &BindGroupLayout, instance_data_buffer: &Buffer<InstanceData>) -> BindGroup {
device.create_bind_group(&BindGroupDescriptor {
label: Some(DRAWER_NAME),
layout: bind_group_layout,
entries: &[BindGroupEntry {
binding: 0,
resource: instance_data_buffer.as_entire_binding(),
}],
})
}
}
Loading
Loading