Merge branch 'main' into renovate/downcast-rs-2.x

This commit is contained in:
hodasemi 2025-03-03 19:10:26 +00:00
commit e0aef9aac9
21 changed files with 415 additions and 411 deletions

View file

@ -34,7 +34,7 @@ chrono = { version = "0.4.35", features = ["serde"] }
anyhow = { version = "1.0.86", features = ["backtrace"] } anyhow = { version = "1.0.86", features = ["backtrace"] }
indexmap = { version = "2.2.6", features = ["rayon"] } indexmap = { version = "2.2.6", features = ["rayon"] }
shaderc = { version = "0.8.3", features = ["build-from-source"] } shaderc = { version = "0.8.3", features = ["build-from-source"] }
rusqlite = { version = "0.32.0", features = ["bundled"] } rusqlite = { version = "0.33.0", features = ["bundled"] }
cgmath = "0.18.0" cgmath = "0.18.0"
http = "1.1.0" http = "1.1.0"
iterchunks = "0.5.0" iterchunks = "0.5.0"

View file

@ -60,7 +60,7 @@ impl Context {
pub fn next_frame<C, F>(&mut self, world: &mut World, mut f: F) -> Result<bool> pub fn next_frame<C, F>(&mut self, world: &mut World, mut f: F) -> Result<bool>
where where
C: Send + Sync + 'static, C: Send + Sync + 'static,
F: FnMut(&mut World, &mut C, Event) -> Result<()> + Send + Sync + 'static, F: FnMut(&mut World, &mut C, Event<'_>) -> Result<()> + Send + Sync + 'static,
{ {
let render_core = self.render_core.clone(); let render_core = self.render_core.clone();
let consumer = world.resources.get_mut_unchecked::<C>(); let consumer = world.resources.get_mut_unchecked::<C>();
@ -72,6 +72,7 @@ impl Context {
) { ) {
Ok(res) => { Ok(res) => {
if !res { if !res {
self.device().wait_idle()?;
return Ok(false); return Ok(false);
} }
} }
@ -116,18 +117,12 @@ impl Context {
self.core.queue() self.core.queue()
} }
pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] { pub fn controllers(&self) -> impl Iterator<Item = &Controller> {
self.presentation.event_system().controllers() self.presentation.event_system().controllers()
} }
pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> { pub fn joysticks(&self) -> impl Iterator<Item = &Joystick> {
self.presentation.event_system().active_controller() self.presentation.event_system().joysticks()
}
pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) {
self.presentation
.event_system_mut()
.set_active_controller(controller)
} }
} }

View file

