summaryrefslogtreecommitdiff
path: root/doc/ASSET_SYSTEM.md
blob: a97886c7bcfae6fda1643dff33567b508dab24cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# Compact Asset System for the 64k Demo

This document outlines the architecture for managing assets, which are compiled into the binary for release builds but loaded from disk during development to speed up iteration.

## Asset Manifest Format

Files: `workspaces/main/assets.txt`, `workspaces/test/assets.txt`

Format (CSV):
```
ASSET_NAME, ASSET_TYPE, path/to/file.ext, "Description"
```

### Asset Types

The `ASSET_TYPE` field explicitly defines how the asset is processed and used at runtime.

| Type | Description |
|------|-------------|
| `WGSL` | WGSL shader source code. |
| `SPEC` | Spectrogram data for audio synthesis. |
| `TEXTURE` | Image file (PNG, JPG, etc.), converted to a raw RGBA8 buffer with a width/height header. |
| `MESH` | 3D model file (.obj), converted to an interleaved vertex/index buffer. |
| `BINARY`| Generic raw binary data. |
| `MP3` | MP3 audio; decoded to a spectrogram at runtime. |
| `PROC(func, ...)` | CPU-based procedural generation at init time. |
| `PROC_GPU(func, ...)`| GPU-based compute shader for procedural generation at init time. |

## Dual-Mode Loading Strategy

The asset system operates in two modes, controlled by the `DEMO_STRIP_ALL` CMake flag:

1.  **Development Mode (`DEMO_STRIP_ALL=OFF`)**:
    *   `WGSL`, `SPEC`, and `MP3` assets are **loaded from disk** at runtime.
    *   The `asset_packer` generates a C-string containing the file path for these assets.
    *   The `AssetManager` reads the file on first access, caches it, and returns the content.
    *   This mode allows for rapid iteration on shaders and audio without requiring a full recompile.

2.  **Release Mode (`DEMO_STRIP_ALL=ON`)**:
    *   All assets are **embedded directly into the binary** as `const` byte arrays.
    *   This creates a single, self-contained executable suitable for distribution.
    *   The `asset_packer` generates C++ byte arrays from the asset files.

This dual-mode system provides both developer convenience and release-ready packaging.

## AssetType Enum

The C++ `AssetType` enum mirrors the types defined in the asset manifest:

```cpp
enum class AssetType : uint8_t {
  WGSL,
  SPEC,
  TEXTURE,
  MESH,
  BINARY,
  MP3,
  PROC,
  PROC_GPU,
};
```

Query at runtime:
```cpp
if (GetAssetType(AssetId::NEVER_MP3) == AssetType::MP3) { ... }
```

## Runtime API

```cpp
#include "util/asset_manager.h"

// Retrieve asset data
size_t size;
const uint8_t* data = GetAsset(AssetId::MY_ASSET, &size);
DropAsset(AssetId::MY_ASSET, data);  // Release procedural or disk-loaded data

// Query type
AssetType t = GetAssetType(AssetId::MY_ASSET);
```

## Build Pipeline

Tool: `tools/asset_packer.cc`

1.  Parse workspace `assets.txt`.
2.  If in **Development Mode**, for `WGSL`, `SPEC`, and `MP3` assets, it generates a C-string with the file path.
3.  If in **Release Mode**, it reads and processes all files into byte arrays (images → RGBA8, meshes → vertex/index, etc.).
4.  Generate `src/generated/assets.h` (enum + declarations).
5.  Generate `src/generated/assets_data.cc` (byte arrays/paths + `AssetRecord` table).
6.  Auto-triggered by CMake on manifest changes.

## Technical Guarantees

- **Alignment**: All embedded data arrays are declared `alignas(16)` for safe `reinterpret_cast`.
- **String Safety**: Embedded assets are null-terminated (safe as C-strings). In disk-load mode, the path itself is a null-terminated C-string.
- **Size**: For embedded assets, `size` reflects the original file size (the buffer is `size + 1`). For disk-loaded assets, it reflects the file path's string length.

## Developer Workflow

**Add a spectrogram:**
```
MY_KICK, SPEC, music/my_kick.spec, "Description"
```

**Add a shader:**
```
MY_SHADER, WGSL, shaders/my_shader.wgsl, "Description"
```

Rebuild: `cmake --build build -j4` — CMake detects manifest changes automatically. In development mode, changes to `.wgsl`, `.spec`, or `.mp3` files do not require a rebuild.