Start reordering code to fit into new ecs concept

This commit is contained in:
Michael Hübner 2025-02-26 14:51:44 +01:00
parent d6469c9181
commit a7bbf4c7d3
18 changed files with 262 additions and 481 deletions

View file

@ -11,6 +11,7 @@ assetpath = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
presentation = { path = "../presentation" } presentation = { path = "../presentation" }
ecs = { path = "../ecs" }
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
shared_library = { workspace = true } shared_library = { workspace = true }

View file

@ -6,6 +6,7 @@ use super::vulkancore::VulkanCore;
#[cfg(feature = "sound")] #[cfg(feature = "sound")]
use audio::SoundHandler; use audio::SoundHandler;
use ecs::World;
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
@ -39,16 +40,7 @@ pub struct Context {
os_specific: OsSpecific, os_specific: OsSpecific,
application_start_time: Instant, fallback: Option<Box<dyn Fn(anyhow::Error) -> Result<()> + Send + Sync>>,
context_object: Arc<RwLock<Option<Box<dyn ContextObject + Send + Sync>>>>,
fallback: Mutex<Option<Box<dyn Fn(anyhow::Error) -> Result<()> + Send + Sync>>>,
push_events: Mutex<Vec<Box<dyn FnOnce() -> Result<()> + Send + Sync>>>,
// queue timer
last_check: Mutex<Duration>,
} }
impl Context { impl Context {
@ -56,20 +48,6 @@ impl Context {
ContextBuilder::default() ContextBuilder::default()
} }
pub fn set_context_object<C>(&self, context_object: Option<C>)
where
C: ContextObject + Send + Sync + 'static,
{
let tmp = self.context_object.clone();
self.push_event(move || {
*tmp.write().unwrap() =
context_object.map(|c| Box::new(c) as Box<dyn ContextObject + Send + Sync>);
Ok(())
})
}
pub fn window_config(&self) -> WindowConfig<'_> { pub fn window_config(&self) -> WindowConfig<'_> {
match self.presentation.backend() { match self.presentation.backend() {
PresentationBackend::Window(wsi) => WindowConfig::new(wsi), PresentationBackend::Window(wsi) => WindowConfig::new(wsi),
@ -82,30 +60,25 @@ impl Context {
} }
} }
pub fn push_event(&self, event: impl FnOnce() -> Result<()> + 'static + Send + Sync) {
self.push_events.lock().unwrap().push(Box::new(event));
}
#[cfg(feature = "sound")] #[cfg(feature = "sound")]
pub fn sound(&self) -> MutexGuard<'_, SoundHandler> { pub fn sound(&self) -> MutexGuard<'_, SoundHandler> {
self.sound_handler.lock().unwrap() self.sound_handler.lock().unwrap()
} }
pub fn run(&self) -> Result<()> { pub fn run<C>(&self, world: &mut World) -> Result<()> {
'running: loop { 'running: loop {
let render_core = self.render_core.clone();
match self.presentation.poll_events( match self.presentation.poll_events(
|event| { |event| {
if let Some(ctx_obj) = &mut *self.context_object.write().unwrap() { // TODO
ctx_obj.event(event)?; // if let Some(ctx_obj) = world.resources.get_mut_opt::<C>() {
} // ctx_obj.event(event)?;
// }
Ok(()) Ok(())
}, },
{ |w, h| render_core.write().unwrap().resize(world, w, h),
let render_core = self.render_core.clone();
move |w, h| render_core.write().unwrap().resize(w, h)
},
) { ) {
Ok(res) => { Ok(res) => {
if !res { if !res {
@ -113,24 +86,17 @@ impl Context {
} }
} }
Err(err) => { Err(err) => {
if let Some(fallback) = self.fallback.lock().unwrap().as_ref() { if let Some(fallback) = &self.fallback {
(fallback)(err)?; (fallback)(err)?;
} }
} }
} }
if let Err(err) = self.update() { if !self.render_core_mut().next_frame(world)? {
if let Some(fallback) = &self.fallback.lock().unwrap().as_ref() {
(fallback)(err)?;
}
}
if !self.render_core_mut().next_frame()? {
break 'running; break 'running;
} }
} }
*self.context_object.write().unwrap() = None;
self.render_core_mut().clear_post_processing_routines(); self.render_core_mut().clear_post_processing_routines();
Ok(()) Ok(())
@ -144,11 +110,11 @@ impl Context {
self.render_core.write().unwrap() self.render_core.write().unwrap()
} }
pub fn set_fallback<F>(&self, fallback: F) pub fn set_fallback<F>(&mut self, fallback: F)
where where
F: Fn(anyhow::Error) -> Result<()> + 'static + Send + Sync, F: Fn(anyhow::Error) -> Result<()> + 'static + Send + Sync,
{ {
*self.fallback.lock().unwrap() = Some(Box::new(fallback)); self.fallback = Some(Box::new(fallback));
} }
pub fn close(&self) -> Result<()> { pub fn close(&self) -> Result<()> {
@ -163,10 +129,6 @@ impl Context {
self.core.queue() self.core.queue()
} }
pub fn time(&self) -> Duration {
self.application_start_time.elapsed()
}
pub fn controllers(&self) -> RwLockReadGuard<'_, Vec<Arc<RwLock<Controller>>>> { pub fn controllers(&self) -> RwLockReadGuard<'_, Vec<Arc<RwLock<Controller>>>> {
self.presentation.event_system().controllers() self.presentation.event_system().controllers()
} }
@ -188,42 +150,6 @@ impl std::fmt::Debug for Context {
} }
} }
impl Context {
#[inline]
fn update(&self) -> Result<()> {
if let Some(ctx_obj) = &mut *self.context_object.write().unwrap() {
if let Err(err) = ctx_obj.update() {
return Err(err);
}
}
let mut events = Vec::new();
{
let mut push_events_lock = self.push_events.lock().unwrap();
mem::swap(&mut events, &mut push_events_lock);
}
for event in events {
event()?;
}
let one_second = Duration::from_secs(1);
let mut last_check = self.last_check.lock().unwrap();
if (self.time() - *last_check) > one_second {
*last_check += one_second;
#[cfg(feature = "sound")]
{
self.sound().check_clear_queue()?;
}
}
Ok(())
}
}
impl ContextInterface for Context { impl ContextInterface for Context {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
self.device() self.device()
@ -465,19 +391,10 @@ impl ContextBuilder {
self self
} }
pub fn build<F, SCENE>(self, create_scene: F) -> Result<Arc<Context>> pub fn build<S: TScene + 'static>(self) -> Result<Context> {
where
SCENE: TScene + 'static,
F: FnOnce(
&Arc<Device>,
&Arc<Mutex<Queue>>,
(f32, f32),
&TargetMode<Vec<Arc<Image>>>,
) -> Result<SCENE>,
{
if self.enable_backtrace { if self.enable_backtrace {
// set environment variable for Rust-debug-trace // set environment variable for Rust-debug-trace
set_var("RUST_BACKTRACE", "1"); unsafe { set_var("RUST_BACKTRACE", "1") };
} }
#[cfg(feature = "openxr")] #[cfg(feature = "openxr")]
@ -515,12 +432,11 @@ impl ContextBuilder {
let os_specific = OsSpecific::new(&self.os_specific_config); let os_specific = OsSpecific::new(&self.os_specific_config);
let (render_core, _target_mode) = create_render_core( let (render_core, _target_mode) = create_render_core::<S>(
&presentation, &presentation,
core.device(), core.device(),
core.queue(), core.queue(),
self.render_core_create_info, self.render_core_create_info,
create_scene,
)?; )?;
if self.enable_mouse { if self.enable_mouse {
@ -535,7 +451,7 @@ impl ContextBuilder {
presentation.event_system().enable_controller(); presentation.event_system().enable_controller();
} }
Ok(Arc::new(Context { Ok(Context {
core, core,
presentation, presentation,
render_core: Arc::new(RwLock::new(render_core)), render_core: Arc::new(RwLock::new(render_core)),
@ -545,16 +461,8 @@ impl ContextBuilder {
os_specific, os_specific,
application_start_time: Instant::now(), fallback: None,
})
context_object: Arc::new(RwLock::new(None)),
fallback: Mutex::new(None),
push_events: Mutex::new(Vec::new()),
last_check: Mutex::new(Duration::from_secs(0)),
}))
} }
#[cfg(feature = "openxr")] #[cfg(feature = "openxr")]
@ -568,13 +476,14 @@ impl ContextBuilder {
fn get_vr_mode(&self) -> Option<VRMode> { fn get_vr_mode(&self) -> Option<VRMode> {
#[cfg(any(feature = "openvr", feature = "openxr"))] #[cfg(any(feature = "openvr", feature = "openxr"))]
// if we requested a VR mode, check if it is available // if we requested a VR mode, check if it is available
match self.vr_mode { return self
Some(vr_mode) => { .vr_mode
.map(|vr_mode| {
let available_vr_modes = PresentationCore::enabled_vr_modes(); let available_vr_modes = PresentationCore::enabled_vr_modes();
// if requested VR mode is enabled, use it // if requested VR mode is enabled, use it
if available_vr_modes.contains(&vr_mode) { if available_vr_modes.contains(&vr_mode) {
return Some(vr_mode); Some(vr_mode)
} }
// fallback to the first available // fallback to the first available
else if !available_vr_modes.is_empty() { else if !available_vr_modes.is_empty() {
@ -585,19 +494,16 @@ impl ContextBuilder {
vr_mode, mode vr_mode, mode
); );
return Some(mode); Some(mode)
} }
// use default desktop, as last resort // use default desktop, as last resort
else { else {
println!("No VRMode present, fallback to Window"); println!("No VRMode present, fallback to Window");
return None; None
} }
} })
None => { .flatten();
return None;
}
}
#[cfg(not(any(feature = "openvr", feature = "openxr")))] #[cfg(not(any(feature = "openvr", feature = "openxr")))]
None None

View file

@ -29,17 +29,23 @@ impl Resources {
} }
pub fn get<T: Any + Send + Sync>(&self) -> &T { pub fn get<T: Any + Send + Sync>(&self) -> &T {
self.get_opt::<T>().unwrap()
}
pub fn get_opt<T: Any + Send + Sync>(&self) -> Option<&T> {
self.map self.map
.get(&TypeId::of::<T>()) .get(&TypeId::of::<T>())
.map(|any| Self::downcast_ref_unchecked(any)) .map(|any| Self::downcast_ref_unchecked(any))
.unwrap()
} }
pub fn get_mut<T: Any + Send + Sync>(&mut self) -> &mut T { pub fn get_mut<T: Any + Send + Sync>(&mut self) -> &mut T {
self.get_mut_opt::<T>().unwrap()
}
pub fn get_mut_opt<T: Any + Send + Sync>(&mut self) -> Option<&mut T> {
self.map self.map
.get_mut(&TypeId::of::<T>()) .get_mut(&TypeId::of::<T>())
.map(|any| Self::downcast_mut_unchecked(any)) .map(|any| Self::downcast_mut_unchecked(any))
.unwrap()
} }
pub fn multi_mut(&mut self) -> ResourceMultiMut<'_> { pub fn multi_mut(&mut self) -> ResourceMultiMut<'_> {

View file

@ -14,6 +14,16 @@ pub struct WorldBuilder {
pub(crate) updates: Updates, pub(crate) updates: Updates,
pub events: Events, pub events: Events,
pub resources: Resources, pub resources: Resources,
systems: Vec<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync + 'static>>,
}
impl WorldBuilder {
pub fn add_system<F>(&mut self, f: F)
where
F: Fn(&mut World) -> Result<()> + Send + Sync + 'static,
{
self.systems.push(Box::new(f));
}
} }
impl WorldBuilder { impl WorldBuilder {
@ -31,6 +41,8 @@ impl WorldBuilder {
entity_object_manager: Default::default(), entity_object_manager: Default::default(),
start_time: Instant::now(), start_time: Instant::now(),
systems: self.systems,
} }
} }
} }
@ -53,6 +65,8 @@ pub struct World {
entity_object_manager: EntityObjectManager, entity_object_manager: EntityObjectManager,
start_time: Instant, start_time: Instant,
systems: Vec<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync + 'static>>,
} }
impl World { impl World {
@ -61,6 +75,7 @@ impl World {
updates: Default::default(), updates: Default::default(),
events: Default::default(), events: Default::default(),
resources: Default::default(), resources: Default::default(),
systems: Default::default(),
} }
} }
@ -311,7 +326,10 @@ impl World {
impl World { impl World {
pub fn run(&mut self) -> Result<()> { pub fn run(&mut self) -> Result<()> {
let systems = std::mem::take(&mut self.systems);
loop { loop {
// we need to take all events because of borrowing rules
let mut events = self.events.take_events(); let mut events = self.events.take_events();
events.fire_events(self)?; events.fire_events(self)?;
@ -325,6 +343,10 @@ impl World {
} }
self.commit_entity_changes()?; self.commit_entity_changes()?;
for system in systems.iter() {
system(self)?;
}
} }
} }
} }

