- BillboardInstance: per-instance uv sub-rect, feet anchor, turn, dithered alpha, flash; BillboardBatch::sharedTexture; Texture createEmpty/update/cellUV/cellAnchor/nearest - SpriteAtlas: fixed-cell runtime atlas with gutters - hd2d::ui: Octopath-style panels, fonts (Cinzel, EB Garamond), dialogue box with typewriter + portraits + choices, menus, nameplates, toasts, ImGui theme - DayCycle (dawn/day/dusk/night keyframes, sun + moon arcs), Weather overcast/mist/ lightning, night-aware presets, stars and moon in the sky - Hidden-window offscreen captures (Window visible=false, Renderer output FBO, OffscreenTarget); --screenshot never opens a window - Camera::worldToScreen; CMake usable via add_subdirectory (HD2D_BUILD_DEMO, HD2D_ENGINE_ASSET_DIR)
3.5 KiB
Notes for AI agents
C++20 / OpenGL 4.5 HD-2D engine (engine/) plus a demo (demo/). Read
README.md for features and the frame pipeline, and docs/ASSET_GUIDE.md
before making any sprite, texture or model.
Build and run
cmake -S . -B build -G Ninja && ninja -C build
./build/hd2d_demo # interactive (WASD, R/O/G = rain/overcast/fog, [ ] = hour, F1 = panels)
./build/hd2d_demo --screenshot out.png --frames 90 \
--pos 25,43.6 --dist 10 --yaw 30 --rain 1 --set dof=0 # scripted capture (hidden)
There is no test suite; verification is visual. After any rendering, asset or
gameplay change, capture screenshots of the affected area and look at them.
Use a Debug build (-DCMAKE_BUILD_TYPE=Debug) to get OpenGL errors printed.
Captures run hidden: --screenshot implies a hidden window + offscreen target
(Window::create(..., visible = false), OffscreenTarget,
Renderer::setOutputFramebuffer) and ignores keyboard/mouse, so they never pop
up on or react to the user's desktop. Add --show only if you really need to
watch a capture. New capture paths in any app must keep this behaviour.
Map
| Path | What |
|---|---|
engine/include/hd2d/, engine/src/ |
engine library (Renderer, Terrain, BillboardBatch, SpriteAtlas, ModelLibrary/ModelBatch, Water, ParticleSystem, Weather, DayCycle, GroundOcclusion, DebugUI) |
assets/shaders/ |
GLSL; common.glsl holds the shared Frame UBO and lighting helpers |
demo/ |
meadow scene: terrain layout, prop scattering, bridge, fires, player movement |
tools/pixellab.py + tools/assets.json |
pixel-art generation (PixelLab API, key in .env) |
tools/scenery_textures.py |
high-res painted textures for models |
tools/blender_scenery.py |
procedural 3D models → assets/models/scenery.glb |
Rules
FrameUBOinengine/src/Renderer.cppmust mirrorFrameinassets/shaders/common.glslexactly (std140, vec4/mat4 only); update thestatic_assertsize when adding fields.BillboardInstance(Billboard.h, 64 bytes = four vec4s) must match the attributes inbillboard.vertand the VAO inBillboard.cpp; keep new fields in vec4-sized groups, update thestatic_assert, and keep the defaults rendering exactly like the old whole-texture sprite.pixelart.glsluses derivatives: include it only in fragment shaders.- Game UI is
hd2d::ui(UI.h): ImDrawList only, sizes in 1080p px ×scaleFor(viewport), OFL fonts inassets/fonts/; verify with--ui-democaptures (--frames 120mid-reveal,420revealed). - Use GL 4.5 DSA calls (
glCreate*,glNamed*,glTexture*) like the rest of the code. Shaders hot-reload with F5. - Shaders and assets load from
HD2D_ASSET_DIR(demo, set by CMake toassets/); thehd2dtarget exportsHD2D_ENGINE_ASSET_DIRfor parent projects thatadd_subdirectorythe engine (demo off by default there). - Generated files (
assets/textures/*,assets/models/*) come from scripts intools/; change the script, not the output. - PixelLab calls cost credits: check
--balance, reusetile_ids, and do not regenerate assets that already exist unless asked. - The Blender script only touches its
HD2D_Scenerycollection; keep it that way when running it inside a user's open Blender session. - New tunables go in
RenderSettings(or the owning class), get a slider inDebugUI.cpp, and, if useful for captures, an entry inapplySettingindemo/main.cpp. - Update
README.md/docs/ASSET_GUIDE.mdwhen behavior or conventions change.