use anyhow::Result; use cgmath::vec2; use rfactor_sm_reader::*; use vulkan_rs::prelude::*; use std::sync::Arc; use super::rendering::PositionOnlyVertex; pub trait RenderObject { fn descriptor(&self) -> &Arc; fn buffer(&self) -> &Arc>; } pub struct RFactorData { // rf2 memory mapped data // telemetry_reader: TelemetryReader, // scoring_reader: ScoringReader, // radar objects background: RadarObject, player_car: RadarObject, cars: Vec, } impl RFactorData { pub fn new(device: Arc, descriptor_layout: &Arc) -> Result { let radar_extent = 0.2; let car_height = 0.05; let car_width = 0.025; Ok(Self { // telemetry_reader: TelemetryReader::new()?, // scoring_reader: ScoringReader::new()?, background: RadarObject::new( device.clone(), descriptor_layout, PositionOnlyVertex::from_2d_corners([ vec2(-radar_extent, -radar_extent), vec2(-radar_extent, radar_extent), vec2(radar_extent, radar_extent), vec2(radar_extent, -radar_extent), ]), [0.5, 0.5, 0.5, 0.5], )?, player_car: RadarObject::new( device.clone(), descriptor_layout, PositionOnlyVertex::from_2d_corners([ vec2(-car_width, -car_height), vec2(-car_width, car_height), vec2(car_width, car_height), vec2(car_width, -car_height), ]), [0.9, 0.9, 0.0, 0.9], )?, cars: Vec::new(), }) } pub fn update(&mut self) -> Result<()> { Ok(()) } pub fn objects(&self) -> Vec<&dyn RenderObject> { let mut objects: Vec<&dyn RenderObject> = Vec::new(); objects.push(&self.background); for other_player_cars in &self.cars { objects.push(other_player_cars); } objects.push(&self.player_car); objects } } struct RadarObject { descriptor_set: Arc, // uniform buffer color_buffer: Arc>, // vertex buffer position_buffer: Arc>, } impl RadarObject { fn new( device: Arc, descriptor_layout: &Arc, positions: [PositionOnlyVertex; 6], color: [f32; 4], ) -> Result { let color_buffer = Buffer::builder() .set_usage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) .set_memory_usage(MemoryUsage::CpuOnly) .set_data(&color) .build(device.clone())?; let position_buffer = Buffer::builder() .set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) .set_memory_usage(MemoryUsage::CpuOnly) .set_data(&positions) .build(device.clone())?; let descriptor_pool = DescriptorPool::builder() .set_layout(descriptor_layout.clone()) .build(device.clone())?; let descriptor_set = descriptor_pool.prepare_set().allocate()?; descriptor_set.update(&[DescriptorWrite::uniform_buffers(0, &[&color_buffer])])?; Ok(Self { descriptor_set, color_buffer, position_buffer, }) } pub fn update_color(&self, color: [f32; 4]) -> Result<()> { self.color_buffer.fill(&color) } } impl RenderObject for RadarObject { fn descriptor(&self) -> &Arc { &self.descriptor_set } fn buffer(&self) -> &Arc> { &self.position_buffer } }