use crate::{self as wgpu, Color, LoadOp};
#[derive(Debug, Default)]
pub struct Builder<'a> {
color_attachments: Vec<Option<wgpu::RenderPassColorAttachment<'a>>>,
depth_stencil_attachment: Option<wgpu::RenderPassDepthStencilAttachment<'a>>,
}
#[derive(Debug)]
pub struct ColorAttachmentDescriptorBuilder<'a> {
descriptor: wgpu::RenderPassColorAttachment<'a>,
}
#[derive(Debug)]
pub struct DepthStencilAttachmentDescriptorBuilder<'a> {
descriptor: wgpu::RenderPassDepthStencilAttachment<'a>,
}
impl<'a> ColorAttachmentDescriptorBuilder<'a> {
pub const DEFAULT_CLEAR_COLOR: Color = Color::TRANSPARENT;
pub const DEFAULT_LOAD_OP: LoadOp<Color> = LoadOp::Clear(Self::DEFAULT_CLEAR_COLOR);
pub const DEFAULT_STORE_OP: bool = true;
fn new(attachment: &'a wgpu::TextureViewHandle) -> Self {
ColorAttachmentDescriptorBuilder {
descriptor: wgpu::RenderPassColorAttachment {
view: attachment,
resolve_target: None,
ops: wgpu::Operations {
load: LoadOp::Clear(Color::TRANSPARENT),
store: true,
},
},
}
}
pub fn resolve_target(mut self, target: Option<&'a wgpu::TextureView>) -> Self {
self.descriptor.resolve_target = target.map(|t| &**t);
self
}
pub fn resolve_target_handle(mut self, target: Option<&'a wgpu::TextureViewHandle>) -> Self {
self.descriptor.resolve_target = target;
self
}
pub fn load_op(mut self, load_op: LoadOp<Color>) -> Self {
self.descriptor.ops.load = load_op;
self
}
pub fn store_op(mut self, store_op: bool) -> Self {
self.descriptor.ops.store = store_op;
self
}
}
impl<'a> DepthStencilAttachmentDescriptorBuilder<'a> {
pub const DEFAULT_DEPTH_LOAD_OP: LoadOp<f32> = LoadOp::Clear(Self::DEFAULT_CLEAR_DEPTH);
pub const DEFAULT_DEPTH_STORE_OP: bool = true;
pub const DEFAULT_CLEAR_DEPTH: f32 = 1.0;
pub const DEFAULT_STENCIL_LOAD_OP: LoadOp<u32> = LoadOp::Clear(Self::DEFAULT_CLEAR_STENCIL);
pub const DEFAULT_STENCIL_STORE_OP: bool = true;
pub const DEFAULT_CLEAR_STENCIL: u32 = 0;
fn new(attachment: &'a wgpu::TextureViewHandle) -> Self {
DepthStencilAttachmentDescriptorBuilder {
descriptor: wgpu::RenderPassDepthStencilAttachment {
view: attachment,
depth_ops: Some(wgpu::Operations {
load: Self::DEFAULT_DEPTH_LOAD_OP,
store: Self::DEFAULT_DEPTH_STORE_OP,
}),
stencil_ops: Some(wgpu::Operations {
load: Self::DEFAULT_STENCIL_LOAD_OP,
store: Self::DEFAULT_STENCIL_STORE_OP,
}),
},
}
}
pub fn depth_load_op(mut self, load: LoadOp<f32>) -> Self {
self.descriptor.depth_ops = Some(wgpu::Operations {
load,
store: self.descriptor.depth_ops.expect("no depth ops field").store,
});
self
}
pub fn depth_store_op(mut self, store: bool) -> Self {
self.descriptor.depth_ops = Some(wgpu::Operations {
load: self.descriptor.depth_ops.expect("no depth ops field").load,
store,
});
self
}
pub fn stencil_load_op(mut self, load: LoadOp<u32>) -> Self {
self.descriptor.stencil_ops = Some(wgpu::Operations {
load,
store: self
.descriptor
.stencil_ops
.expect("no stencil ops field")
.store,
});
self
}
pub fn stencil_store_op(mut self, store: bool) -> Self {
self.descriptor.stencil_ops = Some(wgpu::Operations {
load: self
.descriptor
.stencil_ops
.expect("no stencil ops field")
.load,
store,
});
self
}
}
impl<'a> Builder<'a> {
pub const DEFAULT_COLOR_LOAD_OP: LoadOp<Color> =
ColorAttachmentDescriptorBuilder::DEFAULT_LOAD_OP;
pub const DEFAULT_COLOR_STORE_OP: bool = ColorAttachmentDescriptorBuilder::DEFAULT_STORE_OP;
pub const DEFAULT_CLEAR_COLOR: Color = ColorAttachmentDescriptorBuilder::DEFAULT_CLEAR_COLOR;
pub const DEFAULT_DEPTH_LOAD_OP: LoadOp<f32> =
DepthStencilAttachmentDescriptorBuilder::DEFAULT_DEPTH_LOAD_OP;
pub const DEFAULT_DEPTH_STORE_OP: bool =
DepthStencilAttachmentDescriptorBuilder::DEFAULT_DEPTH_STORE_OP;
pub const DEFAULT_CLEAR_DEPTH: f32 =
DepthStencilAttachmentDescriptorBuilder::DEFAULT_CLEAR_DEPTH;
pub const DEFAULT_STENCIL_LOAD_OP: LoadOp<u32> =
DepthStencilAttachmentDescriptorBuilder::DEFAULT_STENCIL_LOAD_OP;
pub const DEFAULT_STENCIL_STORE_OP: bool =
DepthStencilAttachmentDescriptorBuilder::DEFAULT_STENCIL_STORE_OP;
pub const DEFAULT_CLEAR_STENCIL: u32 =
DepthStencilAttachmentDescriptorBuilder::DEFAULT_CLEAR_STENCIL;
pub fn new() -> Self {
Self::default()
}
pub fn color_attachment<F>(
mut self,
attachment: &'a wgpu::TextureViewHandle,
color_builder: F,
) -> Self
where
F: FnOnce(ColorAttachmentDescriptorBuilder<'a>) -> ColorAttachmentDescriptorBuilder<'a>,
{
let builder = ColorAttachmentDescriptorBuilder::new(attachment);
let descriptor = color_builder(builder).descriptor;
self.color_attachments.push(Some(descriptor));
self
}
pub fn depth_stencil_attachment<F>(
mut self,
attachment: &'a wgpu::TextureViewHandle,
depth_stencil_builder: F,
) -> Self
where
F: FnOnce(
DepthStencilAttachmentDescriptorBuilder<'a>,
) -> DepthStencilAttachmentDescriptorBuilder<'a>,
{
let builder = DepthStencilAttachmentDescriptorBuilder::new(attachment);
let descriptor = depth_stencil_builder(builder).descriptor;
self.depth_stencil_attachment = Some(descriptor);
self
}
pub fn into_inner(
self,
) -> (
Vec<Option<wgpu::RenderPassColorAttachment<'a>>>,
Option<wgpu::RenderPassDepthStencilAttachment<'a>>,
) {
let Builder {
color_attachments,
depth_stencil_attachment,
} = self;
(color_attachments, depth_stencil_attachment)
}
pub fn begin(self, encoder: &'a mut wgpu::CommandEncoder) -> wgpu::RenderPass<'a> {
let (color_attachments, depth_stencil_attachment) = self.into_inner();
let descriptor = wgpu::RenderPassDescriptor {
label: Some("nannou_render_pass"),
color_attachments: &color_attachments,
depth_stencil_attachment,
};
encoder.begin_render_pass(&descriptor)
}
}