Crafter.Graphics/README.md

105 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Crafter.Graphics
Vulkan-based graphics library built around C++20 modules and the bindless
`VK_EXT_descriptor_heap` extension. Provides window management, ray
tracing, and a compute-shader-driven UI on a single, opinionated stack.
## What's in here
- **Window** — Wayland and Win32 backends, swapchain ring, frame pacing,
input events. Pick a backend at build time via the target triple.
- **Device** — single-Vulkan-instance bring-up. The library targets
`VK_EXT_descriptor_heap` exclusively; pipelines are created with
`VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT` so there are no
descriptor-set layouts and push constants travel via
`vkCmdPushDataEXT`.
- **DescriptorHeapVulkan** — bindless slot allocator. `AllocateImageSlots`
/ `AllocateBufferSlots` / `AllocateSamplerSlots`, with byte-offset
helpers for direct descriptor writes.
- **VulkanBuffer\<T, Mapped\>** — typed buffer with optional host mapping
and a `FlushDevice` that issues the right host-write barrier.
- **ImageVulkan\<Pixel\>** — image + staging buffer, mip-chain support,
one-shot uploads via a command buffer.
- **PipelineRTVulkan / ShaderBindingTableVulkan / RTPass** — ray-tracing
pipeline, SBT, and a `RenderPass` that dispatches it.
- **ComputeShader** — the Tier 1 wrapper used by the UI system. Loads a
`.spv`, builds a heap-bound compute pipeline, dispatches with
`vkCmdPushDataEXT`. Use it directly for any custom compute.
- **UI** — three-tier UI system; see below.
- **FontAtlas** — single-channel SDF atlas (1024×1024, 32pt base,
shelf-packed, lazy `Ensure` per codepoint, dirty-flush via `Update`).
- **Mesh / RenderingElement3D / Animation** — BLAS/TLAS construction
and 3D scene plumbing for the ray-tracing path.
## UI system (three tiers)
The UI is *deliberately* layered to balance no-boilerplate against
no-lock-in:
- **Tier 1 — `ComputeShader`.** Load any `.spv`, dispatch with push
constants, library inserts inter-dispatch barriers. The escape hatch:
if the standard shaders don't fit, write your own compute and
dispatch it next to them.
- **Tier 2 — `UIRenderer` + standard shaders.** Four shipped compute
shaders (`drawQuads`, `drawCircles`, `drawImages`, `drawText`), POD
item structs (`QuadItem`, `CircleItem`, `ImageItem`, `GlyphItem`), a
shared GLSL contract in [shaders/ui-shared.glsl](shaders/ui-shared.glsl),
and helpers (`RegisterBuffer`, `RegisterImage`, `RegisterSampler`,
`FillHeader`, `Dispatch*`, `ShapeText`). You build your own per-shader
SSBOs (manual batching) and call one `Dispatch*` per shader type per
frame. Item array order = draw order.
- **Tier 3 — stateless presentation functions.** `DrawButton`,
`DrawCheckbox`, `DrawSlider`, `DrawProgressBar`. Each is a small
function that *appends* items to your buffers — they don't dispatch.
Colors come in as small inline `*Colors` aggregates, no library
`Theme` type. **The source is the customization API**: if a
component doesn't fit, copy its body and edit it. No virtual hooks,
no extension points.
What's *not* in the UI: widget tree, layout engine (just a `Rect::SubRect`
carving helper), theming, hit-testing, focus management. State for
interactive components (hover, drag, focus) lives in user-owned POD
structs, not the library.
### UI dispatch model
Standard shaders dispatch one workgroup per 8×8 *screen tile* — each
thread iterates every item in the SSBO in array order, accumulating
into a local `dst`, and stores once. Total cost is `O(W·H·N)`; works
well up to a few hundred items at 1080p. Splitting one buffer into
multiple dispatches doesn't help — the same total work plus barrier
overhead. If you need to render thousands of UI items, you want a
different shader (tile binning, per-item-list resolve), not more
dispatches.
## Build
The repository is built with `crafter-build` (a project-config based
build system; the project description lives in `project.cpp`):
```bash
crafter-build # build the library
crafter-build -r # build and run (in an example directory)
```
The build picks the window backend automatically: Wayland on Linux,
Win32 on Windows / mingw. Cross-compile via the standard `--target=...`
flag.
## Examples
See [examples/](examples/). Quick map:
- [HelloWindow](examples/HelloWindow/) — minimal window, no rendering.
- [VulkanTriangle](examples/VulkanTriangle/) — ray-traced triangle, the
smallest test of the bindless + ray-tracing path.
- [HelloUI](examples/HelloUI/) — UI smoke test using all three tiers
(background quad, slider, progress bar, button with text label,
cursor-tracking circle).
- [CustomShader](examples/CustomShader/) — Tier 1 demo: a user-authored
compute shader inverting RGB under a list of item-circles, dispatched
alongside the standard `drawQuads`. The "could attempt #2 do this?" test.
## License
LGPL 3.0. See per-file headers and `LICENSE`.