//! Cyborg is a high-performance, modern, experimental rendering engine written //! in Rust. use rayon::prelude::*; use std::sync::{Arc, RwLock}; use strum::IntoEnumIterator; pub mod handle; pub mod pass; pub mod phase; pub mod scene; use pass::*; use phase::*; pub struct Renderer { pub frames_in_flight: usize, pub render_passes: Vec>, } impl Default for Renderer { fn default() -> Self { Self { frames_in_flight: 2, render_passes: Vec::new(), } } } impl Renderer { pub fn add_pass(&mut self, pass: T) { let pass = Arc::new(RwLock::new(pass)); self.add_pass_arc(pass); } pub fn add_pass_arc(&mut self, pass: Arc>) { let pass = RenderPassBox::new(pass, self.frames_in_flight); self.add_pass_box(pass); } pub fn add_pass_box(&mut self, pass: Box) { self.render_passes.push(pass); } pub fn render(&mut self) { let frame_index = 0; let phase_passes = PhaseMultiMap::::default(); let phase_passes = std::sync::Mutex::new(phase_passes); self.render_passes .par_iter_mut() .enumerate() .for_each(|(pass_index, rp)| { let mut phases_buf = PhaseList::default(); phases_buf.clear(); rp.begin_frame(frame_index, &mut phases_buf); phase_passes .lock() .unwrap() .insert_multi(&phases_buf, pass_index); }); let phase_passes = phase_passes.into_inner().unwrap(); PrePhase::iter().par_bridge().for_each(|phase| { for pass_index in phase_passes.iter_pre(&phase) { let pass = &self.render_passes[*pass_index]; let mut encoder = gpu::RenderBundleEncoder; pass.render_pre(phase, frame_index, &mut encoder); } }); let viewport = ViewportData; ViewportPhase::iter().par_bridge().for_each(|phase| { for pass_index in phase_passes.iter_viewport(&phase) { let pass = &self.render_passes[*pass_index]; let mut encoder = gpu::RenderBundleEncoder; pass.render_viewport(phase, frame_index, &viewport, &mut encoder); } }); } } /// Mock GPU API (like Vulkan, WebGPU, or OpenGL) types for prototyping. pub mod gpu { /// Thread-safe GPU command recorder that's later executed in a command buffer. /// /// Also known as a: /// - RenderBundleEncoder in WebGPU /// - secondary command buffer in Vulkan pub struct RenderBundleEncoder; }