/* ENSnano, a 3d graphical application for DNA nanostructures. Copyright (C) 2021 Nicolas Levy and Nicolas Schabanel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ use crate::consts::*; use iced_wgpu::wgpu; use std::ops::Range; pub trait Vertex { fn desc<'a>() -> wgpu::VertexBufferLayout<'a>; } #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct MeshVertex { position: [f32; 3], normal: [f32; 3], } unsafe impl bytemuck::Pod for MeshVertex {} unsafe impl bytemuck::Zeroable for MeshVertex {} impl Vertex for MeshVertex { fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { use std::mem; wgpu::VertexBufferLayout { array_stride: mem::size_of::() as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, attributes: &[ // Position wgpu::VertexAttribute { offset: 0, shader_location: VERTEX_POSITION_ADRESS, format: wgpu::VertexFormat::Float3, }, // Normal wgpu::VertexAttribute { offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, shader_location: VERTEX_NORMAL_ADRESS, format: wgpu::VertexFormat::Float3, }, ], } } } pub struct Mesh { pub vertex_buffer: wgpu::Buffer, pub index_buffer: wgpu::Buffer, pub num_elements: u32, } pub trait DrawModel<'a, 'b> where 'b: 'a, { fn draw_mesh( &mut self, mesh: &'b Mesh, viewer: &'b wgpu::BindGroup, instance_bg: &'b wgpu::BindGroup, light: &'b wgpu::BindGroup, model_matrices: &'b wgpu::BindGroup, ); fn draw_mesh_instanced( &mut self, mesh: &'b Mesh, instances: Range, viewer: &'b wgpu::BindGroup, instances_bg: &'b wgpu::BindGroup, light: &'b wgpu::BindGroup, model_matrices: &'b wgpu::BindGroup, ); } impl<'a, 'b> DrawModel<'a, 'b> for wgpu::RenderPass<'a> where 'b: 'a, { fn draw_mesh( &mut self, mesh: &'b Mesh, viewer: &'b wgpu::BindGroup, instances_bg: &'b wgpu::BindGroup, light: &'b wgpu::BindGroup, model_matrices: &'b wgpu::BindGroup, ) { self.draw_mesh_instanced(mesh, 0..1, viewer, instances_bg, light, model_matrices); } fn draw_mesh_instanced( &mut self, mesh: &'b Mesh, instances: Range, viewer: &'b wgpu::BindGroup, instances_bg: &'b wgpu::BindGroup, light: &'b wgpu::BindGroup, model_matrices: &'b wgpu::BindGroup, ) { self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..)); self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint16); self.set_bind_group(VIEWER_BINDING_ID, &viewer, &[]); self.set_bind_group(INSTANCES_BINDING_ID, &instances_bg, &[]); self.set_bind_group(LIGHT_BINDING_ID, &light, &[]); self.set_bind_group(MODEL_BINDING_ID, &model_matrices, &[]); //self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances); } }