@ -229,7 +229,7 @@ pub enum ComponentRequestType {
#[derive(Debug)] #[derive(Debug)]
pub struct ComponentNotFoundError { pub struct ComponentNotFoundError {
request_type: ComponentRequestType, pub request_type: ComponentRequestType,
} }
impl ComponentNotFoundError { impl ComponentNotFoundError {

View file

@ -341,7 +341,7 @@ pub struct ArchetypeInfo {
} }
impl ArchetypeInfo { impl ArchetypeInfo {
pub(crate) fn new(entities: Vec<(Entity, Option<String>)>) -> Self { pub fn new(entities: Vec<(Entity, Option<String>)>) -> Self {
Self { entities } Self { entities }
} }
@ -388,7 +388,7 @@ impl Archetype {
Ok(()) Ok(())
} }
pub(crate) fn entities( pub fn entities(
&self, &self,
) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut World) -> Result<()> + Send + Sync>> { ) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut World) -> Result<()> + Send + Sync>> {
&self.entities &self.entities
@ -572,12 +572,12 @@ impl Updates {
} }
} }
pub(crate) fn clear(&mut self) { // pub(crate) fn clear(&mut self) {
self.updates.clear(); // self.updates.clear();
#[cfg(feature = "timings")] // #[cfg(feature = "timings")]
self.timings.clear(); // self.timings.clear();
} // }
pub(crate) fn add(&mut self, name: &str, priority: u32, update: Update) -> Result<()> { pub(crate) fn add(&mut self, name: &str, priority: u32, update: Update) -> Result<()> {
#[cfg(feature = "timings")] #[cfg(feature = "timings")]

View file

@ -13,9 +13,7 @@ use crate::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
pub struct GuiHandlerRenderer { pub struct GuiHandlerRenderer;
pub gui_handler: Arc<GuiHandler>,
}
impl TScene for GuiHandlerRenderer { impl TScene for GuiHandlerRenderer {
fn process( fn process(
@ -23,9 +21,12 @@ impl TScene for GuiHandlerRenderer {
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'_>,
_images: &TargetMode<Vec<Arc<Image>>>, _images: &TargetMode<Vec<Arc<Image>>>,
indices: &TargetMode<usize>, indices: &TargetMode<usize>,
_world: &World, world: &World,
) -> Result<()> { ) -> Result<()> {
self.gui_handler.process(buffer_recorder, indices) world
.resources
.get::<Arc<GuiHandler>>()
.process(buffer_recorder, indices)
} }
fn resize( fn resize(
@ -33,16 +34,17 @@ impl TScene for GuiHandlerRenderer {
window_width: f32, window_width: f32,
window_height: f32, window_height: f32,
images: &TargetMode<Vec<Arc<Image>>>, images: &TargetMode<Vec<Arc<Image>>>,
world: &World,
) -> Result<()> { ) -> Result<()> {
self.gui_handler world.resources.get::<Arc<GuiHandler>>().resize(
.resize(window_width as u32, window_height as u32, images) window_width as u32,
window_height as u32,
images,
)
} }
} }
pub struct Engine { pub struct Engine {
// loads and keeps track of raw data
asset_manager: AssetManager,
pub(crate) resource_base_path: String, pub(crate) resource_base_path: String,
} }
@ -171,16 +173,7 @@ impl Engine {
)?; )?;
let asset_manager = AssetManager::new(&engine_settings)?; let asset_manager = AssetManager::new(&engine_settings)?;
let gui_handler = GuiHandler::new(create_info.gui_info, &context)?;
let gui_handler = GuiHandlerRenderer {
gui_handler: GuiHandler::new(create_info.gui_info, &context)?,
};
let engine = Engine {
asset_manager,
resource_base_path: create_info.resource_base_path,
};
context context
.render_core_mut() .render_core_mut()
@ -189,7 +182,7 @@ impl Engine {
world.resources.insert(context); world.resources.insert(context);
let scene = Scene::new( Scene::new(
create_info.rasterizer_info, create_info.rasterizer_info,
create_info.raytracing_info, create_info.raytracing_info,
create_info.graphics_info, create_info.graphics_info,
@ -204,11 +197,13 @@ impl Engine {
direction_mapping.insert(Keycode::Down, GuiDirection::Down); direction_mapping.insert(Keycode::Down, GuiDirection::Down);
world.resources.insert(gui_handler); world.resources.insert(gui_handler);
world.resources.insert(GuiHandlerRenderer);
world.resources.insert(InputMap { direction_mapping }); world.resources.insert(InputMap { direction_mapping });
world.resources.insert(asset_manager);
world.resources.insert(engine); world.resources.insert(Engine {
resource_base_path: create_info.resource_base_path,
});
world.resources.insert(engine_settings); world.resources.insert(engine_settings);
world.resources.insert(scene);
world.add_system(Self::main_system::<T>); world.add_system(Self::main_system::<T>);
@ -254,25 +249,18 @@ impl Engine {
impl Engine { impl Engine {
fn main_system<T: EventConsumer>(world: &mut World) -> Result<bool> { fn main_system<T: EventConsumer>(world: &mut World) -> Result<bool> {
let gui_handler = world.resources.get_unchecked::<GuiHandlerRenderer>(); let gui_handler = world.resources.get_unchecked::<Arc<GuiHandler>>();
let input_map = world.resources.get_unchecked::<InputMap>(); let input_map = world.resources.get_unchecked::<InputMap>();
let context = world.resources.get_unchecked::<Context>(); let context = world.resources.get_unchecked::<Context>();
let res = world.resources.get_mut_unchecked::<Context>().next_frame( let res = world.resources.get_mut_unchecked::<Context>().next_frame(
world, world,
|world, consumer: &mut T, event| { |world, consumer: &mut T, event| {
Self::event( Self::event(world, context, gui_handler, input_map, consumer, event)
world,
context,
&gui_handler.gui_handler,
input_map,
consumer,
event,
)
}, },
)?; )?;
gui_handler.gui_handler.process_callbacks()?; gui_handler.process_callbacks()?;
Ok(res) Ok(res)
} }

View file

@ -1,14 +1,9 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{Arc, RwLock};
// use super::engine_object_data::{EngineObjectAccess, EngineObjectDataHandle};
#[derive(Debug)] #[derive(Debug)]
pub enum EngineEvent { pub enum EngineEvent<'a> {
MouseMotion(u32, u32), MouseMotion(u32, u32),
MouseButtonDown(MouseButton), MouseButtonDown(MouseButton),
MouseButtonUp(MouseButton), MouseButtonUp(MouseButton),
@ -17,18 +12,23 @@ pub enum EngineEvent {
KeyDown(Keycode), KeyDown(Keycode),
KeyUp(Keycode), KeyUp(Keycode),
ButtonDown(ControllerButton), ControllerButtonDown(&'a Controller, ControllerButton),
ButtonUp(ControllerButton), ControllerButtonUp(&'a Controller, ControllerButton),
ControllerAxis(ControllerAxis), ControllerAxis(&'a Controller, ControllerAxis),
ControllerAdded(&'a Controller),
ControllerRemoved(&'a Controller),
ControllerAdded(Arc<RwLock<Controller>>), JoystickButtonDown(&'a Joystick),
ControllerRemoved(Arc<RwLock<Controller>>), JoystickButtonUp(&'a Joystick),
JoystickAxis(&'a Joystick),
JoystickAdded(&'a Joystick),
JoystickRemoved(&'a Joystick),
FileDrop(String), FileDrop(String),
} }
pub trait EventConsumer: Send + Sync + 'static { pub trait EventConsumer: Send + Sync + 'static {
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()>; fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()>;
} }
pub struct InputMap { pub struct InputMap {
@ -42,7 +42,7 @@ impl Engine {
gui_handler: &GuiHandler, gui_handler: &GuiHandler,
input: &InputMap, input: &InputMap,
consumer: &mut T, consumer: &mut T,
event: Event, event: Event<'_>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
match event { match event {
Event::MouseMotion(x, y) => { Event::MouseMotion(x, y) => {
@ -71,15 +71,13 @@ impl Engine {
Event::TextInput(text) => { Event::TextInput(text) => {
Self::text_input(gui_handler, text)?; Self::text_input(gui_handler, text)?;
} }
Event::ControllerButtonDown(button) => { Event::ControllerButtonDown(controller, button) => {
Self::button_down_event(world, gui_handler, consumer, button)?; Self::button_down_event(world, gui_handler, consumer, controller, button)?;
} }
Event::ControllerButtonUp(button) => { Event::ControllerButtonUp(controller, button) => {
Self::button_up_event(world, consumer, button)?; Self::button_up_event(world, consumer, controller, button)?;
} }
Event::ControllerAxis(controller) => { Event::ControllerAxis(controller) => {
let controller = controller.read().unwrap();
if !gui_handler.check_navigatable()? { if !gui_handler.check_navigatable()? {
Self::axis_event(world, consumer, &controller)? Self::axis_event(world, consumer, &controller)?
} else { } else {
@ -92,6 +90,23 @@ impl Engine {
Event::ControllerRemoved(controller) => { Event::ControllerRemoved(controller) => {
Self::controller_removed(world, consumer, controller)? Self::controller_removed(world, consumer, controller)?
} }
Event::JoystickAxis(joystick) => {
consumer.event(world, EngineEvent::JoystickAxis(joystick))?
}
Event::JoystickButtonDown(joystick) => {
consumer.event(world, EngineEvent::JoystickButtonDown(joystick))?
}
Event::JoystickButtonUp(joystick) => {
consumer.event(world, EngineEvent::JoystickButtonUp(joystick))?
}
Event::JoystickAdded(joystick) => {
consumer.event(world, EngineEvent::JoystickAdded(joystick))?
}
Event::JoystickRemoved(joystick) => {
consumer.event(world, EngineEvent::JoystickRemoved(joystick))?
}
Event::FileDrop(filename) => consumer.event(world, EngineEvent::FileDrop(filename))?, Event::FileDrop(filename) => consumer.event(world, EngineEvent::FileDrop(filename))?,
} }
@ -104,7 +119,7 @@ impl Engine {
fn controller_added<T: EventConsumer>( fn controller_added<T: EventConsumer>(
world: &mut World, world: &mut World,
consumer: &mut T, consumer: &mut T,
controller: Arc<RwLock<Controller>>, controller: &Controller,
) -> Result<()> { ) -> Result<()> {
consumer.event(world, EngineEvent::ControllerAdded(controller))?; consumer.event(world, EngineEvent::ControllerAdded(controller))?;
@ -115,7 +130,7 @@ impl Engine {
fn controller_removed<T: EventConsumer>( fn controller_removed<T: EventConsumer>(
world: &mut World, world: &mut World,
consumer: &mut T, consumer: &mut T,
controller: Arc<RwLock<Controller>>, controller: &Controller,
) -> Result<()> { ) -> Result<()> {
consumer.event(world, EngineEvent::ControllerRemoved(controller))?; consumer.event(world, EngineEvent::ControllerRemoved(controller))?;
@ -192,9 +207,10 @@ impl Engine {
fn button_up_event<T: EventConsumer>( fn button_up_event<T: EventConsumer>(
world: &mut World, world: &mut World,
consumer: &mut T, consumer: &mut T,
controller: &Controller,
button: ControllerButton, button: ControllerButton,
) -> Result<()> { ) -> Result<()> {
consumer.event(world, EngineEvent::ButtonUp(button))?; consumer.event(world, EngineEvent::ControllerButtonUp(controller, button))?;
Ok(()) Ok(())
} }
@ -204,12 +220,13 @@ impl Engine {
world: &mut World, world: &mut World,
gui_handler: &GuiHandler, gui_handler: &GuiHandler,
consumer: &mut T, consumer: &mut T,
controller: &Controller,
button: ControllerButton, button: ControllerButton,
) -> Result<()> { ) -> Result<()> {
if gui_handler.check_navigatable()? { if gui_handler.check_navigatable()? {
Self::check_button_down(world, gui_handler, consumer, button)?; Self::check_button_down(world, gui_handler, consumer, controller, button)?;
} else { } else {
consumer.event(world, EngineEvent::ButtonDown(button))?; consumer.event(world, EngineEvent::ControllerButtonDown(controller, button))?;
} }
Ok(()) Ok(())
@ -223,7 +240,7 @@ impl Engine {
) -> Result<()> { ) -> Result<()> {
consumer.event( consumer.event(
world, world,
EngineEvent::ControllerAxis(controller.controller_axis()), EngineEvent::ControllerAxis(controller, controller.controller_axis()),
)?; )?;
Ok(()) Ok(())
@ -234,6 +251,7 @@ impl Engine {
world: &mut World, world: &mut World,
gui_handler: &GuiHandler, gui_handler: &GuiHandler,
consumer: &mut T, consumer: &mut T,
controller: &Controller,
button: ControllerButton, button: ControllerButton,
) -> Result<()> { ) -> Result<()> {
match button { match button {
@ -313,7 +331,7 @@ impl Engine {
} }
if !gui_handler.accept_custom_selection(button)? { if !gui_handler.accept_custom_selection(button)? {
consumer.event(world, EngineEvent::ButtonDown(button))?; consumer.event(world, EngineEvent::ControllerButtonDown(controller, button))?;
} }
Ok(()) Ok(())

View file

@ -205,7 +205,7 @@ impl EngineSettings {
button: ControllerButton, button: ControllerButton,
) -> Result<Option<Arc<Image>>> { ) -> Result<Option<Arc<Image>>> {
// TODO: don't check it every time we request a button // TODO: don't check it every time we request a button
self.check_controller(context)?; // self.check_controller(context)?;
match self.current_controller_type.read().unwrap().as_ref() { match self.current_controller_type.read().unwrap().as_ref() {
Some(controller_type) => Ok(Some(self.controller_button_for( Some(controller_type) => Ok(Some(self.controller_button_for(
@ -347,61 +347,61 @@ impl EngineSettings {
} }
} }
fn check_controller(&self, context: &Context) -> Result<()> { // fn check_controller(&self, context: &Context) -> Result<()> {
let active_controller = context.active_controller(); // let active_controller = context.active_controller();
match &active_controller { // match &active_controller {
// there is an controller connected // // there is an controller connected
Some(controller) => { // Some(controller) => {
let controller_name = controller.read().unwrap().name().clone(); // let controller_name = controller.read().unwrap().name().clone();
// predict controller type from name // // predict controller type from name
let controller_type = if controller_name.contains("PS4") { // let controller_type = if controller_name.contains("PS4") {
ControllerType::PS4 // ControllerType::PS4
} else if controller_name.contains("Steam") { // } else if controller_name.contains("Steam") {
ControllerType::Steam // ControllerType::Steam
} else { // } else {
ControllerType::XBox // ControllerType::XBox
}; // };
let mut current_controller_type = self.current_controller_type.write().unwrap(); // let mut current_controller_type = self.current_controller_type.write().unwrap();
// check if current controller type is set // // check if current controller type is set
if current_controller_type.is_some() { // if current_controller_type.is_some() {
// if controller type is set, check if it is different // // if controller type is set, check if it is different
if *current_controller_type.as_ref().unwrap() != controller_type { // if *current_controller_type.as_ref().unwrap() != controller_type {
*current_controller_type = Some(controller_type); // *current_controller_type = Some(controller_type);
let mut map = self.controller_buttons.write().unwrap(); // let mut map = self.controller_buttons.write().unwrap();
// clear map if filled // // clear map if filled
if !map.is_empty() { // if !map.is_empty() {
map.clear(); // map.clear();
} // }
} // }
} else { // } else {
// set the controller type // // set the controller type
*current_controller_type = Some(controller_type); // *current_controller_type = Some(controller_type);
} // }
} // }
// there is no controller connected // // there is no controller connected
None => { // None => {
let mut current_controller_type = self.current_controller_type.write().unwrap(); // let mut current_controller_type = self.current_controller_type.write().unwrap();
let mut map = self.controller_buttons.write().unwrap(); // let mut map = self.controller_buttons.write().unwrap();
// clear current type if set // // clear current type if set
if current_controller_type.is_some() { // if current_controller_type.is_some() {
*current_controller_type = None; // *current_controller_type = None;
} // }
// clear map if filled // // clear map if filled
if !map.is_empty() { // if !map.is_empty() {
map.clear(); // map.clear();
} // }
} // }
} // }
Ok(()) // Ok(())
} // }
} }

View file

@ -5,7 +5,7 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::{ use utilities::{
impl_reprc, impl_reprc,
prelude::cgmath::{vec3, InnerSpace, Rad, Vector3, Zero}, prelude::cgmath::{InnerSpace, Rad, Vector3, Zero, vec3},
}; };
use utilities::prelude::cgmath::{Matrix4, SquareMatrix}; use utilities::prelude::cgmath::{Matrix4, SquareMatrix};
@ -127,15 +127,15 @@ pub struct Light {
} }
impl Light { impl Light {
pub(crate) fn point_light(device: &Arc<Device>) -> Result<Light> { pub fn point_light(device: &Arc<Device>) -> Result<Light> {
Self::new(LightType::Point, device) Self::new(LightType::Point, device)
} }
pub(crate) fn directional_light(device: &Arc<Device>) -> Result<Light> { pub fn directional_light(device: &Arc<Device>) -> Result<Light> {
Self::new(LightType::Direction, device) Self::new(LightType::Direction, device)
} }
pub(crate) fn spot_light(device: &Arc<Device>) -> Result<Light> { pub fn spot_light(device: &Arc<Device>) -> Result<Light> {
Self::new(LightType::Spot, device) Self::new(LightType::Spot, device)
} }

View file

@ -205,7 +205,7 @@ impl TraditionalRasterizer {
.add_target_info(depth_target) .add_target_info(depth_target)
.set_sample_count(sample_count) .set_sample_count(sample_count)
// swapchain resolve targets // swapchain resolve targets
.add_resolve_targets((images, true)) .add_resolve_targets((images, false))
// resolved position target // resolved position target
.add_resolve_targets(CustomTarget { .add_resolve_targets(CustomTarget {
usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT

View file

@ -14,7 +14,6 @@ use super::super::timings::Timings;
use anyhow::Result; use anyhow::Result;
use ecs::*; use ecs::*;
use rayon::prelude::*;
use utilities::prelude::cgmath::{Matrix4, Vector3, vec3}; use utilities::prelude::cgmath::{Matrix4, Vector3, vec3};
use std::sync::Mutex; use std::sync::Mutex;
@ -28,9 +27,6 @@ pub struct Scene {
screen_width: f32, screen_width: f32,
screen_height: f32, screen_height: f32,
device: Arc<Device>,
queue: Arc<Mutex<Queue>>,
render_type: SceneType, render_type: SceneType,
last_frame: Duration, last_frame: Duration,
@ -92,9 +88,6 @@ impl Scene {
render_type, render_type,
device: device.clone(),
queue: queue.clone(),
frustum_check: None, frustum_check: None,
renderer, renderer,
@ -486,6 +479,7 @@ impl TScene for Scene {
window_width: f32, window_width: f32,
window_height: f32, window_height: f32,
images: &TargetMode<Vec<Arc<Image>>>, images: &TargetMode<Vec<Arc<Image>>>,
_world: &World,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
self.screen_width = window_width; self.screen_width = window_width;
self.screen_height = window_height; self.screen_height = window_height;

View file

@ -3,7 +3,7 @@ use std::path::Path;
use anyhow::Result; use anyhow::Result;
use ecs::*; use ecs::*;
use engine::prelude::*; use engine::prelude::{cgmath::vec3, *};
use skybox::SkyBox; use skybox::SkyBox;
fn main() -> Result<()> { fn main() -> Result<()> {
@ -14,6 +14,7 @@ fn main() -> Result<()> {
world_builder.add_system(GameState::update); world_builder.add_system(GameState::update);
world_builder.resources.insert(GameState::Startup); world_builder.resources.insert(GameState::Startup);
// let dir = Path::new("C:/Users/M.Huebner/Downloads/Space Skybox Generator/Export");
let dir = Path::new("/home/michaelh/Sync/skybox"); let dir = Path::new("/home/michaelh/Sync/skybox");
SkyBox::new( SkyBox::new(
&mut world_builder, &mut world_builder,
@ -28,6 +29,12 @@ fn main() -> Result<()> {
.into_iter(), .into_iter(),
)?; )?;
let view = world_builder.resources.get_mut::<Scene>().view_mut();
let camera = view.camera_mut();
camera.set_eye_offset(vec3(0.0, 1.0, 0.0));
view.update_buffer()?;
world_builder.build().run() world_builder.build().run()
} }
@ -52,7 +59,7 @@ impl GameState {
} }
impl EventConsumer for GameState { impl EventConsumer for GameState {
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> { fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
match self { match self {
GameState::Startup => (), GameState::Startup => (),
GameState::Loading => (), GameState::Loading => (),
@ -71,7 +78,7 @@ impl Game {
Ok(()) Ok(())
} }
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> { fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
Ok(()) Ok(())
} }
} }

View file

@ -1,40 +1,60 @@
use context::prelude::*; use context::prelude::*;
use std::{sync::Arc, thread}; use std::{
sync::{
Arc,
mpsc::{Receiver, channel},
},
thread,
};
use anyhow::Result; use anyhow::Result;
pub struct LoadingScreen; pub struct LoadingScreen<T: Send + Sync + 'static> {
result: Option<T>,
receiver: Receiver<T>,
}
impl LoadingScreen { impl<T: Send + Sync + 'static> LoadingScreen<T> {
pub fn load<T, R, L, G>( pub fn load<R, L, G>(gui: Arc<G>, loader: L) -> Result<Self>
context: &Arc<Context>,
gui: Option<Arc<G>>,
loader: L,
on_ready: R,
) -> Result<()>
where where
R: Fn(T) -> Result<()> + Send + Sync + 'static, R: Fn(T) -> Result<()> + Send + Sync + 'static,
T: Send + Sync + 'static, T: Send + Sync + 'static,
L: FnOnce() -> T + Send + Sync + 'static, L: FnOnce() -> T + Send + Sync + 'static,
G: TopLevelGui + TopGui + Send + Sync + 'static, G: TopLevelGui + TopGui + Send + Sync + 'static,
{ {
if let Some(gui) = &gui { gui.enable()?;
gui.enable()?;
}
let context = context.clone(); let (sender, receiver) = channel();
thread::spawn(move || { thread::spawn(move || {
let result = loader(); let _ = sender.send(loader());
if let Some(gui) = &gui { let _ = gui.disable();
gui.disable().unwrap();
}
todo!();
// context.push_event(move || (on_ready)(result));
}); });
Ok(()) Ok(Self {
result: None,
receiver,
})
}
pub fn check_ready(&mut self) -> bool {
if self.result.is_some() {
return true;
}
match self.receiver.try_recv() {
Ok(result) => {
self.result = Some(result);
true
}
Err(_) => false,
}
}
/// Will panic if there is no result.
/// Use `check_ready` before calling this.
pub fn take_result(mut self) -> T {
self.result.take().unwrap()
} }
} }

View file

@ -3,7 +3,7 @@ use ui::prelude::*;
use super::controlleraxis::ControllerAxis; use super::controlleraxis::ControllerAxis;
use sdl2; use sdl2::{self, GameControllerSubsystem};
#[derive(PartialEq)] #[derive(PartialEq)]
enum State { enum State {
@ -51,7 +51,7 @@ pub struct Controller {
impl Controller { impl Controller {
pub fn new( pub fn new(
controller_subsystem: &sdl2::GameControllerSubsystem, controller_subsystem: &GameControllerSubsystem,
id: u32, id: u32,
deadzones: ControllerDeadzones, deadzones: ControllerDeadzones,
) -> Result<Controller> { ) -> Result<Controller> {
@ -199,7 +199,7 @@ impl Controller {
} }
} }
pub fn set_left_x(&mut self, x: f32) { pub(crate) fn set_left_x(&mut self, x: f32) {
self.controller_axis.left_stick.x = x; self.controller_axis.left_stick.x = x;
let direction = self.check_direction( let direction = self.check_direction(
@ -212,7 +212,7 @@ impl Controller {
} }
} }
pub fn set_left_y(&mut self, y: f32) { pub(crate) fn set_left_y(&mut self, y: f32) {
self.controller_axis.left_stick.y = y; self.controller_axis.left_stick.y = y;
let direction = self.check_direction( let direction = self.check_direction(
@ -225,15 +225,15 @@ impl Controller {
} }
} }
pub fn set_right_x(&mut self, x: f32) { pub(crate) fn set_right_x(&mut self, x: f32) {
self.controller_axis.right_stick.x = x; self.controller_axis.right_stick.x = x;
} }
pub fn set_right_y(&mut self, y: f32) { pub(crate) fn set_right_y(&mut self, y: f32) {
self.controller_axis.right_stick.y = y; self.controller_axis.right_stick.y = y;
} }
pub fn set_left_trigger(&mut self, trigger: f32) { pub(crate) fn set_left_trigger(&mut self, trigger: f32) {
self.controller_axis.left_trigger = trigger; self.controller_axis.left_trigger = trigger;
let left_trigger = self.check_trigger(trigger, self.last_left_trigger); let left_trigger = self.check_trigger(trigger, self.last_left_trigger);
@ -244,7 +244,7 @@ impl Controller {
} }
} }
pub fn set_right_trigger(&mut self, trigger: f32) { pub(crate) fn set_right_trigger(&mut self, trigger: f32) {
self.controller_axis.right_trigger = trigger; self.controller_axis.right_trigger = trigger;
let right_trigger = self.check_trigger(trigger, self.last_right_trigger); let right_trigger = self.check_trigger(trigger, self.last_right_trigger);

View file

@ -2,7 +2,9 @@ use sdl2;
use sdl2::EventPump; use sdl2::EventPump;
use sdl2::EventSubsystem; use sdl2::EventSubsystem;
use sdl2::GameControllerSubsystem; use sdl2::GameControllerSubsystem;
use sdl2::JoystickSubsystem;
use sdl2::Sdl; use sdl2::Sdl;
use sdl2::controller::Axis;
use sdl2::controller::Button; use sdl2::controller::Button;
use sdl2::event::{Event as SdlEvent, EventType as SdlEventType, WindowEvent}; use sdl2::event::{Event as SdlEvent, EventType as SdlEventType, WindowEvent};
use sdl2::keyboard::Keycode; use sdl2::keyboard::Keycode;
@ -10,11 +12,12 @@ use sdl2::mouse::{MouseButton as SdlMouseButton, MouseUtil, MouseWheelDirection}
use ui::prelude::*; use ui::prelude::*;
use std::sync::{Arc, RwLock}; use std::collections::HashMap;
use crate::Result; use crate::Result;
use super::controller::{Controller, ControllerDeadzones}; use super::controller::{Controller, ControllerDeadzones};
use super::joystick::Joystick;
fn convert_button(button: Button) -> ControllerButton { fn convert_button(button: Button) -> ControllerButton {
match button { match button {
@ -51,7 +54,7 @@ fn convert_button(button: Button) -> ControllerButton {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum Event { pub enum Event<'a> {
// mouse events // mouse events
MouseMotion(u32, u32), MouseMotion(u32, u32),
MouseButtonDown(MouseButton), MouseButtonDown(MouseButton),
@ -64,11 +67,18 @@ pub enum Event {
TextInput(String), TextInput(String),
// controller events // controller events
ControllerAxis(Arc<RwLock<Controller>>), ControllerAxis(&'a Controller),
ControllerButtonDown(ControllerButton), ControllerButtonDown(&'a Controller, ControllerButton),
ControllerButtonUp(ControllerButton), ControllerButtonUp(&'a Controller, ControllerButton),
ControllerAdded(Arc<RwLock<Controller>>), ControllerAdded(&'a Controller),
ControllerRemoved(Arc<RwLock<Controller>>), ControllerRemoved(&'a Controller),
// joystick events
JoystickAxis(&'a Joystick),
JoystickButtonDown(&'a Joystick),
JoystickButtonUp(&'a Joystick),
JoystickAdded(&'a Joystick),
JoystickRemoved(&'a Joystick),
// drag'n'drop // drag'n'drop
FileDrop(String), FileDrop(String),
@ -78,12 +88,13 @@ pub struct EventSystem {
event_pump: EventPump, event_pump: EventPump,
mouse: MouseUtil, mouse: MouseUtil,
controller_subsystem: GameControllerSubsystem, controller_subsystem: GameControllerSubsystem,
joystick_subsystem: JoystickSubsystem,
event_subsystem: EventSubsystem, event_subsystem: EventSubsystem,
controller_deadzones: ControllerDeadzones, controller_deadzones: ControllerDeadzones,
selected_controller: Option<Arc<RwLock<Controller>>>, connected_controllers: HashMap<u32, Controller>,
connected_controllers: Vec<Arc<RwLock<Controller>>>, connected_joysticks: HashMap<u32, Joystick>,
} }
impl EventSystem { impl EventSystem {
@ -96,12 +107,13 @@ impl EventSystem {
controller_subsystem: sdl2_context controller_subsystem: sdl2_context
.game_controller() .game_controller()
.map_err(|s| anyhow::Error::msg(s))?, .map_err(|s| anyhow::Error::msg(s))?,
joystick_subsystem: sdl2_context.joystick().map_err(|s| anyhow::Error::msg(s))?,
event_subsystem: sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?, event_subsystem: sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?,
controller_deadzones: ControllerDeadzones::default(), controller_deadzones: ControllerDeadzones::default(),
selected_controller: None, connected_controllers: HashMap::new(),
connected_controllers: Vec::new(), connected_joysticks: HashMap::new(),
}; };
event_system.disable_mouse(); event_system.disable_mouse();
@ -180,11 +192,9 @@ impl EventSystem {
pub fn poll_events<F, R>(&mut self, mut event_callback: F, mut resize: R) -> Result<bool> pub fn poll_events<F, R>(&mut self, mut event_callback: F, mut resize: R) -> Result<bool>
where where
F: FnMut(Event) -> Result<()>, F: FnMut(Event<'_>) -> Result<()>,
R: FnMut(u32, u32) -> Result<()>, R: FnMut(u32, u32) -> Result<()>,
{ {
let mut controller_axis_changed = false;
for event in self.event_pump.poll_iter() { for event in self.event_pump.poll_iter() {
match event { match event {
SdlEvent::Window { win_event, .. } => match win_event { SdlEvent::Window { win_event, .. } => match win_event {
@ -266,184 +276,78 @@ impl EventSystem {
which as u32, which as u32,
self.controller_deadzones.clone(), self.controller_deadzones.clone(),
) { ) {
let controller = { if cfg!(debug_assertions) {
if cfg!(debug_assertions) { println!(
println!( "Controller added: {}({})",
"Controller added: {}({})", controller.name(),
controller.name(), controller.id()
controller.id() );
); }
}
let arc_controller = Arc::new(RwLock::new(controller)); event_callback(Event::ControllerAdded(&controller))?;
self.connected_controllers.push(arc_controller.clone()); self.connected_controllers
.insert(controller.id(), controller);
if self.selected_controller.is_none() {
if cfg!(debug_assertions) {
let contr = arc_controller.read().unwrap();
println!(
"New active controller: {}({})",
contr.name(),
contr.id()
);
}
self.selected_controller = Some(arc_controller.clone());
}
arc_controller
};
event_callback(Event::ControllerAdded(controller))?;
} }
} }
SdlEvent::ControllerDeviceRemoved { which, .. } => { SdlEvent::ControllerDeviceRemoved { which, .. } => {
let removed_controller = { if let Some(controller) = self.connected_controllers.remove(&which) {
if self.selected_controller.is_some() { if cfg!(debug_assertions) {
if cfg!(debug_assertions) { println!(
let contr = "Controller removed: {}({})",
self.selected_controller.as_ref().unwrap().read().unwrap(); controller.name(),
controller.id()
println!( );
"Remove active controller: {}({})",
contr.name(),
contr.id()
);
}
// unwrap is save since we just tested for `is_some()`
if self
.selected_controller
.as_ref()
.unwrap()
.read()
.unwrap()
.id()
== which
{
self.selected_controller = None;
}
} }
self.connected_controllers event_callback(Event::ControllerRemoved(&controller))?;
.iter()
.position(|controller_cell| {
let controller = controller_cell.read().unwrap();
controller.id() == which
})
.map(|remove_index| {
let removed_controller =
self.connected_controllers.swap_remove(remove_index);
if cfg!(debug_assertions) {
let contr = removed_controller.read().unwrap();
println!(
"Controller removed: {}({})",
contr.name(),
contr.id()
);
}
// if we removed the selected controller, take the controller at the first position if possible
if self.selected_controller.is_none()
&& !self.connected_controllers.is_empty()
{
if cfg!(debug_assertions) {
println!(
"Set active controller: {}",
self.connected_controllers[0].read().unwrap().name()
);
}
self.selected_controller =
Some(self.connected_controllers[0].clone());
}
removed_controller
})
};
if let Some(removed_controller) = removed_controller {
event_callback(Event::ControllerRemoved(removed_controller))?;
} }
} }
// maybe make use of `which`, for support of multiple controllers SdlEvent::ControllerButtonDown { button, which, .. } => {
SdlEvent::ControllerButtonDown { event_callback(Event::ControllerButtonDown(
button, self.connected_controllers.get(&which).unwrap(),
// which, convert_button(button),
.. ))?;
} => {
// // only call back if the selected controller pressed a button
// match self.selected_controller.read().unwrap().as_ref() {
// Some(selected_controller) => {
// if selected_controller.read().unwrap().id() != which {
// continue;
// }
// }
// None => continue,
// }
event_callback(Event::ControllerButtonDown(convert_button(button)))?;
} }
// maybe make use of `which`, for support of multiple controllers SdlEvent::ControllerButtonUp { button, which, .. } => {
SdlEvent::ControllerButtonUp { event_callback(Event::ControllerButtonUp(
button, self.connected_controllers.get(&which).unwrap(),
// which, convert_button(button),
.. ))?;
} => {
// // only call back if the selected controller released a button
// match self.selected_controller.read().unwrap().as_ref() {
// Some(selected_controller) => {
// if selected_controller.read().unwrap().id() != which {
// continue;
// }
// }
// None => continue,
// }
event_callback(Event::ControllerButtonUp(convert_button(button)))?;
} }
SdlEvent::ControllerAxisMotion { SdlEvent::ControllerAxisMotion {
axis, axis, value, which, ..
value,
// which,
..
} => { } => {
if let Some(controller) = self.selected_controller.as_mut() { let controller = self.connected_controllers.get_mut(&which).unwrap();
let mut controller = controller.write().unwrap(); let normalized = value as f32 * 0.000_030_518;
// // only update axis, when selected controller made the change match axis {
// if controller.id() != which { Axis::LeftX => {
// continue; controller.set_left_x(normalized);
// } }
Axis::RightX => {
// 1 / 32768 = 0,000030518 controller.set_right_x(normalized);
let normalized = value as f32 * 0.000_030_518; }
Axis::LeftY => {
match axis { controller.set_left_y(-normalized);
sdl2::controller::Axis::LeftX => { }
controller.set_left_x(normalized); Axis::RightY => {
} controller.set_right_y(normalized);
sdl2::controller::Axis::RightX => { }
controller.set_right_x(normalized); Axis::TriggerLeft => {
} controller.set_left_trigger(normalized);
sdl2::controller::Axis::LeftY => { }
controller.set_left_y(-normalized); Axis::TriggerRight => {
} controller.set_right_trigger(normalized);
sdl2::controller::Axis::RightY => {
controller.set_right_y(normalized);
}
sdl2::controller::Axis::TriggerLeft => {
controller.set_left_trigger(normalized);
}
sdl2::controller::Axis::TriggerRight => {
controller.set_right_trigger(normalized);
}
} }
controller_axis_changed = true;
} }
event_callback(Event::ControllerAxis(&*controller))?;
}
SdlEvent::JoyDeviceAdded { which, .. } => {
let joystick = Joystick::new(&self.joystick_subsystem, which)?;
event_callback(Event::JoystickAdded(&joystick))?;
self.connected_joysticks.insert(joystick.id(), joystick);
} }
SdlEvent::DropFile { filename, .. } => { SdlEvent::DropFile { filename, .. } => {
event_callback(Event::FileDrop(filename))?; event_callback(Event::FileDrop(filename))?;
@ -452,58 +356,15 @@ impl EventSystem {
} }
} }
if controller_axis_changed {
if let Some(controller) = &self.selected_controller {
let (left_trigger, right_trigger) = {
let mut controller_lock = controller.write().unwrap();
(
controller_lock.left_trigger(),
controller_lock.right_trigger(),
)
};
if let Some(right_trigger) = right_trigger {
if right_trigger {
event_callback(Event::ControllerButtonDown(
ControllerButton::RightTrigger,
))?;
} else {
event_callback(Event::ControllerButtonUp(ControllerButton::RightTrigger))?;
}
}
if let Some(left_trigger) = left_trigger {
if left_trigger {
event_callback(Event::ControllerButtonDown(ControllerButton::LeftTrigger))?;
} else {
event_callback(Event::ControllerButtonUp(ControllerButton::LeftTrigger))?;
}
}
event_callback(Event::ControllerAxis(controller.clone()))?;
}
}
Ok(true) Ok(true)
} }
pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] { pub fn controllers(&self) -> impl Iterator<Item = &Controller> {
&self.connected_controllers self.connected_controllers.values()
} }
pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> { pub fn joysticks(&self) -> impl Iterator<Item = &Joystick> {
&self.selected_controller self.connected_joysticks.values()
}
pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) {
if let Some(res) = self
.connected_controllers
.iter()
.find(|c| Arc::ptr_eq(c, controller))
{
self.selected_controller = Some(res.clone());
}
} }
} }

View file

@ -0,0 +1,40 @@
use anyhow::Result;
use sdl2::JoystickSubsystem;
pub struct Joystick {
_sdl2_joystick: sdl2::joystick::Joystick,
id: u32,
name: String,
}
impl Joystick {
pub fn new(joystick_subsystem: &JoystickSubsystem, id: u32) -> Result<Self> {
let sdl2_joystick = joystick_subsystem.open(id)?;
Ok(Self {
name: sdl2_joystick.name(),
id,
_sdl2_joystick: sdl2_joystick,
})
}
pub fn id(&self) -> u32 {
self.id
}
pub fn name(&self) -> &str {
&self.name
}
}
impl std::fmt::Debug for Joystick {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Joystick")
.field("id", &self.id)
.field("name", &self.name)
.finish()
}
}
unsafe impl Send for Joystick {}
unsafe impl Sync for Joystick {}

View file

@ -3,3 +3,4 @@
pub mod controller; pub mod controller;
pub mod controlleraxis; pub mod controlleraxis;
pub mod eventsystem; pub mod eventsystem;
pub mod joystick;

View file

@ -1,6 +1,6 @@
pub use crate::traits::*; pub use crate::traits::*;
pub use crate::{create_render_core, RenderCoreCreateInfo}; pub use crate::{RenderCoreCreateInfo, create_render_core};
pub use crate::presentationcore::{ApplicationInfo, PresentationBackend, PresentationCore, VRMode}; pub use crate::presentationcore::{ApplicationInfo, PresentationBackend, PresentationCore, VRMode};
@ -10,6 +10,7 @@ pub use crate::renderbackend::{Eye, VRTransformations};
pub use crate::input::{ pub use crate::input::{
controller::{Controller, ControllerDeadzones}, controller::{Controller, ControllerDeadzones},
controlleraxis::ControllerAxis, controlleraxis::ControllerAxis,
joystick::Joystick,
}; };
// wsi // wsi

View file

@ -113,7 +113,7 @@ impl PresentationCore {
pub fn poll_events<F, R>(&mut self, event_callback: F, resize_event: R) -> Result<bool> pub fn poll_events<F, R>(&mut self, event_callback: F, resize_event: R) -> Result<bool>
where where
F: FnMut(Event) -> Result<()>, F: FnMut(Event<'_>) -> Result<()>,
R: FnMut(u32, u32) -> Result<()>, R: FnMut(u32, u32) -> Result<()>,
{ {
self.event_system.poll_events(event_callback, resize_event) self.event_system.poll_events(event_callback, resize_event)

View file

@ -89,7 +89,7 @@ impl SceneHandle {
world world
.resources .resources
.get_mut_unchecked::<T>() .get_mut_unchecked::<T>()
.resize(width, height, images) .resize(width, height, images, world)
}), }),
} }
} }

View file

@ -25,6 +25,7 @@ pub trait TScene: Send + Sync + 'static {
window_width: f32, window_width: f32,
window_height: f32, window_height: f32,
images: &TargetMode<Vec<Arc<Image>>>, images: &TargetMode<Vec<Arc<Image>>>,
world: &World,
) -> Result<()>; ) -> Result<()>;
} }

View file

@ -1,6 +1,6 @@
mod vertex; mod vertex;
use std::{path::PathBuf, sync::Arc}; use std::{path::PathBuf, sync::Arc, time::Duration};
use anyhow::Result; use anyhow::Result;
use ecs::*; use ecs::*;
@ -37,6 +37,8 @@ impl<T: ExactSizeIterator<Item = PathBuf>> From<T> for SkyBoxImages {
} }
pub struct SkyBox { pub struct SkyBox {
enabled: bool,
_cube_map: Arc<Image>, _cube_map: Arc<Image>,
cube_buffer: Arc<Buffer<VertexPoint>>, cube_buffer: Arc<Buffer<VertexPoint>>,
@ -94,8 +96,24 @@ impl SkyBox {
.add_descriptor_set_layout(&descriptor_set_layout) .add_descriptor_set_layout(&descriptor_set_layout)
.build(context.device().clone())?; .build(context.device().clone())?;
let pipeline = let vertex_shader = ShaderModule::from_slice(
Self::create_pipeline(context, sample_count, &render_target, &pipeline_layout)?; context.device().clone(),
include_bytes!("../shader/skybox.vert.spv"),
)?;
let fragment_shader = ShaderModule::from_slice(
context.device().clone(),
include_bytes!("../shader/skybox.frag.spv"),
)?;
let pipeline = Self::create_pipeline(
context,
sample_count,
&render_target,
&pipeline_layout,
&vertex_shader,
&fragment_shader,
)?;
let descriptor_pool = DescriptorPool::builder() let descriptor_pool = DescriptorPool::builder()
.set_layout(descriptor_set_layout) .set_layout(descriptor_set_layout)
@ -124,17 +142,34 @@ impl SkyBox {
.map(|t| VertexPoint::new(t[0] as f32, t[1] as f32, t[2] as f32)) .map(|t| VertexPoint::new(t[0] as f32, t[1] as f32, t[2] as f32))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let cube_buffer = Buffer::builder() let command_buffer = CommandBuffer::new_primary()
.set_memory_usage(MemoryUsage::GpuOnly) .build(context.device().clone(), context.queue().clone())?;
.set_sharing_mode(VK_SHARING_MODE_EXCLUSIVE)
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) let cube_buffer = SingleSubmit::builder(&command_buffer, context.queue(), |recorder| {
.set_data(&cube_mesh) Buffer::builder()
.build(context.device().clone())?; .set_memory_usage(MemoryUsage::CpuToGpu)
.set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
.set_data(&cube_mesh)
.build(context.device().clone())?
.into_device_local(
recorder,
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
)
})
.wait_for_timeout(Duration::from_secs(2))
.submit()?;
let me = Self { let me = Self {
enabled: true,
_cube_map: cube_map, _cube_map: cube_map,
cube_buffer, cube_buffer,
vertex_shader,
fragment_shader,
render_target, render_target,
pipeline, pipeline,
descriptor_set, descriptor_set,
@ -144,6 +179,14 @@ impl SkyBox {
Ok(()) Ok(())
} }
pub fn enable(&mut self) {
self.enabled = true;
}
pub fn disable(&mut self) {
self.enabled = false;
}
fn create_render_target( fn create_render_target(
context: &Context, context: &Context,
sample_count: VkSampleCountFlags, sample_count: VkSampleCountFlags,
@ -195,11 +238,18 @@ impl SkyBox {
sample_count: VkSampleCountFlags, sample_count: VkSampleCountFlags,
render_target: &TargetMode<RenderTarget>, render_target: &TargetMode<RenderTarget>,
pipeline_layout: &Arc<PipelineLayout>, pipeline_layout: &Arc<PipelineLayout>,
vertex_shader: &Arc<ShaderModule<Vertex>>,
fragment_shader: &Arc<ShaderModule<Fragment>>,
) -> Result<TargetMode<Arc<Pipeline>>> { ) -> Result<TargetMode<Arc<Pipeline>>> {
render_target.execute(|render_target| { render_target.execute(|render_target| {
Pipeline::new_graphics() Pipeline::new_graphics()
.set_vertex_shader::<VertexPoint>(vertex_shader.clone())
.set_fragment_shader(fragment_shader.clone())
.input_assembly(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false)
.default_multisample(sample_count) .default_multisample(sample_count)
.default_color_blend(vec![VkPipelineColorBlendAttachmentState::default()])
.default_rasterization(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE) .default_rasterization(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE)
.whole_area(render_target.width(), render_target.height())
.build( .build(
context.device().clone(), context.device().clone(),
pipeline_layout, pipeline_layout,
@ -218,6 +268,10 @@ impl TScene for SkyBox {
indices: &TargetMode<usize>, indices: &TargetMode<usize>,
_world: &World, _world: &World,
) -> Result<()> { ) -> Result<()> {
if !self.enabled {
return Ok(());
}
self.render_target self.render_target
.chain(indices) .chain(indices)
.chain(&self.pipeline) .chain(&self.pipeline)
@ -241,10 +295,34 @@ impl TScene for SkyBox {
fn resize( fn resize(
&mut self, &mut self,
window_width: f32, _window_width: f32,
window_height: f32, _window_height: f32,
images: &TargetMode<Vec<Arc<Image>>>, _images: &TargetMode<Vec<Arc<Image>>>,
world: &World,
) -> Result<()> { ) -> Result<()> {
todo!() let sample_count = world
.resources
.get::<EngineSettings>()
.graphics_info()?
.sample_count;
let context = world.resources.get::<Context>();
let pipeline_layout = match &self.pipeline {
TargetMode::Mono(p) => p.pipeline_layout().clone(),
TargetMode::Stereo(p, _) => p.pipeline_layout().clone(),
};
self.render_target = Self::create_render_target(context, sample_count)?;
self.pipeline = Self::create_pipeline(
context,
sample_count,
&self.render_target,
&pipeline_layout,
&self.vertex_shader,
&self.fragment_shader,
)?;
Ok(())
} }
} }