From ccd94ef58b0195b670a14e1376f5af9cac315d69 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 21 Mar 2025 23:24:20 +0100 Subject: [PATCH] Re-use `fj-viewer` --- experiments/2025-03-18/src/app.rs | 92 ----------- experiments/2025-03-18/src/main.rs | 4 +- experiments/2025-03-18/src/render/geometry.rs | 71 --------- experiments/2025-03-18/src/render/mod.rs | 7 - experiments/2025-03-18/src/render/pipeline.rs | 145 ------------------ experiments/2025-03-18/src/render/renderer.rs | 125 --------------- .../src/render/shaders/triangles.wgsl | 32 ---- experiments/2025-03-18/src/render/uniforms.rs | 19 --- experiments/2025-03-18/src/render/vertex.rs | 13 -- 9 files changed, 1 insertion(+), 507 deletions(-) delete mode 100644 experiments/2025-03-18/src/app.rs delete mode 100644 experiments/2025-03-18/src/render/geometry.rs delete mode 100644 experiments/2025-03-18/src/render/mod.rs delete mode 100644 experiments/2025-03-18/src/render/pipeline.rs delete mode 100644 experiments/2025-03-18/src/render/renderer.rs delete mode 100644 experiments/2025-03-18/src/render/shaders/triangles.wgsl delete mode 100644 experiments/2025-03-18/src/render/uniforms.rs delete mode 100644 experiments/2025-03-18/src/render/vertex.rs diff --git a/experiments/2025-03-18/src/app.rs b/experiments/2025-03-18/src/app.rs deleted file mode 100644 index 7cd84944f..000000000 --- a/experiments/2025-03-18/src/app.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::sync::Arc; - -use fj_interop::TriMesh; -use winit::{ - application::ApplicationHandler, - event::{KeyEvent, WindowEvent}, - event_loop::{ActiveEventLoop, EventLoop}, - keyboard::{Key, NamedKey}, - window::{Window, WindowAttributes, WindowId}, -}; - -use crate::render::Renderer; - -pub fn run(tri_mesh: TriMesh) -> anyhow::Result<()> { - let event_loop = EventLoop::new()?; - - let mut app = App { - tri_mesh, - window: None, - renderer: None, - }; - event_loop.run_app(&mut app)?; - - Ok(()) -} - -struct App { - tri_mesh: TriMesh, - window: Option>, - renderer: Option, -} - -impl ApplicationHandler for App { - fn resumed(&mut self, event_loop: &ActiveEventLoop) { - let (window, renderer) = match init(event_loop) { - Ok(ok) => ok, - Err(err) => { - eprintln!("Initialization error: `{err:?}`"); - event_loop.exit(); - return; - } - }; - - self.window = Some(window); - self.renderer = Some(renderer); - } - - fn window_event( - &mut self, - event_loop: &ActiveEventLoop, - _: WindowId, - event: WindowEvent, - ) { - let Some(renderer) = self.renderer.as_mut() else { - return; - }; - - match event { - WindowEvent::CloseRequested => { - event_loop.exit(); - } - WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - } => { - event_loop.exit(); - } - WindowEvent::RedrawRequested => { - if let Err(err) = renderer.render(&self.tri_mesh) { - eprintln!("Render error: {err}"); - } - } - _ => {} - } - } -} - -fn init( - event_loop: &ActiveEventLoop, -) -> anyhow::Result<(Arc, Renderer)> { - let window = { - let window = event_loop.create_window(WindowAttributes::default())?; - Arc::new(window) - }; - let renderer = pollster::block_on(Renderer::new(window.clone()))?; - - Ok((window, renderer)) -} diff --git a/experiments/2025-03-18/src/main.rs b/experiments/2025-03-18/src/main.rs index d4e723d9d..3fa4a0782 100644 --- a/experiments/2025-03-18/src/main.rs +++ b/experiments/2025-03-18/src/main.rs @@ -1,20 +1,18 @@ #![allow(clippy::module_inception)] -mod app; mod extra; mod geometry; mod handle; mod math; mod model; mod operations; -mod render; mod topology; fn main() -> anyhow::Result<()> { let tri_mesh = model::model(); fj_export::export(&tri_mesh, "output.3mf")?; - app::run(tri_mesh)?; + fj_viewer::display(tri_mesh, false)?; Ok(()) } diff --git a/experiments/2025-03-18/src/render/geometry.rs b/experiments/2025-03-18/src/render/geometry.rs deleted file mode 100644 index be58e3756..000000000 --- a/experiments/2025-03-18/src/render/geometry.rs +++ /dev/null @@ -1,71 +0,0 @@ -use fj_interop::TriMesh; -use glam::Vec3; -use wgpu::util::DeviceExt; - -use super::vertex::Vertex; - -pub struct Geometry { - pub vertices: wgpu::Buffer, - pub indices: wgpu::Buffer, - pub num_indices: u32, -} - -impl Geometry { - pub fn new(device: &wgpu::Device, tri_mesh: &TriMesh) -> Self { - let mut indices = Vec::new(); - let mut vertices = Vec::new(); - - for triangle in tri_mesh.all_triangles() { - let triangle = triangle.points.each_ref().map(|point| { - Vec3::from( - point - .coords - .components - .map(|coord| coord.into_f64() as f32), - ) - }); - let normal = { - let [a, b, c] = triangle; - - let ab = b - a; - let ac = c - a; - - ab.cross(ac) - }; - - for point in triangle { - let index = vertices.len() as u32; - let vertex = Vertex { - position: point.into(), - normal: normal.into(), - }; - - indices.push(index); - vertices.push(vertex); - } - } - - let Ok(num_indices) = indices.len().try_into() else { - panic!("Unsupported number of indices: `{}`", indices.len()); - }; - - let vertices = - device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: None, - contents: bytemuck::cast_slice(&vertices), - usage: wgpu::BufferUsages::VERTEX, - }); - let indices = - device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: None, - contents: bytemuck::cast_slice(&indices), - usage: wgpu::BufferUsages::INDEX, - }); - - Self { - vertices, - indices, - num_indices, - } - } -} diff --git a/experiments/2025-03-18/src/render/mod.rs b/experiments/2025-03-18/src/render/mod.rs deleted file mode 100644 index 7fcb193d1..000000000 --- a/experiments/2025-03-18/src/render/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod geometry; -mod pipeline; -mod renderer; -mod uniforms; -mod vertex; - -pub use self::renderer::Renderer; diff --git a/experiments/2025-03-18/src/render/pipeline.rs b/experiments/2025-03-18/src/render/pipeline.rs deleted file mode 100644 index 22ce834ac..000000000 --- a/experiments/2025-03-18/src/render/pipeline.rs +++ /dev/null @@ -1,145 +0,0 @@ -use std::f32::consts::PI; - -use glam::{Mat4, Vec3}; -use wgpu::util::DeviceExt; - -use super::{geometry::Geometry, uniforms::Uniforms, vertex::Vertex}; - -pub struct Pipeline { - render_pipeline: wgpu::RenderPipeline, - bind_group: wgpu::BindGroup, -} - -impl Pipeline { - pub fn new( - device: &wgpu::Device, - surface_configuration: &wgpu::SurfaceConfiguration, - ) -> Self { - let aspect_ratio = surface_configuration.width as f32 - / surface_configuration.height as f32; - let uniforms = - device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: None, - contents: bytemuck::cast_slice(&[Uniforms::from_transform( - default_transform(aspect_ratio), - )]), - usage: wgpu::BufferUsages::UNIFORM, - }); - - let bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: None, - entries: &[wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: None, - }, - count: None, - }], - }); - - let pipeline_layout = - device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: None, - bind_group_layouts: &[&bind_group_layout], - push_constant_ranges: &[], - }); - - let shader_module = device.create_shader_module(wgpu::include_wgsl!( - "shaders/triangles.wgsl" - )); - - let render_pipeline = - device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: None, - layout: Some(&pipeline_layout), - vertex: wgpu::VertexState { - module: &shader_module, - entry_point: Some("vertex"), - compilation_options: - wgpu::PipelineCompilationOptions::default(), - buffers: &[wgpu::VertexBufferLayout { - array_stride: size_of::() - as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: Vertex::ATTRIBUTES, - }], - }, - fragment: Some(wgpu::FragmentState { - module: &shader_module, - entry_point: Some("fragment"), - compilation_options: - wgpu::PipelineCompilationOptions::default(), - targets: &[Some(wgpu::ColorTargetState { - format: surface_configuration.format, - blend: Some(wgpu::BlendState::REPLACE), - write_mask: wgpu::ColorWrites::all(), - })], - }), - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleList, - strip_index_format: None, - front_face: wgpu::FrontFace::Ccw, - cull_mode: None, - unclipped_depth: false, - polygon_mode: wgpu::PolygonMode::Fill, - conservative: false, - }, - depth_stencil: Some(wgpu::DepthStencilState { - format: wgpu::TextureFormat::Depth32Float, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, - stencil: wgpu::StencilState::default(), - bias: wgpu::DepthBiasState::default(), - }), - multisample: wgpu::MultisampleState::default(), - multiview: None, - cache: None, - }); - - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - label: None, - layout: &bind_group_layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: uniforms.as_entire_binding(), - }], - }); - - Pipeline { - render_pipeline, - bind_group, - } - } - - pub fn draw( - &self, - render_pass: &mut wgpu::RenderPass, - geometry: &Geometry, - ) { - if geometry.num_indices > 0 { - render_pass.set_index_buffer( - geometry.indices.slice(..), - wgpu::IndexFormat::Uint32, - ); - render_pass.set_vertex_buffer(0, geometry.vertices.slice(..)); - render_pass.set_pipeline(&self.render_pipeline); - render_pass.set_bind_group(0, &self.bind_group, &[]); - render_pass.draw_indexed(0..geometry.num_indices, 0, 0..1); - } - } -} - -fn default_transform(aspect_ratio: f32) -> Mat4 { - let fov_y_radians = std::f32::consts::PI / 2.; - let z_near = 0.1; - let z_far = 10.; - - Mat4::perspective_rh(fov_y_radians, aspect_ratio, z_near, z_far) - * Mat4::from_translation(Vec3::new(0., 0., -4.)) - * Mat4::from_rotation_x(-PI / 4.) - * Mat4::from_rotation_z(PI / 4.) -} diff --git a/experiments/2025-03-18/src/render/renderer.rs b/experiments/2025-03-18/src/render/renderer.rs deleted file mode 100644 index 9879c6288..000000000 --- a/experiments/2025-03-18/src/render/renderer.rs +++ /dev/null @@ -1,125 +0,0 @@ -use std::sync::Arc; - -use anyhow::anyhow; -use fj_interop::TriMesh; -use winit::window::Window; - -use super::{geometry::Geometry, pipeline::Pipeline}; - -pub struct Renderer { - pub surface: wgpu::Surface<'static>, - pub device: wgpu::Device, - pub queue: wgpu::Queue, - pub pipeline: Pipeline, - pub depth_view: wgpu::TextureView, -} - -impl Renderer { - pub async fn new(window: Arc) -> anyhow::Result { - let instance = wgpu::Instance::default(); - let surface = instance.create_surface(window.clone())?; - let adapter = instance - .request_adapter(&wgpu::RequestAdapterOptions { - compatible_surface: Some(&surface), - ..Default::default() - }) - .await - .ok_or_else(|| anyhow!("Failed to request adapter"))?; - let (device, queue) = adapter - .request_device( - &wgpu::DeviceDescriptor { - label: None, - required_features: wgpu::Features::default(), - required_limits: wgpu::Limits::default(), - memory_hints: wgpu::MemoryHints::default(), - }, - None, - ) - .await?; - - let size = window.inner_size(); - let surface_config = surface - .get_default_config(&adapter, size.width, size.height) - .ok_or_else(|| anyhow!("Failed to get default surface config"))?; - surface.configure(&device, &surface_config); - - let pipeline = Pipeline::new(&device, &surface_config); - - let depth_view = { - let depth_texture = - device.create_texture(&wgpu::TextureDescriptor { - label: None, - size: wgpu::Extent3d { - width: surface_config.width, - height: surface_config.height, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Depth32Float, - usage: wgpu::TextureUsages::RENDER_ATTACHMENT - | wgpu::TextureUsages::TEXTURE_BINDING, - view_formats: &[], - }); - - depth_texture.create_view(&wgpu::TextureViewDescriptor::default()) - }; - - Ok(Self { - surface, - device, - queue, - pipeline, - depth_view, - }) - } - - pub fn render(&mut self, tri_mesh: &TriMesh) -> anyhow::Result<()> { - let geometry = Geometry::new(&self.device, tri_mesh); - - let mut encoder = self - .device - .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); - let frame = self.surface.get_current_texture().unwrap(); - let color_view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - - { - let mut render_pass = - encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some( - wgpu::RenderPassColorAttachment { - view: &color_view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::WHITE), - store: wgpu::StoreOp::Store, - }, - }, - )], - depth_stencil_attachment: Some( - wgpu::RenderPassDepthStencilAttachment { - view: &self.depth_view, - depth_ops: Some(wgpu::Operations { - load: wgpu::LoadOp::Clear(1.0), - store: wgpu::StoreOp::Store, - }), - stencil_ops: None, - }, - ), - timestamp_writes: None, - occlusion_query_set: None, - }); - - self.pipeline.draw(&mut render_pass, &geometry); - } - - self.queue.submit(Some(encoder.finish())); - frame.present(); - - Ok(()) - } -} diff --git a/experiments/2025-03-18/src/render/shaders/triangles.wgsl b/experiments/2025-03-18/src/render/shaders/triangles.wgsl deleted file mode 100644 index 90e89a92f..000000000 --- a/experiments/2025-03-18/src/render/shaders/triangles.wgsl +++ /dev/null @@ -1,32 +0,0 @@ -struct Uniforms { - transform: mat4x4, - transform_for_normals: mat4x4, -}; - -@group(0) @binding(0) -var uniforms: Uniforms; - -struct VertexInput { - @location(0) position: vec3, - @location(1) normal: vec3, -} - -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) normal: vec3, -} - -@vertex -fn vertex(in: VertexInput) -> VertexOutput { - var out: VertexOutput; - out.position = uniforms.transform * vec4(in.position, 1.0); - out.normal = (uniforms.transform_for_normals * vec4(in.normal, 0.0)).xyz; - - return out; -} - -@fragment -fn fragment(in: VertexOutput) -> @location(0) vec4 { - var color = vec4(in.normal, 1.0); - return color; -} diff --git a/experiments/2025-03-18/src/render/uniforms.rs b/experiments/2025-03-18/src/render/uniforms.rs deleted file mode 100644 index c533b0738..000000000 --- a/experiments/2025-03-18/src/render/uniforms.rs +++ /dev/null @@ -1,19 +0,0 @@ -use glam::Mat4; - -#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] -#[repr(C)] -pub struct Uniforms { - pub transform: Mat4, - pub transform_for_normals: Mat4, -} - -impl Uniforms { - pub fn from_transform(transform: Mat4) -> Self { - let transform_for_normals = transform.inverse().transpose(); - - Self { - transform, - transform_for_normals, - } - } -} diff --git a/experiments/2025-03-18/src/render/vertex.rs b/experiments/2025-03-18/src/render/vertex.rs deleted file mode 100644 index 9003fdea4..000000000 --- a/experiments/2025-03-18/src/render/vertex.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] -#[repr(C)] -pub struct Vertex { - pub position: [f32; 3], - pub normal: [f32; 3], -} - -impl Vertex { - pub const ATTRIBUTES: &[wgpu::VertexAttribute] = &wgpu::vertex_attr_array![ - 0 => Float32x3, - 1 => Float32x3, - ]; -}