Getting Started

Easy3D / Guide / Getting Started

This page gets Easy3D building on your machine in a few minutes: requirements, the expected repository layout, the default (light) build, and a first program. For the full story of CNA linkage and every CMake option, continue to Building & CMake.

Requirements

RequirementVersionNotes
C++ compilerC++23-capableEasy3D follows CNA and uses C++23 (kept in sync with CNA).
CMake≥ 3.20
CNA headersCNA's public headers must be visible (expected at ../cna/include). The default build needs only the headers, not a built CNA.

Repository layout

Easy3D expects its sibling repositories to sit next to it, all inside one parent directory:

.../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

If CNA lives somewhere else, point Easy3D at it with -DEASY3D_CNA_DIR=/path/to/cna.

The default build (light, headers-only)

The default build is deliberately light and self-contained. It compiles the easy3d static library against CNA's headers alone and runs the CNA-free tests — no SDL, no ffmpeg, no graphics backend:

cmake -S . -B build
cmake --build build
ctest --test-dir build

This produces:

CNA's math types (Vector3, Matrix, …) are declared in headers but implemented in CNA's compiled .cpp files. The easy3d library compiles fine against the headers alone, but anything that actually runs camera math (e.g. Camera3D::GetViewMatrix()) must link the CNA library. See Building & CMake for the three ways this is resolved.

Building with CNA linked (cameras at runtime)

To also build and run the camera example and the camera/batch/cube-mesh tests, let Easy3D build CNA itself:

cmake -S . -B build -DEASY3D_LINK_CNA=ON     # backend defaults to EASY_GL
cmake --build build
ctest --test-dir build                        # runs all tests, including camera

This pulls in CNA's heavier dependencies (SHARP_RUNTIME, SDL3, ffmpeg, a graphics backend), which is exactly why it is opt-in and off by default.

Your first program

Everything public is reachable through one umbrella header:

#include <Easy3D/Easy3D.hpp>

Or include individual headers (<Easy3D/Camera3D.hpp>, <Easy3D/TextureAtlas.hpp>, …) if you prefer. A tiny CNA-free program — this needs nothing but the easy3d library from the default build:

#include <Easy3D/TextureAtlas.hpp>
#include <Easy3D/Version.hpp>
#include <iostream>

int main()
{
    std::cout << "Easy3D " << Easy3D::VersionString() << "\n";

    // Describe a 256x256 atlas texture with one named region.
    Easy3D::TextureAtlas atlas(256, 256);
    atlas.Add("blupi_idle_0", Easy3D::AtlasRect{0, 0, 32, 48});

    const Easy3D::UvRect uv = atlas.GetUv("blupi_idle_0");
    std::cout << "UV top-left: (" << uv.U0 << ", " << uv.V0 << ")\n";
    return 0;
}

Wiring it up in CMake (standalone consumer):

add_subdirectory(path/to/easy-3d easy-3d)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE easy3d::easy3d)

As soon as your program constructs CNA math values at runtime (a Camera3D, a Vector3, …), you must also link CNA — read on in Building & CMake for the recommended game setup.

Using Easy3D + CNA together in a game

A game (e.g. Galaxy Eggbert) uses CNA directly and Easy3D for convenience. Pull both in as subdirectories — add CNA first, then Easy3D auto-detects and links it:

add_subdirectory(../cna       cna)        # defines the CNA target (+ chosen backend)
add_subdirectory(../easy-3d   easy-3d)    # detects CNA, links it automatically

add_executable(my_game src/main.cpp)
target_link_libraries(my_game PRIVATE CNA easy3d)
#                                     ^^^         the game still uses CNA directly
#                                         ^^^^^^  and Easy3D helpers beside it

Next steps