| Crates.io | charge |
| lib.rs | charge |
| version | 0.1.1 |
| created_at | 2025-12-09 06:18:09.988555+00 |
| updated_at | 2025-12-09 06:18:09.988555+00 |
| description | Modern, minimal, efficient Vulkan game engine |
| homepage | |
| repository | https://github.com/example/charge |
| max_upload_size | |
| id | 1974921 |
| size | 177,893 |
[!WARNING] Beta Release (v0.1.1): This version is an early release and is not fully optimized. Full optimization and missing features will be available in v0.1.8, which is scheduled for release within one month.
archetype_ecsglslc in PATH for shader compilation)Add to your Cargo.toml:
[dependencies]
charge = { path = "path/to/charge" }
winit = "0.30"
use charge::{Renderer, ChargeApp};
use winit::{
application::ApplicationHandler,
event::WindowEvent,
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
window::{Window, WindowId},
};
struct App {
window: Option<Window>,
renderer: Option<Renderer>,
}
impl ApplicationHandler for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let window = event_loop
.create_window(Default::default())
.expect("Failed to create window");
let renderer = Renderer::new(&window)
.expect("Failed to create renderer");
self.window = Some(window);
self.renderer = Some(renderer);
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {
match event {
WindowEvent::CloseRequested => event_loop.exit(),
WindowEvent::RedrawRequested => {
if let Some(renderer) = &mut self.renderer {
let _ = renderer.render_frame();
}
}
_ => {}
}
}
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
if let Some(window) = &self.window {
window.request_redraw();
}
}
}
fn main() {
let event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(ControlFlow::Poll);
let mut app = App { window: None, renderer: None };
let _ = event_loop.run_app(&mut app);
}
ChargeApp (Recommended)ChargeApp is a high-level wrapper that combines the renderer with an ECS world:
use charge::ChargeApp;
use charge::renderer::mesh::{MeshDescriptor, MaterialDescriptor};
use charge::renderer::Mesh;
use charge::ecs::components::Material;
// Create app
let mut app = ChargeApp::new(&window)?;
// Load a mesh from GLB
let mesh = Mesh::from_gltf("assets/model.glb")?;
// Create descriptors
let mesh_descriptor = MeshDescriptor {
key: mesh.name.clone(),
vertices: mesh.vertices.clone(),
indices: mesh.indices.clone(),
texture: mesh.texture_data.clone(),
normal_texture: mesh.normal_texture_data.clone(),
metallic_roughness_texture: mesh.metallic_roughness_texture_data.clone(),
occlusion_texture: mesh.occlusion_texture_data.clone(),
emissive_texture: mesh.emissive_texture_data.clone(),
material_properties: mesh.material_properties().cloned(),
};
let material_descriptor = MaterialDescriptor {
material: Material::default(),
};
// Register mesh with ECS (spawns entity automatically)
let (entity_id, mesh_handle, material_handle, key) =
app.register_mesh_entity(&mesh_descriptor, &material_descriptor, None)?;
// Game loop
loop {
app.update(); // Tick ECS systems
app.render()?; // Render frame
}
Renderer DirectlyFor lower-level control without ECS:
use charge::Renderer;
use charge::renderer::Mesh;
let mut renderer = Renderer::new(&window)?;
// Load and set mesh
let mesh = Mesh::from_gltf("assets/model.glb")?;
renderer.set_mesh(mesh);
// Configure camera
let camera = renderer.camera_mut();
camera.position = glam::Vec3::new(0.0, 2.0, 5.0);
camera.target = glam::Vec3::ZERO;
// Render loop
loop {
renderer.render_frame()?;
}
// Position the camera
let camera = renderer.camera_mut();
camera.position = glam::Vec3::new(0.0, 5.0, 10.0);
camera.target = glam::Vec3::new(0.0, 0.0, 0.0);
camera.up = glam::Vec3::Y;
camera.fov = 60.0_f32.to_radians();
camera.near = 0.1;
camera.far = 1000.0;
// Rotate and scale the mesh
let transform = renderer.transform_mut();
transform.set_position(glam::Vec3::new(0.0, 1.0, 0.0));
transform.set_rotation(glam::Vec3::new(0.0, 1.57, 0.0)); // radians
transform.set_scale(glam::Vec3::splat(2.0));
// Enable HDR + tonemapping + bloom
renderer.enable_post_processing()?;
// Tonemapping settings
renderer.set_tonemapping_enabled(true);
renderer.set_tonemapping_exposure(1.2); // HDR exposure
renderer.set_tonemapping_gamma(2.2); // Display gamma
// Bloom settings
renderer.set_bloom_enabled(true);
renderer.set_bloom_intensity(0.3);
use charge::renderer::Material;
let material = renderer.material_mut();
material.base_color = glam::Vec4::new(1.0, 0.5, 0.2, 1.0);
material.metallic = 0.8;
material.roughness = 0.2;
material.emissive = glam::Vec3::new(0.0, 0.0, 0.0);
use charge::renderer::diagnostics::DiagnosticsMode;
// Enable on-screen diagnostics
renderer.set_diagnostics_mode(DiagnosticsMode::Overlay);
// Or console-only output
renderer.set_diagnostics_mode(DiagnosticsMode::ConsoleOnly);
// Toggle with F6 key (in examples)
renderer.toggle_diagnostics();
Run the included examples:
# Simple triangle rendering
cargo run --example triangle
# Load and view GLB models
cargo run --example glb_view
cargo run --example glb_view -- assets/your_model.glb
# Interactive camera controls
cargo run --example interactive
# Post-processing demo (tonemapping + bloom)
cargo run --example postprocess_demo
| Key | Action |
|---|---|
WASD |
Move camera |
Space/Shift |
Move up/down |
Arrow Keys |
Rotate view |
R |
Toggle auto-rotation |
1-6 |
Adjust post-processing |
B |
Toggle bloom |
T |
Toggle tonemapping |
F6 |
Toggle diagnostics |
ESC |
Exit |
cargo build --release
cargo test --lib
cargo clippy
Shaders are pre-compiled, but if you modify them:
# Windows
./scripts/compile_shaders.ps1
# Linux/Mac (if script exists)
./scripts/compile_shaders.sh
charge/
โโโ src/
โ โโโ lib.rs # Library entry point
โ โโโ app/ # ChargeApp high-level wrapper
โ โโโ asset/ # Model, texture, LOD loading
โ โโโ camera/ # Camera system
โ โโโ ecs/ # Entity Component System
โ โโโ input/ # Input handling
โ โโโ renderer/ # Core Vulkan renderer
โ โโโ vulkan/ # Low-level Vulkan abstractions
โ โโโ features/ # Render features (shadows, bloom, etc.)
โ โโโ diagnostics/ # Performance overlay
โ โโโ resources/ # Resource management
โโโ shaders/ # GLSL shaders + compiled SPIR-V
โโโ examples/ # Example applications
โโโ assets/ # Demo assets (GLB models)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ChargeApp โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โ
โ โ EcsWorld โ โ Renderer โ โ InputState โ โ
โ โ โโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโ โ โ โ โ
โ โ โ Entities โ โ โ โ Vulkan โ โ โ โ โ
โ โ โComponents โ โโโโ โ Backend โ โ โ โ โ
โ โ โ Systems โ โ โ โ โ โ โ โ โ
โ โ โโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโ โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Vulkan Rendering โ
โ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โ Swapchain โ โ Pipelines โ โDescriptorsโ โ Shaders โ โ
โ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โ Shadows โ โ Bloom โ โTonemappingโ โ Bindless โ โ
โ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
This project is licensed under the Apache License 2.0.
Saptak Santra
๐ง saptaksantra7777@gmail.com
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)