Skip to content
Open
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
2 changes: 1 addition & 1 deletion crates/viewer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ examples = { path = "../../examples", default-features = false }
glam = { version = "0.24", features = ["bytemuck"] }
kicad-parser = { path = "../kicad-parser" }
opencascade = { version = "0.2", path = "../opencascade", default-features = false }
simple-game = { git = "https://github.com/bschwind/simple-game.git", rev = "651a57a9f28b0707afbb5a43fe1cbc8f6755169c", default-features = false }
simple-game = { git = "https://github.com/bschwind/simple-game.git", rev = "db993a9d4a2fce4a11f143a033142bb4f397b75c", default-features = false }
smaa = "0.12"
wgpu = "0.18"
winit = { version = "0.29", features = ["rwh_05"] }
Expand Down
22 changes: 22 additions & 0 deletions crates/viewer/shaders/clipping_plane.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
struct VertexInput {
@location(0)
pos: vec2<f32>,
};

struct VertexOutput {
@builtin(position)
pos: vec4<f32>,
};

@vertex
fn vs_main(input: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.pos = vec4<f32>(input.pos, 0.0, 1.0);

return out;
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return vec4<f32>(0.976, 0.384, 0.035, 1.0);
}
12 changes: 12 additions & 0 deletions crates/viewer/shaders/edge.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ struct VertexOutput {

@location(0)
dist: f32,

@location(1)
plane_distance: f32,
};

@vertex
Expand All @@ -46,6 +49,8 @@ fn main_vs(input: VertexInput) -> VertexOutput {
let clip0 = globals.proj * globals.transform * vec4<f32>(input.point_a.xyz, 1.0);
let clip1 = globals.proj * globals.transform * vec4<f32>(input.point_b.xyz, 1.0);

let interpolated_pos = vec4<f32>(mix(input.point_a.xyz, input.point_b.xyz, vec3<f32>(input.pos.z)), 1.0);

// Transform the segment endpoints to screen space
let a = globals.resolution.xy * (0.5 * clip0.xy / clip0.w + 0.5);
let b = globals.resolution.xy * (0.5 * clip1.xy / clip1.w + 0.5);
Expand All @@ -63,11 +68,18 @@ fn main_vs(input: VertexInput) -> VertexOutput {
out.pos = vec4<f32>(clip.w * ((2.0 * final_pos) / globals.resolution.xy - 1.0), clip.z, clip.w);
out.dist = mix(input.length_so_far_a.x, input.length_so_far_b.x, input.pos.z);

var plane = vec4<f32>(-1.0, 0.8, 1.2, 40.0);
out.plane_distance = dot(plane, interpolated_pos);

return out;
}

@fragment
fn main_fs(input: VertexOutput) -> @location(0) vec4<f32> {
if input.plane_distance > 0.0 {
discard;
}

let r = 0.0;
let g = 0.0;
let b = 0.0;
Expand Down
14 changes: 13 additions & 1 deletion crates/viewer/shaders/surface.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,32 @@ struct VertexOutput {

@location(1)
normal: vec3<f32>,

@location(2)
plane_distance: f32,
};

@vertex
fn vs_main(input: VertexInput) -> VertexOutput {
var out: VertexOutput;

var plane = vec4<f32>(-1.0, 0.8, 1.2, 40.0);

out.uv = input.uv;
out.normal = input.normal; // TODO(bschwind) - Need to transform this.
out.pos = globals.proj * globals.transform * vec4<f32>(input.pos, 1.0);
out.plane_distance = dot(plane, vec4<f32>(input.pos, 1.0));

return out;
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return vec4<f32>(1.0, 1.0, 1.0, 1.0);

if in.plane_distance > 0.0 {
discard;
}

//return vec4<f32>(1.0, 1.0, 1.0, 1.0);
return vec4<f32>(in.normal.x + 1.0 / 2.0, in.normal.y + 1.0 / 2.0, in.normal.z + 1.0 / 2.0, 1.0);
}
141 changes: 141 additions & 0 deletions crates/viewer/src/clipping_plane.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use crate::GraphicsDevice;
use bytemuck::{Pod, Zeroable};
use wgpu::util::DeviceExt;

#[repr(C)]
#[derive(Clone, Copy, Pod, Zeroable)]
struct ClippingPlaneVertex {
pos: [f32; 2],
}

#[cfg_attr(feature = "bevy", derive(crate::bevy::Resource))]
pub struct ClippingPlane {
vertex_buf: wgpu::Buffer,
index_buf: wgpu::Buffer,
bind_group: wgpu::BindGroup,
pipeline: wgpu::RenderPipeline,
}

impl ClippingPlane {
pub fn new(
device: &wgpu::Device,
target_format: wgpu::TextureFormat,
depth_format: wgpu::TextureFormat,
) -> Self {
let vertex_data = vec![
ClippingPlaneVertex { pos: [-1.0, -1.0] },
ClippingPlaneVertex { pos: [-1.0, 1.0] },
ClippingPlaneVertex { pos: [1.0, 1.0] },
ClippingPlaneVertex { pos: [1.0, -1.0] },
];

let index_data = vec![0u16, 1, 3, 2];

let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("ClippingPlane Vertex Buffer"),
contents: bytemuck::cast_slice(&vertex_data),
usage: wgpu::BufferUsages::VERTEX,
});

let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("ClippingPlane Index Buffer"),
contents: bytemuck::cast_slice(&index_data),
usage: wgpu::BufferUsages::INDEX,
});

