camera_demo/
camera_demo.rs

1//! Camera Demo - Orthographic and Perspective Cameras
2//!
3//! Demonstrates camera systems for 3D rendering:
4//! - Orthographic cameras (2D/UI, isometric games)
5//! - Perspective cameras (3D scenes)
6//! - View matrix construction
7//! - Projection matrix construction
8//! - Screen-to-world conversion
9//! - Camera movement and controls
10//!
11//! **Note:** This demonstrates the Camera API structure.
12
13use astrelis_core::logging;
14use astrelis_render::{Color, GraphicsContext, RenderTarget, RenderableWindow, WindowContextDescriptor, wgpu};
15use astrelis_winit::{
16    FrameTime, WindowId,
17    app::{App, AppCtx, run_app},
18    event::EventBatch,
19    window::{WinitPhysicalSize, WindowBackend, WindowDescriptor},
20};
21use std::sync::Arc;
22
23struct CameraDemo {
24    _context: Arc<GraphicsContext>,
25    window: RenderableWindow,
26    window_id: WindowId,
27}
28
29fn main() {
30    logging::init();
31
32    run_app(|ctx| {
33        let graphics_ctx = GraphicsContext::new_owned_sync_or_panic();
34
35        let window = ctx
36            .create_window(WindowDescriptor {
37                title: "Camera Demo - View & Projection".to_string(),
38                size: Some(WinitPhysicalSize::new(1024.0, 768.0)),
39                ..Default::default()
40            })
41            .expect("Failed to create window");
42
43        let window = RenderableWindow::new_with_descriptor(
44            window,
45            graphics_ctx.clone(),
46            WindowContextDescriptor {
47                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
48                ..Default::default()
49            },
50        ).expect("Failed to create renderable window");
51
52        let window_id = window.id();
53
54        println!("\n═══════════════════════════════════════════════════════");
55        println!("  📹 CAMERA DEMO - View & Projection");
56        println!("═══════════════════════════════════════════════════════");
57        println!("\n  CAMERA API FEATURES:");
58        println!("    • Orthographic cameras (2D, UI, isometric)");
59        println!("    • Perspective cameras (3D scenes)");
60        println!("    • View matrix (position, rotation, look-at)");
61        println!("    • Projection matrix (FOV, aspect, near/far planes)");
62        println!("    • Screen-to-world coordinate conversion");
63        println!("    • Camera movement helpers");
64        println!("\n  CAMERA TYPES:");
65        println!("    • OrthographicCamera - 2D games, UI overlays");
66        println!("      camera.orthographic(left, right, bottom, top, near, far)");
67        println!("    • PerspectiveCamera - 3D scenes");
68        println!("      camera.perspective(fov, aspect, near, far)");
69        println!("\n  Camera API Usage:");
70        println!("    let camera = Camera::new()");
71        println!("        .position(Vec3::new(0.0, 5.0, 10.0))");
72        println!("        .look_at(Vec3::ZERO)");
73        println!("        .perspective(60.0, aspect, 0.1, 100.0);");
74        println!("    let view_proj = camera.view_projection_matrix();");
75        println!("═══════════════════════════════════════════════════════\n");
76
77        tracing::info!("Camera demo initialized");
78
79        Box::new(CameraDemo {
80            _context: graphics_ctx,
81            window,
82            window_id,
83        })
84    });
85}
86
87impl App for CameraDemo {
88    fn update(&mut self, _ctx: &mut AppCtx, _time: &FrameTime) {}
89
90    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
91        if window_id != self.window_id {
92            return;
93        }
94
95        events.dispatch(|event| {
96            if let astrelis_winit::event::Event::WindowResized(size) = event {
97                self.window.resized(*size);
98                astrelis_winit::event::HandleStatus::consumed()
99            } else {
100                astrelis_winit::event::HandleStatus::ignored()
101            }
102        });
103
104        let mut frame = self.window.begin_drawing();
105        frame.clear_and_render(
106            RenderTarget::Surface,
107            Color::from_rgb_u8(20, 30, 40),
108            |_pass| {},
109        );
110        frame.finish();
111    }
112}