aboutsummaryrefslogtreecommitdiff
path: root/src/nodes.rs
blob: b33b2a0d16201fdb9f181eb24f26f95cad766529 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use bevy::{prelude::*, render::{render_graph::{ViewNode, NodeRunError, RenderGraphContext, RenderLabel}, view::ViewTarget, renderer::RenderContext, render_resource::{PipelineCache, BindGroupEntries, RenderPassDescriptor, RenderPassColorAttachment, Operations}, render_asset::RenderAssets}, ecs::query::QueryItem};

use super::components;
use super::resources;

#[derive(RenderLabel, Clone, Eq, PartialEq, Hash, Debug)]
pub struct DitherRenderLabel;

#[derive(Default)]
pub struct DitherRenderNode;

impl ViewNode for DitherRenderNode {
    type ViewQuery = (
        &'static ViewTarget,
        &'static components::DitherPostProcessSettings,
    );

    fn run(
        &self,
        _graph: &mut RenderGraphContext,
        render_context: &mut RenderContext,
        (view_target, dither_post_process_settings): QueryItem<Self::ViewQuery>,
        world: &World,
    ) -> Result<(), NodeRunError> {
        let render_pipeline = world.resource::<resources::DitherPostProcessPipeline>();
        let pipeline_cache = world.resource::<PipelineCache>();
        let Some(pipeline) = pipeline_cache.get_render_pipeline(render_pipeline.pipeline_id) else {
            warn!("Failed to get render pipeline from cache, skipping...");
            return Ok(());
        };

        let post_process = view_target.post_process_write();

        let Some(threshold_map) = world.resource::<RenderAssets<Image>>().get(dither_post_process_settings.handle()) else {
            warn!("Failed to get threshold map, skipping...");
            return Ok(());
        };

        let bind_group = render_context.render_device().create_bind_group(
            "dither_post_process_bind_group",
            &render_pipeline.layout,
            &BindGroupEntries::sequential((
                post_process.source,
                &render_pipeline.screen_sampler,
                &threshold_map.texture_view,
                &render_pipeline.threshold_map_sampler,
            )),
        );

        let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
            label: Some("dither_post_process_render_pass"),
            color_attachments: &[Some(RenderPassColorAttachment {
                view: post_process.destination,
                ops: Operations::default(),
                resolve_target: None,
            })],
            timestamp_writes: None,
            depth_stencil_attachment: None,
            occlusion_query_set: None,
        });

        render_pass.set_render_pipeline(pipeline);
        render_pass.set_bind_group(0, &bind_group, &[]);
        render_pass.draw(0..3, 0..1);
        Ok(())
    }
}