let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("ClippingPlane bind group layout"),
entries: &[],
});

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("ClippingPlane pipeline layout"),
bind_group_layouts: &[&bind_group_layout],
push_constant_ranges: &[],
});

let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("ClippingPlane bind group"),
layout: &bind_group_layout,
entries: &[],
});

let vertex_buffers = &[wgpu::VertexBufferLayout {
array_stride: (std::mem::size_of::<ClippingPlaneVertex>()) as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &wgpu::vertex_attr_array![
0 => Float32x2, // pos
],
}];

let draw_shader = GraphicsDevice::load_wgsl_shader(
device,
include_str!("../shaders/clipping_plane.wgsl"),
);

let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("ClippingPlane render pipeline"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: &draw_shader,
entry_point: "vs_main",
buffers: vertex_buffers,
},
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleStrip,
strip_index_format: Some(wgpu::IndexFormat::Uint16),
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
..wgpu::PrimitiveState::default()
},
depth_stencil: Some(wgpu::DepthStencilState {
format: depth_format,
depth_write_enabled: false,
depth_compare: wgpu::CompareFunction::Always,
stencil: wgpu::StencilState {
front: wgpu::StencilFaceState {
compare: wgpu::CompareFunction::Less,
..wgpu::StencilFaceState::default()
},
back: wgpu::StencilFaceState {
compare: wgpu::CompareFunction::Less,
..wgpu::StencilFaceState::default()
},
read_mask: 0xff,
write_mask: 0xff,
},
bias: wgpu::DepthBiasState::default(),
}),
multisample: wgpu::MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
},
fragment: Some(wgpu::FragmentState {
module: &draw_shader,
entry_point: "fs_main",
targets: &[Some(wgpu::ColorTargetState {
format: target_format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent::REPLACE,
alpha: wgpu::BlendComponent::REPLACE,
}),
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});

Self { vertex_buf, index_buf, pipeline, bind_group }
}

pub fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
render_pass.set_pipeline(&self.pipeline);
render_pass.set_bind_group(0, &self.bind_group, &[]);
render_pass.set_index_buffer(self.index_buf.slice(..), wgpu::IndexFormat::Uint16);
render_pass.set_vertex_buffer(0, self.vertex_buf.slice(..));
render_pass.draw_indexed(0..4u32, 0, 0..1);
}
}
15 changes: 13 additions & 2 deletions crates/viewer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use winit::{
};

mod camera;
mod clipping_plane;
mod edge_drawer;
mod surface_drawer;

