# Crafter.Graphics Catcrafts' Vulkan-based graphics + UI library. C++20 modules, ray-traced 3D, compute-shader UI, fully bindless via `VK_EXT_descriptor_heap`. This is **V2** of the library — a from-scratch rewrite that replaces the old `RenderingElement2D`-style UI (verbose, no batching, per-element descriptor surgery) with a declarative widget tree rendered through a single compute dispatch. ## Capabilities - **3D rendering** through `VK_KHR_ray_tracing_pipeline`. `RTPass` is the reusable wrapper; `Mesh` builds BLAS, `RenderingElement3D` builds TLAS. - **2D / UI rendering** through one compute shader per frame. Widgets emit `UIItem`s into a per-frame mapped SSBO; the shader scans it and composites onto the swapchain image. SDF glyph atlas means one texture covers all sizes / DPI scales. - **Bindless descriptor model** via `VK_EXT_descriptor_heap` — one resource heap + one sampler heap, bound once per frame. RT and UI passes share the same heap. - **`Window::passes`** — render passes are pluggable (`RenderPass*` vector). Add `RTPass`, `UIScene`, your own pass, in any order. Window inserts storage→storage barriers between consecutive passes. - **Cross-platform window backend** — Wayland (with fractional scale + XKB keyboard) or Win32, picked at compile time from the target triple. ## Quick start ```bash # Build the library cd Crafter.Graphics2 crafter-build # Build + run an example cd examples/VulkanUI crafter-build -r ``` Build dependencies (cloned automatically): `Vulkan-Headers`, `Vulkan-Utility-Libraries`, `Crafter.Event`, `Crafter.Math`, `Crafter.Asset`. System dependencies: `clang++` with C++20 modules and `libstd` PCM, `libvulkan`, `libwayland-client` + `xkbcommon` (or `kernel32/user32/gdi32` on Windows). ## Module layout The library is one C++20 module, `Crafter.Graphics`, with partitions grouped by concern: | Partition family | Purpose | |------------------------|------------------------------------------------------------| | `:Window`, `:Device` | Window + Vulkan instance/device | | `:RenderPass`, `:RTPass` | Pluggable pass interface + ray-tracing helper | | `:DescriptorHeapVulkan`, `:VulkanBuffer`, `:ImageVulkan`, `:SamplerVulkan` | Bindless heap + GPU buffers / images / samplers | | `:PipelineRTVulkan`, `:ShaderVulkan`, `:ShaderBindingTableVulkan` | RT pipeline plumbing | | `:Mesh`, `:RenderingElement3D` | BLAS / TLAS for ray tracing | | `:Font` | TTF loading + UTF-8 metrics | | `:UI*` | Widget tree, layout, hit-testing, theme, draw list, atlas, renderer, scene | The umbrella `import Crafter.Graphics;` re-exports everything. ## UI architecture (one paragraph) Widgets are value types with a fluent builder API. Composite containers (`VStack`, `HStack`, `Stack`, `Overlay`, `TabView`, `ScrollView`) take children as `&&` parameter packs and own them inside a `UIScene` arena. Layout is two-pass measure/arrange (WPF / Avalonia / Flutter style) with `Length::Px` / `Pct` / `Auto` / `Frac` units and DPI scaling threaded through. Each frame, `UIScene` walks the tree, emits a flat `UIItem` array into a mapped SSBO, and the compute shader scans it front-to-back compositing rectangles, rounded rectangles, SDF glyphs, and bindless images. Mouse clicks bubble through `OnMouseClick`; focus + `OnTextInput` / `OnKeyDown` route to the focused widget. Themes are flat structs (`ButtonStyle`, `InputFieldStyle`) applied per-instance via `.style(theme.primary)`. ## Examples - [`examples/VulkanTriangle`](examples/VulkanTriangle/) — minimal ray-traced triangle. The reference for `RTPass` + descriptor heap setup with no UI. - [`examples/VulkanUI`](examples/VulkanUI/) — the full Phase 2/3 surface: stacks, themed buttons, progress bar, tab view, focusable input fields with caret blink + key repeat. - [`examples/VulkanAnimated`](examples/VulkanAnimated/) — `Observable` + per-frame ticks driving live HUD bars and labels with no manual invalidation. ## V1 known limitations - Single-font, LTR-only text. No bold / italic / kerning beyond stb's default. No multi-line wrap or BiDi. - No tile-binning in the UI compute shader; the naive front-to-back per-pixel scan handles a few hundred items effortlessly. Past ~5,000 items the data layout supports tile-binning without an API change. - No render-target-to-texture for world-space UI yet. - No animation primitives in the UI module — drive `Observable`s yourself from `onUpdate`. ## Status Phase 1, 2, and 3 V1 of the rewrite are complete: ray-traced 3D path migrated to `RenderPass`, full UI widget set rendering through compute, focus + keyboard input + Wayland key repeat working end-to-end. Verified on NVIDIA GeForce RTX 4090 with `VK_EXT_descriptor_heap` and `VK_LAYER_KHRONOS_validation` clean. ## License LGPL v3 — see [LICENSE](LICENSE).