Skip to main content

render_graph_demo/
render_graph_demo.rs

1//! Render Graph Demo - Multi-Pass Rendering Pipeline
2//!
3//! Demonstrates the render graph system for complex rendering pipelines:
4//! - Declaring render passes
5//! - Resource dependencies
6//! - Automatic pass ordering and optimization
7//! - Multi-target rendering
8//! - Post-processing chains
9//!
10//! **Note:** This is a placeholder example demonstrating the Render Graph API structure.
11//! Full graph-based rendering is in development.
12
13use astrelis_core::logging;
14use astrelis_render::{Color, GraphicsContext, RenderWindow, RenderWindowBuilder, wgpu};
15use astrelis_winit::{
16    FrameTime, WindowId,
17    app::{App, AppCtx, run_app},
18    event::EventBatch,
19    window::{WindowDescriptor, WinitPhysicalSize},
20};
21use std::sync::Arc;
22
23struct RenderGraphDemo {
24    _context: Arc<GraphicsContext>,
25    window: RenderWindow,
26    window_id: WindowId,
27}
28
29fn main() {
30    logging::init();
31
32    run_app(|ctx| {
33        let graphics_ctx =
34            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
35
36        let window = ctx
37            .create_window(WindowDescriptor {
38                title: "Render Graph Demo - Multi-Pass Rendering".to_string(),
39                size: Some(WinitPhysicalSize::new(1024.0, 768.0)),
40                ..Default::default()
41            })
42            .expect("Failed to create window");
43
44        let window = RenderWindowBuilder::new()
45            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
46            .with_depth_default()
47            .build(window, graphics_ctx.clone())
48            .expect("Failed to create render window");
49
50        let window_id = window.id();
51
52        println!("\n═══════════════════════════════════════════════════════");
53        println!("  🔀 RENDER GRAPH DEMO - Multi-Pass Rendering");
54        println!("═══════════════════════════════════════════════════════");
55        println!("\n  RENDER GRAPH FEATURES:");
56        println!("    • Declarative pass definition");
57        println!("    • Automatic dependency resolution");
58        println!("    • Resource lifetime management");
59        println!("    • Parallel pass execution");
60        println!("    • Automatic optimization");
61        println!("\n  EXAMPLE PIPELINE:");
62        println!("    1. Shadow Pass → depth texture");
63        println!("    2. Geometry Pass → color + normal + depth");
64        println!("    3. Lighting Pass → lit scene");
65        println!("    4. Post-Processing → bloom, tone mapping");
66        println!("    5. UI Pass → final composite");
67        println!("\n  Render Graph API Usage:");
68        println!("    let mut graph = RenderGraph::new();");
69        println!("    graph.add_pass(\"shadow\", shadow_pass_descriptor);");
70        println!("    graph.add_pass(\"geometry\", geometry_pass_descriptor);");
71        println!("    graph.add_dependency(\"lighting\", \"geometry\");");
72        println!("    graph.compile();");
73        println!("    graph.execute(&mut encoder);");
74        println!("═══════════════════════════════════════════════════════\n");
75
76        tracing::info!("Render graph demo initialized");
77
78        Box::new(RenderGraphDemo {
79            _context: graphics_ctx,
80            window,
81            window_id,
82        })
83    });
84}
85
86impl App for RenderGraphDemo {
87    fn update(&mut self, _ctx: &mut AppCtx, _time: &FrameTime) {}
88
89    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
90        if window_id != self.window_id {
91            return;
92        }
93
94        events.dispatch(|event| {
95            if let astrelis_winit::event::Event::WindowResized(size) = event {
96                self.window.resized(*size);
97                astrelis_winit::event::HandleStatus::consumed()
98            } else {
99                astrelis_winit::event::HandleStatus::ignored()
100            }
101        });
102
103        let Some(frame) = self.window.begin_frame() else {
104            return; // Surface not available
105        };
106        {
107            let _pass = frame
108                .render_pass()
109                .clear_color(Color::from_rgb_u8(20, 30, 40))
110                .label("render_graph_demo_pass")
111                .build();
112        }
113        // Frame auto-submits on drop
114    }
115}