Search code examples
rustgraphicswgpu-rs

How can I draw a line while only using vertices and indices?


I use wgpu as my graphics backend for my project.

this is my current implementation:

pub fn draw_line(
    points: Vec<[f32; 2]>,
) -> (Vec<Vertex>, Vec<u16>) {
    let mut vertices: Vec<Vertex> = Vec::new();
    let mut indices: Vec<u16> = Vec::new();

    let w = WIDTH / 2.0;

    let x1 = points[0][0];
    let x2 = points[1][0];
    let y1 = points[0][1];
    let y2 = points[1][1];

    let color: [f32; 3] = [1.0, 1.0, 1.0];

    vertices.push(Vertex { position: [x1,  y1 - w, 0.0],   color });
    vertices.push(Vertex { position: [x1,  y1 + w, 0.0],   color });
    vertices.push(Vertex { position: [x2,  y2 + w, 0.0],   color });
    vertices.push(Vertex { position: [x2,  y2 - w, 0.0],   color });

    indices.push(2);
    indices.push(1);
    indices.push(0);
    indices.push(2);
    indices.push(0);
    indices.push(3);

    return (vertices, indices);
}

But when trying to draw a line between 2 points the width of the line gets distorted relative to the height difference of those points. And the X and Y values of point1 must be smaller than the ones on point2 otherwise they dont show up because wgpu needs either Clockwise or CounterClockwise front faces

line_1 line_2

Is there any better function that that returns the vertices and indices, for a line between 2 Points


Solution

  • Untested but should work:

    pub fn draw_line(
        points: Vec<[f32; 2]>,
    ) -> (Vec<Vertex>, Vec<u16>) {
        let mut vertices: Vec<Vertex> = Vec::new();
        let mut indices: Vec<u16> = Vec::new();
    
        let w = WIDTH / 2.0;
    
        let x1 = points[0][0];
        let x2 = points[1][0];
        let y1 = points[0][1];
        let y2 = points[1][1];
    
        let color: [f32; 3] = [1.0, 1.0, 1.0];
    
        let dx = x2 - x1;
        let dy = y2 - y1;
        let l = dx.hypot (dy);
        let u = dx * WIDTH * 0.5 / l;
        let v = dy * WIDTH * 0.5 / l;
    
        vertices.push(Vertex { position: [x1 + v,  y1 - u, 0.0],   color });
        vertices.push(Vertex { position: [x1 - v,  y1 + u, 0.0],   color });
        vertices.push(Vertex { position: [x2 - v,  y2 + u, 0.0],   color });
        vertices.push(Vertex { position: [x2 + v,  y2 - u, 0.0],   color });
    
        indices.push(2);
        indices.push(1);
        indices.push(0);
        indices.push(2);
        indices.push(0);
        indices.push(3);
    
        return (vertices, indices);
    }