use bevy::app::App;
use bevy::asset::{Asset, Handle};
use bevy::mesh::MeshVertexBufferLayoutRef;
use bevy::pbr::{ExtendedMaterial, MaterialExtension, MaterialExtensionKey, MaterialExtensionPipeline, StandardMaterial};
use bevy::reflect::Reflect;
use bevy::render::render_resource::{AsBindGroup, RenderPipelineDescriptor, SpecializedMeshPipelineError};
use bevy::render::storage::ShaderBuffer;
use bevy::shader::ShaderRef;
use super::{ATTRIBUTE_GROWTH_AXIS, ATTRIBUTE_GROWTH_ID, ATTRIBUTE_GROWTH_OFFSET};
pub type GrowthMaterial = ExtendedMaterial<StandardMaterial, GrowthExtension>;
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
pub struct GrowthExtension {
#[storage(100, read_only)]
pub nodes: Handle<ShaderBuffer>,
}
impl MaterialExtension for GrowthExtension {
fn vertex_shader() -> ShaderRef {
"embedded://bevy_flora/gpu/growth.wesl".into()
}
fn prepass_vertex_shader() -> ShaderRef {
"embedded://bevy_flora/gpu/growth_prepass.wesl".into()
}
fn specialize(
_pipeline: &MaterialExtensionPipeline,
descriptor: &mut RenderPipelineDescriptor,
layout: &MeshVertexBufferLayoutRef,
_key: MaterialExtensionKey<Self>,
) -> Result<(), SpecializedMeshPipelineError> {
let growth = layout.0.get_layout(&[
ATTRIBUTE_GROWTH_ID.at_shader_location(8),
ATTRIBUTE_GROWTH_AXIS.at_shader_location(9),
ATTRIBUTE_GROWTH_OFFSET.at_shader_location(10),
])?;
descriptor.vertex.buffers[0].attributes.extend(growth.attributes);
Ok(())
}
}
pub(crate) fn add_shaders(app: &mut App) {
bevy::shader::load_shader_library!(app, "growth_common.wesl");
bevy::asset::embedded_asset!(app, "growth.wesl");
bevy::asset::embedded_asset!(app, "growth_prepass.wesl");
}