A physics-accurate 3D solar system simulation built from scratch using C++17 and OpenGL 3.3. This project demonstrates a custom rendering engine with clean architecture, modular design, and extensible systems.
This project showcases a custom graphics engine architecture built for real-time 3D rendering. While the solar system simulation demonstrates orbital mechanics using Kepler's laws, the underlying engine is designed to be extended into different 3D applications.
Core Focus: Professional C++ architecture, graphics programming fundamentals, and scalable system design.
The engine follows a layered architecture with clear separation between systems:
Application Layer (SolarSystemApp)
โ
Engine Core (Engine, EngineContext, Managers)
โ
Graphics Systems (Rendering, Buffers, Shaders, Meshes)
โ
Platform Layer (GLFW, OpenGL, GLM)
Each layer depends only on layers below it, preventing circular dependencies and maintaining modularity.
Central orchestration of all subsystems with a fixed-timestep game loop.
Key responsibilities:
- Main loop management (62.5 tick/sec logic, independent render rate)
- System lifecycle coordination
- Frame timing and FPS tracking
- Callback-driven update and render cycles
Why this matters: Decouples physics simulation from rendering, ensuring consistent behavior across different hardware.
Centralized OpenGL buffer management with RAII principles and automatic resource tracking.
Features:
- Unified interface for VAO/VBO/EBO creation
- VRAM usage monitoring and reporting
- Named buffer ownership for debugging
- Automatic cleanup through
BufferHandlewrapper (move-only semantics)
Architecture benefit: Single point of truth for all GPU memory allocations. Resources can't leakโhandles guarantee cleanup on destruction.
Modular rendering system with separated concerns:
- SceneRenderer: 3D scene rendering with proper depth testing and state management
- UIRenderer: 2D overlay rendering for controls and info panels
- TextRenderer: Real-time text rendering using FreeType and orthographic projection
Rendering order:
- Skybox (modified depth test for background)
- Opaque objects (front-to-back for early depth rejection)
- Transparent objects (back-to-front with alpha blending)
Type-safe shader program wrapper with compile-time error checking and uniform setters.
Design choice: Each renderable manages its own shader instance rather than using a global shader pool. This trades some memory for flexibilityโobjects can customize shaders without affecting others.
Specialized managers for different resource types:
- TextureManager: Texture loading (STB Image integration), cubemap creation
- MeshGenerator: Procedural geometry (spheres, boxes, parametric control)
- WindowManager: GLFW window and context management
- InputManager: Event-driven input with GLFW callback forwarding
- AudioManager: Background music playback using miniaudio library. Plays a drum and bass track during simulation to enhance the space exploration atmosphere.
Pattern: Manager objects own resources and provide factory methods. Resources are referenced by ID/handle, never by pointer.
Orbital mechanics implementation using Kepler's laws with real astronomical data (semi-major axis, eccentricity, orbital period).
Implementation: Fixed timestep updates ensure physics determinism independent of frame rate. Angular velocity calculated from orbital period drives position updates.
Systems receive their dependencies through constructor injection:
CelestialBody(BufferManager& bufferManager,
MeshGenerator& meshGenerator,
TextureManager& textureManager);Benefit: Testable, loosely coupled, dependencies explicit at construction.
All resources wrapped in RAII objects (smart pointers, custom handles):
class BufferHandle {
// Non-copyable, moveable
~BufferHandle(); // Automatic cleanup
};Benefit: Exception-safe, no manual cleanup, impossible to leak resources.
Common interface for all scene objects:
class ISceneRenderable {
virtual void render(glm::mat4 model, glm::mat4 view,
glm::mat4 projection) const = 0;
virtual void update(float deltaTime) {}
};Benefit: Renderer doesn't know concrete types. New renderables integrate without modifying existing code.
- Core layer: Engine loop, system management
- Graphics layer: Rendering, buffers, shaders
- Domain layer: Physics, celestial body logic
- Application layer: User-facing logic, UI
Clear boundaries prevent coupling between unrelated systems.
- Smart pointers for ownership semantics
- Move semantics for efficient resource transfer
- Structured bindings for cleaner iteration
- RAII throughout for automatic resource management
constexprfor compile-time computation
- VAO/VBO/EBO for efficient rendering
- Custom shader pipeline with GLSL
- Texture mapping and cubemap skyboxes
- Alpha blending for transparency
- Depth testing and state management
- Real-time text rendering with FreeType
- Cross-platform configuration
- Platform-specific compiler flags
- Warning level enforcement (
-Wall -Wextra -pedantic//W3) - Debug sanitizers (AddressSanitizer on GCC/Clang)
- Automatic resource copying to build directory
- Batch buffer creation minimizes GPU state changes
- Static draw hints for GPU optimization
- Vertex data uploaded once, reused via handles
- State changes minimized in render loop
- Objects sorted by shader/texture when possible
- Render state cached to avoid redundant calls
Real-time VRAM monitoring for profiling:
void BufferManager::printActiveBuffers() const;
size_t getTotalVRAMUsage() const;Delta time ensures physics behaves identically on all hardware:
void update(float deltaTime) {
position += velocity * deltaTime;
}The architecture supports extension in multiple directions:
The ISceneRenderable interface makes it trivial to add new 3D objects to the scene. Any class implementing this interface can be rendered by the existing rendering pipeline without modifications.
Examples of new renderables that could be added:
// Asteroid - small rocky object with custom mesh
class Asteroid : public ISceneRenderable {
public:
Asteroid(BufferManager& bufferManager,
MeshGenerator& meshGenerator,
TextureManager& textureManager);
void render(glm::mat4 model, glm::mat4 view,
glm::mat4 projection) const override;
void update(float deltaTime) override;
};
// Spaceship - player-controlled vehicle with animation
class Spaceship : public ISceneRenderable {
public:
Spaceship(BufferManager& bufferManager,
TextureManager& textureManager);
void render(glm::mat4 model, glm::mat4 view,
glm::mat4 projection) const override;
void update(float deltaTime) override;
void setThrust(float amount);
void rotate(glm::vec3 axis, float angle);
};
// ParticleEmitter - engine effects, explosions
class ParticleEmitter : public ISceneRenderable {
public:
ParticleEmitter(BufferManager& bufferManager,
size_t maxParticles);
void render(glm::mat4 model, glm::mat4 view,
glm::mat4 projection) const override;
void update(float deltaTime) override;
void emit(glm::vec3 position, glm::vec3 velocity);
};
// Terrain - height-mapped ground with LOD
class Terrain : public ISceneRenderable {
public:
Terrain(BufferManager& bufferManager,
const std::string& heightmapPath);
void render(glm::mat4 model, glm::mat4 view,
glm::mat4 projection) const override;
float getHeightAt(float x, float z) const;
};Each new type would:
- Implement
ISceneRenderableinterface - Use existing
BufferManagerandShadersystems - Integrate automatically with the rendering pipeline
- Require no changes to core engine code
The rendering engine is application-agnostic:
- Data visualization: Replace celestial bodies with data points for 3D charts
- Architectural visualization: Use mesh importers instead of procedural generation
- Game development: Add gameplay systems using existing engine core
- Scientific simulation: Swap physics system while keeping rendering intact
Manager pattern and layered architecture support adding:
- Entity-Component-System (ECS)
- Scene graph hierarchy
- Serialization system
- Asset pipeline and hot-reloading
# Windows
- Visual Studio 2019+ or MinGW
- CMake 3.16+git clone <repository-url>
cd solar-system-simulation
mkdir build && cd build
cmake ..
cmake --build . --config Release.\bin\Release\solar_system_opengl.exesrc/
โโโ core/ # Engine core systems (Engine, Shader, EngineContext)
โ โโโ audio/ # Audio playback system with miniaudio
โ โโโ input/ # Keyboard/mouse input handling with GLFW callbacks
โ โโโ texturing/ # Texture loading and management with STB Image
โ โโโ window/ # GLFW window creation and OpenGL context management
โ
โโโ graphics/ # Graphics layer systems
โ โโโ buffer/ # GPU buffer management (VAO/VBO/EBO) with RAII wrappers
โ โโโ mesh/ # Procedural geometry generation (spheres, boxes, primitives)
โ
โโโ rendering/ # Rendering pipeline
โ โโโ renderers/ # Specialized renderers (Scene, UI, Text with FreeType)
โ โโโ renderables/ # Renderable object implementations
โ โโโ scene/ # 3D scene objects (CelestialBody, Skybox, ISceneRenderable)
โ
โโโ celestialbody/ # Domain-specific logic
โ # Planet factory, ray casting picker, data structures
โ
โโโ utils/ # Utility functions (debug macros, math helpers)
โ
โโโ SolarSystemApp.h/cpp + main.cpp # Application entry point
shaders/ # GLSL shader programs (vertex/fragment)
textures/ # Planet textures (NASA sources) and skybox cubemap
audio/ # Background music (dnb.mp3)
include/ # Third-party headers (GLFW, GLM, GLAD, STB Image)
CMakeLists.txt # Cross-platform build configuration
- 12 independent modules with clear interfaces
- 4 architectural layers with unidirectional dependencies
- 60+ FPS on integrated graphics
- <50 MB typical VRAM usage
- <30 seconds clean build time
C++ Expertise:
- Modern C++17 features and best practices
- Memory management and RAII patterns
- Template metaprogramming for compile-time optimization
- Move semantics and perfect forwarding
Graphics Programming:
- OpenGL 3.3 core profile from scratch
- Vertex pipeline and shader programming
- 3D mathematics (matrices, vectors, transformations)
- Rendering techniques (alpha blending, depth testing, cubemaps)
Software Architecture:
- Layered architecture with dependency inversion
- Design patterns (Factory, Manager, RAII, Dependency Injection)
- Interface-based design for extensibility
- Separation of concerns across modules
System Design:
- Resource management at scale
- Performance profiling and optimization
- Cross-platform build systems (CMake)
- Debugging and error handling strategies
- Textures: NASA and public domain resources
- Learning Resources: learnopengl.com, Khronos documentation
- Libraries: GLFW, GLM, GLAD, STB Image, miniaudio
Danylo Golosov
Portfolio: wallerthedeveloper.itch.io
