-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharchitecture.html
More file actions
390 lines (358 loc) · 27.4 KB
/
Copy patharchitecture.html
File metadata and controls
390 lines (358 loc) · 27.4 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Architecture - CNA</title>
<meta name="description" content="CNA 0.1.0-alpha.1 architecture: XNA-compatible APIs over independent platform, audio and graphics interfaces, 50 renderer identities in 46 families, and opt-in runtime renderer selection.">
<meta property="og:type" content="website">
<meta property="og:site_name" content="CNA">
<meta property="og:url" content="https://libcna.com/architecture.html">
<meta property="og:title" content="Architecture - CNA">
<meta property="og:description" content="CNA 0.1.0-alpha.1 architecture: XNA-compatible APIs over independent platform, audio and graphics interfaces, 50 renderer identities in 46 families, and opt-in runtime renderer selection.">
<link rel="stylesheet" href="css/style.css">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="canonical" href="https://libcna.com/architecture.html">
<link rel="stylesheet" href="css/prism-tomorrow.min.css">
<script>(function(){try{var t=localStorage.getItem("cna-theme");if(t==="light"||t==="dark")document.documentElement.setAttribute("data-theme",t);}catch(e){}})();</script>
</head>
<body>
<a class="skip-link" href="#main-content">Skip to content</a>
<nav class="nav">
<div class="nav-container">
<a href="index.html" class="nav-brand">CNA</a>
<button class="nav-toggle" aria-label="Toggle navigation" aria-expanded="false">
<span></span><span></span><span></span>
</button>
<div class="nav-menu">
<a href="index.html" class="nav-link">Home</a>
<a href="about.html" class="nav-link">About</a>
<a href="features.html" class="nav-link">Features</a>
<a href="architecture.html" class="nav-link">Architecture</a>
<a href="documentation.html" class="nav-link">Documentation</a>
<a href="tutorials.html" class="nav-link">Tutorials</a>
<a href="demos.html" class="nav-link">Demos</a>
<a href="showcase.html" class="nav-link">Showcase</a>
<a href="videos.html" class="nav-link">Videos</a>
<a href="roadmap.html" class="nav-link">Roadmap</a>
<a href="contact.html" class="nav-link">Contact</a>
<a href="search.html" class="nav-link">Search</a>
<a href="https://github.com/openeggbert/cna" class="nav-link nav-link--github" target="_blank" rel="noopener">GitHub</a>
<a href="https://discord.gg/vrnc4n6DaE" class="nav-link nav-link--discord" target="_blank" rel="noopener">Discord</a>
</div>
<button class="theme-toggle" type="button" aria-label="Switch to light theme" title="Switch to light theme">
<svg class="theme-icon-light" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 17a5 5 0 1 1 0-10 5 5 0 0 1 0 10zm0-2a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.5 4.9l1.4-1.4 2.1 2.1-1.4 1.4L3.5 4.9zm13.5 13.5l1.4-1.4 2.1 2.1-1.4 1.4-2.1-2.1zM19.1 3.5l1.4 1.4-2.1 2.1-1.4-1.4 2.1-2.1zM5.6 17l1.4 1.4-2.1 2.1-1.4-1.4L5.6 17zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></svg>
<svg class="theme-icon-dark" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12.3 22a10 10 0 0 1-1.6-19.9c.6-.1 1 .5.8 1a7.9 7.9 0 0 0 9.7 10.6c.5-.2 1 .3.9.8A10 10 0 0 1 12.3 22z"/></svg>
</button>
</div>
</nav>
<main id="main-content">
<div class="page-header">
<div class="container">
<span class="section-label">Architecture</span>
<h1>How CNA is structured</h1>
<p>CNA is organised into four clear, strictly separated layers - from high-level game code down to hardware-specific renderers.</p>
</div>
</div>
<section class="section">
<div class="container">
<!-- ASCII diagram -->
<span class="section-label">Overview Diagram</span>
<h2>Layer overview</h2>
<div class="arch-diagram">
<pre>
┌─────────────────────────────────────────────────────────────────┐
│ Game / Application Code │
│ Uses: Microsoft::Xna::Framework API │
│ Example: MyGame extends Game, calls SpriteBatch::Draw() │
└────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ XNA-Compatible Public API Layer │
│ include/Microsoft/Xna/Framework/... │
│ Game · GraphicsDevice · SpriteBatch · Texture2D · Color │
│ Vector2/3/4 · Matrix · Rectangle · GameTime · Input │
└────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ CNA Internal Abstraction Layer (sharp-runtime support) │
│ include/CNA/Internal/Renderers/... │
│ IGraphicsRenderer · ISpriteBatchRenderer · ITextureRenderer │
│ Registry · descriptors · GraphicsRendererSelection │
└──────────┬───────────────┬──────────────┬───────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌────────────────────────────┐
│ OPENGLES3 │ │ VULKAN │ │ DIRECTX11 · METAL · BGFX │
│ WEBGL2 · … │ │ SDL_GPU │ │ CANVAS · SOFTWARE · … │
│ │ │ │ │ (50 identities total) │
└──────┬───────┘ └──────┬───────┘ └──────────────┬─────────────┘
│ │ │
└─────────────────┴──────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Independent host and audio services │
│ CNA_PLATFORM: SDL3 · SDL2 · HEADLESS · TERMINAL │
│ CNA_AUDIO_PLATFORM: SDL3 · SDL2 · NULL │
└─────────────────────────────────────────────────────────────────┘
</pre>
</div>
<p style="margin-top:1rem;">Every renderer family publishes a descriptor and namespaced factory into a generated runtime registry. A normal build emits one entry; <code>CNA_GRAPHICS_RENDERERS</code> can emit a compatible set. The 50 public identities include five EasyGL profiles and the newer <code>TINYGL</code>, <code>IGL</code>, <code>PIXIJS</code> and <code>NANOVG</code> identities. See the <a href="docs/rendering-backends.html">renderer reference</a>.</p>
<!-- Visual diagram -->
<span class="section-label">Visual Diagram</span>
<h2>Detailed architecture diagram</h2>
<div style="background:#ffffff; border-radius:var(--radius-lg); padding:1.5rem; margin-top:1.5rem; overflow-x:auto;">
<img src="mermaid-diagram.png" alt="CNA detailed architecture diagram" style="max-width:100%; height:auto; display:block; margin:0 auto;">
</div>
<!-- Layer descriptions -->
<span class="section-label" style="margin-top:3rem; display:block;">Layers</span>
<h2>Layer descriptions</h2>
<div class="arch-layer arch-layer--app">
<div class="arch-layer-label">Layer 1 - Highest</div>
<h4>Game / Application Code</h4>
<p>Your game logic. Subclasses <code>Game</code>, overrides <code>LoadContent()</code>, <code>Update()</code>, <code>Draw()</code>. Calls XNA-style APIs exclusively. Has zero knowledge of which renderer is in use - this is the contract CNA enforces. Games written against this layer are portable across renderers.</p>
</div>
<div class="arch-layer arch-layer--api">
<div class="arch-layer-label">Layer 2 - Public API</div>
<h4>XNA-Compatible API Layer</h4>
<p>Lives under <code>include/Microsoft/Xna/Framework/</code>. This is the surface that game code touches. Class names, namespaces, and method signatures mirror the original XNA 4.0 API as faithfully as practical in C++. No renderer-specific code leaks into this layer. Includes: <code>Game</code>, <code>GraphicsDevice</code>, <code>GraphicsDeviceManager</code>, <code>SpriteBatch</code>, <code>Texture2D</code>, <code>Color</code>, all math types, input surfaces, <code>GameTime</code>, <code>GameComponent</code>, etc.</p>
</div>
<div class="arch-layer arch-layer--internal">
<div class="arch-layer-label">Layer 3 - Internal Abstractions</div>
<h4>CNA Internal Layer & sharp-runtime Support</h4>
<p>Lives under <code>modules/graphics/include/CNA/Internal/Renderers/</code>, in the <code>CNA::Internal::Renderers</code> namespace. It defines renderer interfaces plus the descriptor/registry contract used before a device exists. <code>GraphicsRendererSelection</code> resolves the compiled default or an explicit runtime choice and then dispatches through the selected family's namespaced factory.</p>
</div>
<div class="arch-layer arch-layer--renderer">
<div class="arch-layer-label">Layer 4 - Lowest</div>
<h4>Renderer, platform and audio implementations</h4>
<p>Concrete renderers live under <code>modules/renderers/<family>/</code>: 46 implementation families carrying 50 identities. Platform implementations separately implement <code>CNA::Platform::IPlatform</code>; audio implementations separately implement the audio device surface. The target OS is a fourth concern, reported by <code>CNA::TargetPlatform</code>.</p>
<h5 style="margin-top:1rem; margin-bottom:0.5rem;">SDL3 and SDL2</h5>
<p>SDL3 remains the default platform and audio selection, but it is no longer inseparable from CNA. <code>CNA_PLATFORM=SDL2</code> uses the real SDL 2.30 API, while Headless and POSIX Terminal avoid a graphical host. Audio-device code may independently be SDL3, SDL2 or Null; only SDL3 defines <code>SOUND_ENABLED</code> and supplies alpha.1's high-level SDL3_mixer playback/decoding engine.</p>
<ul>
<li><strong>SDL3_mixer</strong> uses the <code>MIX_Mixer</code> model with track-based, per-mixer channels — unlike SDL2_mixer's global audio system.</li>
<li><strong>SDL3_image</strong> is used for texture/image loading.</li>
<li>All three libraries (<code>SDL</code>, <code>SDL_image</code>, <code>SDL_mixer</code>) are vendored as Git submodules under <code>third_party/</code>. No system SDL install is required by default; pass <code>-DCNA_USE_SYSTEM_SDL=ON</code> to use system packages instead.</li>
</ul>
<p>The platform service contract covers:</p>
<ul>
<li><strong>Windowing</strong> — <code>SDL_Window</code> creation and management</li>
<li><strong>Event loop</strong> — cross-platform event pumping</li>
<li><strong>Input</strong> — <code>SDL_Keyboard</code>, <code>SDL_Mouse</code>, <code>SDL_Gamepad</code>, <code>SDL_Touch</code></li>
<li><strong>Audio initialisation</strong> — SDL3_mixer setup</li>
<li><strong>OpenGL context creation</strong> — used by the EasyGL renderer</li>
<li><strong>Vulkan surface creation</strong> — used by the VULKAN renderer</li>
<li><strong>Native surface creation</strong> — used by the WEBGPU renderer (Win32/Metal/X11/Wayland surfaces built directly from SDL3 window properties, no separate compatibility library needed)</li>
<li><strong>Android JNI Activity layer</strong> — Android platform integration</li>
<li><strong>Emscripten main loop</strong> — WebAssembly/browser event scheduling</li>
</ul>
<p style="margin-top:1rem;">A renderer asks for narrow services such as a native surface, GL context or Vulkan surface. Headless and Terminal applications can still choose the full SDL3 audio engine; graphical applications can select Null to remove it, with the resulting no-playback boundary documented explicitly. See <a href="docs/platforms.html">Platform Support</a> for valid combinations.</p>
</div>
<!-- Sibling Libraries -->
<span class="section-label" style="margin-top:3rem; display:block;">Sibling Libraries</span>
<h2>Required sibling repositories</h2>
<p>CNA depends on two sibling C++ libraries that must be cloned adjacent to the CNA repository. They are not vendored inside CNA — they live at predictable relative paths and are discovered by CMake automatically.</p>
<div class="arch-layer arch-layer--internal" style="margin-top:1.5rem;">
<div class="arch-layer-label">Sibling — clone at <code>../sharp-runtime/</code></div>
<h4>sharp-runtime</h4>
<p><code>sharp-runtime</code> is a C++ library that provides .NET-style type primitives for C++23. It allows CNA code to closely mirror XNA C# code structure without a managed runtime. Clone it at <code>../sharp-runtime/</code> relative to the CNA repo root.</p>
<p><strong>Integer aliases:</strong></p>
<ul>
<li><code>bytecs</code> — alias for <code>uint8_t</code></li>
<li><code>shortcs</code> — alias for <code>int16_t</code></li>
<li><code>intcs</code> — alias for <code>int32_t</code></li>
<li><code>longcs</code> — alias for <code>int64_t</code></li>
<li><code>ushortcs</code>, <code>uintcs</code>, <code>ulongcs</code> — unsigned variants</li>
</ul>
<p><strong>Other primitives:</strong></p>
<ul>
<li><code>Single</code> — alias for <code>float</code></li>
<li><code>String</code> — <code>std::string</code> wrapper</li>
<li><code>IDisposable</code> — virtual <code>Dispose()</code> interface</li>
<li><code>IEquatable<T></code> — <code>Equals</code> method interface</li>
<li><code>IComparable<T></code> — comparison interface</li>
<li><code>EventHandler<TArgs></code> — multicast delegate-style callbacks</li>
<li><code>List<T></code>, <code>Dictionary<K,V></code> — collection wrappers</li>
<li>I/O primitives</li>
</ul>
</div>
<div class="arch-layer arch-layer--renderer" style="margin-top:1.5rem;">
<div class="arch-layer-label">Sibling — clone at <code>../easy-gl/</code> (OPENGLES3 renderer only)</div>
<h4>easy-gl</h4>
<p><code>easy-gl</code> wraps OpenGL ES 3.0/3.2 for CNA's <code>OPENGLES3</code> renderer. Clone it at <code>../easy-gl/</code> relative to the CNA repo root. It is required <strong>only</strong> for the <code>OPENGLES3</code> renderer — not needed for <code>SDL_RENDERER</code>, <code>VULKAN</code>, <code>BGFX</code>, <code>WEBGPU</code>, <code>HEADLESS</code>, <code>SOFTWARE</code>, <code>DIRECTX11</code>, or <code>DIRECTX12</code>.</p>
<ul>
<li>Abstracts GLSL shader compilation, linking, and uniform binding</li>
<li>Manages VAOs, VBOs, FBOs, textures, and renderbuffers</li>
<li>Provides the OpenGL context for both Linux desktop (OpenGL 3.0+ with ES emulation) and WebGL 2 (via Emscripten)</li>
</ul>
</div>
<!-- Renderer Selection Guide -->
<span class="section-label" style="margin-top:3rem; display:block;">Renderer Selection</span>
<h2>Which renderer should I choose?</h2>
<p>Select your renderer at configure time with <code>-DCNA_GRAPHICS_RENDERER=<NAME></code>. Use the table below to pick the best fit for your target platform and requirements.</p>
<div class="table-wrap">
<table>
<thead>
<tr><th>Renderer</th><th>Best for</th><th>Scope</th><th>Platform</th></tr>
</thead>
<tbody>
<tr><td><code>OPENGLES3</code></td><td>Most Linux and Android games</td><td>2D + 3D</td><td>Desktop/mobile GL (default on Linux)</td></tr>
<tr><td><code>WEBGL2</code></td><td>Browser games with 3D</td><td>2D + 3D</td><td>Emscripten only (the web default)</td></tr>
<tr><td><code>SDL_RENDERER</code></td><td>Pure 2D, maximum portability</td><td>2D only</td><td>Anywhere SDL3 runs (default elsewhere)</td></tr>
<tr><td><code>VULKAN</code></td><td>Low-level GPU control</td><td>2D + 3D</td><td>Any Vulkan-capable target</td></tr>
<tr><td><code>DIRECTX11</code></td><td>Native Windows 3D</td><td>2D + 3D</td><td>Windows only</td></tr>
<tr><td><code>DIRECTX9</code></td><td>XNA pixel authenticity</td><td>2D + 3D</td><td>Windows only</td></tr>
<tr><td><code>FNA3D</code></td><td>Running XNA's real compiled stock effects</td><td>2D + 3D</td><td>Any; cannot compile custom shaders</td></tr>
<tr><td><code>METAL</code></td><td>Native macOS</td><td>2D + 3D</td><td>macOS only</td></tr>
<tr><td><code>CANVAS</code></td><td>Browser 2D with no GPU context</td><td>2D only</td><td>Emscripten only</td></tr>
<tr><td><code>SKIA</code></td><td>2D vector rasterisation</td><td>2D only</td><td>Any; needs a pre-built Skia</td></tr>
<tr><td><code>SOFTWARE</code></td><td>Deterministic pixels with no GPU</td><td>2D + 3D</td><td>Any; never presents to a window</td></tr>
<tr><td><code>HEADLESS</code></td><td>Fast CI of game logic</td><td>no output</td><td>Any; renders nothing by design</td></tr>
</tbody>
</table>
</div>
<p style="margin-top:1rem;">This is a starting point, not the full list: the tag exposes <strong>50 identities across 46 families</strong>. Judge a renderer by the scope, dependencies and platform it actually claims; see the <a href="docs/rendering-backends.html">renderer reference</a>.</p>
<!-- Principles -->
<span class="section-label">Design Principles</span>
<h2>Key architectural decisions</h2>
<div class="cards cards--2 mt-3">
<div class="card">
<span class="card-icon">🔒</span>
<h3>Interface/Implementation separation</h3>
<p>Public API headers (<code>Microsoft/Xna/Framework/...</code>) never include renderer headers. Renderer code never bleeds into game-facing APIs. This boundary is enforced by directory and include structure.</p>
</div>
<div class="card">
<span class="card-icon">⚙</span>
<h3>Compact default, opt-in runtime selection</h3>
<p><code>CNA_GRAPHICS_RENDERER</code> keeps single-renderer builds small. <code>CNA_GRAPHICS_RENDERERS</code> opts into a compatible registry and selects before the first device, with hard failure by default and explicit fallback when requested.</p>
</div>
<div class="card">
<span class="card-icon">📦</span>
<h3>Vendored dependencies</h3>
<p>SDL3, SDL3_image, and SDL3_mixer are vendored as Git submodules. No system SDL packages needed. bgfx is fetched via CMake <code>FetchContent</code>. This ensures reproducible builds across environments.</p>
</div>
<div class="card">
<span class="card-icon">🧬</span>
<h3>XNA namespace mirroring</h3>
<p>C++ namespaces mirror XNA's hierarchy: <code>Microsoft::Xna::Framework</code>, <code>Microsoft::Xna::Framework::Graphics</code>, <code>Microsoft::Xna::Framework::Input</code>, etc. Reduces conceptual migration cost from XNA/MonoGame experience.</p>
</div>
<div class="card">
<span class="card-icon">📝</span>
<h3>sharp-runtime support layer</h3>
<p>The <code>sharp-runtime</code> library provides utility and runtime support primitives that CNA's internals depend on. It builds cleanly on all supported platforms with no external dependencies of its own.</p>
</div>
</div>
<!-- C++23 Features -->
<span class="section-label" style="margin-top:3rem; display:block;">C++23 Features</span>
<h2>Key C++23 features used in CNA</h2>
<p>CNA targets C++23 and uses several modern standard library features to mirror XNA's C# semantics cleanly without a managed runtime.</p>
<div class="arch-layer arch-layer--api" style="margin-top:1.5rem;">
<div class="arch-layer-label">Standard Library & Language Features</div>
<ul>
<li><code>std::optional<T></code> — replaces XNA nullable types (<code>Nullable<T></code>) for missing or unset values.</li>
<li><code>std::span<T></code> — provides buffer views in <code>GetData()</code>/<code>SetData()</code> without copying data.</li>
<li><code>std::string_view</code> — zero-copy string parameters wherever a string is read but not owned.</li>
<li><code>std::unique_ptr<T></code> / <code>std::shared_ptr<T></code> — RAII resource management, replacing C# <code>using</code> blocks and <code>IDisposable</code> patterns.</li>
<li><strong>Ranges and concepts</strong> (where available) — type-safe template constraints replacing unconstrained templates.</li>
<li><code>[[nodiscard]]</code> attributes — applied to <code>Load<T>()</code>, <code>Begin()</code>, and similar factory/guard calls to catch accidentally discarded return values.</li>
<li><strong>Structured bindings</strong> — used for returning multiple values from internal helpers without heavyweight output-parameter patterns.</li>
<li><code>if constexpr</code> — compile-time template branching in <code>PackedVector</code> implementations and format-dispatch helpers.</li>
<li><strong>Inline variables</strong> — for static constants defined directly in header-only types without requiring a separate <code>.cpp</code> definition.</li>
</ul>
</div>
<!-- File layout -->
<span class="section-label">Source Layout</span>
<h2>Directory structure</h2>
<pre><code>cna/
├── modules/ ← every source file lives in a module
│ ├── core/
│ ├── math/
│ ├── graphics/ ← the XNA graphics API + renderer interfaces
│ │ ├── include/
│ │ │ ├── Microsoft/Xna/Framework/Graphics/ ← public XNA API
│ │ │ │ ├── GraphicsDevice.hpp
│ │ │ │ ├── SpriteBatch.hpp
│ │ │ │ └── Texture2D.hpp
│ │ │ └── CNA/Internal/Renderers/ ← renderer interfaces
│ │ │ ├── Common/IGraphicsRenderer.hpp
│ │ │ ├── ISpriteBatchRenderer.hpp
│ │ │ └── ITextureRenderer.hpp
│ │ ├── src/
│ │ ├── tests/
│ │ └── examples/
│ ├── graphics-ext/ ← CNAEXT engine layer (-DCNA_CNAEXT=ON)
│ ├── content/ audio/ input/ media/ net/ storage/
│ ├── devices/ devices-ext/ gamer-services/ runtime/
│ └── renderers/ ← 46 families, 50 public identities
│ ├── easygl/ ← OPENGLES2/3, OPENGL33, WEBGL1/2
│ ├── vulkan/ sdl-gpu/ bgfx/ webgpu/ metal/
│ ├── directx1/ … directx12/ ← the Windows Direct3D ladder
│ ├── canvas/ html-dom/ svg-dom/ ← Emscripten-only
│ ├── skia/ blend2d/ openvg/ ← 2D vector rasterizers
│ └── software/ portablegl/ headless/ stub/ ← no GPU required
│
├── third_party/ ← SDL, SDL_image, SDL_mixer, cgltf, enet, stb
├── tools/ ← gltf_to_cnj, xna-oracle, reference dumpers
├── cmake/ ← CMake helpers and renderer selection
├── examples/ tests/ docs/ scripts/
└── CMakeLists.txt</code></pre>
</div>
</section>
</main>
<footer>
<div class="footer-inner">
<div class="footer-top">
<div class="footer-brand">
<div class="footer-brand-name">CNA</div>
<p>Documentation snapshot for CNA 0.1.0-alpha.1, the first tagged pre-release. CNA exposes 50 renderer identities across 46 implementation families; APIs may change before 1.0.</p>
</div>
<div class="footer-col">
<h4>Project</h4>
<ul>
<li><a href="about.html">About</a></li>
<li><a href="features.html">Features</a></li>
<li><a href="architecture.html">Architecture</a></li>
<li><a href="roadmap.html">Roadmap</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Docs</h4>
<ul>
<li><a href="docs/getting-started.html">Getting Started</a></li>
<li><a href="docs/building.html">Building</a></li>
<li><a href="docs/platforms.html">Platforms</a></li>
<li><a href="docs/rendering-backends.html">Renderers</a></li>
<li><a href="docs/faq.html">FAQ</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Community</h4>
<ul>
<li><a href="https://github.com/openeggbert/cna" target="_blank" rel="noopener">GitHub</a></li>
<li><a href="https://discord.gg/vrnc4n6DaE" target="_blank" rel="noopener">Discord</a></li>
<li><a href="demos.html">Demos</a></li>
<li><a href="videos.html">Videos</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>CNA is not affiliated with or endorsed by Microsoft Corporation. XNA is a trademark of Microsoft. Licensed under the Microsoft Public License (Ms-PL).</p>
<div class="footer-links">
<a href="https://github.com/openeggbert/cna/blob/master/LICENSE" target="_blank" rel="noopener">License</a>
<a href="contact.html">Contact</a>
</div>
</div>
</div>
</footer>
<script src="js/main.js"></script>
<script src="js/prism/prism.min.js" defer></script>
<script src="js/prism/prism-cpp.min.js" defer></script>
<script src="js/prism/prism-glsl.min.js" defer></script>
<script src="js/prism/prism-json.min.js" defer></script>
<script src="js/prism/prism-bash.min.js" defer></script>
<script src="js/prism/prism-cmake.min.js" defer></script>
</body>
</html>