veloren_voxygen/render/pipelines/
trail.rs1use 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}