//! 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. Since the winit 0.30 migration, 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. Since Step 7 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. Since Step 8 //! (DRAFT 8.4/8.5) 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`, DRAFT Step 7.3.5) — 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) }