rFactor2_vk_hud/src/overlay/mod.rs

273 lines
6.5 KiB
Rust
Raw Normal View History

2023-01-12 16:45:06 +00:00
use crate::write_log;
2023-01-14 19:15:43 +00:00
use self::{
rendering::Rendering,
2023-01-17 11:18:53 +00:00
rfactor_data::{DataReceiver, RFactorData},
2023-01-14 19:15:43 +00:00
};
2023-01-12 09:10:09 +00:00
2023-01-17 11:18:53 +00:00
mod elements;
2023-01-12 09:10:09 +00:00
mod rendering;
2023-01-12 16:45:06 +00:00
mod rfactor_data;
2023-01-12 09:10:09 +00:00
use anyhow::Result;
2023-01-17 06:57:56 +00:00
use assetpath::AssetPath;
2023-01-17 11:18:53 +00:00
use std::{
cell::RefCell,
rc::Rc,
sync::{Arc, Mutex},
};
2023-01-17 06:57:56 +00:00
use ui::prelude::*;
2023-01-12 09:10:09 +00:00
use vulkan_rs::prelude::*;
2023-01-17 11:18:53 +00:00
use elements::*;
2023-01-16 16:07:39 +00:00
use serde::{Deserialize, Serialize};
2023-01-17 11:18:53 +00:00
pub trait UiOverlay: DataReceiver {
fn enable_ui(&mut self) -> Result<()>;
}
2023-01-16 16:07:39 +00:00
#[derive(Deserialize, Serialize)]
pub struct OverlayConfig {
2023-01-17 06:57:56 +00:00
pub radar_config: RadarConfig,
pub font_path: String,
2023-01-16 16:07:39 +00:00
}
impl OverlayConfig {
pub const fn new() -> Self {
Self {
2023-01-17 06:57:56 +00:00
radar_config: RadarConfig::new(),
font_path: String::new(),
2023-01-16 16:07:39 +00:00
}
}
}
2023-01-12 09:10:09 +00:00
pub struct Overlay {
2023-01-16 16:07:39 +00:00
config: OverlayConfig,
2023-01-12 09:10:09 +00:00
instance: Option<Arc<Instance>>,
device: Option<Arc<Device>>,
2023-01-12 16:45:06 +00:00
queue: Option<Arc<Mutex<Queue>>>,
rendering: Option<Rendering>,
2023-01-17 06:57:56 +00:00
gui_handler: Option<Arc<GuiHandler>>,
2023-01-12 16:45:06 +00:00
2023-01-17 11:18:53 +00:00
ui_elements: Vec<Rc<RefCell<dyn UiOverlay>>>,
rfactor_data: Option<RFactorData>,
2023-01-12 09:10:09 +00:00
}
impl Overlay {
pub const fn new() -> Self {
Self {
2023-01-16 16:07:39 +00:00
config: OverlayConfig::new(),
2023-01-12 09:10:09 +00:00
instance: None,
device: None,
2023-01-12 16:45:06 +00:00
queue: None,
rendering: None,
2023-01-17 06:57:56 +00:00
gui_handler: None,
2023-01-17 11:18:53 +00:00
ui_elements: Vec::new(),
2023-01-12 16:45:06 +00:00
rfactor_data: None,
2023-01-12 09:10:09 +00:00
}
}
2023-01-16 16:07:39 +00:00
pub fn set_config(&mut self, config: OverlayConfig) {
self.config = config;
}
2023-01-12 09:10:09 +00:00
pub fn set_instance(&mut self, instance: Arc<Instance>) {
self.instance = Some(instance);
}
pub fn instance(&self) -> Arc<Instance> {
self.instance.as_ref().unwrap().clone()
}
pub fn set_device(&mut self, device: Arc<Device>) {
self.device = Some(device);
}
pub fn device(&self) -> Arc<Device> {
self.device.as_ref().unwrap().clone()
}
2023-01-14 07:08:40 +00:00
pub fn set_queue(&mut self, queue: Arc<Mutex<Queue>>) {
2023-01-12 16:45:06 +00:00
self.queue = Some(queue);
2023-01-12 12:52:44 +00:00
}
2023-01-12 16:45:06 +00:00
pub fn queue(&self) -> Arc<Mutex<Queue>> {
self.queue.as_ref().unwrap().clone()
2023-01-12 12:52:44 +00:00
}
2023-01-13 14:00:01 +00:00
pub fn swapchain(&self, swapchain: VkSwapchainKHR) -> Option<&Arc<Swapchain>> {
let sc = self.rendering.as_ref().unwrap().swapchain();
if sc.vk_handle() == swapchain {
Some(sc)
} else {
None
}
2023-01-12 12:52:44 +00:00
}
2023-01-12 16:45:06 +00:00
pub fn create_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> {
2023-01-14 19:15:43 +00:00
write_log!("-> create rendering: start");
2023-01-12 16:45:06 +00:00
self.rendering = None;
2023-01-14 19:15:43 +00:00
write_log!("-> create rendering: old cleared");
2023-01-12 16:45:06 +00:00
2023-01-17 11:18:53 +00:00
let mut rendering = Rendering::new(self.queue(), swapchain.clone())?;
write_log!("-> create rendering: new created");
2023-01-17 06:57:56 +00:00
// only font is used
let mut create_info = GuiHandlerCreateInfo::default();
create_info.font_path = AssetPath::from(self.config.font_path.clone());
create_info.font_path.assume_prefix_free();
2023-01-17 11:18:53 +00:00
// provide trait required by GuiHandler
2023-01-17 06:57:56 +00:00
let ctx = Arc::new(ContextImpl::new(
self.device(),
self.queue(),
swapchain,
rendering.images().clone(),
));
2023-01-17 11:18:53 +00:00
// create GuiHandler
let gui_handler = GuiHandler::new(create_info, &(ctx as Arc<dyn ContextInterface>))?;
2023-01-17 06:57:56 +00:00
2023-01-17 11:18:53 +00:00
// create ui elements
2023-01-12 16:45:06 +00:00
2023-01-17 11:18:53 +00:00
// create radar
let radar = Rc::new(RefCell::new(Radar::new(
self.config.radar_config,
self.device(),
self.queue(),
&rendering,
)?));
// create pedals
let pedals = Rc::new(RefCell::new(Pedals::new(&gui_handler)?));
// add rendering callbacks
rendering.add_render_callback({
let radar = radar.clone();
move |index| radar.borrow().render(index)
});
rendering.add_render_callback({
let gui_handler = gui_handler.clone();
let device = self.device();
let queue = self.queue();
move |index| {
let command_buffer =
CommandBuffer::new_primary().build(device.clone(), queue.clone())?;
{
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
))?;
gui_handler.process(&mut recorder, &TargetMode::Mono(index as usize))?;
}
Ok(command_buffer)
}
});
// add ui elements to local list
self.ui_elements.push(radar);
self.ui_elements.push(pedals);
2023-01-17 06:57:56 +00:00
2023-01-14 19:15:43 +00:00
write_log!("-> create rendering: end");
2023-01-12 09:10:09 +00:00
2023-01-17 11:18:53 +00:00
self.rendering = Some(rendering);
self.gui_handler = Some(gui_handler);
2023-01-12 09:10:09 +00:00
Ok(())
}
2023-01-14 07:08:40 +00:00
pub fn render(&mut self) -> Result<()> {
if self.rfactor_data.is_none() {
2023-01-17 11:18:53 +00:00
self.rfactor_data = RFactorData::new().ok();
if let Some(data) = &mut self.rfactor_data {
write_log!("created RFactorData");
for receiver in self.ui_elements.iter() {
receiver.borrow_mut().enable_ui()?;
data.add_receiver(receiver.clone());
}
}
}
// check twice for rfactor data, because of borrowing rules
if let Some(rfactor) = &mut self.rfactor_data {
rfactor.update()?;
}
2023-01-17 11:18:53 +00:00
self.rendering.as_ref().unwrap().render()
2023-01-12 09:10:09 +00:00
}
}
2023-01-17 06:57:56 +00:00
struct ContextImpl {
device: Arc<Device>,
queue: Arc<Mutex<Queue>>,
swapchain: Arc<Swapchain>,
images: Vec<Arc<Image>>,
}
impl ContextImpl {
fn new(
device: Arc<Device>,
queue: Arc<Mutex<Queue>>,
swapchain: Arc<Swapchain>,
images: Vec<Arc<Image>>,
) -> Self {
Self {
device,
queue,
swapchain,
images,
}
}
}
impl ContextInterface for ContextImpl {
fn device(&self) -> &Arc<Device> {
&self.device
}
fn queue(&self) -> &Arc<Mutex<Queue>> {
&self.queue
}
fn format(&self) -> VkFormat {
self.swapchain.format()
}
fn image_layout(&self) -> VkImageLayout {
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
}
fn image_count(&self) -> usize {
self.images.len()
}
fn images(&self) -> TargetMode<Vec<Arc<Image>>> {
TargetMode::Mono(self.images.clone())
}
fn width(&self) -> u32 {
self.swapchain.width()
}
fn height(&self) -> u32 {
self.swapchain.height()
}
}