Skip to content

Graphics

Requirements

  • Draw a 2D game: hundreds of sprites (players, Bydos, missiles, explosions), a scrolling star field, text for the HUD; 60 frames per second on school machines.
  • Run on Linux and Windows (cross-play), and on macOS for development.
  • Stay behind an engine interface (IRenderer) so game code never sees the graphics API.
  • Be learnable by the team within the project's time frame.

Graphics API

API Platforms Strengths Weaknesses for this project
OpenGL 4.5 core (chosen) Linux, Windows; 4.1 on macOS Mature, well documented, immediate feedback, every team member can debug it; direct state access (4.5) removes most bind-to-edit bugs; enough for batched 2D Deprecated on macOS (4.1 is the maximum); driver-dependent error behaviour, mitigated with the KHR_debug callback
Vulkan Linux, Windows; macOS via MoltenVK Explicit, predictable performance, modern tooling Several thousand lines before the first sprite (instances, swapchain, synchronisation, memory); the extra control brings nothing to a 2D game of this size
Direct3D 11/12 Windows only Excellent Windows tooling Breaks the Linux requirement; would need a second backend
Metal Apple only Native on macOS Not on the target platforms
SDL3 GPU API Vulkan, D3D12, Metal behind one API Modern and portable Recent, fewer learning resources; shader cross-compilation adds a build step

Decision: OpenGL 4.5 core profile, generated with glad, with a 4.1 build option (AEGIS2D_MACOS_GL41) so macOS developers can run the client. The renderer is reached only through IRenderer, so a Vulkan or SDL GPU backend could replace it later without touching the game.

Windowing, input and audio library

Library Scope Assessment
SDL3 (chosen) Window, GL context, input, gamepads, audio Small, portable, used by many commercial games; we keep full control of rendering; gamepads and audio come for free
SFML Window, 2D graphics, audio, network Allowed by the subject and simple, but its built-in sprite renderer would do the engine's work for us and hides batching decisions
raylib Window, 2D/3D rendering, audio Very quick to start, but close to an engine itself: little left to design
GLFW Window, context, input Good, but no audio and weaker gamepad support: a second library would be needed

Rendering techniques

  • Sprite batching (planned): sprites sharing a texture and layer are written into one vertex buffer and drawn with a single call. Drawing each sprite with its own call costs one driver round-trip per sprite and becomes the bottleneck long before the GPU.
  • Texture atlases / sprite sheets (planned): one texture per sheet keeps batches large and texture switches rare.
  • Nearest filtering (planned): keeps pixel art sharp when scaled.
  • Fixed logical resolution with letterboxing (planned): the game is laid out in a fixed virtual resolution and scaled to the window, so every player sees the same play area whatever the window size.
  • Interpolated rendering (planned): the simulation runs at a fixed step; rendering interpolates between the last two states, so movement is smooth at any frame rate and never tied to CPU speed.
  • stb_image for PNG loading (in place): a single header, no system library, and only the decoder we need. Alternatives (SDL_image, libpng) add dependencies for formats we do not use.
  • GLM for maths (in place): the reference maths library for OpenGL, header-only, types matching GLSL.

Benchmark

The sprite stress-test scene (planned) renders N moving sprites in batched and naive modes and records CPU and GPU frame times. Its results, measured on Linux and Windows, will be published on the benchmark page and justify the batching choice with numbers.