Expand Down Expand Up @@ -199,7 +200,12 @@ impl GameApp for ViewerApp {

let surface_texture_format = graphics_device.surface_texture_format();

let depth_texture = DepthTexture::new(device, width, height);
let depth_texture = DepthTexture::new_with_format(
device,
width,
height,
wgpu::TextureFormat::Depth24PlusStencil8,
);
let depth_texture_format = depth_texture.format();

Self {
Expand Down Expand Up @@ -230,7 +236,12 @@ impl GameApp for ViewerApp {
fn resize(&mut self, graphics_device: &mut GraphicsDevice, width: u32, height: u32) {
self.client_rect = vec2(width as f32, height as f32);
self.camera.resize(width, height);
self.depth_texture = DepthTexture::new(graphics_device.device(), width, height);
self.depth_texture = DepthTexture::new_with_format(
graphics_device.device(),
width,
height,
wgpu::TextureFormat::Depth24PlusStencil8,
);
self.text_system.resize(width, height);
self.line_drawer.resize(width, height);
self.smaa_target.resize(graphics_device.device(), width, height);
Expand Down
33 changes: 29 additions & 4 deletions crates/viewer/src/surface_drawer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::clipping_plane::ClippingPlane;
use bytemuck::{Pod, Zeroable};
use glam::Mat4;
use opencascade::mesh::Mesh;
Expand All @@ -8,6 +9,7 @@ pub struct SurfaceDrawer {
vertex_uniform: wgpu::Buffer,
uniform_bind_group: wgpu::BindGroup,
pipeline: RenderPipeline,
clipping_plane: ClippingPlane,
}

impl SurfaceDrawer {
Expand All @@ -16,6 +18,8 @@ impl SurfaceDrawer {
target_format: wgpu::TextureFormat,
depth_format: wgpu::TextureFormat,
) -> Self {
let clipping_plane = ClippingPlane::new(device, target_format, depth_format);

// Uniform buffer
let cad_mesh_uniforms = CadMeshUniforms::default();

Expand Down Expand Up @@ -72,7 +76,7 @@ impl SurfaceDrawer {
topology: wgpu::PrimitiveTopology::TriangleList,
// strip_index_format: Some(wgpu::IndexFormat::Uint32),
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
cull_mode: None,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
..wgpu::PrimitiveState::default()
Expand All @@ -81,7 +85,20 @@ impl SurfaceDrawer {
format: depth_format,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Less,
stencil: wgpu::StencilState::default(),
stencil: wgpu::StencilState {
front: wgpu::StencilFaceState {
pass_op: wgpu::StencilOperation::DecrementWrap,
depth_fail_op: wgpu::StencilOperation::DecrementWrap,
..wgpu::StencilFaceState::default()
},
back: wgpu::StencilFaceState {
pass_op: wgpu::StencilOperation::IncrementWrap,
depth_fail_op: wgpu::StencilOperation::IncrementWrap,
..wgpu::StencilFaceState::default()
},
read_mask: 0xff,
write_mask: 0xff,
},
bias: wgpu::DepthBiasState::default(),
}),
multisample: wgpu::MultisampleState {
Expand Down Expand Up @@ -113,7 +130,7 @@ impl SurfaceDrawer {
label: None,
});

Self { vertex_uniform, uniform_bind_group, pipeline }
Self { vertex_uniform, uniform_bind_group, pipeline, clipping_plane }
}

#[allow(clippy::too_many_arguments)]
Expand Down Expand Up @@ -147,17 +164,25 @@ impl SurfaceDrawer {
load: wgpu::LoadOp::Clear(1.0),
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
// stencil_ops: None,
stencil_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(128),
store: wgpu::StoreOp::Store,
}),
}),
occlusion_query_set: None,
timestamp_writes: None,
});

render_pass.set_stencil_reference(128);

render_pass.set_pipeline(&self.pipeline);
render_pass.set_bind_group(0, &self.uniform_bind_group, &[]);
render_pass.set_index_buffer(cad_mesh.index_buf.slice(..), wgpu::IndexFormat::Uint32);
render_pass.set_vertex_buffer(0, cad_mesh.vertex_buf.slice(..));
render_pass.draw_indexed(0..(cad_mesh.num_indices as u32), 0, 0..1);

self.clipping_plane.render(&mut render_pass);
}
}

Expand Down