veloren_voxygen/render/pipelines/
trail.rs

1use super::super::{AaMode, GlobalsLayouts, Vertex as VertexTrait};
2use bytemuck::{Pod, Zeroable};
3use std::{
4    mem,
5    ops::{Add, Mul},
6};
7
8#[repr(C)]
9#[derive(Copy, Clone, Debug, Zeroable, Pod, PartialEq)]
10pub struct Vertex {
11    pub pos: [f32; 3],
12}
13
14impl Vertex {
15    fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
16        const ATTRIBUTES: [wgpu::VertexAttribute; 1] = wgpu::vertex_attr_array![0 => Float32x3];
17        wgpu::VertexBufferLayout {
18            array_stride: Self::STRIDE,
19            step_mode: wgpu::VertexStepMode::Vertex,
20            attributes: &ATTRIBUTES,
21        }
22    }
23
24    pub fn zero() -> Self { Self { pos: [0.0; 3] } }
25}
26
27impl Mul<f32> for Vertex {
28    type Output = Self;
29
30    fn mul(self, val: f32) -> Self::Output {
31        Self {
32            pos: self.pos.map(|a| a * val),
33        }
34    }
35}
36
37impl Add<Vertex> for Vertex {
38    type Output = Self;
39
40    fn add(self, other: Self) -> Self::Output {
41        Self {
42            pos: [
43                self.pos[0] + other.pos[0],
44                self.pos[1] + other.pos[1],
45                self.pos[2] + other.pos[2],
46            ],
47        }
48    }
49}
50
51impl VertexTrait for Vertex {
52    const QUADS_INDEX: Option<wgpu::IndexFormat> = Some(wgpu::IndexFormat::Uint16);
53    const STRIDE: wgpu::BufferAddress = mem::size_of::<Self>() as wgpu::BufferAddress;
54}
55
56pub struct TrailPipeline {
57    pub pipeline: wgpu::RenderPipeline,
58}
59
60impl TrailPipeline {
61    pub fn new(
62        device: &wgpu::Device,
63        vs_module: &wgpu::ShaderModule,
64        fs_module: &wgpu::ShaderModule,
65        global_layout: &GlobalsLayouts,
66        aa_mode: AaMode,
67        format: wgpu::TextureFormat,
68    ) -> Self {
69        common_base::span!(_guard, "TrailPipeline::new");
70        let render_pipeline_layout =
71            device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
72                label: Some("Trail pipeline layout"),
73                push_constant_ranges: &[],
74                bind_group_layouts: &[&global_layout.globals, &global_layout.shadow_textures],
75            });
76
77        let samples = aa_mode.samples();
78
79        let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
80            label: Some("Trail pipeline"),
81            layout: Some(&render_pipeline_layout),
82            vertex: wgpu::VertexState {
83                module: vs_module,
84                entry_point: "main",
85                buffers: &[Vertex::desc()],
86            },
87            primitive: wgpu::PrimitiveState {
88                topology: wgpu::PrimitiveTopology::TriangleList,
89                strip_index_format: None,
90                front_face: wgpu::FrontFace::Ccw,
91                cull_mode: None,
92                unclipped_depth: false,
93                polygon_mode: wgpu::PolygonMode::Fill,
94                conservative: false,
95            },
96            depth_stencil: Some(wgpu::DepthStencilState {
97                format: wgpu::TextureFormat::Depth32Float,
98                depth_write_enabled: false,
99                depth_compare: wgpu::CompareFunction::GreaterEqual,
100                stencil: wgpu::StencilState {
101                    front: wgpu::StencilFaceState::IGNORE,
102                    back: wgpu::StencilFaceState::IGNORE,
103                    read_mask: !0,
104                    write_mask: 0,
105                },
106                bias: wgpu::DepthBiasState {
107                    constant: 0,
108                    slope_scale: 0.0,
109                    clamp: 0.0,
110                },
111            }),
112            multisample: wgpu::MultisampleState {
113                count: samples,
114                mask: !0,
115                alpha_to_coverage_enabled: false,
116            },
117            fragment: Some(wgpu::FragmentState {
118                module: fs_module,
119                entry_point: "main",
120                targets: &[Some(wgpu::ColorTargetState {
121                    format,
122                    blend: Some(wgpu::BlendState {
123                        color: wgpu::BlendComponent {
124                            src_factor: wgpu::BlendFactor::SrcAlpha,
125                            dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
126                            operation: wgpu::BlendOperation::Add,
127                        },
128                        alpha: wgpu::BlendComponent {
129                            src_factor: wgpu::BlendFactor::One,
130                            dst_factor: wgpu::BlendFactor::One,
131                            operation: wgpu::BlendOperation::Add,
132                        },
133                    }),
134                    write_mask: wgpu::ColorWrites::ALL,
135                })],
136            }),
137            multiview: None,
138        });
139
140        Self {
141            pipeline: render_pipeline,
142        }
143    }
144}