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();
}
}