use super::Material;
use crate::Ctx;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C)] pub struct Effect {
pub(crate) id: u32,
}
impl Effect {
#[doc(hidden)]
#[must_use]
pub fn id(self) -> u32 {
self.id
}
#[doc(hidden)]
#[must_use]
pub fn from_id(id: u32) -> Self {
Self { id }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ScreenEffect {
pub effect: Effect,
pub material: Option<Material>,
}
impl ScreenEffect {
#[must_use]
pub fn new(effect: Effect) -> Self {
Self { effect, material: None }
}
#[must_use]
pub fn with_material(self, material: Material) -> Self {
Self {
material: Some(material),
..self
}
}
}
impl Ctx {
pub fn load_effect(&mut self, path: &str) -> Effect {
self.try_load_effect(path).unwrap_or_else(|e| panic!("ponko: {e}"))
}
#[doc(hidden)]
pub fn try_load_effect(&mut self, path: &str) -> Result<Effect, String> {
let file = crate::assets::resolve(path)?;
if let Some(&effect) = self.assets3d.loaded_effects.get(&file) {
return Ok(effect);
}
let source = crate::assets::read_to_string(&file)?;
let effect = self.try_create_effect(path, &source)?;
self.assets3d.loaded_effects.insert(file.clone(), effect);
self.watcher
.watch(path, file, crate::hot_reload::Asset::Effect(effect.id));
Ok(effect)
}
pub fn create_effect(&mut self, name: &str, source: &str) -> Effect {
self.try_create_effect(name, source)
.unwrap_or_else(|e| panic!("ponko: {e}"))
}
#[doc(hidden)]
pub fn try_create_effect(&mut self, name: &str, source: &str) -> Result<Effect, String> {
#[cfg(feature = "window")]
crate::render::check_shader(name, &crate::render::compose_effect(source))?;
let id = self.assets3d.effects;
if let Some(renderer) = self.renderer.as_mut()
&& !self.headless
{
let gpu_id = renderer.create_effect(name, source)?;
debug_assert_eq!(gpu_id, id);
}
self.assets3d.effects += 1;
Ok(Effect { id })
}
pub(crate) fn reload_effect(&mut self, id: u32, name: &str, source: &str) -> Result<(), String> {
#[cfg(feature = "window")]
crate::render::check_shader(name, &crate::render::compose_effect(source))?;
if let Some(renderer) = self.renderer.as_mut()
&& !self.headless
{
renderer.replace_effect(id, name, source)?;
}
Ok(())
}
#[doc(hidden)]
#[must_use]
pub fn has_effect(&self, effect: Effect) -> bool {
effect.id < self.assets3d.effects
}
}