2023-01-12 09:10:09 +00:00
|
|
|
use anyhow::Result;
|
2023-01-13 07:11:53 +00:00
|
|
|
use cgmath::{Vector2, Vector4};
|
2023-01-12 09:10:09 +00:00
|
|
|
use vulkan_rs::prelude::*;
|
|
|
|
|
2023-01-12 12:52:44 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
2023-01-13 07:11:53 +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
|
|
|
|
2023-01-13 07:11:53 +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-12 16:45:06 +00:00
|
|
|
submit_info: SubmitInfo,
|
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()
|
|
|
|
));
|
|
|
|
let images = match swapchain.wrap_images(&vk_images, &queue) {
|
|
|
|
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-12 12:52:44 +00:00
|
|
|
Ok(Self {
|
|
|
|
swapchain,
|
|
|
|
pipeline: SingleColorPipeline::new(device, render_target.render_pass())?,
|
|
|
|
render_target,
|
2023-01-12 16:45:06 +00:00
|
|
|
submit_info: SubmitInfo::default(),
|
2023-01-12 12:52:44 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn swapchain(&self) -> &Arc<Swapchain> {
|
|
|
|
&self.swapchain
|
2023-01-12 09:10:09 +00:00
|
|
|
}
|
|
|
|
|
2023-01-13 07:11:53 +00:00
|
|
|
pub fn single_color_pipeline(&self) -> &SingleColorPipeline {
|
|
|
|
&self.pipeline
|
|
|
|
}
|
|
|
|
|
2023-01-12 16:45:06 +00:00
|
|
|
pub fn render(
|
|
|
|
&mut self,
|
|
|
|
device: Arc<Device>,
|
|
|
|
queue: Arc<Mutex<Queue>>,
|
|
|
|
swapchain: Arc<Swapchain>,
|
2023-01-13 07:11:53 +00:00
|
|
|
objects: &[&dyn RenderObject],
|
2023-01-12 16:45:06 +00:00
|
|
|
) -> Result<VkSubmitInfo> {
|
|
|
|
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(),
|
|
|
|
},
|
|
|
|
}];
|
|
|
|
|
|
|
|
let command_buffer = CommandBuffer::new_primary().build(device, queue)?;
|
|
|
|
|
|
|
|
{
|
|
|
|
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
|
|
|
|
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
|
|
|
))?;
|
|
|
|
|
|
|
|
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 07:11:53 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.submit_info = SubmitInfo::default()
|
|
|
|
.add_wait_stage(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
|
|
|
|
.add_command_buffer(command_buffer);
|
|
|
|
|
|
|
|
Ok(self.submit_info.as_vk_submit())
|
2023-01-12 09:10:09 +00:00
|
|
|
}
|
|
|
|
}
|