111 lines
4.9 KiB
Markdown
111 lines
4.9 KiB
Markdown
# 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<T>`
|
|
+ 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<T>`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).
|