text// Dependency: GLFW must be initialized before creating any Window
main.cpp
    │
    ├── DarkMoonEngine dm {}                ← initialize GLFW before any Window
    │
    ├── Window win { 800, 600, "Title" }    ← GLFW window + GLAD + shaders
    │       ├── glfwCreateWindow()
    │       ├── gladLoadGLLoader()          ← only for the first window
    │       └── LoadBasicShaders()          ← basic2D, basicTexture2D, basicFont2D, ...
    │
    └── ~DarkMoonEngine()                   ← its called when the program finishes
            ├── glfwTerminate()
            └── unloadAllResources()
C++#include <darkmoon/graphics.hpp>

int main() {
    DarkMoonEngine dm{};

    Window win = Window(800, 600, "Window Title");

    while(!win.ShouldClose()){
        win.BeginDrawing(BLACK);
        win.EndDrawing();
    }
}

Window(w, h, title, shared?) -
Close() void
ShouldClose() bool
Iconify() void
Maximize() void
Restore() void
Hide() void
Show() void
Focus() void
Current() void
WasResized() bool

textBeginDrawing(color)   ← sets projection matrix + clears background
        │
        │   your render calls here
        │
EndDrawing()          ← caps FPS + updates deltaTime + PollEvents + SwapBuffers
        │
        └── EndDrawingNoPoll()   ← same but skips glfwPollEvents (manual control)

BeginDrawing() void
BeginDrawing(color) void
EndDrawing() void
EndDrawingNoPoll() void
ClearBackground(color) void

GetBasicShader2D() "basic2D"
GetBasicTextureShader2D() "basicTexture2D"
GetBasicFontShader2D() "basicFont2D"

CreateShader(vertPath, fragPath, geoPath?) Shader*
CreateShader(vertSrc, fragSrc, geoSrc?) Shader*
C++// From file paths
Shader* myShader = win.CreateShader("shaders/custom.vert", "shaders/custom.frag");

// From source strings (inline GLSL)
const std::string vert = R"(
    #version 330 core
    layout(location = 0) in vec3 aPos;
    void main(){ gl_Position = vec4(aPos, 1.0); }
)";

const std::string frag = R"(
    #version 330 core
    out vec4 fragColor;
    uniform vec4 customColor;
    void main(){ fragColor = customColor; }
)";

Shader* myShader = win.CreateShader(vert, frag);

IsKeyPressed(key) bool
IsKeyReleased(key) bool
IsKeyDown(key) bool
IsKeyUp(key) bool
GetLastCharPressed() char
SetExitKey(key) void
GetExitKey() int
PollEvents() void
C++// Pressed  → only the frame the key goes down
// Down     → every frame the key is held
// Released → only the frame the key goes up
// Up       → every frame the key is not held

if (win.IsKeyPressed(KEY_SPACE))  fire();
if (win.IsKeyDown(KEY_W))         moveForward();
if (win.IsKeyReleased(KEY_ENTER)) confirmMenu();

// Read text input (e.g., for a text box)
char c = win.GetLastCharPressed();
if (c != 0) textBuffer += c;

IsMouseButtonPressed(btn) bool
IsMouseButtonReleased(btn) bool
IsMouseButtonDown(btn) bool
IsMouseButtonUp(btn) bool
GetCursorPosition() Vector2Df
GetCursorPositionX() int
GetCursorPositionY() int
SetCursorPosition(pos) void
SetCursorPositionX(x) void
SetCursorPositionY(y) void
GetXoffsetScroll() int
GetYoffsetScroll() int
IsCursorHover() bool
DisableCursor() void
HideCursor() void
EnableCursor() void
SetCustomCursor(path) void
ResetCursor() void

IsGamepadAvailable(id) bool
GetGamepadName(id) const char*
IsGamepadButtonPressed(button, id) bool
IsGamepadButtonReleased(button, id) bool
IsGamepadButtonDown(button, id) bool
IsGamepadButtonUp(button, id) bool
GetGamepadAxis(axis, id) float
GetGamepadAxisDelta(axis, id) float
GetGamepadAxisDeadzone(axis, deadzone, id) float
GetGamepadLeftStick(deadzone, id) Vector2Df
GetGamepadRightStick(deadzone, id) Vector2Df
GetGamepadLeftTrigger(deadzone, id) float
GetGamepadRightTrigger(deadzone, id) float

WindowMode

C++enum struct WindowMode {
    Windowed,     // Normal resizable window
    Borderless,   // Borderless fullscreen (no title bar)
    Fullscreen    // Exclusive fullscreen
};

