astrelis-render 0.2.4

Astrelis Core Rendering Module
Documentation
//! Multi-window example demonstrating multiple RenderableWindows.
//!
//! This example creates 3 windows, each with a different clear color:
//! - Red window
//! - Green window
//! - Blue window
//!
//! Each window shares the same GraphicsContext and renders independently
//! using the RenderPassBuilder API.

use astrelis_core::logging;
use astrelis_render::{Color, GraphicsContext, RenderWindow, RenderWindowBuilder};
use astrelis_winit::{
    WindowId,
    app::run_app,
    window::{WindowDescriptor, WinitPhysicalSize},
};
use std::collections::HashMap;

struct App {
    // Each window gets its own RenderWindow (owns a wgpu::Surface) plus a clear color.
    windows: HashMap<WindowId, (RenderWindow, wgpu::Color)>,
}

fn main() {
    logging::init();

    run_app(|ctx| {
        let graphics_ctx =
            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");

        let mut windows = HashMap::new();

        // Create 3 windows with different colors
        let colors = [
            wgpu::Color {
                r: 0.8,
                g: 0.2,
                b: 0.2,
                a: 1.0,
            },
            wgpu::Color {
                r: 0.2,
                g: 0.8,
                b: 0.2,
                a: 1.0,
            },
            wgpu::Color {
                r: 0.2,
                g: 0.2,
                b: 0.8,
                a: 1.0,
            },
        ];

        for (i, color) in colors.iter().enumerate() {
            let window = ctx
                .create_window(WindowDescriptor {
                    title: format!("Window {} - Multi-Window Example", i + 1),
                    size: Some(WinitPhysicalSize::new(400.0, 300.0)),
                    ..Default::default()
                })
                .expect("Failed to create window");

            let renderable_window = RenderWindowBuilder::new()
                .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
                .with_depth_default()
                .build(window, graphics_ctx.clone())
                .expect("Failed to create render window");

            let window_id = renderable_window.id();
            windows.insert(window_id, (renderable_window, *color));
        }

        Box::new(App { windows })
    });
}

impl astrelis_winit::app::App for App {
    fn update(
        &mut self,
        _ctx: &mut astrelis_winit::app::AppCtx,
        _time: &astrelis_winit::FrameTime,
    ) {
        // Global logic - called once per frame
        // (none needed for this example)
    }

    fn render(
        &mut self,
        _ctx: &mut astrelis_winit::app::AppCtx,
        window_id: WindowId,
        events: &mut astrelis_winit::event::EventBatch,
    ) {
        // Get the window and color for this specific window
        let Some((window, color)) = self.windows.get_mut(&window_id) else {
            return;
        };

        // Handle resize: each window dispatches events independently.
        events.dispatch(|event| {
            if let astrelis_winit::event::Event::WindowResized(size) = event {
                window.resized(*size);
                astrelis_winit::event::HandleStatus::consumed()
            } else {
                astrelis_winit::event::HandleStatus::ignored()
            }
        });

        // Render this specific window
        let Some(frame) = window.begin_frame() else {
            return; // Surface not available
        };

        {
            let _pass = frame
                .render_pass()
                .clear_color(Color::rgba(
                    color.r as f32,
                    color.g as f32,
                    color.b as f32,
                    color.a as f32,
                ))
                .label("multi_window_pass")
                .build();
            // Just clearing - no rendering commands needed
        }
        // Frame auto-submits on drop
    }
}