Files
wsg/lib/examples/simple.rs
T
Jérôme Bousquié 3dd372410f update demos et docs
2026-09-21 12:01:28 +02:00

54 lines
2.4 KiB
Rust

//! Minimal declarative workflow, no explicit WGPU handling in this file.
//! `AppBuilder` creates the event loop, then `App::run` opens the window, builds the `Context`/`Renderer`
//! and drives the update → render → present loop. In winit 0.30 the GPU only exists
//! after `resumed`: that is why shader registration + mesh/material/entity creation live in
//! the `AppHandler::setup` hook, called once the context is ready. The PipelineCache
//! lives in the scene (`Scene::init_gpu`, called in `resumed`): go through `register_shader` +
//! `add_material_shader` + `create_mesh` + `add_entity`, the material being bound to the mesh. The mesh
//! is declared from a **`Geometry`**: per-vertex positions + colors
//! for the unlit quad. The scene renders automatically: the default `render()` method calls
//! `app.render_scene(frame.view())`.
use wsg_lib::AppHandler;
use wsg_lib::app::AppBuilder;
use wsg_lib::resources::Geometry;
use wsg_lib::utils::WsgError;
struct MonQuad;
impl AppHandler for MonQuad {
fn setup(&mut self, app: &mut wsg_lib::App) {
// Flat 2D example: the `standard` shader in **unlit** mode (options.x = 1) returns the vertex
// color as-is. Flat 2D is thus a special case of 3D — a single pipeline for all.
app.renderer_mut().set_unlit(true);
app.scene
.register_shader("standard", wsg_lib::utils::STANDARD_SHADER_PATH)
.unwrap();
let geometry = Geometry::new(vec![
[-0.5, 0.5, 0.0], // top-left
[0.5, 0.5, 0.0], // top-right
[0.5, -0.5, 0.0], // bottom-right
[-0.5, -0.5, 0.0], // bottom-left
])
.with_normals(vec![[0.0, 0.0, 1.0]; 4])
.with_colors(vec![
[1.0, 0.0, 0.0, 1.0], // top-left (red)
[0.0, 1.0, 0.0, 1.0], // top-right (green)
[0.0, 0.0, 1.0, 1.0], // bottom-right (blue)
[1.0, 1.0, 0.0, 1.0], // bottom-left (yellow)
])
.with_indices(vec![0, 1, 2, 0, 2, 3]);
// Default material: `None` lets the Scene inject its `standard` at render time
// (`Scene::default_material`) — this exercises the default path.
app.scene.create_mesh("quad_mesh", geometry, None).unwrap();
app.scene.add_entity("quad", "quad_mesh").unwrap();
}
}
#[pollster::main]
async fn main() -> Result<(), WsgError> {
let app = AppBuilder::new().title("WSG Simple").build().await?;
app.run(MonQuad)
}