use nightshade_ecs::Entity;
use std::collections::HashMap;
pub struct UiFrameInputs {
pub rects: Vec<crate::paint::DrawRect>,
pub rect_entities: Vec<Option<Entity>>,
pub images: Vec<crate::paint::DrawImage>,
pub text_meshes: Vec<crate::paint::DrawText>,
pub render_slots: crate::paint::RenderSlotAllocator,
pub background_color: Option<nalgebra_glm::Vec4>,
}
pub struct ViewInputs {
pub active_camera: Option<Entity>,
pub uptime_milliseconds: u64,
pub delta_time: f32,
pub viewport_size: Option<(u32, u32)>,
pub camera_tile_rects: HashMap<Entity, crate::config::ViewportRect>,
pub camera_tile_render_iteration: u32,
pub active_viewport_rect: Option<crate::config::ViewportRect>,
}
#[derive(Clone, Copy)]
pub struct CameraMatricesInputs {
pub view: nalgebra_glm::Mat4,
pub projection: nalgebra_glm::Mat4,
pub camera_position: nalgebra_glm::Vec3,
}
#[derive(Clone, Copy)]
pub struct CameraProjectionParams {
pub z_near: f32,
pub z_far: f32,
pub y_fov_rad: f32,
pub aspect: f32,
pub orthographic: Option<(f32, f32)>,
}
impl Default for CameraProjectionParams {
fn default() -> Self {
Self {
z_near: 0.1,
z_far: 1000.0,
y_fov_rad: std::f32::consts::FRAC_PI_4,
aspect: 1.78,
orthographic: None,
}
}
}
#[derive(Clone, Copy)]
pub struct CameraTarget {
pub size: (u32, u32),
pub host_owned: bool,
}
#[derive(Clone)]
pub struct CameraFrameInputs {
pub entity: Entity,
pub matrices: Option<CameraMatricesInputs>,
pub projection: CameraProjectionParams,
pub constrained_aspect: Option<f32>,
pub effective_shading: crate::config::EffectiveShading,
pub update_mode: crate::config::ViewportUpdateMode,
pub world_transform: Option<nalgebra_glm::Mat4>,
pub target: Option<CameraTarget>,
}
pub enum RendererCommand {
UploadUiImageLayer {
layer: u32,
rgba_data: Vec<u8>,
width: u32,
height: u32,
},
LoadHdrSkybox {
hdr_data: Vec<u8>,
},
ReloadTexture {
name: String,
rgba_data: Vec<u8>,
width: u32,
height: u32,
},
SetColorLut {
data: Vec<u8>,
},
CaptureScreenshot {
path: Option<std::path::PathBuf>,
max_dimension: Option<u32>,
},
}
#[derive(Clone, Copy, Debug)]
pub struct RenderLine {
pub start: nalgebra_glm::Vec3,
pub end: nalgebra_glm::Vec3,
pub color: nalgebra_glm::Vec4,
pub entity_id: u32,
pub depth_mode: u32,
}
#[derive(Clone, Copy, Debug)]
pub struct RenderBoundingVolume {
pub center: nalgebra_glm::Vec3,
pub half_extents: nalgebra_glm::Vec3,
pub orientation: nalgebra_glm::Vec4,
pub transform: nalgebra_glm::Mat4,
pub color: nalgebra_glm::Vec4,
}
#[derive(Clone, Copy, Debug)]
pub struct RenderNormal {
pub position: nalgebra_glm::Vec3,
pub normal: nalgebra_glm::Vec3,
pub transform: nalgebra_glm::Mat4,
pub color: nalgebra_glm::Vec4,
pub length: f32,
}
#[derive(Default)]
pub struct LinesFrameInputs {
pub lines: Vec<RenderLine>,
pub bounding_volumes: Option<Vec<RenderBoundingVolume>>,
pub normals: Option<Vec<RenderNormal>>,
}
pub struct FrameInputs {
pub commands: Vec<RendererCommand>,
pub cameras: Vec<CameraFrameInputs>,
pub active_camera_frame: Option<CameraFrameInputs>,
pub fallback_shading: crate::config::EffectiveShading,
pub pick_request: Option<(u32, u32)>,
pub has_skinned_meshes: bool,
pub mesh_frame_state: Option<crate::mesh_state::MeshRenderStateInner>,
pub dirty_world_spheres: Vec<(nalgebra_glm::Vec3, f32)>,
pub global_dirty_signal: bool,
pub mouse_position: nalgebra_glm::Vec2,
pub force_render_cameras: std::collections::HashSet<Entity>,
pub debug_lines: LinesFrameInputs,
#[cfg(feature = "egui")]
pub egui: Option<EguiFrameInputs>,
}
#[cfg(feature = "egui")]
pub struct EguiFrameInputs {
pub textures_delta: egui::TexturesDelta,
pub pixels_per_point: f32,
pub paint_jobs: Vec<egui::ClippedPrimitive>,
}
#[derive(Default)]
pub struct FrameOutputs {
pub viewport_texture_sizes: Vec<(u32, u32)>,
pub force_render_cleared: Vec<Entity>,
pub frame_executed: bool,
}
pub struct RenderInputs {
pub scene_world: nightshade_ecs::dynamic::DynWorld,
pub settings: crate::config::RenderSettings,
pub debug_draw: crate::config::DebugDraw,
pub scene: crate::config::RendererState,
pub ibl_views: crate::config::IblViews,
pub shadow_atlas: crate::wgpu::passes::shadow_depth::atlas::SpotlightAtlasAssignment,
pub wind: crate::wind::Wind,
pub mesh_cache: crate::mesh_cache::MeshCache,
pub texture_cache: crate::wgpu::texture_cache::TextureCache,
pub texture_store: crate::wgpu::texture_cache::TextureStore,
pub pending_particle_textures: Vec<crate::particles::ParticleTextureUpload>,
pub ui: UiFrameInputs,
pub view: ViewInputs,
pub world_id: u64,
pub frame: FrameInputs,
#[cfg(feature = "grass")]
pub grass: crate::grass_config::GrassSettings,
#[cfg(feature = "terrain")]
pub terrain: crate::terrain_config::TerrainSettings,
#[cfg(feature = "terrain")]
pub terrain_render: crate::terrain_config::TerrainRenderState,
}
impl CameraFrameInputs {
pub fn perspective(
entity: Entity,
view: nalgebra_glm::Mat4,
position: nalgebra_glm::Vec3,
projection: CameraProjectionParams,
effective_shading: crate::config::EffectiveShading,
) -> Self {
Self {
entity,
matrices: Some(CameraMatricesInputs {
view,
projection: crate::config::reverse_z_perspective(
projection.y_fov_rad,
projection.aspect,
projection.z_near,
projection.z_far,
),
camera_position: position,
}),
projection,
constrained_aspect: None,
effective_shading,
update_mode: crate::config::ViewportUpdateMode::Always,
world_transform: None,
target: None,
}
}
}
pub struct ViewFrame {
pub camera: CameraFrameInputs,
pub viewport: (u32, u32),
pub uptime_milliseconds: u64,
pub delta_time: f32,
}
impl RenderInputs {
pub fn single_view(
scene_world: nightshade_ecs::dynamic::DynWorld,
scene: crate::config::RendererState,
mesh_cache: crate::mesh_cache::MeshCache,
texture_cache: crate::wgpu::texture_cache::TextureCache,
settings: crate::config::RenderSettings,
debug_draw: crate::config::DebugDraw,
frame: ViewFrame,
) -> Self {
let ViewFrame {
camera,
viewport,
uptime_milliseconds,
delta_time,
} = frame;
let shading = camera.effective_shading;
let active_camera = camera.entity;
let has_skinned_meshes = !scene.render_skinned_meshes.is_empty();
Self {
scene_world,
settings,
debug_draw,
scene,
ibl_views: Default::default(),
shadow_atlas: Default::default(),
wind: crate::wind::Wind::default(),
mesh_cache,
texture_cache,
texture_store: Default::default(),
pending_particle_textures: Vec::new(),
ui: UiFrameInputs {
rects: Vec::new(),
rect_entities: Vec::new(),
images: Vec::new(),
text_meshes: Vec::new(),
render_slots: Default::default(),
background_color: None,
},
view: ViewInputs {
active_camera: Some(active_camera),
uptime_milliseconds,
delta_time,
viewport_size: Some(viewport),
camera_tile_rects: HashMap::new(),
camera_tile_render_iteration: 0,
active_viewport_rect: None,
},
world_id: 0,
frame: FrameInputs {
commands: Vec::new(),
cameras: Vec::new(),
active_camera_frame: Some(camera),
fallback_shading: shading,
pick_request: None,
has_skinned_meshes,
mesh_frame_state: Some(crate::mesh_state::MeshRenderStateInner {
full_rebuild_needed: true,
..Default::default()
}),
dirty_world_spheres: Vec::new(),
global_dirty_signal: true,
mouse_position: nalgebra_glm::Vec2::zeros(),
force_render_cameras: std::collections::HashSet::new(),
debug_lines: LinesFrameInputs::default(),
#[cfg(feature = "egui")]
egui: None,
},
#[cfg(feature = "grass")]
grass: Default::default(),
#[cfg(feature = "terrain")]
terrain: Default::default(),
#[cfg(feature = "terrain")]
terrain_render: Default::default(),
}
}
}
pub struct SingleViewHost {
pub scene_world: nightshade_ecs::dynamic::DynWorld,
pub state: crate::config::RendererState,
pub mesh_cache: crate::mesh_cache::MeshCache,
pub texture_cache: crate::wgpu::texture_cache::TextureCache,
pub settings: crate::config::RenderSettings,
pub debug_draw: crate::config::DebugDraw,
}
pub fn compose_single_view(host: &mut SingleViewHost, frame: ViewFrame) -> RenderInputs {
RenderInputs::single_view(
std::mem::replace(
&mut host.scene_world,
nightshade_ecs::dynamic::DynWorld::new(),
),
std::mem::take(&mut host.state),
std::mem::take(&mut host.mesh_cache),
std::mem::take(&mut host.texture_cache),
std::mem::take(&mut host.settings),
std::mem::take(&mut host.debug_draw),
frame,
)
}
pub fn restore_single_view(host: &mut SingleViewHost, inputs: RenderInputs) {
*host = SingleViewHost {
scene_world: inputs.scene_world,
state: inputs.scene,
mesh_cache: inputs.mesh_cache,
texture_cache: inputs.texture_cache,
settings: inputs.settings,
debug_draw: inputs.debug_draw,
};
}