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: Some("main"),
85                buffers: &[Vertex::desc()],
86                compilation_options: Default::default(),
87            },
88            primitive: wgpu::PrimitiveState {
89                topology: wgpu::PrimitiveTopology::TriangleList,
90                strip_index_format: None,
91                front_face: wgpu::FrontFace::Ccw,
92                cull_mode: None,
93                unclipped_depth: false,
94                polygon_mode: wgpu::PolygonMode::Fill,
95                conservative: false,
96            },
97            depth_stencil: Some(wgpu::DepthStencilState {
98                format: wgpu::TextureFormat::Depth32Float,
99                depth_write_enabled: false,
100                depth_compare: wgpu::CompareFunction::GreaterEqual,
101                stencil: wgpu::StencilState {
102                    front: wgpu::StencilFaceState::IGNORE,
103                    back: wgpu::StencilFaceState::IGNORE,
104                    read_mask: !0,
105                    write_mask: 0,
106                },
107                bias: wgpu::DepthBiasState {
108                    constant: 0,
109                    slope_scale: 0.0,
110                    clamp: 0.0,
111                },
112            }),
113            multisample: wgpu::MultisampleState {
114                count: samples,
115                mask: !0,
116                alpha_to_coverage_enabled: false,
117            },
118            fragment: Some(wgpu::FragmentState {
119                module: fs_module,
120                entry_point: Some("main"),
121                targets: &[Some(wgpu::ColorTargetState {
122                    format,
123                    blend: Some(wgpu::BlendState {
124                        color: wgpu::BlendComponent {
125                            src_factor: wgpu::BlendFactor::SrcAlpha,
126                            dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
127                            operation: wgpu::BlendOperation::Add,
128                        },
129                        alpha: wgpu::BlendComponent {
130                            src_factor: wgpu::BlendFactor::One,
131                            dst_factor: wgpu::BlendFactor::One,
132                            operation: wgpu::BlendOperation::Add,
133                        },
134                    }),
135                    write_mask: wgpu::ColorWrites::ALL,
136                })],
137                compilation_options: Default::default(),
138            }),
139            multiview: None,
140            cache: None,
141        });
142
143        Self {
144            pipeline: render_pipeline,
145        }
146    }
147}