nightshade 0.13.3

A cross-platform data-oriented game engine.
Documentation
//! wgpu rendering backend.
//!
//! Implements the [`Render`](crate::ecs::world::Render) trait using wgpu, supporting
//! DirectX 12, Metal, Vulkan, and WebGPU backends.
//!
//! Key types:
//!
//! - [`WgpuRenderer`]: Main renderer managing the GPU device, surface, and render graph
//! - [`CameraViewport`]: Off-screen render target for camera output (used by egui viewports)
//! - [`SecondarySurface`]: Surface state for multi-window rendering
//!
//! Submodules:
//!
//! - [`rendergraph`]: Declarative pass-based render graph with automatic resource management
//! - [`passes`]: Built-in geometry, shadow, and post-processing passes
//! - [`texture_cache`]: GPU texture caching and lifecycle management
//! - [`font_atlas`]: SDF font atlas for text rendering
//! - [`sprite_texture_atlas`]: Texture atlas for 2D sprite batching

pub mod brdf_lut;
#[cfg(feature = "egui")]
mod egui_integration;
#[cfg(feature = "assets")]
pub mod envmap_filter;
mod execution;
pub mod font_atlas;
#[cfg(feature = "assets")]
pub mod hdr;
mod initialization;
pub mod passes;
mod render_trait;
pub mod rendergraph;
pub mod sprite_shapes;
pub mod sprite_texture_atlas;
pub mod text_mesh;
pub mod texture_cache;

#[cfg(feature = "egui")]
pub struct CameraViewport {
    pub texture: wgpu::Texture,
    pub view: wgpu::TextureView,
    pub texture_id: egui::TextureId,
    pub size: (u32, u32),
}

#[cfg(not(feature = "egui"))]
pub struct CameraViewport {
    pub texture: wgpu::Texture,
    pub view: wgpu::TextureView,
    pub size: (u32, u32),
}

#[cfg(feature = "egui")]
type SecondaryCameraViewportCache = std::collections::HashMap<
    usize,
    std::collections::HashMap<freecs::Entity, (egui::TextureId, (u32, u32))>,
>;

const DEPTH_PICK_SAMPLE_SIZE: u32 = 5;

pub struct SecondarySurface {
    pub surface: wgpu::Surface<'static>,
    pub config: wgpu::SurfaceConfiguration,
    pub format: wgpu::TextureFormat,
    pub width: u32,
    pub height: u32,
    #[cfg(feature = "egui")]
    pub egui_renderer: Option<egui_wgpu::Renderer>,
    #[cfg(feature = "egui")]
    pub egui_depth_texture: Option<wgpu::Texture>,
    #[cfg(feature = "egui")]
    pub egui_depth_view: Option<wgpu::TextureView>,
    #[cfg(feature = "egui")]
    pub egui_depth_size: (u32, u32),
}

pub struct WgpuRenderer {
    instance: wgpu::Instance,
    adapter: wgpu::Adapter,
    secondary_surfaces: std::collections::HashMap<usize, SecondarySurface>,
    surface: wgpu::Surface<'static>,
    device: wgpu::Device,
    queue: wgpu::Queue,
    surface_config: wgpu::SurfaceConfiguration,
    surface_format: wgpu::TextureFormat,
    graph: rendergraph::RenderGraph<crate::ecs::world::World>,
    depth_id: rendergraph::ResourceId,
    scene_color_id: rendergraph::ResourceId,
    compute_output_id: rendergraph::ResourceId,
    swapchain_id: rendergraph::ResourceId,
    viewport_resource_id: rendergraph::ResourceId,
    ui_depth_id: rendergraph::ResourceId,
    entity_id_id: rendergraph::ResourceId,
    view_normals_id: rendergraph::ResourceId,
    ssao_raw_id: rendergraph::ResourceId,
    ssao_id: rendergraph::ResourceId,
    ssgi_raw_id: rendergraph::ResourceId,
    ssgi_id: rendergraph::ResourceId,
    ssr_raw_id: rendergraph::ResourceId,
    ssr_id: rendergraph::ResourceId,
    ui_image_pass: Option<Box<passes::UiImagePass>>,
    #[cfg(feature = "egui")]
    egui_pass: Option<Box<passes::EguiPass>>,
    msdf_font_textures: Vec<(wgpu::Texture, wgpu::TextureView)>,
    bitmap_font_textures: Vec<(wgpu::Texture, wgpu::TextureView)>,
    font_data: Vec<crate::ecs::text::resources::FontAtlasData>,
    bitmap_font_data: Vec<crate::ecs::text::resources::FontAtlasData>,
    font_initialized: bool,
    bitmap_atlas_scale: f32,
    bitmap_atlas_subpixel: bool,
    bitmap_font_sources: Vec<(Vec<u8>, f32)>,
    camera_viewports: std::collections::HashMap<freecs::Entity, CameraViewport>,
    _brdf_lut_texture: wgpu::Texture,
    brdf_lut_view: wgpu::TextureView,
    depth_pick_compute_pipeline: wgpu::ComputePipeline,
    depth_pick_bind_group_layout: wgpu::BindGroupLayout,
    depth_pick_storage_buffer: wgpu::Buffer,
    depth_pick_uniform_buffer: wgpu::Buffer,
    depth_pick_staging_buffer: wgpu::Buffer,
    depth_pick_bind_group: Option<wgpu::BindGroup>,
    depth_pick_pending: bool,
    depth_pick_map_complete: std::sync::Arc<std::sync::atomic::AtomicBool>,
    depth_pick_center: (u32, u32),
    #[cfg(not(target_arch = "wasm32"))]
    screenshot_staging_buffer: wgpu::Buffer,
    #[cfg(not(target_arch = "wasm32"))]
    screenshot_pending: bool,
    #[cfg(not(target_arch = "wasm32"))]
    screenshot_map_complete: std::sync::Arc<std::sync::atomic::AtomicBool>,
    #[cfg(not(target_arch = "wasm32"))]
    screenshot_path: Option<std::path::PathBuf>,
    #[cfg(not(target_arch = "wasm32"))]
    screenshot_width: u32,
    #[cfg(not(target_arch = "wasm32"))]
    screenshot_height: u32,
    render_buffer_size: (u32, u32),
    #[cfg(feature = "egui")]
    secondary_camera_viewport_cache: SecondaryCameraViewportCache,
}

type AcquiredSurface = (wgpu::SurfaceTexture, wgpu::TextureView, u32, u32);

enum PassMode {
    World { enable_ui: bool },
    UiOnly,
}

struct SavedUiState {
    did_swap: bool,
    frame_rects: Vec<passes::UiRect>,
    frame_ui_images: Vec<passes::UiImage>,
    frame_text_meshes: Vec<crate::ecs::ui::UiTextInstance>,
    cached_viewport_size: Option<(u32, u32)>,
    render_buffer_size: (u32, u32),
}

pub async fn create_wgpu_renderer<W>(
    window_handle: W,
    initial_width: u32,
    initial_height: u32,
) -> Result<WgpuRenderer, Box<dyn std::error::Error>>
where
    W: Into<wgpu::SurfaceTarget<'static>>,
{
    WgpuRenderer::new_async(window_handle, initial_width, initial_height).await
}