resonance 0.1.0

A modular game engine. Heavy work in progress.
Documentation

use crate::assets::loader::{AssetLoader, LoadError};
use std::path::Path;

#[derive(Clone, Debug)]
pub struct ShaderData {
    pub source: String,
    pub shader_type: ShaderType,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ShaderType {
    Wgsl,
    Glsl,
}

impl ShaderData {
    pub fn new(source: String, shader_type: ShaderType) -> Self {
        Self {
            source,
            shader_type,
        }
    }

    pub fn fallback() -> Self {
        let source = r#"

struct VertexOutput {
    @builtin(position) position: vec4<f32>,
}

@vertex
fn vs_main(@location(0) position: vec3<f32>) -> VertexOutput {
    var out: VertexOutput;
    out.position = vec4<f32>(position, 1.0);
    return out;
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 1.0, 1.0);
}
"#
        .to_string();

        Self {
            source,
            shader_type: ShaderType::Wgsl,
        }
    }
}

pub struct WgslLoader;

impl AssetLoader for WgslLoader {
    type Asset = ShaderData;

    fn load(&self, path: &Path) -> Result<Self::Asset, LoadError> {
        let source = std::fs::read_to_string(path)
            .map_err(|e| LoadError::LoadFailed(format!("Failed to read shader file: {}", e)))?;

        if !source.contains("@vertex") && !source.contains("@fragment") {
            log::warn!("Shader may not be valid WGSL (missing @vertex or @fragment)");
        }

        log::info!("Loaded WGSL shader from {:?}", path);

        Ok(ShaderData {
            source,
            shader_type: ShaderType::Wgsl,
        })
    }

    fn extensions(&self) -> &[&str] {
        &["wgsl"]
    }
}

pub fn load_shader_from_bytes(bytes: &[u8], shader_type: ShaderType) -> Result<ShaderData, LoadError> {
    let source = String::from_utf8(bytes.to_vec())
        .map_err(|e| LoadError::LoadFailed(format!("Invalid UTF-8 in shader: {}", e)))?;

    Ok(ShaderData {
        source,
        shader_type,
    })
}