> For the complete documentation index, see [llms.txt](https://azuriohs-organization.gitbook.io/r-type/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://azuriohs-organization.gitbook.io/r-type/subsystems/our-subsystems/rendering.md).

# Rendering

## Table of Contents

* [Introduction](#introduction)
* [Overview](#overview)
* [Architecture](#architecture)
* [Getting Started](#getting-started)
* [Core Components](#core-components)
  * [Window](#window)
  * [Texture](#texture)
  * [Sprite](#sprite)
  * [Text](#text)
  * [Image](#image)
  * [Clock](#clock)
* [2D Rendering](#2d-rendering)
* [3D Rendering](#3d-rendering)
  * [Camera](#camera)
  * [Mesh](#mesh)
  * [Model](#model)
* [Particle System](#particle-system)
  * [Particle](#particle)
  * [Particle Emitter](#particle-emitter)
* [Input Handling](#input-handling)
* [Advanced Features](#advanced-features)
* [Examples](#examples)

***

## Introduction

The Raylib Render Engine is a C++ rendering subsystem implementation built on top of the [Raylib](https://www.raylib.com/) graphics library. It provides a high-level, object-oriented interface for 2D and 3D rendering, window management, texture handling, sprite animation, particle systems, and input processing.

This render engine is designed as a modular library that can be dynamically loaded into the R-Type game engine, following the plugin architecture pattern. It implements the `IRender` interface from the common engine subsystem, allowing for easy swapping between different rendering backends.

***

## Overview

### Features

* **2D Rendering**: Sprites, textures, text rendering with font support
* **3D Rendering**: Mesh generation, 3D models, camera system
* **Animation**: Sprite sheet animation support
* **Particle Systems**: Configurable particle emitters with physics
* **Input Handling**: Unified input adapter for keyboard, mouse, and gamepad
* **Window Management**: Flexible window creation and viewport handling
* **Memory Management**: Smart pointer-based resource management

### Dependencies

* **Raylib**: Core graphics library
* **GLFW3**: Window management
* **SDL2**: Gamepad input support

### Build Requirements

* CMake 3.10.0 or higher
* C++20 compiler
* vcpkg for dependency management

***

## Architecture

### Module Structure

The Raylib Render Engine follows a modular architecture:

```
RenderModule (Entry Point)
├── Window Management
│   ├── Window
│   └── RaylibAdapter (Input)
├── 2D Rendering
│   ├── Texture
│   ├── Sprite
│   ├── Text
│   └── Image
├── 3D Rendering
│   ├── Camera
│   ├── Mesh
│   └── Model
├── Particle System
│   ├── Particle
│   └── ParticleEmitter
└── Utilities
    └── Clock
```

### Entry Point

The module exports an entry point function that returns a `RenderModule` instance:

```cpp
extern "C" Subsystems::Render::RenderModule *entryPoint(void);
```

This allows the engine to dynamically load the render library at runtime.

***

## Getting Started

### Building the Module

1. **Configure CMake**:

```bash
cd lib/Render/Raylib
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
```

2. **Build**:

```bash
cmake --build build
```

The compiled library (`librender_raylib.dylib` on macOS, `.so` on Linux, `.dll` on Windows) will be placed in the `lib/` directory.

### Basic Usage

```cpp
#include "RenderModule.hpp"

// Create render module
auto render = std::make_unique<Subsystems::Render::RenderModule>();

// Create window
auto window = render->CreateWindow();
window->SetWidth(1920);
window->SetHeight(1080);
window->SetWindowName("My Game");
window->InitWindow();

// Create texture and sprite
auto texture = render->CreateTexture();
texture->SetTexture("assets/player.png");

auto sprite = render->CreateSprite();
sprite->SetTexture(*texture);

// Main loop
while (window->IsOpen()) {
    // Handle events
    auto input = window->HandleEvents(1920, 1080);

    // Clear window
    window->ClearWindow(Subsystems::Render::IWindow::BLACK_COLOR); // Black background

    // Draw sprite
    Components::Position pos{100, 100, 0};
    Components::Scale scale{1.0f, 1.0f};
    Components::Origin origin{0, 0};
    sprite->DrawSprite(pos, scale, origin);

    // Display
    window->DisplayWindow();
}
```

***

## Core Components

### Window

The `Window` class manages the application window and rendering context.

#### Key Methods

* `InitWindow()`: Initializes the window with configured parameters
* `IsOpen()`: Checks if the window is still open
* `GetWidth()` / `GetHeight()`: Get window dimensions
* `SetWidth()` / `SetHeight()`: Set window dimensions
* `SetWindowName()`: Set the window title
* `ClearWindow(Color)`: Clear the window with a specified color
* `DisplayWindow()`: Present the rendered frame
* `CloseWindow()`: Close the window
* `HandleEvents(width, height)`: Process input events and return input values
* `Draw(ISprite&)`: Draw a sprite to the window
* `Draw(IText&)`: Draw text to the window

#### Example

```cpp
auto window = render->CreateWindow();
window->SetWidth(1920);
window->SetHeight(1080);
window->SetWindowName("R-Type");
window->InitWindow();
```

***

### Texture

The `Texture` class handles image loading and GPU texture management.

#### Key Methods

* `SetTexture(std::string imagePath)`: Load texture from file
* `SetTexture(std::vector<char> buffer, std::string format)`: Load texture from memory
* `GetTexture()`: Get the underlying texture object (as `std::any`)

#### Example

```cpp
auto texture = render->CreateTexture();
texture->SetTexture("assets/ship.png");

// Or from memory
std::vector<char> imageData = loadImageData();
texture->SetTexture(imageData, ".png");
```

#### Supported Formats

The engine supports all formats supported by Raylib, including:

* PNG, JPEG, BMP, GIF, TGA, DDS
* QOI (Quite OK Image format)

***

### Sprite

The `Sprite` class represents a 2D image that can be drawn to the window. It supports sprite sheet animation.

#### Key Methods

* `SetTexture(ITexture&)`: Associate a texture with the sprite
* `SetFrameSize(width, height, count, duration, columns)`: Configure sprite sheet animation
* `UpdateAnimation(float dt)`: Update animation frame based on delta time
* `DrawSprite(Position&, Scale&, Origin&)`: Draw the sprite at a position
* `GetSpriteWidth()` / `GetSpriteHeight()`: Get sprite dimensions

#### Animation

Sprites support sprite sheet animation:

```cpp
auto sprite = render->CreateSprite();
sprite->SetTexture(*texture);
sprite->SetFrameSize(64, 64, 8, 0.1f, 4); // 8 frames, 0.1s per frame, 4 columns

// In update loop
float deltaTime = clock->GetElapsedTime();
sprite->UpdateAnimation(deltaTime);
```

#### Example

```cpp
auto sprite = render->CreateSprite();
sprite->SetTexture(*texture);

Components::Position pos{100, 100, 0};
Components::Scale scale{1.0f, 1.0f};
Components::Origin origin{0, 0};
sprite->DrawSprite(pos, scale, origin);
```

***

### Text

The `Text` class handles text rendering with custom fonts.

#### Key Methods

* `SetTextStr(std::string)`: Set the text string to display
* `SetFontPath(std::string)`: Load a font from file
* `SetCharacterSize(unsigned int)`: Set font size
* `RefreshText()`: Rebuild text after changes
* `Draw(Position&, Scale&)`: Draw text at a position

#### Example

```cpp
auto text = render->CreateText();
text->SetFontPath("assets/font.ttf");
text->SetCharacterSize(24);
text->SetTextStr("Score: 1000");
text->RefreshText();

Components::Position pos{10, 10, 0};
Components::Scale scale{1.0f, 1.0f};
text->Draw(pos, scale);
```

***

### Image

The `Image` class provides image loading and manipulation capabilities.

#### Key Methods

* `SetImage(std::string imagePath)`: Load image from file
* `SetImage(std::vector<char> buffer, std::string format)`: Load image from memory
* `GetImage()`: Get the underlying image object

#### Use Cases

Images are primarily used for:

* Loading textures from files
* Image manipulation before texture creation
* Screenshot capture
* Image processing

***

### Clock

The `Clock` class provides timing functionality for animations and game loops.

#### Key Methods

* `InitClock()`: Initialize the clock
* `GetElapsedTime()`: Get elapsed time since initialization/restart (in seconds)
* `Restart()`: Reset the clock to zero

#### Example

```cpp
auto clock = render->CreateClock();
clock->InitClock();

// In game loop
float deltaTime = clock->GetElapsedTime();
clock->Restart();

// Use deltaTime for frame-independent animations
sprite->UpdateAnimation(deltaTime);
```

***

## 2D Rendering

### Rendering Pipeline

1. **Start Rendering**: Call `StartRendering(window)` to begin the rendering frame
2. **Clear Window**: Use `window->ClearWindow(color)` to clear the previous frame
3. **Draw Objects**: Draw sprites, text, and other 2D elements
4. **Display**: Call `window->DisplayWindow()` to present the frame
5. **Stop Rendering**: Call `StopRendering(window, width, height)` when done

### Basic 2D Scene

```cpp
render->StartRendering(*window);
window->ClearWindow({0, 0, 0, 255}); // Black background

// Draw sprites
for (auto& entity : entities) {
    auto pos = entity->GetComponent<Components::Position>();
    auto scale = entity->GetComponent<Components::Scale>();
    auto sprite = entity->GetComponent<Components::Sprite>();
    sprite->DrawSprite(*pos, *scale, origin);
}

// Draw UI text
uiText->Draw(textPos, textScale);

window->DisplayWindow();
render->StopRendering(*window, 1920, 1080);
```

***

## 3D Rendering

The render engine supports full 3D rendering with cameras, meshes, and models.

### Camera

The `Camera` class represents a 3D camera for viewing 3D scenes.

#### Key Methods

* `SetFOV(float)`: Set field of view (FOV)
* `SetTarget(std::tuple<float, float, float>)`: Set camera target position
* `SetUp(std::tuple<float, float, float>)`: Set camera up vector
* `SetProjection(Projection)`: Set projection type (PERSPECTIVE or ORTHOGRAPHIC)
* `GetCamera()`: Get the underlying camera object

#### Projection Types

* `PERSPECTIVE`: Perspective projection (3D depth effect)
* `ORTHOGRAPHIC`: Orthographic projection (no depth distortion)

#### Example

```cpp
auto camera = render->CreateCamera();
camera->SetFOV(60.0f);
camera->SetTarget({0.0f, 0.0f, 0.0f});
camera->SetUp({0.0f, 1.0f, 0.0f});
camera->SetProjection(ICamera::Projection::PERSPECTIVE);

Components::Position camPos{0.0f, 5.0f, 10.0f};
render->Start3DRendering(*camera, camPos);
```

***

### Mesh

The `Mesh` class represents 3D geometry data. It provides methods to generate primitive shapes.

#### Primitive Generation Methods

* `GenerateCube(height, width, length)`: Generate a cube mesh
* `GenerateSphere(radius, rings, slices)`: Generate a sphere mesh
* `GeneratePlane(width, length, resX, resZ)`: Generate a plane mesh
* `GenerateCylinder(radius, height, slices)`: Generate a cylinder mesh
* `GenerateCone(radius, height, slices)`: Generate a cone mesh
* `GenerateTorus(radius, size, radSeg, sides)`: Generate a torus mesh
* `GenerateHemiSphere(radius, rings, slices)`: Generate a hemisphere mesh
* `GeneratePoly(sides, radius)`: Generate a polygon mesh
* `GenerateKnot(radius, size, radSeg, sides)`: Generate a knot mesh

#### Mesh Operations

* `UploadToGPU()`: Upload mesh data to GPU for rendering
* `GetVertexCount()`: Get number of vertices
* `GetTriangleCount()`: Get number of triangles

#### Example

```cpp
auto mesh = render->CreateMesh();
mesh->GenerateCube(1.0f, 1.0f, 1.0f);
mesh->UploadToGPU();
```

***

### Model

The `Model` class represents a complete 3D model that can be loaded from files or created from meshes.

#### Key Methods

* `LoadFromFile(std::string filename)`: Load model from file (OBJ, GLTF, etc.)
* `LoadFromMesh(IMesh&)`: Create model from a mesh
* `LoadAnimation(std::string filename)`: Load animation data
* `SetTexture(ITexture&)`: Apply texture to model
* `UpdateAnimation()`: Update model animation frame
* `Draw(Position&, Scale&, Color, Rotation)`: Draw the model

#### Example

```cpp
auto model = render->CreateModel();
model->LoadFromFile("assets/player.gltf");
model->LoadAnimation("assets/player_animation.gltf");

auto texture = render->CreateTexture();
texture->SetTexture("assets/player_texture.png");
model->SetTexture(*texture);

// In render loop
Components::Position pos{0, 0, 0};
Components::Scale scale{1.0f, 1.0f, 1.0f};
Components::Rotation rot{0.0f, 1.0f, 0.0f};
IWindow::Color color{255, 255, 255, 255};
model->UpdateAnimation();
model->Draw(pos, scale, color, rot);
```

### 3D Rendering Pipeline

```cpp
// Setup camera
auto camera = render->CreateCamera();
camera->SetFOV(60.0f);
camera->SetTarget({0, 0, 0});
camera->SetUp({0, 1, 0});

Components::Position camPos{0, 5, 10};

// Start 3D rendering
render->Start3DRendering(*camera, camPos);

// Draw 3D primitives
Components::Position cubePos{0, 0, 0};
render->DrawCube(cubePos, 1.0f, 1.0f, 1.0f, {255, 0, 0, 255});

Components::Position spherePos{2, 0, 0};
render->DrawSphere(spherePos, 0.5f, {0, 255, 0, 255});

// Stop 3D rendering
render->Stop3DRendering();
```

***

## Particle System

The render engine includes a comprehensive particle system for visual effects.

### Particle

The `Particle` class represents a single particle in a particle system.

#### Key Methods

* `SetLifetime(float)`: Set particle lifetime in seconds
* `SetColor(Color)`: Set particle color
* `Update(deltaTime, Position&, Velocity&)`: Update particle state
* `Draw(Position&, Scale&)`: Draw the particle
* `IsAlive()`: Check if particle is still alive
* `GetLifetime()`: Get remaining lifetime

#### Example

```cpp
auto particle = render->CreateParticule();
particle->SetLifetime(2.0f);
particle->SetColor({255, 255, 0, 255}); // Yellow

float deltaTime = clock->GetElapsedTime();
Components::Position pos{100, 100, 0};
Components::Velocity vel{50, -50, 0};
particle->Update(deltaTime, pos, vel);

if (particle->IsAlive()) {
    Components::Scale scale{1.0f, 1.0f};
    particle->Draw(pos, scale);
}
```

***

### Particle Emitter

The `ParticleEmitter` class generates and manages multiple particles.

#### Key Methods

* `SetDirection(Direction)`: Set emission direction
* `SetPower(std::size_t)`: Set number of particles emitted per frame
* `SetLifetime(float)`: Set particle lifetime
* `SetColor(Color)`: Set particle color
* `SetSpread(float)`: Set spread angle in radians
* `SetSpeed(float)`: Set particle speed
* `EmitParticule(Position&, GameEngine*)`: Emit particles at position

#### Direction Enum

Particle emission directions:

* `UP`, `DOWN`, `LEFT`, `RIGHT`
* `RANDOM`: Random direction

#### Example

```cpp
auto emitter = render->CreateParticuleEmitter();
emitter->SetDirection(IParticuleEmitter::Direction::UP);
emitter->SetPower(10); // 10 particles per frame
emitter->SetLifetime(1.0f);
emitter->SetColor({255, 100, 0, 255}); // Orange
emitter->SetSpread(0.5f); // 30 degree spread
emitter->SetSpeed(100.0f);

// In update loop
Components::Position emitterPos{400, 300, 0};
emitter->EmitParticule(emitterPos, engine);
```

***

## Input Handling

The render engine includes an input adapter (`RaylibAdapter`) that translates Raylib/SDL input events into a unified input system.

### Input Sources

* **Keyboard**: Standard keyboard input
* **Mouse**: Mouse buttons and position
* **Gamepad**: SDL2 gamepad support with multiple controllers

### Supported Input Codes

#### Keyboard

* Standard keys: A-Z, 0-9
* Special keys: Space, Enter, Escape, Arrow keys, etc.
* Modifier keys: Shift, Control, Alt

#### Mouse

* Buttons: Left, Right, Middle
* Scroll: Scroll up, Scroll down

#### Gamepad

* Buttons: A, B, X, Y, Shoulders, Triggers, D-Pad
* Axes: Left stick, Right stick, Triggers

***

## Advanced Features

### Custom Viewport

The window supports custom viewport rendering:

```cpp
auto window = render->CreateWindow();
window->SetWidth(1920);
window->SetHeight(1080);
auto view = window->GetView(); // Get render texture viewport
```

### Texture from Memory

Load textures dynamically from network or memory:

```cpp
std::vector<char> imageData = downloadImageFromNetwork();
auto texture = render->CreateTexture();
texture->SetTexture(imageData, ".png");
```

### Wireframe Rendering

3D primitives can be rendered in wireframe mode:

```cpp
Components::Position cubePos{0, 0, 0};
render->DrawCube(cubePos, 1.0f, 1.0f, 1.0f, {255, 255, 255, 255}, true); // Wireframe
```

### 3D Primitives

Direct primitive drawing methods:

* `DrawCube(Position&, width, height, length, Color, isWires)`
* `DrawSphere(Position&, radius, Color, isWires)`
* `DrawPlane(Position&, width, length, Color)`
* `DrawCircle3D(Position&, radius, Rotation&, angle, Color)`

***

## Examples

### Complete 2D Game Scene

```cpp
#include "RenderModule.hpp"

void GameLoop() {
    auto render = std::make_unique<Subsystems::Render::RenderModule>();

    // Setup window
    auto window = render->CreateWindow();
    window->SetWidth(1920);
    window->SetHeight(1080);
    window->SetWindowName("R-Type");
    window->InitWindow();

    // Load resources
    auto texture = render->CreateTexture();
    texture->SetTexture("assets/ship.png");

    auto sprite = render->CreateSprite();
    sprite->SetTexture(*texture);
    sprite->SetFrameSize(64, 64, 4, 0.1f, 2); // Animated sprite

    auto clock = render->CreateClock();
    clock->InitClock();

    // Game loop
    while (window->IsOpen()) {
        float deltaTime = clock->GetElapsedTime();
        clock->Restart();

        // Handle input
        auto input = window->HandleEvents(1920, 1080);

        // Update
        sprite->UpdateAnimation(deltaTime);

        // Render
        render->StartRendering(*window);
        window->ClearWindow({0, 0, 50, 255}); // Dark blue

        Components::Position pos{100, 100, 0};
        Components::Scale scale{2.0f, 2.0f};
        Components::Origin origin{0, 0};
        sprite->DrawSprite(pos, scale, origin);

        window->DisplayWindow();
        render->StopRendering(*window, 1920, 1080);
    }

    window->CloseWindow();
}
```

### 3D Scene with Particles

```cpp
void Render3DScene() {
    auto render = std::make_unique<Subsystems::Render::RenderModule>();

    // Setup window
    auto window = render->CreateWindow();
    window->SetWidth(1920);
    window->SetHeight(1080);
    window->InitWindow();

    // Setup camera
    auto camera = render->CreateCamera();
    camera->SetFOV(60.0f);
    camera->SetTarget({0, 0, 0});
    camera->SetUp({0, 1, 0});

    Components::Position camPos{0, 5, 10};

    // Create particle emitter
    auto emitter = render->CreateParticuleEmitter();
    emitter->SetDirection(IParticuleEmitter::Direction::UP);
    emitter->SetPower(20);
    emitter->SetLifetime(2.0f);
    emitter->SetColor({255, 200, 0, 255});
    emitter->SetSpread(1.0f);
    emitter->SetSpeed(50.0f);

    // Render loop
    while (window->IsOpen()) {
        window->HandleEvents(1920, 1080);

        render->Start3DRendering(*camera, camPos);
        window->ClearWindow({20, 20, 30, 255});

        // Draw 3D objects
        Components::Position cubePos{0, 0, 0};
        render->DrawCube(cubePos, 2.0f, 2.0f, 2.0f, {255, 0, 0, 255});

        // Emit particles
        Components::Position emitterPos{0, -1, 0};
        emitter->EmitParticule(emitterPos, engine);

        render->Stop3DRendering();
        window->DisplayWindow();
    }
}
```

***

## Best Practices

### Resource Management

* Always use smart pointers for render objects
* Load textures once and reuse them
* Unload textures when no longer needed
* Use sprite sheets for animated sprites

### Performance

* Batch draw calls when possible
* Use appropriate texture sizes (power of 2 recommended)
* Limit particle count for performance
* Use mesh LOD for distant 3D objects

### Memory

* Load resources asynchronously when possible
* Use texture compression for large images
* Release unused resources promptly

***

## Troubleshooting

### Common Issues

**Window doesn't open:**

* Check that GLFW is properly linked
* Verify window dimensions are valid
* Ensure graphics drivers are up to date

**Textures not loading:**

* Verify file paths are correct
* Check file format is supported
* Ensure sufficient memory for texture

**Performance issues:**

* Reduce particle count
* Lower texture resolutions
* Use fewer draw calls per frame

***

## API Reference

For detailed API documentation, refer to the header files in the `include/` directory:

* `RenderModule.hpp`: Main render module interface
* `Window.hpp`: Window management
* `Texture.hpp`: Texture handling
* `Sprite.hpp`: Sprite rendering
* `Text.hpp`: Text rendering
* `Camera.hpp`: 3D camera
* `Mesh.hpp`: 3D mesh generation
* `Model.hpp`: 3D model loading
* `Particule.hpp`: Particle system
* `ParticuleEmitter.hpp`: Particle emitter
* `Image.hpp`: Image loading
* `Clock.hpp`: Timing utilities
* `RaylibAdapter.hpp`: Input adapter

***

## Version Information

* **Version**: 1.0.0
* **Build System**: CMake 3.10.0+
* **C++ Standard**: C++20
* **Platform Support**: macOS, Linux, Windows

***

## License

This render engine is part of the R-Type project (EPITECH, 2025).

***

## Contributing

When contributing to the render engine:

1. Follow the existing code style
2. Add documentation for new features
3. Update this documentation file
4. Test on multiple platforms
5. Ensure backward compatibility with the `IRender` interface

***

*Last Updated: 2025*
