veloren_voxygen/render/renderer/
locals.rs

1use super::{
2    super::{
3        consts::Consts,
4        pipelines::{bloom, clouds, postprocess},
5    },
6    Layouts,
7};
8
9pub struct BloomParams<'a> {
10    pub locals: [Consts<bloom::Locals>; bloom::NUM_SIZES],
11    pub src_views: [&'a wgpu::TextureView; bloom::NUM_SIZES],
12    pub final_tgt_view: &'a wgpu::TextureView,
13}
14
15pub struct Locals {
16    pub clouds: Consts<clouds::Locals>,
17    pub clouds_bind: clouds::BindGroup,
18
19    pub bloom_binds: Option<[bloom::BindGroup; bloom::NUM_SIZES]>,
20
21    pub postprocess: Consts<postprocess::Locals>,
22    pub postprocess_bind: postprocess::BindGroup,
23}
24
25fn arr_zip_map<const N: usize, A, B, C>(a: [A; N], b: [B; N], f: impl Fn(A, B) -> C) -> [C; N] {
26    let mut b = b.into_iter();
27    a.map(|a| f(a, b.next().unwrap()))
28}
29
30impl Locals {
31    pub(super) fn new(
32        device: &wgpu::Device,
33        layouts: &Layouts,
34        clouds_locals: Consts<clouds::Locals>,
35        postprocess_locals: Consts<postprocess::Locals>,
36        tgt_color_view: &wgpu::TextureView,
37        tgt_mat_view: &wgpu::TextureView,
38        tgt_depth_view: &wgpu::TextureView,
39        bloom: Option<BloomParams>,
40        tgt_color_pp_view: &wgpu::TextureView,
41        sampler: &wgpu::Sampler,
42        depth_sampler: &wgpu::Sampler,
43    ) -> Self {
44        let clouds_bind = layouts.clouds.bind(
45            device,
46            tgt_color_view,
47            tgt_mat_view,
48            tgt_depth_view,
49            sampler,
50            depth_sampler,
51            &clouds_locals,
52        );
53
54        let postprocess_bind = layouts.postprocess.bind(
55            device,
56            tgt_color_pp_view,
57            tgt_depth_view,
58            tgt_mat_view,
59            bloom.as_ref().map(|b| b.final_tgt_view),
60            sampler,
61            depth_sampler,
62            &postprocess_locals,
63        );
64
65        let bloom_binds = bloom.map(|bloom| {
66            arr_zip_map(bloom.src_views, bloom.locals, |view, locals| {
67                layouts.bloom.bind(device, view, sampler, locals)
68            })
69        });
70
71        Self {
72            clouds: clouds_locals,
73            clouds_bind,
74            bloom_binds,
75            postprocess: postprocess_locals,
76            postprocess_bind,
77        }
78    }
79
80    pub(super) fn rebind(
81        &mut self,
82        device: &wgpu::Device,
83        layouts: &Layouts,
84        // Call when these are recreated and need to be rebound
85        // e.g. resizing
86        tgt_color_view: &wgpu::TextureView,
87        tgt_mat_view: &wgpu::TextureView,
88        tgt_depth_view: &wgpu::TextureView,
89        bloom: Option<BloomParams>,
90        tgt_color_pp_view: &wgpu::TextureView,
91        sampler: &wgpu::Sampler,
92        depth_sampler: &wgpu::Sampler,
93    ) {
94        self.clouds_bind = layouts.clouds.bind(
95            device,
96            tgt_color_view,
97            tgt_mat_view,
98            tgt_depth_view,
99            sampler,
100            depth_sampler,
101            &self.clouds,
102        );
103        self.postprocess_bind = layouts.postprocess.bind(
104            device,
105            tgt_color_pp_view,
106            tgt_depth_view,
107            tgt_mat_view,
108            bloom.as_ref().map(|b| b.final_tgt_view),
109            sampler,
110            depth_sampler,
111            &self.postprocess,
112        );
113        self.bloom_binds = bloom.map(|bloom| {
114            arr_zip_map(bloom.src_views, bloom.locals, |view, locals| {
115                layouts.bloom.bind(device, view, sampler, locals)
116            })
117        });
118    }
119}