Architecture
Easy3D / Guide / Architecture
Easy3D is a companion library, not an engine. It sits beside CNA: a game still creates and drives its CNA Game, devices, graphics device, and input directly. Easy3D only removes repetitive glue — cameras, billboard/cube batching, a texture atlas, debug drawing.
The big picture
Galaxy Eggbert
-> uses CNA directly
-> uses Easy3D helpers
-> may use Mobile Eggbert as existing reference/library/data source
Easy3D
-> depends on CNA
-> does not hide CNA
-> contains helper classes only
CNA
-> XNA 4.0-style runtime and future CNA/NOXNA extensions
Dependency direction
galaxy-eggbert ──depends on──> easy-3d ──depends on──> cna
│ ▲
└───────────────── also depends on ─────────────┘
(uses CNA directly too)
Easy3D depends on CNA. Nothing in CNA depends on Easy3D. A game depends on both, and is free to call CNA directly whenever Easy3D does not help.
Principles
Easy3D APIs may expose CNA types
It is normal and encouraged for Easy3D functions to take or return Microsoft::Xna::Framework::Vector3, Matrix, and friends. Easy3D must not invent parallel math types that hide CNA, and must not wrap CNA objects just to rename them. The one deliberate exception: TextureAtlas uses two small Easy3D-local PODs (AtlasRect, UvRect) because pixel/UV rectangles are not CNA concepts — this also keeps it CNA-free and unit-testable on its own.
The intended design — CNA stays in charge
// A bad design (Easy3D hiding everything):
Easy3D::Game game;
game.RunEverything(); // NO — this is not what Easy3D is for
// The intended design (CNA stays in charge, Easy3D just helps):
Easy3D::Camera3D camera;
Easy3D::OrbitCamera orbit;
Easy3D::TextureAtlas atlas;
Eggbert-specific rules stay out of Easy3D
Anything that only makes sense for Galaxy Eggbert / Mobile Eggbert — tile meanings, Blupi animation tables, level formats, gameplay rules — belongs in those projects, never in Easy3D. Likewise, Mobile Eggbert is an existing, working reference and is not refactored just because Galaxy Eggbert (or Easy3D) would find it convenient.
How Easy3D consumes CNA
- CNA's public headers are under
../cna/include(namespaceMicrosoft::Xna::Framework). - CNA's CMake library target is named
CNA— aSTATIClibrary built with C++23. It links SHARP_RUNTIME, a graphics backend target, and (privately) SDL3 / ffmpeg. - CNA math types such as
Vector3andMatrixare declared in headers but defined in CNA's compiled.cppfiles. Therefore:- The
easy3dstatic library compiles against CNA headers alone. - Code that actually executes CNA math (e.g.
Camera3D::GetViewMatrix()) must link theCNAlibrary at final link time.
- The
- Easy3D's CMake resolves CNA linkage three ways — parent-provided target, standalone
-DEASY3D_LINK_CNA=ON, or headers-only. When CNA is linked,EASY3D_HAS_CNA_LINKis defined. Full details on Building & CMake. - Easy3D does not depend on
sharp-runtimedirectly, even though CNA does (it comes in transitively when CNA is linked).
Sibling repository layout
.../openeggbert/
├── cna/ <- required: the CNA runtime (headers under cna/include)
├── sharp-runtime/ <- optional: used by CNA; Easy3D does NOT depend on it (yet)
└── easy-3d/ <- the Easy3D repository
Anatomy of the library
The public API is nine headers under include/Easy3D/, plus the umbrella header Easy3D.hpp that includes them all:
| Header | Provides | CNA at runtime? |
|---|---|---|
Easy3D/Version.hpp | Version macros, constants, VersionString() | No |
Easy3D/Camera3D.hpp | Camera3D | Yes (matrices) |
Easy3D/OrbitCamera.hpp | OrbitCamera | Yes |
Easy3D/FollowCamera.hpp | FollowCamera | Yes |
Easy3D/TextureAtlas.hpp | TextureAtlas, AtlasRect, UvRect | No (CNA-free) |
Easy3D/BillboardBatch.hpp | BillboardBatch, BillboardItem | Stores CNA types |
Easy3D/CubeBatch.hpp | CubeBatch, CubeItem | Stores CNA types |
Easy3D/CubeMesh.hpp | CubeVertex, AppendCubeMesh, BuildCubeMesh | Yes (Vector3 math) |
Easy3D/DebugDraw.hpp | DebugDraw, DebugLine, DebugBox | Stores CNA types |
The data-first pipeline
Easy3D is being built in deliberate phases (see the Roadmap). The batching classes are data recorders, not renderers:
BillboardBatch / CubeBatch / DebugDraw store plain items (done)BuildCubeMesh() → std::vector of vertices/indices (in progress)This keeps every step testable without a GPU, and defers the concrete CNA draw-path decision to the phase that actually needs it.
What Easy3D is deliberately NOT
No ECS, no generic engine object hierarchy, no Lua, no physics, no navigation, no networking, no editor, no asset database, no resource cache, no model importer, no plugin system, no PBR renderer. If one of these starts to appear, it is a sign Easy3D is drifting toward being an engine — stop and reconsider. See Design Principles.