shdrlib 0.1.5

A three-tiered Vulkan shader compilation and rendering framework built in pure Rust
Documentation
//! # EZ Tier (Tier 2) - Simplified Rendering API
//!
//! The EZ tier provides a minimal API for shader compilation and rendering with
//! sensible defaults and automatic resource management. This tier wraps the EX tier
//! into a unified interface suitable for learning and prototyping.
//!
//! ## Philosophy
//!
//! - **Simple**: Minimal setup with sensible defaults
//! - **Focused**: Concentrate on shaders rather than Vulkan details
//! - **Safe**: Automatic memory management and resource cleanup
//! - **Accessible**: Suitable for learning and rapid prototyping
//! - **Progressive**: Access EX/CORE tiers when more control is needed
//!
//! ## Key Components
//!
//! | Component | Purpose |
//! |-----------|---------|
//! | `EzRenderer` | Unified renderer with defaults |
//! | `EzFrame` | Frame rendering context |
//! | `EzConfig` | Optional configuration |
//! | `Mesh` | Bundled vertex and index buffers |
//! | Buffer Helpers | Simplified buffer creation |
//! | Image Helpers | Simplified image creation |
//! | Pipeline Helpers | `quick_pipeline()`, `quick_compute()` |
//!
//! ## Code Reduction
//!
//! EZ tier reduces code complexity through simplified abstractions:
//!
//! - **Triangle**: 25 lines (16x reduction from CORE)
//! - **Mesh Creation**: 1 line (vs 11 lines manual buffer management)
//! - **Drawing**: 1 line with `draw_mesh()` (vs 6+ separate operations)
//! - **Setup**: 1 line (80x reduction from CORE)
//!
//! ## Mesh API
//!
//! The Mesh API simplifies geometry management:
//!
//! ```rust,no_run
//! use shdrlib::ez::*;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let mut renderer = EzRenderer::new()?;
//!
//! // Option 1: Use pre-built fullscreen quad (perfect for shaders!)
//! let quad = renderer.create_fullscreen_quad()?;
//!
//! // Option 2: Create custom mesh from your data
//! let vertices: Vec<f32> = vec![/* ... */];
//! let indices: Vec<u16> = vec![0, 1, 2];
//! let mesh = renderer.create_mesh(&vertices, Some(&indices))?;
//!
//! // Create pipeline
//! let pipeline = renderer.quick_pipeline(VERTEX_GLSL, FRAGMENT_GLSL)?;
//!
//! // Draw with ONE line!
//! renderer.render_frame(|frame| {
//!     frame.draw_mesh(pipeline, &quad)?;
//!     Ok(())
//! })?;
//! # Ok(())
//! # }
//! # const VERTEX_GLSL: &str = "#version 450\nvoid main() {}";
//! # const FRAGMENT_GLSL: &str = "#version 450\nvoid main() {}";
//! ```
//!
//! ### Before and After Comparison
//!
//! **Manual approach (11 lines):**
//! ```rust,no_run
//! # use shdrlib::ez::*;
//! # use shdrlib::core::Buffer;
//! # use shdrlib::ex::PipelineId;
//! # use ash::vk;
//! # fn example(renderer: &mut EzRenderer, pipeline: PipelineId, vbuf: &Buffer, ibuf: &Buffer) -> Result<(), Box<dyn std::error::Error>> {
//! renderer.render_frame(|frame| {
//!     frame.bind_pipeline(pipeline)?;
//!     frame.bind_vertex_buffers(0, &[vbuf.handle()], &[0]);
//!     frame.bind_index_buffer(ibuf.handle(), 0, vk::IndexType::UINT16);
//!     frame.set_viewport(0.0, 0.0, 800.0, 600.0);
//!     frame.set_scissor(0, 0, 800, 600);
//!     frame.draw_indexed(6, 1, 0, 0, 0);
//!     Ok(())
//! })?;
//! # Ok(())
//! # }
//! ```
//!
//! **With Mesh API (1 line):**
//! ```rust,no_run
//! # use shdrlib::ez::*;
//! # use shdrlib::ex::PipelineId;
//! # fn example(renderer: &mut EzRenderer, pipeline: PipelineId, mesh: &Mesh) -> Result<(), Box<dyn std::error::Error>> {
//! renderer.render_frame(|frame| {
//!     frame.draw_mesh(pipeline, &mesh)?;
//!     Ok(())
//! })?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Usage Example
//!
//! ```rust,no_run
//! use shdrlib::ez::*;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // One-liner setup with intelligent defaults
//! let mut renderer = EzRenderer::new()?;
//!
//! // Create buffers
//! let vertices: Vec<f32> = vec![0.0, -0.5, 0.5, 0.5, -0.5, 0.5];
//! let vertex_buffer = renderer.create_vertex_buffer(&vertices)?;
//!
//! // Create pipelines
//! let graphics = renderer.quick_pipeline(VERTEX_GLSL, FRAGMENT_GLSL)?;
//! let compute = renderer.quick_compute(COMPUTE_GLSL)?;
//!
//! // Render loop with closure-based API
//! renderer.render_frame(|frame| {
//!     frame.bind_pipeline(graphics)?;
//!     frame.bind_vertex_buffers(0, &[vertex_buffer.handle()], &[0]);
//!     frame.set_viewport(0.0, 0.0, 800.0, 600.0);
//!     frame.set_scissor(0, 0, 800, 600);
//!     frame.draw(3, 1, 0, 0);
//!     Ok(())
//! })?;
//! # Ok(())
//! # }
//! # const VERTEX_GLSL: &str = "#version 450\nvoid main() {}";
//! # const FRAGMENT_GLSL: &str = "#version 450\nvoid main() {}";
//! # const COMPUTE_GLSL: &str = "#version 450\nvoid main() {}";
//! ```
//!
//! ## When to Use EZ
//!
//! **Use EZ when:**
//! - Learning Vulkan and shader programming basics
//! - Rapid prototyping of rendering ideas
//! - Teaching graphics programming concepts
//! - Building simple demos or experiments
//! - Focusing on shaders, not Vulkan boilerplate
//! - Exploring graphics techniques quickly
//!
//! **Don't use EZ when:**
//! - Building production applications (use EX tier)
//! - Need fine-grained configuration control (use EX tier)
//! - Optimizing for specific hardware (use EX or CORE tier)
//! - Building complex render graphs (use EX tier)
//! - Implementing custom resource management (use CORE tier)
//!
//! ## Tier Comparison
//!
//! | Feature | CORE | EX | EZ (Manual) | EZ (Mesh) |
//! |---------|------|----|----|-----|
//! | Setup complexity | Maximum | Medium | Minimal | Minimal |
//! | Control level | Total | Explicit | Limited | Limited |
//! | Safety | Manual | Automatic | Automatic | Automatic |
//! | Configuration | Explicit | Explicit | Defaults | Defaults |
//! | Lines for triangle | ~400 | ~100 | ~30 | ~25 |
//! | Drawing code | ~15 | ~8 | ~6 | 1 |
//! | Buffer creation | ~30 lines | 1 line | 1 line | 1 line |
//! | Mesh creation | ~50 lines | 2 lines | 2 lines | 1 line |
//! | Best for | Frameworks | Applications | Learning | Shaders |
//!
//! ## Features
//!
//! ### Renderer (`EzRenderer`)
//! - `new()` / `with_config()` - Simple setup
//! - `quick_pipeline()` - Graphics pipeline in one call
//! - `quick_compute()` - Compute pipeline in one call
//! - `render_frame()` - Closure-based rendering
//! - `create_mesh()` - Bundle vertex and index buffers
//! - `create_fullscreen_quad()` - Pre-built quad geometry
//!
//! ### Mesh API
//! - `Mesh` - Bundled vertex and index buffers
//! - `create_mesh()` - Create from vertex and index data
//! - `create_fullscreen_quad()` - Pre-built quad for shader experiments
//! - `draw_mesh()` - Simplified drawing
//!
//! ### Buffer Helpers
//! - `create_vertex_buffer()` - Vertex buffer with automatic cleanup
//! - `create_index_buffer()` - Index buffer with automatic cleanup
//! - `create_uniform_buffer::<T>()` - Uniform buffer with automatic cleanup
//! - `create_storage_buffer()` - Storage buffer with automatic cleanup
//! - `write_buffer()` - Buffer data upload
//!
//! ### Image Helpers
//! - `create_render_target()` - Color attachment with automatic cleanup
//! - `create_depth_stencil()` - Depth buffer with automatic cleanup
//! - `create_texture()` - Sampled texture with automatic cleanup
//! - `create_storage_image()` - Storage image with automatic cleanup
//!
//! ### Frame API (`EzFrame`)
//! - `draw_mesh()` - Simplified mesh drawing
//! - `bind_pipeline()` / `bind_compute_pipeline()` - Pipeline binding
//! - `bind_vertex_buffers()` / `bind_index_buffer()` - Buffer binding
//! - `draw()` / `draw_indexed()` - Draw commands
//! - `dispatch()` - Compute dispatch
//! - `set_viewport()` / `set_scissor()` - Dynamic state
//! - `bind_descriptor_sets()` - Descriptor binding
//! - `push_constants()` - Push constants
//! - `begin_rendering()` - Begin rendering with automatic viewport and scissor
//!
//! ## Progressive Access
//!
//! EZ tier provides access to lower tiers when additional control is needed:
//!
//! ```rust,no_run
//! use shdrlib::ez::*;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let mut renderer = EzRenderer::new()?;
//!
//! // Drop down to EX tier for more control
//! let shader_manager = renderer.shader_manager_mut();
//! let runtime = renderer.runtime_mut();
//!
//! // Or drop to CORE tier for maximum control
//! let device = runtime.device();
//! let raw_device_handle = device.handle(); // ash::Device
//! # Ok(())
//! # }
//! ```
//!
//! ## Examples
//!
//! See `demos/ez/` for complete working examples:
//!
//! - **01_hello_triangle.rs** - Complete triangle in 25 lines
//! - **02_compute_multiply.rs** - Compute shader example  
//! - **03_buffers_demo.rs** - Mesh API demonstration
//! - **04_splash_screen.rs** - Fullscreen quad in 15 lines
//!
//! Run with: `cargo run --bin ez_01_hello_triangle`

pub mod errors;
pub mod mesh;
pub mod renderer;

#[cfg(test)]
mod tests;

// Re-exports for convenience
pub use errors::EzError;
pub use mesh::Mesh;
pub use renderer::{EzConfig, EzFrame, EzRenderer};