camera_demo/
camera_demo.rs1use astrelis_core::logging;
15use astrelis_render::{Color, GraphicsContext, RenderWindow, RenderWindowBuilder, wgpu};
16use astrelis_winit::{
17 FrameTime, WindowId,
18 app::{App, AppCtx, run_app},
19 event::EventBatch,
20 window::{WindowDescriptor, WinitPhysicalSize},
21};
22use std::sync::Arc;
23
24struct CameraDemo {
25 _context: Arc<GraphicsContext>,
26 window: RenderWindow,
27 window_id: WindowId,
28}
29
30fn main() {
31 logging::init();
32
33 run_app(|ctx| {
34 let graphics_ctx =
35 GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
36
37 let window = ctx
38 .create_window(WindowDescriptor {
39 title: "Camera Demo - View & Projection".to_string(),
40 size: Some(WinitPhysicalSize::new(1024.0, 768.0)),
41 ..Default::default()
42 })
43 .expect("Failed to create window");
44
45 let window = RenderWindowBuilder::new()
46 .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
47 .with_depth_default()
48 .build(window, graphics_ctx.clone())
49 .expect("Failed to create render window");
50
51 let window_id = window.id();
52
53 println!("\n═══════════════════════════════════════════════════════");
54 println!(" 📹 CAMERA DEMO - View & Projection");
55 println!("═══════════════════════════════════════════════════════");
56 println!("\n CAMERA API FEATURES:");
57 println!(" • Orthographic cameras (2D, UI, isometric)");
58 println!(" • Perspective cameras (3D scenes)");
59 println!(" • View matrix (position, rotation, look-at)");
60 println!(" • Projection matrix (FOV, aspect, near/far planes)");
61 println!(" • Screen-to-world coordinate conversion");
62 println!(" • Camera movement helpers");
63 println!("\n CAMERA TYPES:");
64 println!(" • OrthographicCamera - 2D games, UI overlays");
65 println!(" camera.orthographic(left, right, bottom, top, near, far)");
66 println!(" • PerspectiveCamera - 3D scenes");
67 println!(" camera.perspective(fov, aspect, near, far)");
68 println!("\n Camera API Usage:");
69 println!(" let camera = Camera::new()");
70 println!(" .position(Vec3::new(0.0, 5.0, 10.0))");
71 println!(" .look_at(Vec3::ZERO)");
72 println!(" .perspective(60.0, aspect, 0.1, 100.0);");
73 println!(" let view_proj = camera.view_projection_matrix();");
74 println!("═══════════════════════════════════════════════════════\n");
75
76 tracing::info!("Camera demo initialized");
77
78 Box::new(CameraDemo {
79 _context: graphics_ctx,
80 window,
81 window_id,
82 })
83 });
84}
85
86impl App for CameraDemo {
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; };
106 {
107 let _pass = frame
108 .render_pass()
109 .clear_color(Color::from_rgb_u8(20, 30, 40))
110 .label("camera_demo_pass")
111 .build();
112 }
113 }
115}