move from imgui to CLAY

This commit is contained in:
2026-02-25 15:20:47 -05:00
parent 6656b6d0b2
commit 12dae774e4
41 changed files with 6835 additions and 77320 deletions

View File

@@ -4,17 +4,51 @@ Graphical interface for automatically recording samples from existing analog aud
## Build
Requires MSVC (Visual Studio or Build Tools) with the Windows SDK.
Requires MSVC (Visual Studio 2019 Build Tools or later) with the Windows SDK and C++20 support.
Open a Developer Command Prompt, then:
```
cl /nologo nob.c
nob.exe
nob.exe debug
build\autosample.exe
```
The first command is a one-time bootstrap. After that, `nob.exe` detects changes to `nob.c` and rebuilds itself automatically.
The first command is a one-time bootstrap. After that, `nob.exe` detects changes to `nob.c` and rebuilds itself automatically. Pass `debug` for a debug build (default is release). Pass `clean` to wipe the build directory.
## Architecture
The project uses a **unity build**: `src/main.cpp` includes all other `.cpp` files, producing a single translation unit compiled with one `$CC` invocation.
### Base layer (`src/base/`)
Foundational types and utilities shared across the project. Provides sized integer/float typedefs (`U8`, `S32`, `F32`, `B32`, etc.), math primitives (`Vec2F32`), string helpers, and arena allocators. This layer has no dependencies beyond the C standard library.
### Platform layer (`src/platform/`)
Abstracts window creation, event polling, and native handles behind a C-style API with opaque `PlatformWindow` handles. The Win32 backend (`platform_win32.cpp`) implements the interface. Other backends can be added without touching the rest of the code.
### UI layer (`src/ui/`)
A thin wrapper around [Clay](https://github.com/nicbarker/clay) (v0.14), a single-header C layout library. Clay uses macros (`CLAY()`, `CLAY_TEXT()`, etc.) for declarative layout with automatic sizing, flex-like child arrangement, and built-in text measurement.
- `ui_core.h` / `ui_core.cpp` — Defines `UI_Context` and `UI_Theme`, handles Clay initialization, lifecycle (`ui_begin_frame` / `ui_end_frame`), text measurement bridge, and error handling. `CLAY_IMPLEMENTATION` is defined here.
- `ui_widgets.h` / `ui_widgets.cpp` — Widget abstractions (currently stubs, reserved for future use).
The application layout is built in `main.cpp` using Clay macros directly. Panel builder functions (`build_browser_panel`, `build_main_panel`, etc.) compose the UI each frame.
### Renderer (`src/renderer/`)
DirectX 12 renderer with a custom SDF-based pipeline for UI rendering. Processes Clay's `Clay_RenderCommandArray` output directly — no intermediate scene graph.
- **Font atlas**: Built at startup using GDI (`TextOutA` into a DIB section), converted to a single-channel R8 texture. Covers ASCII 32126 (Segoe UI).
- **Text measurement**: GDI-based (`GetTextExtentPoint32A`), exposed to Clay via the `Clay_SetMeasureTextFunction` callback.
- **Render commands**: Handles `RECTANGLE` (SDF rounded rect with corner radius), `BORDER` (individual sides as thin rects), `TEXT` (glyph quads from the font atlas), and `SCISSOR_START`/`SCISSOR_END` (clip regions).
- **Vertex format**: Position, UV, color, rect bounds, corner radius, border thickness, softness, and mode (0 = SDF rect, 1 = textured glyph). Alpha blending with premultiplied SDF anti-aliasing.
### MIDI (`src/midi/`)
Enumerates MIDI input and output devices via the Win32 multimedia API (`midiInGetDevCapsA` / `midiOutGetDevCapsA`). Provides a simple `MidiEngine` with device listing and refresh.
## Project structure
@@ -22,19 +56,42 @@ The first command is a one-time bootstrap. After that, `nob.exe` detects changes
nob.c Build script (compiled to nob.exe)
nob.h nob build system (vendored, single-header)
src/
main.cpp Entry point and main loop
main.cpp Entry point, unity build includes, Clay layout
menus.cpp Menu bar setup
theme.cpp Theme stub
base/
base_core.h Sized types, macros
base_arena.h / .cpp Arena allocator
base_math.h Vec2, min/max
base_strings.h / .cpp String utilities
base_inc.h / .cpp Aggregate include/impl
platform/
platform.h Window management API (platform-agnostic)
platform_win32.cpp Win32 implementation
renderer/
renderer.h Renderer API (graphics-agnostic)
renderer_dx12.cpp DirectX 12 implementation + Dear ImGui backend
renderer_dx12.cpp DirectX 12 implementation, SDF pipeline, font atlas
ui/
ui_core.h Clay wrapper types and lifecycle API
ui_core.cpp Clay init, text measurement bridge, theme
ui_widgets.h / .cpp Widget stubs (reserved)
midi/
midi.h MIDI device enumeration API
midi_win32.cpp Win32 multimedia implementation
vendor/
imgui/ Dear ImGui (vendored source)
backends/ Platform and renderer backends (Win32, DX12)
clay/
clay.h Clay v0.14 (modified for MSVC C++ compatibility)
```
The platform and renderer layers are C-style APIs with opaque handles. `platform.h` abstracts window creation so other backends can be added without touching the rest of the code. `renderer.h` abstracts graphics initialization and frame management.
### Modifications to `vendor/clay/clay.h`
Two targeted patches for MSVC C++ compatibility:
1. **`CLAY__CONFIG_WRAPPER` bypass** (lines 158163): MSVC C++ rejects designated initializers inside function-style casts. In C++ mode, the wrapper struct is bypassed: `(type { __VA_ARGS__ })` instead of `(WrapperType { .field = ... }).wrapped`.
2. **Debug view stub** (lines ~31553858): Clay's built-in debug view functions use `CLAY__INIT(type) { .field = ... }` directly (not through `CLAY__CONFIG_WRAPPER`), which also fails in MSVC C++. An `#ifdef __cplusplus` guard stubs out the 4 debug view functions as empty no-ops. The debug overlay is not needed.
These patches allow the entire project (including Clay) to compile as a single C++20 translation unit, avoiding C/C++ ABI mismatches with `CLAY_PACKED_ENUM` (which controls enum sizing differently in C vs C++ mode).
## Code style
@@ -42,14 +99,14 @@ This project is written in C-style C++. We use `.cpp` files and a small subset o
Memory should be managed with arena allocators where possible rather than individual `malloc`/`free` or `new`/`delete` calls. Arenas make allocation fast, avoid fragmentation, and simplify cleanup.
### Syntax Style
### Syntax style
- Opening braces go on the same line as the function signature (K&R style), not on the next line.
- use CAPS_SNAKE_CASE for constants, lower_snake_case for functions and variables, and CapsCamelCase for types.
- Use `CAPS_SNAKE_CASE` for constants, `lower_snake_case` for functions and variables, and `CapsCamelCase` for types.
## Dependencies
All dependencies are vendored as source. Nothing to download or install beyond the Windows SDK.
- [nob.h](https://github.com/tsoding/nob.h) - build system
- [Dear ImGui](https://github.com/ocornut/imgui) - GUI
- [nob.h](https://github.com/tsoding/nob.h) build system
- [Clay](https://github.com/nicbarker/clay) — single-header C layout library (v0.14, with MSVC C++ patches)