use crate::managers::asset_manager::AssetManager;
use wgpu;
pub struct RuntimeManager<'a> {
asset_manager: &'a AssetManager,
surface: Option<wgpu::Surface<'a>>,
surface_config: Option<wgpu::SurfaceConfiguration>,
}
impl<'a> RuntimeManager<'a> {
pub fn new(asset_manager: &'a AssetManager) -> Self {
Self {
asset_manager,
surface: None,
surface_config: None,
}
}
pub fn with_surface(
mut self,
surface: wgpu::Surface<'a>,
width: u32,
height: u32,
format: wgpu::TextureFormat,
) -> Self {
let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format,
width,
height,
present_mode: wgpu::PresentMode::Fifo,
alpha_mode: wgpu::CompositeAlphaMode::Auto,
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(self.asset_manager.device(), &config);
self.surface = Some(surface);
self.surface_config = Some(config);
self
}
pub fn render_pass(
&self,
pipeline_name: &str,
target_view: &wgpu::TextureView,
clear_color: wgpu::Color,
vertex_count: u32,
) -> Result<wgpu::CommandBuffer, String> {
let duo = self.asset_manager.get_pipeline(pipeline_name)
.ok_or_else(|| format!("Pipeline '{}' not found", pipeline_name))?;
let mut encoder = self.asset_manager.device().create_command_encoder(
&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
}
);
{
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: target_view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(clear_color),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_pipeline(&duo.pipeline);
render_pass.draw(0..vertex_count, 0..1);
}
Ok(encoder.finish())
}
pub fn render_to_surface(
&self,
pipeline_name: &str,
clear_color: wgpu::Color,
vertex_count: u32,
) -> Result<(), String> {
let surface = self.surface.as_ref()
.ok_or("Surface not configured")?;
let output = surface.get_current_texture()
.map_err(|e| format!("Failed to get surface texture: {:?}", e))?;
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
let command_buffer = self.render_pass(pipeline_name, &view, clear_color, vertex_count)?;
self.asset_manager.queue().submit(Some(command_buffer));
output.present();
Ok(())
}
pub fn render_to_texture(
&self,
pipeline_name: &str,
width: u32,
height: u32,
format: wgpu::TextureFormat,
clear_color: wgpu::Color,
vertex_count: u32,
) -> Result<wgpu::Texture, String> {
let texture = self.asset_manager.device().create_texture(&wgpu::TextureDescriptor {
label: Some("Render Target"),
size: wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let command_buffer = self.render_pass(pipeline_name, &view, clear_color, vertex_count)?;
self.asset_manager.queue().submit(Some(command_buffer));
Ok(texture)
}
}