Modern OpenGL Programming
A practical, engine‑oriented journey into today’s programmable graphics pipeline.
OpenGL Banner
Chapter 2. Designing the Engine’s Module Layout

Before implementing OpenGL, physics, or window creation, we need to define the engine’s module layout. This blueprint determines:

A strong module layout separates a hobby project from a production-quality engine.

This article defines the core modules, their responsibilities and boundaries, and the way they interact.

Core Modules Overview

The engine consists of six primary modules, each with one clear responsibility.

1. Math

Responsible for:

This module contains pure logic: no OpenGL and no platform-specific code. It supports both rendering and simulation.

2. Platform

Responsible for:

This module handles all platform-specific functionality, including window creation, input events, and timing. It abstracts away the underlying OS and library details from the rest of the engine.

3. Renderer

Responsible for:

The renderer is GPU-focused and data-driven. It depends on math and platform, while no other module depends on it.

4. Resources

Responsible for:

This module ensures that:

It serves as the engine’s “asset manager”.

5. Simulation

Responsible for:

Simulation depends on math, but not on renderer. This separation ensures physics can run headless.

6. Utils

Responsible for:

This module provides shared utilities without creating dependency cycles.

Folder Structure & Public/Private Boundaries

A clear folder structure keeps the engine organized as it grows.

1. Recommended Folder Layout
engine/
    include/
        math/
        platform/
        renderer/
        resources/
        simulation/
        utils/
    src/
        math/
        platform/
        renderer/
        resources/
        simulation/
        utils/
examples/
thirdparty/
CMakeLists.txt

Key principles:

This structure scales cleanly with the engine.

2. Public vs Private Headers

Public headers (in include/):

Private headers (in src/):

This separation keeps module boundaries explicit.

3. Module Level CMakeLists

Each module has its own CMakeLists:

add_library(engine_math)
target_sources(engine_math PRIVATE src/*.cpp)
target_include_directories(engine_math PUBLIC include)

This approach keeps:

Dependency Rules

The engine must prevent dependency cycles and hidden coupling.

1. Allowed Dependencies
math        → (no dependencies)
platform    → math
renderer    → math, platform
resources   → math, renderer
simulation  → math
utils       → (no dependencies)
2. Forbidden Dependencies
renderer    → simulation
simulation  → renderer
platform    → renderer
any module  → utils internals
any module  → another module’s src/

These constraints protect the architecture from gradual breakdown.

3. Why These Rules Matter

Maintainability: The renderer can change without disrupting physics.

Testability: Simulation can be tested without a GPU.

Extensibility: New modules can be added without rewriting existing ones.

Clarity: Developers can quickly determine where each piece of code belongs.

Project Boundaries: GusOnGames Engine as a Standalone Framework
Ecosystem

GusOnGames is part of a broader ecosystem:

Focus and Audience

GusOnGames covers:

BeforeTheMesh and TheMeshProject cover:

Despite overlap in mathematics, simulation, and rendering, these domains differ fundamentally in:

GusOnGames therefore remains a standalone framework, not a shared base for CAE projects.

Why the Engine Should Be Independent

Different goals

Different performance profiles

Different user expectations

What “Separation” Means in Practice

The GusOnGames engine is free to evolve according to the needs of simple games and physics simulations — without inheriting the complexity of CAE tools.

Summary of the Revised Perspective

This keeps the GusOnGames engine clean, focused, and true to its purpose.

Summary

This article established the engine’s architectural foundation:

This layout forms the engine’s backbone and provides the foundation for every article that follows.