Start reordering code to fit into new ecs concept
This commit is contained in:
parent
d6469c9181
commit
a7bbf4c7d3
18 changed files with 262 additions and 481 deletions
|
@ -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 }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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<'_> {
|
||||||
|
|
|
@ -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)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -7,3 +7,4 @@ edition = "2024"
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
|
||||||
ecs = { path = "../../ecs" }
|
ecs = { path = "../../ecs" }
|
||||||
|
engine = { path = "../../engine" }
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(())
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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<'_>,
|
||||||
|
|
|
@ -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>);
|
||||||
|
|
|
@ -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!()
|
||||||
|
|
|
@ -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 {{ }}")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
)))
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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!()
|
||||||
|
|
Loading…
Reference in a new issue