View file

@ -72,8 +72,9 @@ impl context::prelude::PostProcess for GuiPostProcess {
} }
} }
struct GraphicsObjects { pub struct Engine {
context: Arc<Context>, engine_settings: Arc<EngineSettings>,
gui_handler: Arc<GuiHandler>, gui_handler: Arc<GuiHandler>,
gui_post_process: Arc<GuiPostProcess>, gui_post_process: Arc<GuiPostProcess>,
input: Arc<RwLock<Input>>, input: Arc<RwLock<Input>>,
@ -84,24 +85,8 @@ struct GraphicsObjects {
resource_base_path: String, resource_base_path: String,
} }
impl Drop for GraphicsObjects {
fn drop(&mut self) {
self.context
.render_core()
.remove_post_processing_routine(self.gui_post_process.clone());
}
}
pub struct Engine {
engine_settings: Arc<EngineSettings>,
graphical: GraphicsObjects,
entity_object_manager: EntityObjectManager,
}
impl Engine { impl Engine {
pub fn new(#[allow(unused)] mut create_info: EngineCreateInfo<'_>) -> Result<Arc<Self>> { pub fn new(#[allow(unused)] mut create_info: EngineCreateInfo<'_>) -> Result<Self> {
if let Font::Path(path) = &mut create_info.gui_info.font { if let Font::Path(path) = &mut create_info.gui_info.font {
path.set_prefix(&create_info.resource_base_path); path.set_prefix(&create_info.resource_base_path);
} }
@ -193,17 +178,7 @@ impl Engine {
context_builder = context_builder.enable_backtrace(); context_builder = context_builder.enable_backtrace();
} }
context_builder.build(|device, queue, window_extents, images| { context_builder.build::<Scene>()?
Scene::new(
device,
queue,
window_extents,
images,
create_info.rasterizer_info,
create_info.raytracing_info,
create_info.graphics_info,
)
})?
}; };
// update sound handler center // update sound handler center
@ -234,97 +209,41 @@ impl Engine {
create_info.resource_base_path.clone(), create_info.resource_base_path.clone(),
)?); )?);
let engine = Arc::new(Engine { let asset_manager = AssetManager::new(engine_settings.clone())?;
graphical: {
let asset_manager = AssetManager::new(engine_settings.clone())?;
let gui_handler = GuiHandler::new( let gui_handler = GuiHandler::new(
create_info.gui_info, create_info.gui_info,
&(context.clone() as Arc<dyn ContextInterface>), &(context.clone() as Arc<dyn ContextInterface>),
)?; )?;
// default keyboard navigation // default keyboard navigation
let mut direction_mapping = HashMap::new(); let mut direction_mapping = HashMap::new();
// direction_mapping.insert(Keycode::A, GuiDirection::Left); // direction_mapping.insert(Keycode::A, GuiDirection::Left);
// direction_mapping.insert(Keycode::D, GuiDirection::Right); // direction_mapping.insert(Keycode::D, GuiDirection::Right);
// direction_mapping.insert(Keycode::W, GuiDirection::Up); // direction_mapping.insert(Keycode::W, GuiDirection::Up);
// direction_mapping.insert(Keycode::S, GuiDirection::Down); // direction_mapping.insert(Keycode::S, GuiDirection::Down);
direction_mapping.insert(Keycode::Left, GuiDirection::Left); direction_mapping.insert(Keycode::Left, GuiDirection::Left);
direction_mapping.insert(Keycode::Right, GuiDirection::Right); direction_mapping.insert(Keycode::Right, GuiDirection::Right);
direction_mapping.insert(Keycode::Up, GuiDirection::Up); direction_mapping.insert(Keycode::Up, GuiDirection::Up);
direction_mapping.insert(Keycode::Down, GuiDirection::Down); direction_mapping.insert(Keycode::Down, GuiDirection::Down);
let input = Input { direction_mapping }; let input = Input { direction_mapping };
let gui_post_process = Arc::new(GuiPostProcess(gui_handler.clone())); let gui_post_process = Arc::new(GuiPostProcess(gui_handler.clone()));
context context
.render_core() .render_core()
.add_post_processing_routine(gui_post_process.clone()); .add_post_processing_routine(gui_post_process.clone());
GraphicsObjects { Ok(Engine {
context, gui_post_process,
gui_post_process, gui_handler,
gui_handler, input: Arc::new(RwLock::new(input)),
input: Arc::new(RwLock::new(input)),
asset_manager: RwLock::new(asset_manager), asset_manager: RwLock::new(asset_manager),
resource_base_path: create_info.resource_base_path, resource_base_path: create_info.resource_base_path,
}
},
entity_object_manager: EntityObjectManager::default(),
engine_settings, engine_settings,
});
Ok(engine)
}
fn convert_scene_ref(tscene: &Box<dyn TScene>) -> Option<NonNull<Scene>> {
unsafe {
let ptr_to_ptr: *const *mut Scene =
std::mem::transmute(destructure_traitobject::data(tscene as *const _));
NonNull::new(*ptr_to_ptr)
}
}
pub fn scene(&self) -> &Scene {
unsafe {
Self::convert_scene_ref(self.graphical.context.render_core_mut().scene_mut())
.unwrap()
.as_ref()
}
}
pub fn on_scene<'a, F>(&'a self, f: F) -> Result<()>
where
F: FnOnce(&Scene) -> Result<()> + 'a,
{
f(unsafe {
Self::convert_scene_ref(self.graphical.context.render_core().scene())
.unwrap()
.as_ref()
})
}
pub fn scene_mut(&self) -> &mut Scene {
unsafe {
Self::convert_scene_ref(self.graphical.context.render_core_mut().scene_mut())
.unwrap()
.as_mut()
}
}
pub fn on_scene_mut<'a, F>(&'a self, f: F) -> Result<()>
where
F: FnOnce(&mut Scene) -> Result<()> + 'a,
{
f(unsafe {
Self::convert_scene_ref(self.graphical.context.render_core_mut().scene_mut())
.unwrap()
.as_mut()
}) })
} }
@ -360,17 +279,6 @@ impl Engine {
LoadingScreen::load(self.context(), gui, loader, on_ready) LoadingScreen::load(self.context(), gui, loader, on_ready)
} }
pub fn set_fallback<F>(&self, fallback: F)
where
F: Fn(anyhow::Error) -> anyhow::Result<()> + 'static + Send + Sync,
{
self.context().set_fallback(fallback);
}
pub fn run(self: &Arc<Engine>) -> Result<()> {
self.graphical.context.run()
}
pub fn new_point_light(&self) -> Result<Light> { pub fn new_point_light(&self) -> Result<Light> {
Light::point_light(self.context().device()) Light::point_light(self.context().device())
} }
@ -383,42 +291,6 @@ impl Engine {
Light::spot_light(self.context().device()) Light::spot_light(self.context().device())
} }
pub fn window_config(&self) -> WindowConfig<'_> {
self.context().window_config()
}
pub fn quit(&self) -> Result<()> {
self.context().close()
}
pub fn gui_handler(&self) -> &Arc<GuiHandler> {
&self.graphical.gui_handler
}
pub fn device(&self) -> &Arc<Device> {
self.context().device()
}
pub fn queue(&self) -> &Arc<Mutex<Queue>> {
self.context().queue()
}
pub fn sound(&self) -> MutexGuard<'_, SoundHandler> {
self.context().sound()
}
pub fn controllers(&self) -> RwLockReadGuard<'_, Vec<Arc<RwLock<Controller>>>> {
self.context().controllers()
}
pub fn active_controller(&self) -> Result<Option<Arc<RwLock<Controller>>>> {
self.context().active_controller()
}
pub fn set_active_controller(&self, controller: &Arc<RwLock<Controller>>) {
self.context().set_active_controller(controller);
}
pub fn controller_icon(&self, button: ControllerButton) -> Result<Arc<Image>> { pub fn controller_icon(&self, button: ControllerButton) -> Result<Arc<Image>> {
Ok(self.settings().controller_icon(self, button)?.unwrap_or( Ok(self.settings().controller_icon(self, button)?.unwrap_or(
self.settings() self.settings()
@ -426,12 +298,8 @@ impl Engine {
)) ))
} }
pub fn context(&self) -> &Arc<Context> {
&self.graphical.context
}
pub fn build_path(&self, path: &str) -> AssetPath { pub fn build_path(&self, path: &str) -> AssetPath {
(self.graphical.resource_base_path.as_str(), path).into() (self.resource_base_path.as_str(), path).into()
} }
pub fn assets(&self) -> AssetHandler<'_> { pub fn assets(&self) -> AssetHandler<'_> {
@ -455,3 +323,11 @@ impl Engine {
&self.engine_settings &self.engine_settings
} }
} }
impl Drop for Engine {
fn drop(&mut self) {
self.context
.render_core()
.remove_post_processing_routine(self.gui_post_process.clone());
}
}

