use askama::Template;
use crate::{
render_passes::geometry::shader::cache_key::ShaderCacheKeyGeometry,
shaders::{AwsmShaderError, Result},
};
#[derive(Debug)]
pub struct ShaderTemplateGeometry {
pub bind_groups: ShaderTemplateGeometryBindGroups,
pub vertex: ShaderTemplateGeometryVertex,
pub fragment: ShaderTemplateGeometryFragment,
}
#[derive(Template, Debug)]
#[template(path = "geometry_wgsl/bind_groups.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateGeometryBindGroups {
meta_storage_array: bool,
}
impl ShaderTemplateGeometryBindGroups {
pub fn new(cache_key: &ShaderCacheKeyGeometry) -> Self {
Self {
meta_storage_array: cache_key.meta_storage_array,
}
}
}
#[derive(Template, Debug)]
#[template(path = "geometry_wgsl/vertex.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateGeometryVertex {
max_morph_unroll: u32,
max_skin_unroll: u32,
instancing_transforms: bool,
meta_storage_array: bool,
}
impl ShaderTemplateGeometryVertex {
pub fn new(cache_key: &ShaderCacheKeyGeometry) -> Self {
Self {
max_morph_unroll: 2,
max_skin_unroll: 2,
instancing_transforms: cache_key.instancing_transforms,
meta_storage_array: cache_key.meta_storage_array,
}
}
}
#[derive(Template, Debug)]
#[template(path = "geometry_wgsl/fragment.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateGeometryFragment {}
impl ShaderTemplateGeometryFragment {
pub fn new(_cache_key: &ShaderCacheKeyGeometry) -> Self {
Self {}
}
}
impl TryFrom<&ShaderCacheKeyGeometry> for ShaderTemplateGeometry {
type Error = AwsmShaderError;
fn try_from(value: &ShaderCacheKeyGeometry) -> Result<Self> {
Ok(Self {
bind_groups: ShaderTemplateGeometryBindGroups::new(value),
vertex: ShaderTemplateGeometryVertex::new(value),
fragment: ShaderTemplateGeometryFragment::new(value),
})
}
}
impl ShaderTemplateGeometry {
pub fn into_source(self) -> Result<String> {
let bind_groups_source = self.bind_groups.render()?;
let vertex_source = self.vertex.render()?;
let fragment_source = self.fragment.render()?;
let source = format!(
"{}\n{}\n{}",
bind_groups_source, vertex_source, fragment_source
);
Ok(source)
}
pub fn debug_label(&self) -> Option<&str> {
Some("Geometry")
}
}