use wgpu::{TextureView, CommandEncoder, SurfaceTexture};
use super::render_engine::RenderEngine;
pub struct RenderResources {
pub output: SurfaceTexture,
pub view: TextureView,
pub encoder: CommandEncoder
}
pub fn prepare_render(
engine: &RenderEngine
) -> Result<RenderResources, wgpu::SurfaceError> {
let output = engine.surface.get_current_texture()?;
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
let encoder = engine.device.create_command_encoder(
&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
}
);
Ok(
RenderResources {
output,
view,
encoder
}
)
}
pub fn finalize_render(
engine: &mut RenderEngine,
resources: RenderResources
) {
engine.queue.submit(std::iter::once(resources.encoder.finish()));
resources.output.present();
let now = web_time::SystemTime::now().duration_since(web_time::UNIX_EPOCH).unwrap().as_millis();
let old_time = engine.time_since_start;
let ms_since_start = if now > engine.start_time { now - engine.start_time } else { 0 };
engine.time_since_start = ms_since_start as f32 / 1000.0;
engine.delta_time = engine.time_since_start - old_time;
}
#[macro_export]
macro_rules! start_render {
($engine: expr) => {
{
use forte_engine::render::render_utils;
let resources = render_utils::prepare_render(&$engine);
let mut resources = if resources.is_ok() { resources.unwrap() } else { return };
resources
}
}
}
#[macro_export]
macro_rules! end_render {
($engine: expr, $resources: expr) => {
use forte_engine::render::render_utils;
render_utils::finalize_render(&mut $engine, $resources);
};
}
#[macro_export]
macro_rules! pass {
($engine: expr, $resources: expr) => {
pass!($engine, $resources, wgpu::Color { r: 0.0, g: 0.0, b: 0.0, a: 1.0 })
};
($engine: expr, $resources: expr, $color: expr) => {
{
use forte_engine::render::render_utils;
let color_attachment = wgpu::RenderPassColorAttachment {
view: &$resources.view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear($color),
store: wgpu::StoreOp::Store,
},
};
let mut pass = $resources.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[Some(color_attachment)],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
view: &$engine.depth_texture.view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: wgpu::StoreOp::Store
}),
stencil_ops: None
}),
occlusion_query_set: None,
timestamp_writes: None,
});
pass
}
};
}