slam-viewer 0.1.2

Simple wgpu based SLAM map viewer.
Documentation
use core::marker::PhantomData;

use super::point::Point;
use super::renderer::PointsRendener;
use super::source::PointSource;
use crate::pipes::{GpuVec, StaticShaderModule, VertexFormat};

use nalgebra::Point3;
use slam_cv::Number;

pub struct PointsBuilder<N, S>
where
    N: 'static + Number,
    Point3<N>: VertexFormat<N>,
    S: PointSource<N>,
{
    pub source: S,

    number: PhantomData<N>,
}

impl<N, S> PointsBuilder<N, S>
where
    N: 'static + Number,
    Point3<N>: VertexFormat<N>,
    S: PointSource<N>,
{
    pub fn new(source: S) -> Self {
        Self {
            source,

            number: Default::default(),
        }
    }

    pub fn build(
        self,
        device: &wgpu::Device,
        texture_format: wgpu::TextureFormat,
        uniform_bind_group_layout: &wgpu::BindGroupLayout,
    ) -> PointsRendener<N, S> {
        let render_pipeline =
            self.build_render_pipeline(device, texture_format, uniform_bind_group_layout);

        PointsRendener {
            render_pipeline,
            buffer: GpuVec::new(wgpu::BufferUsage::VERTEX),

            number: Default::default(),
            source: self.source,
        }
    }

    fn build_render_pipeline(
        &self,
        device: &wgpu::Device,
        texture_format: wgpu::TextureFormat,
        uniform_bind_group_layout: &wgpu::BindGroupLayout,
    ) -> wgpu::RenderPipeline {
        const VS_SRC: StaticShaderModule = StaticShaderModule {
            glsl_source: include_str!("shader.vert"),
            shader_type: glsl_to_spirv::ShaderType::Vertex,
            entry_point: None,
        };
        const FS_SRC: StaticShaderModule = StaticShaderModule {
            glsl_source: include_str!("shader.frag"),
            shader_type: glsl_to_spirv::ShaderType::Fragment,
            entry_point: None,
        };

        let render_pipeline_layout =
            device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
                bind_group_layouts: &[&uniform_bind_group_layout],
            });

        device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
            layout: &render_pipeline_layout,
            vertex_stage: wgpu::ProgrammableStageDescriptor {
                module: &VS_SRC.build(device),
                entry_point: VS_SRC.entry_point(),
            },
            fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
                module: &FS_SRC.build(device),
                entry_point: FS_SRC.entry_point(),
            }),
            rasterization_state: Some(wgpu::RasterizationStateDescriptor {
                front_face: wgpu::FrontFace::Ccw,
                cull_mode: wgpu::CullMode::Back,
                depth_bias: 0,
                depth_bias_slope_scale: 0.0,
                depth_bias_clamp: 0.0,
            }),
            color_states: &[wgpu::ColorStateDescriptor {
                format: texture_format,
                color_blend: wgpu::BlendDescriptor::REPLACE,
                alpha_blend: wgpu::BlendDescriptor::REPLACE,
                write_mask: wgpu::ColorWrite::ALL,
            }],
            primitive_topology: wgpu::PrimitiveTopology::PointList,
            depth_stencil_state: None,
            vertex_state: wgpu::VertexStateDescriptor {
                index_format: wgpu::IndexFormat::Uint16,
                vertex_buffers: &[Point::desc(&Point::attributes())],
            },
            sample_count: 1,
            sample_mask: !0,
            alpha_to_coverage_enabled: false,
        })
    }
}