View file

@ -341,16 +341,71 @@ impl Scene {
(((v + 1.0) / 2.0) * max) as i32 (((v + 1.0) / 2.0) * max) as i32
} }
pub fn world_to_screen_space(&self, world_space: Vector3<f32>) -> Result<(i32, i32)> {
Self::_world_to_screen_space(
(self.screen_width, self.screen_height),
world_space,
self.view(),
)
}
pub fn screen_space_to_world(&self, x: u32, y: u32) -> Result<Option<Vector3<f32>>> {
let scale = self.renderer.render_scale();
self.renderer
.screen_to_world((x as f32 * scale) as u32, (y as f32 * scale) as u32)
}
pub fn particle_system_vulkan_objects_mut(&mut self) -> &mut ParticleSystemVulkanObjects {
&mut self.particle_system_vulkan_objects
}
pub fn particle_system_vulkan_objects(&self) -> &ParticleSystemVulkanObjects {
&self.particle_system_vulkan_objects
}
pub fn add_light(&mut self, light: Light) -> Result<()> {
self.renderer.add_light(light)?;
Ok(())
}
pub fn remove_light(&mut self, light: Light) -> Result<()> {
self.renderer.remove_light(light)?;
Ok(())
}
pub fn clear_lights(&mut self) -> Result<()> {
self.renderer.clear_lights()?;
Ok(())
}
pub fn view(&self) -> &View { pub fn view(&self) -> &View {
self.renderer.view() self.renderer.view()
} }
fn _process( pub fn view_mut(&mut self) -> &mut View {
self.renderer.view_mut()
}
pub fn render_type(&self) -> SceneType {
self.render_type
}
pub fn frame_time(&self) -> Duration {
self.frame_time
}
}
impl TScene for Scene {
fn process(
&mut self, &mut self,
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'_>,
images: &TargetMode<Vec<Arc<Image>>>, images: &TargetMode<Vec<Arc<Image>>>,
indices: &TargetMode<usize>, indices: &TargetMode<usize>,
) -> Result<()> { ) -> anyhow::Result<()> {
self.frame_time = { self.frame_time = {
let now = self.now(); let now = self.now();
@ -402,7 +457,7 @@ impl Scene {
let frustum = view.frustum(); let frustum = view.frustum();
let planes = frustum.planes(); let planes = frustum.planes();
let content: Vec<Option<&EntityObject<Self>>> = self let content: Vec<Option<&EntityObject>> = self
.entities .entities
.par_values() .par_values()
.map(|entity_object| { .map(|entity_object| {
@ -439,70 +494,6 @@ impl Scene {
Ok(()) Ok(())
} }
pub fn world_to_screen_space(&self, world_space: Vector3<f32>) -> Result<(i32, i32)> {
Self::_world_to_screen_space(
(self.screen_width, self.screen_height),
world_space,
self.view(),
)
}
pub fn screen_space_to_world(&self, x: u32, y: u32) -> Result<Option<Vector3<f32>>> {
let scale = self.renderer.render_scale();
self.renderer
.screen_to_world((x as f32 * scale) as u32, (y as f32 * scale) as u32)
}
pub fn particle_system_vulkan_objects_mut(&mut self) -> &mut ParticleSystemVulkanObjects {
&mut self.particle_system_vulkan_objects
}
pub fn particle_system_vulkan_objects(&self) -> &ParticleSystemVulkanObjects {
&self.particle_system_vulkan_objects
}
pub fn add_light(&mut self, light: Light) -> Result<()> {
self.renderer.add_light(light)?;
Ok(())
}
pub fn remove_light(&mut self, light: Light) -> Result<()> {
self.renderer.remove_light(light)?;
Ok(())
}
pub fn clear_lights(&mut self) -> Result<()> {
self.renderer.clear_lights()?;
Ok(())
}
pub fn view_mut(&mut self) -> &mut View {
self.renderer.view_mut()
}
pub fn render_type(&self) -> SceneType {
self.render_type
}
pub fn frame_time(&self) -> Duration {
self.frame_time
}
}
impl TScene for Scene {
fn process(
&mut self,
buffer_recorder: &mut CommandBufferRecorder<'_>,
images: &TargetMode<Vec<Arc<Image>>>,
indices: &TargetMode<usize>,
) -> anyhow::Result<()> {
self._process(buffer_recorder, images, indices)
}
fn resize( fn resize(
&mut self, &mut self,
window_width: f32, window_width: f32,

View file

@ -7,3 +7,4 @@ edition = "2024"
anyhow.workspace = true anyhow.workspace = true
ecs = { path = "../../ecs" } ecs = { path = "../../ecs" }
engine = { path = "../../engine" }

View file

@ -1,9 +1,35 @@
use anyhow::Result; use anyhow::Result;
use ecs::*; use ecs::*;
use engine::prelude::*;
fn main() -> Result<()> { fn main() -> Result<()> {
let mut world_builder = World::builder(); let mut world_builder = World::builder();
// world_builder.
let (context, engine, scene) = Engine::new(EngineCreateInfo {
app_info: todo!(),
window_info: todo!(),
os_specific_config: todo!(),
vulkan_debug_info: todo!(),
volume_info: todo!(),
gui_info: todo!(),
enable_backtrace: todo!(),
enable_mouse: todo!(),
enable_keyboard: todo!(),
enable_controller: todo!(),
controller_deadzones: todo!(),
resource_base_path: todo!(),
controller_directories: todo!(),
asset_directories: todo!(),
graphics_info: todo!(),
raytracing_info: todo!(),
rasterizer_info: todo!(),
key_backgrounds: todo!(),
})?;
world_builder.resources.insert(context);
world_builder.resources.insert(engine);
world_builder.resources.insert(scene);
world_builder.build().run() world_builder.build().run()
} }

View file

@ -16,7 +16,6 @@ impl LoadingScreen {
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,
{ {
@ -32,7 +31,8 @@ impl LoadingScreen {
gui.disable().unwrap(); gui.disable().unwrap();
} }
context.push_event(move || (on_ready)(result)); todo!();
// context.push_event(move || (on_ready)(result));
}); });
Ok(()) Ok(())

View file

@ -13,6 +13,8 @@ anyhow = { workspace = true }
openxr = { workspace = true, optional = true } openxr = { workspace = true, optional = true }
openvr = { workspace = true, optional = true } openvr = { workspace = true, optional = true }
ecs = { path = "../ecs" }
[features] [features]
OpenXR = ["openxr"] OpenXR = ["openxr"]
OpenVR = ["openvr"] OpenVR = ["openvr"]

View file

@ -16,6 +16,7 @@ use anyhow::Result;
use traits::RenderCore; use traits::RenderCore;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use wsi::vulkanwindowrendercore::VulkanWindowRenderCore;
use crate::prelude::*; use crate::prelude::*;
@ -28,32 +29,16 @@ pub struct RenderCoreCreateInfo {
pub vsync: bool, pub vsync: bool,
} }
pub fn create_render_core<SCENE, F>( pub fn create_render_core<S: TScene + 'static>(
presentation_core: &PresentationCore, presentation_core: &PresentationCore,
device: &Arc<Device>, device: &Arc<Device>,
queue: &Arc<Mutex<Queue>>, queue: &Arc<Mutex<Queue>>,
create_info: RenderCoreCreateInfo, create_info: RenderCoreCreateInfo,
create_scene: F, ) -> Result<(Box<dyn RenderCore>, TargetMode<()>)> {
) -> Result<(Box<dyn RenderCore>, TargetMode<()>)>
where
SCENE: TScene + 'static,
F: FnOnce(
&Arc<Device>,
&Arc<Mutex<Queue>>,
(f32, f32),
&TargetMode<Vec<Arc<Image>>>,
) -> Result<SCENE>,
{
match presentation_core.backend() { match presentation_core.backend() {
PresentationBackend::Window(wsi) => { PresentationBackend::Window(wsi) => {
let (render_core, target_mode) = let (render_core, target_mode) =
wsi::vulkanwindowrendercore::VulkanWindowRenderCore::new( VulkanWindowRenderCore::<S>::new(wsi.clone(), device, queue, create_info)?;
wsi.clone(),
device,
queue,
create_info,
create_scene,
)?;
Ok((Box::new(render_core), target_mode)) Ok((Box::new(render_core), target_mode))
} }

View file

@ -114,7 +114,7 @@ impl PresentationCore {
pub fn poll_events<F, R>(&self, event_callback: F, resize_event: R) -> Result<bool> pub fn poll_events<F, R>(&self, event_callback: F, resize_event: R) -> Result<bool>
where where
F: Fn(Event) -> Result<()>, F: Fn(Event) -> Result<()>,
R: Fn(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)
} }
@ -169,7 +169,11 @@ impl PresentationCore {
impl std::fmt::Debug for PresentationCore { impl std::fmt::Debug for PresentationCore {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "WindowSystemIntegration {{ sdl_context: SDL2, eventsystem: EventSystem, backend: {:#?} }}", self.backend) write!(
f,
"WindowSystemIntegration {{ sdl_context: SDL2, eventsystem: EventSystem, backend: {:#?} }}",
self.backend
)
} }
} }

View file

@ -1,14 +1,16 @@
use crate::prelude::*;
use crate::Result; use crate::Result;
use crate::prelude::*;
use cgmath::{Matrix4, SquareMatrix}; use cgmath::{Matrix4, SquareMatrix};
use ecs::World;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use std::marker::PhantomData;
use std::ops::Deref; use std::ops::Deref;
use std::sync::{ use std::sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Arc, Mutex, RwLock, Arc, Mutex, RwLock,
atomic::{AtomicUsize, Ordering::SeqCst},
}; };
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -47,7 +49,7 @@ impl Default for VRTransformations {
} }
} }
pub struct RenderBackend { pub struct RenderBackend<S: TScene + 'static> {
device: Arc<Device>, device: Arc<Device>,
queue: Arc<Mutex<Queue>>, queue: Arc<Mutex<Queue>>,
@ -59,16 +61,16 @@ pub struct RenderBackend {
command_buffer: Arc<CommandBuffer>, command_buffer: Arc<CommandBuffer>,
scene: Box<dyn TScene>,
post_processes: Mutex<Vec<Arc<dyn PostProcess>>>, post_processes: Mutex<Vec<Arc<dyn PostProcess>>>,
s: PhantomData<S>,
} }
impl RenderBackend { impl<S: TScene + 'static> RenderBackend<S> {
pub fn new<SCENE: TScene + 'static>( pub fn new(
device: &Arc<Device>, device: &Arc<Device>,
queue: &Arc<Mutex<Queue>>, queue: &Arc<Mutex<Queue>>,
images: TargetMode<Vec<Arc<Image>>>, images: TargetMode<Vec<Arc<Image>>>,
scene: SCENE,
) -> Result<Self> { ) -> Result<Self> {
let image_count = match &images { let image_count = match &images {
TargetMode::Mono(images) => images.len(), TargetMode::Mono(images) => images.len(),
@ -92,8 +94,9 @@ impl RenderBackend {
command_buffer, command_buffer,
scene: Box::new(scene),
post_processes: Mutex::new(Vec::new()), post_processes: Mutex::new(Vec::new()),
s: PhantomData,
}) })
} }
@ -102,7 +105,7 @@ impl RenderBackend {
} }
} }
impl RenderBackend { impl<S: TScene + 'static> RenderBackend<S> {
pub fn device(&self) -> &Arc<Device> { pub fn device(&self) -> &Arc<Device> {
&self.device &self.device
} }
@ -115,7 +118,11 @@ impl RenderBackend {
*self.clear_color.write().unwrap() = VkClearColorValue::float32(clear_color); *self.clear_color.write().unwrap() = VkClearColorValue::float32(clear_color);
} }
pub fn render(&mut self, image_indices: TargetMode<usize>) -> Result<&Arc<CommandBuffer>> { pub fn render(
&mut self,
world: &mut World,
image_indices: TargetMode<usize>,
) -> Result<&Arc<CommandBuffer>> {
// begin main command buffer // begin main command buffer
let mut buffer_recorder = self.command_buffer.begin(VkCommandBufferBeginInfo::new( let mut buffer_recorder = self.command_buffer.begin(VkCommandBufferBeginInfo::new(
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
@ -164,7 +171,7 @@ impl RenderBackend {
} }
// make a call to the connected scene // make a call to the connected scene
self.scene.process( world.resources.get_mut::<S>().process(
&mut buffer_recorder, &mut buffer_recorder,
&*self.swapchain_images.lock().unwrap(), &*self.swapchain_images.lock().unwrap(),
&image_indices, &image_indices,
@ -180,6 +187,7 @@ impl RenderBackend {
pub fn resize( pub fn resize(
&mut self, &mut self,
world: &mut World,
images: TargetMode<Vec<Arc<Image>>>, images: TargetMode<Vec<Arc<Image>>>,
width: u32, width: u32,
height: u32, height: u32,
@ -195,7 +203,10 @@ impl RenderBackend {
SeqCst, SeqCst,
); );
self.scene.resize(width as f32, height as f32, &images)?; world
.resources
.get_mut::<S>()
.resize(width as f32, height as f32, &images)?;
*self.swapchain_images.lock().unwrap() = images; *self.swapchain_images.lock().unwrap() = images;
for post_process in self.post_processes.lock().unwrap().iter() { for post_process in self.post_processes.lock().unwrap().iter() {
@ -205,15 +216,6 @@ impl RenderBackend {
Ok(()) Ok(())
} }
// scene handling
pub fn scene(&self) -> &Box<dyn TScene> {
&self.scene
}
pub fn scene_mut(&mut self) -> &mut Box<dyn TScene> {
&mut self.scene
}
pub fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) { pub fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
let mut post_processes = self.post_processes.lock().unwrap(); let mut post_processes = self.post_processes.lock().unwrap();
@ -254,7 +256,7 @@ impl RenderBackend {
} }
} }
impl RenderBackend { impl<S: TScene + 'static> RenderBackend<S> {
#[inline] #[inline]
fn clear_image( fn clear_image(
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'_>,

View file

@ -1,3 +1,4 @@
use ecs::World;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
@ -36,9 +37,9 @@ pub trait PostProcess: Send + Sync {
} }
pub trait RenderCore: std::fmt::Debug + Send + Sync { pub trait RenderCore: std::fmt::Debug + Send + Sync {
fn next_frame(&mut self) -> Result<bool>; fn next_frame(&mut self, world: &mut World) -> Result<bool>;
fn resize(&mut self, w: u32, h: u32) -> Result<()>; fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()>;
fn format(&self) -> VkFormat; fn format(&self) -> VkFormat;
fn image_layout(&self) -> VkImageLayout { fn image_layout(&self) -> VkImageLayout {
@ -47,10 +48,6 @@ pub trait RenderCore: std::fmt::Debug + Send + Sync {
fn set_clear_color(&self, color: [f32; 4]); fn set_clear_color(&self, color: [f32; 4]);
// scene handling
fn scene(&self) -> &Box<dyn TScene>;
fn scene_mut(&mut self) -> &mut Box<dyn TScene>;
// post process handling // post process handling
fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>); fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>);
fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>); fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>);

View file

@ -48,6 +48,7 @@ pub mod openvrrendercore;
#[cfg(not(feature = "OpenVR"))] #[cfg(not(feature = "OpenVR"))]
pub mod openvrrendercore { pub mod openvrrendercore {
use crate::Result; use crate::Result;
use ecs::World;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
@ -55,8 +56,8 @@ pub mod openvrrendercore {
use super::openvrintegration::OpenVRIntegration; use super::openvrintegration::OpenVRIntegration;
use crate::prelude::*;
use crate::RenderCoreCreateInfo; use crate::RenderCoreCreateInfo;
use crate::prelude::*;
pub struct OpenVRRenderCore { pub struct OpenVRRenderCore {
_dummy: u32, _dummy: u32,
@ -78,11 +79,11 @@ pub mod openvrrendercore {
unimplemented!() unimplemented!()
} }
fn resize(&mut self, _: u32, _: u32) -> Result<()> { fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
unimplemented!() unimplemented!()
} }
fn next_frame(&mut self) -> Result<bool> { fn next_frame(&mut self, _: &mut World) -> Result<bool> {
unimplemented!() unimplemented!()
} }
@ -90,15 +91,6 @@ pub mod openvrrendercore {
unimplemented!() unimplemented!()
} }
// scene handling
fn scene(&self) -> &Box<dyn TScene> {
unimplemented!()
}
fn scene_mut(&mut self) -> &mut Box<dyn TScene> {
unimplemented!()
}
// post process handling // post process handling
fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) { fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) {
unimplemented!() unimplemented!()

View file

@ -1,19 +1,20 @@
use crate::{prelude::*, renderbackend::RenderBackend, RenderCoreCreateInfo}; use crate::{RenderCoreCreateInfo, prelude::*, renderbackend::RenderBackend};
use super::windowsystemintegration::WindowSystemIntegration; use super::windowsystemintegration::WindowSystemIntegration;
use crate::Result; use crate::Result;
use ecs::World;
// use ui::prelude::*; // use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use std::sync::{ use std::sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Arc, Mutex, RwLock, Arc, Mutex, RwLock,
atomic::{AtomicUsize, Ordering::SeqCst},
}; };
use std::time::Duration; use std::time::Duration;
use std::u64; use std::u64;
pub struct VulkanWindowRenderCore { pub struct VulkanWindowRenderCore<S: TScene + 'static> {
device: Arc<Device>, device: Arc<Device>,
// driver provided images // driver provided images
@ -26,30 +27,20 @@ pub struct VulkanWindowRenderCore {
render_finished_sem: Arc<Semaphore>, render_finished_sem: Arc<Semaphore>,
render_fence: Arc<Fence>, render_fence: Arc<Fence>,
render_backend: RenderBackend, render_backend: RenderBackend<S>,
current_image_index: AtomicUsize, current_image_index: AtomicUsize,
wsi: Arc<WindowSystemIntegration>, wsi: Arc<WindowSystemIntegration>,
} }
impl VulkanWindowRenderCore { impl<S: TScene + 'static> VulkanWindowRenderCore<S> {
pub fn new<SCENE, F>( pub fn new(
wsi: Arc<WindowSystemIntegration>, wsi: Arc<WindowSystemIntegration>,
device: &Arc<Device>, device: &Arc<Device>,
queue: &Arc<Mutex<Queue>>, queue: &Arc<Mutex<Queue>>,
create_info: RenderCoreCreateInfo, create_info: RenderCoreCreateInfo,
create_scene: F, ) -> Result<(Self, TargetMode<()>)> {
) -> Result<(Self, TargetMode<()>)>
where
SCENE: TScene + 'static,
F: FnOnce(
&Arc<Device>,
&Arc<Mutex<Queue>>,
(f32, f32),
&TargetMode<Vec<Arc<Image>>>,
) -> Result<SCENE>,
{
// check swapchain extension // check swapchain extension
if !device.enabled_extensions().swapchain { if !device.enabled_extensions().swapchain {
return Err(anyhow::Error::msg("Swapchain Extension must be enabled")); return Err(anyhow::Error::msg("Swapchain Extension must be enabled"));
@ -66,7 +57,7 @@ impl VulkanWindowRenderCore {
))); )));
} }
let usage = create_info.usage | RenderBackend::required_image_usage(); let usage = create_info.usage | RenderBackend::<S>::required_image_usage();
// create swapchain // create swapchain
let swapchain = Swapchain::new( let swapchain = Swapchain::new(
@ -87,14 +78,8 @@ impl VulkanWindowRenderCore {
let fence = Fence::builder().build(device.clone())?; let fence = Fence::builder().build(device.clone())?;
let images = TargetMode::Mono(swapchain_images); let images = TargetMode::Mono(swapchain_images);
let scene = create_scene(
device,
queue,
(swapchain.width() as f32, swapchain.height() as f32),
&images,
)?;
let render_backend = RenderBackend::new(device, queue, images, scene)?; let render_backend = RenderBackend::new(device, queue, images)?;
let window_render_core = VulkanWindowRenderCore { let window_render_core = VulkanWindowRenderCore {
device: device.clone(), device: device.clone(),
@ -118,7 +103,7 @@ impl VulkanWindowRenderCore {
Ok((window_render_core, TargetMode::Mono(()))) Ok((window_render_core, TargetMode::Mono(())))
} }
fn aquire_next_image_index(&mut self) -> Result<()> { fn aquire_next_image_index(&mut self, world: &mut World) -> Result<()> {
// there was a bug that a windows never reacted after it was minimized // there was a bug that a windows never reacted after it was minimized
// with this timeout, the window has 250ms delay // with this timeout, the window has 250ms delay
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -141,7 +126,7 @@ impl VulkanWindowRenderCore {
} }
OutOfDate::OutOfDate => { OutOfDate::OutOfDate => {
let (w, h) = self.wsi.window_size(); let (w, h) = self.wsi.window_size();
resize_mut.resize(w, h)?; resize_mut.resize(world, w, h)?;
*semaphore = Semaphore::new(self.device.clone())?; *semaphore = Semaphore::new(self.device.clone())?;
} }
@ -155,12 +140,12 @@ impl VulkanWindowRenderCore {
} }
} }
impl RenderCore for VulkanWindowRenderCore { impl<S: TScene + 'static> RenderCore for VulkanWindowRenderCore<S> {
fn format(&self) -> VkFormat { fn format(&self) -> VkFormat {
self.format self.format
} }
fn resize(&mut self, w: u32, h: u32) -> Result<()> { fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> {
self.swapchain.recreate((w, h))?; self.swapchain.recreate((w, h))?;
let swapchain_images = self.swapchain.wrap_images( let swapchain_images = self.swapchain.wrap_images(
@ -170,6 +155,7 @@ impl RenderCore for VulkanWindowRenderCore {
)?; )?;
self.render_backend.resize( self.render_backend.resize(
world,
TargetMode::Mono(swapchain_images), TargetMode::Mono(swapchain_images),
self.swapchain.width(), self.swapchain.width(),
self.swapchain.height(), self.swapchain.height(),
@ -178,12 +164,13 @@ impl RenderCore for VulkanWindowRenderCore {
Ok(()) Ok(())
} }
fn next_frame(&mut self) -> Result<bool> { fn next_frame(&mut self, world: &mut World) -> Result<bool> {
self.aquire_next_image_index()?; self.aquire_next_image_index(world)?;
let command_buffer = self let command_buffer = self.render_backend.render(
.render_backend world,
.render(TargetMode::Mono(self.current_image_index.load(SeqCst)))?; TargetMode::Mono(self.current_image_index.load(SeqCst)),
)?;
let submits = &[SubmitInfo::default() let submits = &[SubmitInfo::default()
.add_wait_semaphore( .add_wait_semaphore(
@ -205,7 +192,7 @@ impl RenderCore for VulkanWindowRenderCore {
)? )?
} { } {
let (w, h) = self.wsi.window_size(); let (w, h) = self.wsi.window_size();
self.resize(w, h)?; self.resize(world, w, h)?;
self.render_fence.reset(); self.render_fence.reset();
return Ok(true); return Ok(true);
} }
@ -225,15 +212,6 @@ impl RenderCore for VulkanWindowRenderCore {
self.render_backend.set_clear_color(color); self.render_backend.set_clear_color(color);
} }
// scene handling
fn scene(&self) -> &Box<dyn TScene> {
self.render_backend.scene()
}
fn scene_mut(&mut self) -> &mut Box<dyn TScene> {
self.render_backend.scene_mut()
}
// post process handling // post process handling
fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) { fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
self.render_backend self.render_backend
@ -271,7 +249,7 @@ impl RenderCore for VulkanWindowRenderCore {
} }
} }
impl std::fmt::Debug for VulkanWindowRenderCore { impl<S: TScene + 'static> std::fmt::Debug for VulkanWindowRenderCore<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "VulkanWindowRenderCore {{ }}") write!(f, "VulkanWindowRenderCore {{ }}")
} }

View file

@ -3,13 +3,13 @@
use anyhow::Error; use anyhow::Error;
use sdl2; use sdl2;
use sdl2::Sdl;
use sdl2::clipboard::ClipboardUtil; use sdl2::clipboard::ClipboardUtil;
use sdl2::messagebox::{show_simple_message_box, MessageBoxFlag}; use sdl2::messagebox::{MessageBoxFlag, show_simple_message_box};
use sdl2::mouse::Cursor; use sdl2::mouse::Cursor;
use sdl2::surface::Surface as SDL_Surface; use sdl2::surface::Surface as SDL_Surface;
use sdl2::sys::SDL_Window; use sdl2::sys::SDL_Window;
use sdl2::video::{FullscreenType, WindowPos}; use sdl2::video::{FullscreenType, WindowPos};
use sdl2::Sdl;
use crate::Result; use crate::Result;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
@ -18,8 +18,8 @@ use std::mem::MaybeUninit;
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::sync::{ use std::sync::{
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
Arc, Mutex, Arc, Mutex,
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
}; };
const SDL_SYSWM_WINDOWS: u32 = 0x1; const SDL_SYSWM_WINDOWS: u32 = 0x1;
@ -35,7 +35,7 @@ struct SdlSysWmInfo {
info: [u64; 32], info: [u64; 32],
} }
extern "C" { unsafe extern "C" {
fn SDL_GetWindowWMInfo(window: *const sdl2::sys::SDL_Window, info: *mut SdlSysWmInfo) -> bool; fn SDL_GetWindowWMInfo(window: *const sdl2::sys::SDL_Window, info: *mut SdlSysWmInfo) -> bool;
} }
@ -421,7 +421,7 @@ impl WindowSystemIntegration {
return Err(anyhow::Error::msg(format!( return Err(anyhow::Error::msg(format!(
"Unsupported window subsystem flag {}", "Unsupported window subsystem flag {}",
sys_wm_info.subsystem sys_wm_info.subsystem
))) )));
} }
} }

View file

@ -46,6 +46,7 @@ pub mod openxrrendercore;
#[cfg(not(feature = "OpenXR"))] #[cfg(not(feature = "OpenXR"))]
pub mod openxrrendercore { pub mod openxrrendercore {
use crate::Result; use crate::Result;
use ecs::World;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
@ -53,8 +54,8 @@ pub mod openxrrendercore {
use super::openxrintegration::OpenXRIntegration; use super::openxrintegration::OpenXRIntegration;
use crate::prelude::*;
use crate::RenderCoreCreateInfo; use crate::RenderCoreCreateInfo;
use crate::prelude::*;
pub struct OpenXRRenderCore { pub struct OpenXRRenderCore {
_dummy: u32, _dummy: u32,
@ -76,11 +77,11 @@ pub mod openxrrendercore {
unimplemented!() unimplemented!()
} }
fn resize(&mut self, _: u32, _: u32) -> Result<()> { fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
unimplemented!() unimplemented!()
} }
fn next_frame(&mut self) -> Result<bool> { fn next_frame(&mut self, _: &mut World) -> Result<bool> {
unimplemented!() unimplemented!()
} }
@ -88,15 +89,6 @@ pub mod openxrrendercore {
unimplemented!() unimplemented!()
} }
// scene handling
fn scene(&self) -> &Box<dyn TScene> {
unimplemented!()
}
fn scene_mut(&mut self) -> &mut Box<dyn TScene> {
unimplemented!()
}
// post process handling // post process handling
fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) { fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) {
unimplemented!() unimplemented!()