phosphor-crt 0.1.0

A real-time plotter of waveforms, imitating oscillscope CRTs
Documentation
use wgpu::util::DeviceExt;
use wgpu::{Buffer, Device, VertexBufferLayout};

#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
pub(crate) enum WaveformMode {
    YT,
    XY,
}
#[derive(Debug)]
pub(crate) struct WaveformResources {
    num_samples: usize,
    buffer: Buffer,
    mode: WaveformMode,
}

impl WaveformResources {
    pub(crate) fn samples_size_bytes(&self) -> usize {
        match self.mode {
            WaveformMode::YT => size_of::<[f32; 1]>(),
            WaveformMode::XY => size_of::<[f32; 2]>(),
        }
    }
}

impl WaveformResources {
    pub(crate) fn new(waveform: &[f32], device: &Device, mode: WaveformMode) -> WaveformResources {
        let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
            label: Some("Waveform buffer"),
            usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
            contents: bytemuck::cast_slice(waveform),
        });

        let num_samples = match mode {
            WaveformMode::YT => waveform.len(),
            WaveformMode::XY => waveform.len() / 2,
        };

        WaveformResources {
            buffer,
            num_samples,
            mode,
        }
    }

    pub(crate) fn buffer_layout(&self) -> VertexBufferLayout<'static> {
        match self.mode {
            WaveformMode::YT => VertexBufferLayout {
                array_stride: 2 * size_of::<f32>() as wgpu::BufferAddress,
                step_mode: wgpu::VertexStepMode::Instance,
                attributes: &[
                    wgpu::VertexAttribute {
                        offset: 0,
                        shader_location: 0,
                        format: wgpu::VertexFormat::Float32,
                    },
                    wgpu::VertexAttribute {
                        offset: size_of::<f32>() as wgpu::BufferAddress,
                        shader_location: 1,
                        format: wgpu::VertexFormat::Float32,
                    },
                ],
            },
            WaveformMode::XY => VertexBufferLayout {
                array_stride: 4 * size_of::<f32>() as wgpu::BufferAddress,
                step_mode: wgpu::VertexStepMode::Instance,
                attributes: &[
                    wgpu::VertexAttribute {
                        offset: 0,
                        shader_location: 0,
                        format: wgpu::VertexFormat::Float32x2,
                    },
                    wgpu::VertexAttribute {
                        offset: 2 * size_of::<f32>() as wgpu::BufferAddress,
                        shader_location: 1,
                        format: wgpu::VertexFormat::Float32x2,
                    },
                ],
            },
        }
    }

    pub(crate) fn num_samples(&self) -> usize {
        self.num_samples
    }

    pub(crate) fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn mode(&self) -> WaveformMode {
        self.mode
    }
}