rFactor2_vk_hud/src/overlay/rendering.rs

171 lines
4.8 KiB
Rust
Raw Normal View History

2023-01-12 09:10:09 +00:00
use anyhow::Result;
use cgmath::{Vector2, Vector4};
2023-01-12 09:10:09 +00:00
use vulkan_rs::prelude::*;
2023-01-14 07:08:40 +00:00
use std::{
sync::{Arc, Mutex},
time::Duration,
};
2023-01-12 12:52:44 +00:00
use super::{pipeline::SingleColorPipeline, rfactor_data::RenderObject};
2023-01-12 16:45:06 +00:00
use crate::write_log;
2023-01-12 09:10:09 +00:00
#[derive(Clone)]
pub struct PositionOnlyVertex {
pub position: Vector4<f32>,
}
impl PositionOnlyVertex {
///
/// corners[0] - bottom left
/// corners[1] - top left
/// corners[2] - top right
/// corners[3] - bottom right
///
pub fn from_2d_corners(corners: [Vector2<f32>; 4]) -> [Self; 6] {
[
Self {
position: corners[0].extend(0.0).extend(1.0),
},
Self {
position: corners[1].extend(0.0).extend(1.0),
},
Self {
position: corners[2].extend(0.0).extend(1.0),
},
Self {
position: corners[2].extend(0.0).extend(1.0),
},
Self {
position: corners[3].extend(0.0).extend(1.0),
},
Self {
position: corners[0].extend(0.0).extend(1.0),
},
]
}
}
2023-01-12 09:10:09 +00:00
pub struct Rendering {
swapchain: Arc<Swapchain>,
2023-01-12 12:52:44 +00:00
pipeline: SingleColorPipeline,
render_target: RenderTarget,
2023-01-13 14:00:01 +00:00
command_buffer: Arc<CommandBuffer>,
2023-01-14 07:08:40 +00:00
device: Arc<Device>,
queue: Arc<Mutex<Queue>>,
2023-01-12 09:10:09 +00:00
}
impl Rendering {
2023-01-12 12:52:44 +00:00
pub fn new(
device: Arc<Device>,
queue: Arc<Mutex<Queue>>,
swapchain: Arc<Swapchain>,
) -> Result<Self> {
2023-01-12 16:45:06 +00:00
write_log("-> Rendering ctor: begin");
let vk_images = swapchain.vk_images()?;
write_log(format!(
"-> Rendering ctor: vk images ({})",
vk_images.len()
));
2023-01-13 07:47:30 +00:00
let images = match swapchain.wrap_images(&vk_images, &queue, true) {
2023-01-12 16:45:06 +00:00
Ok(images) => images,
Err(err) => {
write_log(format!("-> Rendering ctor: failed wrapper: {:?}", err));
return Err(err);
}
};
write_log("-> Rendering ctor: wrapped images");
2023-01-12 12:52:44 +00:00
let render_target = RenderTarget::builder()
.add_sub_pass(
SubPass::builder(swapchain.width(), swapchain.height())
.set_prepared_targets(&images, 0, [0.0, 0.0, 0.0, 1.0], false)
.build(&device, &queue)?,
)
.build(&device)?;
2023-01-12 16:45:06 +00:00
write_log("-> Rendering ctor: created render_target");
2023-01-13 08:27:58 +00:00
write_log(format!(
"-> Rendering swapchain extents ({}, {})",
swapchain.width(),
swapchain.height(),
));
2023-01-12 12:52:44 +00:00
Ok(Self {
swapchain,
2023-01-13 14:00:01 +00:00
pipeline: SingleColorPipeline::new(device.clone(), render_target.render_pass())?,
2023-01-12 12:52:44 +00:00
render_target,
2023-01-14 07:08:40 +00:00
command_buffer: CommandBuffer::new_primary().build(device.clone(), queue.clone())?,
device,
queue,
2023-01-12 12:52:44 +00:00
})
}
pub fn swapchain(&self) -> &Arc<Swapchain> {
&self.swapchain
2023-01-12 09:10:09 +00:00
}
pub fn single_color_pipeline(&self) -> &SingleColorPipeline {
&self.pipeline
}
2023-01-12 16:45:06 +00:00
pub fn render(
&mut self,
swapchain: Arc<Swapchain>,
objects: &[&dyn RenderObject],
2023-01-14 07:08:40 +00:00
) -> Result<()> {
2023-01-12 16:45:06 +00:00
let image_index = self.swapchain.current_index();
let viewport = [VkViewport {
x: 0.0,
y: 0.0,
width: swapchain.width() as f32,
height: swapchain.height() as f32,
minDepth: 0.0,
maxDepth: 1.0,
}];
let scissor = [VkRect2D {
offset: VkOffset2D { x: 0, y: 0 },
extent: VkExtent2D {
width: swapchain.width(),
height: swapchain.height(),
},
}];
{
2023-01-13 14:00:01 +00:00
let mut recorder = self.command_buffer.begin(VkCommandBufferBeginInfo::new(
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
2023-01-12 16:45:06 +00:00
))?;
self.render_target
.begin(&recorder, VK_SUBPASS_CONTENTS_INLINE, image_index as usize);
recorder.bind_pipeline(self.pipeline.pipeline())?;
recorder.set_scissor(&scissor);
recorder.set_viewport(&viewport);
2023-01-13 08:27:58 +00:00
write_log(format!("-> Rendering {} objects", objects.len()));
for object in objects {
let buffer = object.buffer();
recorder.bind_descriptor_sets_minimal(&[object.descriptor()]);
recorder.bind_vertex_buffer(buffer);
recorder.draw_complete_single_instance(buffer.size() as u32);
}
2023-01-12 16:45:06 +00:00
self.render_target.end(&recorder);
}
2023-01-14 07:08:40 +00:00
let queue = self.queue.lock().unwrap();
queue.minimal_submit(Duration::from_secs(10), &[self.command_buffer.clone()])?;
Ok(())
2023-01-12 09:10:09 +00:00
}
}