SetFullscreen(monitor?) void
SetBorderless(monitor?) void
SetWindowed() void
SetWindowMode(mode, monitor?) void
SetSize(w, h) void
SetSize(Vector2Df) void
SetPosition(x, y) void
SetPosition(Vector2Df) void
SetTitle(title) void
SetIcon(path) void
SetIconDefault() void
SetOpacity(opacity) void

GetWindowMode() WindowMode
GetWindow() GLFWwindow*
GetWidth() int
GetHeight() int
GetSize() Vector2Df
GetPositionX() int
GetPositionY() int
GetPosition() Vector2Df
GetOpacity() float

SetTargetFPS(fps) void
GetTargetFPS() int
GetFPS() int
GetDeltaTime() float
GetTime() double

textEndDrawing()
    │
    ├── calculate deltaTime = currentTime - lastTime
    │
    ├── FPS cap (busy-wait)
    │       ├── sleep(remaining - 2ms)   ← OS sleep for most of the wait
    │       └── spin-wait for the rest   ← tight loop for precision
    │
    ├── update FPS counter (averaged every 100ms)
    │
    └── PollEvents() + glfwSwapBuffers()

GetClipboardString() const char*
SetClipboardString(text) void

SetDropCallback(fn) void
GetLastDroppedPath() const std::string&
IsFileDropped() bool
ClearDroppedPath() void

C++#include <darkmoon/graphics.hpp>

int main(){
    DarkMoonEngine dm{};

    Window win = Window(800, 600, "My First Window");
    win.SetTargetFPS(120); // By default is 60
    win.SetIcon("./assets/ghost.png");

    while(!win.ShouldClose()){
        win.BeginDrawing(BLACK);
        win.EndDrawing();
    }
}

C++#include <darkmoon/graphics.hpp>

constexpr static float speed = 300.0f;

int main() {
    DarkMoonEngine dm{};

    Window win = Window(800, 600, "Example Delta Time");
    win.SetTargetFPS(60);

    Vector2Df position { win.GetWidth() / 2.0f, win.GetHeight() / 2.0f };

    while(!win.ShouldClose()){
        // Input
        if(win.IsKeyDown(KEY_UP))
            position.y -= speed * win.GetDeltaTime();
        if(win.IsKeyDown(KEY_DOWN))
            position.y += speed * win.GetDeltaTime();
        if(win.IsKeyDown(KEY_LEFT))
            position.x -= speed * win.GetDeltaTime();
        if(win.IsKeyDown(KEY_RIGHT))
            position.x += speed * win.GetDeltaTime();

        // Drawing
        win.BeginDrawing(BLACK);
        Rectangle(position, 20, 20, GREEN, &win).Draw();
        win.EndDrawing();
    }
}

C++#include <darkmoon/graphics.hpp>

int main() {
    DarkMoonEngine dm {};

    // Primary window: loads GLAD and basic shaders
    Window main { 1280, 720, "Main View" };

    // Secondary window: shares context -> no extra GLAD init, inherits shaders
    Window debug { 640, 480, "Debug View", &main };

    while (!main.ShouldClose() && !debug.ShouldClose()) {
        main.BeginDrawing(BLACK);
        main.EndDrawing();

        debug.BeginDrawing(GRAY);
        debug.EndDrawing();
    }
}

C++#include <darkmoon/graphics.hpp>

int main() {
    DarkMoonEngine dm{};

    Window win = Window(800, 600, "ClipboardTest");

    std::string pathTexture {};

    while(!win.ShouldClose()){

        // Copy to cliboard
        if(win.IsKeyPressed(KEY_C))
            win.SetClipboardString("Hello from DarkMoon!");

        // Read the cliboard
        if(win.IsKeyPressed(KEY_V)){
            const char* text = win.GetClipboardString();
            if(text)
                std::cout << "Clipboard: " << text << "\n";
        }

        // Read the path from dropped file
        if(win.IsFileDropped()){
            std::cout << win.GetLastDroppedPath() << "\n";
            if(win.GetLastDroppedPath().ends_with(".png")){
                pathTexture = win.GetLastDroppedPath();
            }
            win.ClearDroppedPath();
        }

        win.BeginDrawing(BLACK);

        // Load texture from path
        if(!pathTexture.empty())
            Texture({win.GetWidth() / 2, win.GetHeight() / 2}, {10, 10}, 0, pathTexture.c_str(), &win).Draw();

        win.EndDrawing();
    }
}