Add project documentation for morning setup
- Confluent: Conlang skeleton (phonology + proto-roots) - GroveEngine RenderModule: Window + 2D UI rendering architecture - Aissia: AI subsystem with LLM API calls + async processing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e16ddd3422
commit
0654db6a81
@ -79,6 +79,233 @@ Projets/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## AI Subsystem Architecture
|
||||||
|
|
||||||
|
### API Call Management
|
||||||
|
|
||||||
|
**LLM Provider Abstraction**
|
||||||
|
```cpp
|
||||||
|
class ILLMProvider {
|
||||||
|
public:
|
||||||
|
virtual ~ILLMProvider() = default;
|
||||||
|
|
||||||
|
struct Message {
|
||||||
|
std::string role; // "user", "assistant", "system"
|
||||||
|
std::string content;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompletionRequest {
|
||||||
|
std::vector<Message> messages;
|
||||||
|
float temperature = 0.7f;
|
||||||
|
int max_tokens = 1000;
|
||||||
|
std::string model;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompletionResponse {
|
||||||
|
std::string content;
|
||||||
|
int tokens_used;
|
||||||
|
float cost_usd;
|
||||||
|
bool success;
|
||||||
|
std::string error;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual CompletionResponse Complete(const CompletionRequest& req) = 0;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Implementations**
|
||||||
|
```cpp
|
||||||
|
// Claude API (Anthropic)
|
||||||
|
class ClaudeProvider : public ILLMProvider {
|
||||||
|
std::string api_key;
|
||||||
|
std::string endpoint = "https://api.anthropic.com/v1/messages";
|
||||||
|
|
||||||
|
CompletionResponse Complete(const CompletionRequest& req) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// GPT API (OpenAI)
|
||||||
|
class GPTProvider : public ILLMProvider {
|
||||||
|
std::string api_key;
|
||||||
|
std::string endpoint = "https://api.openai.com/v1/chat/completions";
|
||||||
|
|
||||||
|
CompletionResponse Complete(const CompletionRequest& req) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Local LLM (Llama via llama.cpp server)
|
||||||
|
class LocalLLMProvider : public ILLMProvider {
|
||||||
|
std::string endpoint = "http://localhost:8080/v1/chat/completions";
|
||||||
|
|
||||||
|
CompletionResponse Complete(const CompletionRequest& req) override;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### AISubsystem Module
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class AISubsystem : public grove::IModule {
|
||||||
|
public:
|
||||||
|
void initialize(const IDataNode& config, IIO* io) override;
|
||||||
|
void update(float dt) override;
|
||||||
|
void shutdown() override;
|
||||||
|
|
||||||
|
// High-level API
|
||||||
|
std::string AskQuestion(const std::string& question, const std::string& context);
|
||||||
|
std::string GenerateResponse(const std::vector<Message>& conversation);
|
||||||
|
|
||||||
|
// Context management
|
||||||
|
void SetSystemPrompt(const std::string& prompt);
|
||||||
|
void AddContext(const std::string& key, const std::string& value);
|
||||||
|
void ClearContext();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<ILLMProvider> provider;
|
||||||
|
std::string system_prompt;
|
||||||
|
std::map<std::string, std::string> context_data;
|
||||||
|
|
||||||
|
// Request queue (async processing)
|
||||||
|
std::queue<CompletionRequest> pending_requests;
|
||||||
|
std::thread worker_thread;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTTP Client (API Calls)
|
||||||
|
|
||||||
|
**Using libcurl (C++ wrapper)**
|
||||||
|
```cpp
|
||||||
|
class HTTPClient {
|
||||||
|
public:
|
||||||
|
struct Request {
|
||||||
|
std::string url;
|
||||||
|
std::string method; // GET, POST
|
||||||
|
std::map<std::string, std::string> headers;
|
||||||
|
std::string body;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Response {
|
||||||
|
int status_code;
|
||||||
|
std::string body;
|
||||||
|
std::map<std::string, std::string> headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
Response Send(const Request& req);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CURL* curl;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Usage pour LLM API
|
||||||
|
HTTPClient client;
|
||||||
|
HTTPClient::Request req;
|
||||||
|
req.url = "https://api.anthropic.com/v1/messages";
|
||||||
|
req.method = "POST";
|
||||||
|
req.headers["x-api-key"] = api_key;
|
||||||
|
req.headers["Content-Type"] = "application/json";
|
||||||
|
req.body = R"({
|
||||||
|
"model": "claude-3-5-sonnet-20241022",
|
||||||
|
"messages": [{"role": "user", "content": "Hello!"}],
|
||||||
|
"max_tokens": 1024
|
||||||
|
})";
|
||||||
|
|
||||||
|
auto response = client.Send(req);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Async Processing (Non-blocking)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void AISubsystem::update(float dt) {
|
||||||
|
// Process pending requests asynchronously
|
||||||
|
if (!pending_requests.empty() && !worker_thread.joinable()) {
|
||||||
|
auto request = pending_requests.front();
|
||||||
|
pending_requests.pop();
|
||||||
|
|
||||||
|
worker_thread = std::thread([this, request]() {
|
||||||
|
auto response = provider->Complete(request);
|
||||||
|
|
||||||
|
// Send response via IIO to other modules
|
||||||
|
io->SendMessage("ai_response", response.content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup finished threads
|
||||||
|
if (worker_thread.joinable()) {
|
||||||
|
worker_thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
**Config file : `aissia_ai_config.json`**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ai_subsystem": {
|
||||||
|
"provider": "claude",
|
||||||
|
"api_key_env": "ANTHROPIC_API_KEY",
|
||||||
|
"model": "claude-3-5-sonnet-20241022",
|
||||||
|
"default_temperature": 0.7,
|
||||||
|
"max_tokens": 1000,
|
||||||
|
"system_prompt": "You are AISSIA, an AI assistant helping manage hyperfocus and time management.",
|
||||||
|
"timeout_seconds": 30,
|
||||||
|
"retry_attempts": 3
|
||||||
|
},
|
||||||
|
"providers": {
|
||||||
|
"claude": {
|
||||||
|
"endpoint": "https://api.anthropic.com/v1/messages",
|
||||||
|
"cost_per_1k_input": 0.003,
|
||||||
|
"cost_per_1k_output": 0.015
|
||||||
|
},
|
||||||
|
"gpt": {
|
||||||
|
"endpoint": "https://api.openai.com/v1/chat/completions",
|
||||||
|
"cost_per_1k_input": 0.00015,
|
||||||
|
"cost_per_1k_output": 0.0006
|
||||||
|
},
|
||||||
|
"local": {
|
||||||
|
"endpoint": "http://localhost:8080/v1/chat/completions",
|
||||||
|
"cost_per_1k_input": 0.0,
|
||||||
|
"cost_per_1k_output": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### TTS/STT (Bonus)
|
||||||
|
|
||||||
|
**Text-to-Speech Options**
|
||||||
|
```cpp
|
||||||
|
class ITTSProvider {
|
||||||
|
public:
|
||||||
|
virtual void Speak(const std::string& text) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Windows SAPI (already documented in daily check system)
|
||||||
|
class WindowsSAPIProvider : public ITTSProvider {
|
||||||
|
void Speak(const std::string& text) override {
|
||||||
|
// Use SAPI COM interface
|
||||||
|
// See: anki_tingting/CLAUDE.md for implementation
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ElevenLabs API (cloud, high quality)
|
||||||
|
class ElevenLabsProvider : public ITTSProvider {
|
||||||
|
void Speak(const std::string& text) override;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Speech-to-Text Options**
|
||||||
|
```cpp
|
||||||
|
class ISTTProvider {
|
||||||
|
public:
|
||||||
|
virtual std::string Transcribe(const std::vector<uint8_t>& audio_data) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Whisper API (OpenAI)
|
||||||
|
class WhisperProvider : public ISTTProvider {
|
||||||
|
std::string Transcribe(const std::vector<uint8_t>& audio_data) override;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Modules AISSIA Prévus
|
## Modules AISSIA Prévus
|
||||||
|
|
||||||
Architecture modulaire GroveEngine :
|
Architecture modulaire GroveEngine :
|
||||||
@ -288,9 +515,15 @@ GetWindowThreadProcessId(hwnd, &processId);
|
|||||||
**Immédiat** :
|
**Immédiat** :
|
||||||
1. ✅ Build test GroveEngine (vérifier que ça compile)
|
1. ✅ Build test GroveEngine (vérifier que ça compile)
|
||||||
2. ⏳ Créer `aissia-core.exe` (DebugEngine wrapper)
|
2. ⏳ Créer `aissia-core.exe` (DebugEngine wrapper)
|
||||||
3. ⏳ Développer premier module (MonitoringModule simple)
|
3. ⏳ Développer AISubsystem (LLM API calls + management)
|
||||||
4. ⏳ Valider hot-reload 0.4ms avec module AISSIA
|
4. ⏳ Valider hot-reload 0.4ms avec module AISSIA
|
||||||
|
|
||||||
|
**Base Running Requirements** :
|
||||||
|
- ✅ GroveEngine integrated
|
||||||
|
- ⏳ LLM API subsystem (Claude/GPT calls)
|
||||||
|
- ⏳ AI subsystem management (context, prompts, responses)
|
||||||
|
- 🎁 Bonus: TTS/STT APIs (optionnel)
|
||||||
|
|
||||||
**Questions bloquantes** :
|
**Questions bloquantes** :
|
||||||
- LLM choice pour AIAssistantModule ?
|
- LLM choice pour AIAssistantModule ?
|
||||||
- Niveau d'intervention acceptable (kill process ou juste notifs) ?
|
- Niveau d'intervention acceptable (kill process ou juste notifs) ?
|
||||||
|
|||||||
76
Projects/WIP/Confluent.md
Normal file
76
Projects/WIP/Confluent.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Confluent - Langue Construite
|
||||||
|
|
||||||
|
**Statut** : WIP
|
||||||
|
**Type** : Conlang (langue construite)
|
||||||
|
**Contexte** : Lié au projet civjdr (Civilisation de la Confluence)
|
||||||
|
**Dernière mise à jour** : 26 novembre 2025
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vue d'ensemble
|
||||||
|
|
||||||
|
Langue construite pour la Civilisation de la Confluence (civjdr).
|
||||||
|
|
||||||
|
**À compléter** : Informations détaillées depuis laptop
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phonologie & Phonétique
|
||||||
|
|
||||||
|
### Inventaire Phonémique
|
||||||
|
|
||||||
|
**À compléter**
|
||||||
|
|
||||||
|
#### Consonnes
|
||||||
|
|
||||||
|
[Tableau des consonnes à ajouter]
|
||||||
|
|
||||||
|
#### Voyelles
|
||||||
|
|
||||||
|
[Tableau des voyelles à ajouter]
|
||||||
|
|
||||||
|
### Règles Phonotactiques
|
||||||
|
|
||||||
|
**À compléter**
|
||||||
|
|
||||||
|
- Structure syllabique :
|
||||||
|
- Contraintes :
|
||||||
|
- Assimilations :
|
||||||
|
- Stress/Accent :
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Racines Proto-Confluent
|
||||||
|
|
||||||
|
### Système de Racines
|
||||||
|
|
||||||
|
**À compléter**
|
||||||
|
|
||||||
|
### Racines Fondamentales
|
||||||
|
|
||||||
|
**À compléter**
|
||||||
|
|
||||||
|
| Racine | Sens | Dérivations | Notes |
|
||||||
|
|--------|------|-------------|-------|
|
||||||
|
| | | | |
|
||||||
|
|
||||||
|
### Évolution Diachronique
|
||||||
|
|
||||||
|
**À compléter**
|
||||||
|
|
||||||
|
- Proto-Confluent → Confluent moderne
|
||||||
|
- Changements sonores majeurs
|
||||||
|
- Innovations grammaticales
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes de Développement
|
||||||
|
|
||||||
|
**26 novembre 2025** : Squelette créé, données détaillées à transférer depuis laptop
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ressources
|
||||||
|
|
||||||
|
- Lien civjdr : `Projects/CONSTANT/civjdr.md`
|
||||||
|
- [Autres ressources à ajouter]
|
||||||
561
Projects/WIP/GroveEngine_RenderModule.md
Normal file
561
Projects/WIP/GroveEngine_RenderModule.md
Normal file
@ -0,0 +1,561 @@
|
|||||||
|
# GroveEngine - RenderModule (Framework Module)
|
||||||
|
|
||||||
|
**Type** : Framework Module (base avancée)
|
||||||
|
**Stack** : bgfx + SDL2
|
||||||
|
**Objectif** : Window + UI 2D element rendering
|
||||||
|
**Dernière mise à jour** : 26 novembre 2025
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vue d'ensemble
|
||||||
|
|
||||||
|
Module framework pour GroveEngine fournissant les capacités de rendu 2D de base :
|
||||||
|
- **Window management** via SDL2
|
||||||
|
- **Rendering 2D** via bgfx (multi-backend : Vulkan/DX12/Metal/OpenGL)
|
||||||
|
- **UI element rendering** (primitives 2D)
|
||||||
|
|
||||||
|
**Base avancée** = Intégration complète dans le GroveEngine + capacités rendering fonctionnelles
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture Module
|
||||||
|
|
||||||
|
### Integration GroveEngine
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class RenderModule : public grove::IModule {
|
||||||
|
public:
|
||||||
|
// IModule interface
|
||||||
|
void initialize(const IDataNode& config, IIO* io) override;
|
||||||
|
void update(float dt) override;
|
||||||
|
void shutdown() override;
|
||||||
|
|
||||||
|
// Rendering API
|
||||||
|
void BeginFrame();
|
||||||
|
void EndFrame();
|
||||||
|
|
||||||
|
// 2D Primitives
|
||||||
|
void DrawRect(const Rect& rect, Color color);
|
||||||
|
void DrawSprite(const Sprite& sprite);
|
||||||
|
void DrawText(const std::string& text, Font font, Vec2 pos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Window* window;
|
||||||
|
bgfx::ViewId main_view;
|
||||||
|
Renderer2D renderer;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Composants Clés
|
||||||
|
|
||||||
|
**1. Window Management (SDL2)**
|
||||||
|
```cpp
|
||||||
|
struct WindowConfig {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
std::string title;
|
||||||
|
bool fullscreen;
|
||||||
|
bool vsync;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Création window SDL2
|
||||||
|
window = SDL_CreateWindow(
|
||||||
|
config.title.c_str(),
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
config.width,
|
||||||
|
config.height,
|
||||||
|
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. bgfx Initialization**
|
||||||
|
```cpp
|
||||||
|
bgfx::Init init;
|
||||||
|
init.type = bgfx::RendererType::Count; // Auto-detect
|
||||||
|
init.resolution.width = width;
|
||||||
|
init.resolution.height = height;
|
||||||
|
init.resolution.reset = BGFX_RESET_VSYNC;
|
||||||
|
|
||||||
|
// Utilise window SDL2
|
||||||
|
SDL_SysWMinfo wmi;
|
||||||
|
SDL_VERSION(&wmi.version);
|
||||||
|
SDL_GetWindowWMInfo(window, &wmi);
|
||||||
|
|
||||||
|
#if BX_PLATFORM_WINDOWS
|
||||||
|
init.platformData.nwh = wmi.info.win.window;
|
||||||
|
#elif BX_PLATFORM_LINUX
|
||||||
|
init.platformData.ndt = wmi.info.x11.display;
|
||||||
|
init.platformData.nwh = (void*)(uintptr_t)wmi.info.x11.window;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bgfx::init(init);
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Renderer2D (Primitives)**
|
||||||
|
```cpp
|
||||||
|
class Renderer2D {
|
||||||
|
public:
|
||||||
|
void DrawRect(const Rect& rect, Color color);
|
||||||
|
void DrawSprite(const Sprite& sprite);
|
||||||
|
void Flush(); // Submit batched draws
|
||||||
|
|
||||||
|
private:
|
||||||
|
bgfx::ProgramHandle sprite_shader;
|
||||||
|
bgfx::ProgramHandle color_shader;
|
||||||
|
|
||||||
|
struct SpriteBatch {
|
||||||
|
std::vector<SpriteVertex> vertices;
|
||||||
|
bgfx::TextureHandle texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<SpriteBatch> batches;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rendering Pipeline
|
||||||
|
|
||||||
|
### Frame Structure
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void RenderModule::update(float dt) {
|
||||||
|
BeginFrame();
|
||||||
|
|
||||||
|
// Rendering commands
|
||||||
|
DrawRect({100, 100, 200, 150}, Color::Red());
|
||||||
|
DrawSprite(test_sprite);
|
||||||
|
DrawText("Hello GroveEngine", main_font, {50, 50});
|
||||||
|
|
||||||
|
EndFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderModule::BeginFrame() {
|
||||||
|
bgfx::touch(main_view);
|
||||||
|
bgfx::setViewClear(main_view,
|
||||||
|
BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH,
|
||||||
|
0x303030ff, 1.0f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderModule::EndFrame() {
|
||||||
|
renderer.Flush(); // Submit batched draws
|
||||||
|
bgfx::frame(); // Advance frame
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vertex Formats
|
||||||
|
|
||||||
|
**Sprite Vertex (textured quad)**
|
||||||
|
```cpp
|
||||||
|
struct SpriteVertex {
|
||||||
|
float x, y, z; // Position
|
||||||
|
float u, v; // UV coords
|
||||||
|
uint32_t color; // Tint (ABGR)
|
||||||
|
};
|
||||||
|
|
||||||
|
bgfx::VertexLayout sprite_layout;
|
||||||
|
sprite_layout.begin()
|
||||||
|
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
|
||||||
|
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
|
||||||
|
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
|
||||||
|
.end();
|
||||||
|
```
|
||||||
|
|
||||||
|
**Color Vertex (solid color quad)**
|
||||||
|
```cpp
|
||||||
|
struct ColorVertex {
|
||||||
|
float x, y, z;
|
||||||
|
uint32_t color;
|
||||||
|
};
|
||||||
|
|
||||||
|
bgfx::VertexLayout color_layout;
|
||||||
|
color_layout.begin()
|
||||||
|
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
|
||||||
|
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
|
||||||
|
.end();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shaders
|
||||||
|
|
||||||
|
### Sprite Shader (Vertex)
|
||||||
|
|
||||||
|
```glsl
|
||||||
|
// vs_sprite.sc
|
||||||
|
$input a_position, a_texcoord0, a_color0
|
||||||
|
$output v_texcoord0, v_color0
|
||||||
|
|
||||||
|
#include <bgfx_shader.sh>
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0));
|
||||||
|
v_texcoord0 = a_texcoord0;
|
||||||
|
v_color0 = a_color0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sprite Shader (Fragment)
|
||||||
|
|
||||||
|
```glsl
|
||||||
|
// fs_sprite.sc
|
||||||
|
$input v_texcoord0, v_color0
|
||||||
|
|
||||||
|
#include <bgfx_shader.sh>
|
||||||
|
|
||||||
|
SAMPLER2D(s_texture, 0);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texColor = texture2D(s_texture, v_texcoord0);
|
||||||
|
gl_FragColor = texColor * v_color0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Compilation** :
|
||||||
|
```bash
|
||||||
|
shaderc -f vs_sprite.sc -o vs_sprite.bin --type vertex --platform linux -p 120
|
||||||
|
shaderc -f fs_sprite.sc -o fs_sprite.bin --type fragment --platform linux -p 120
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Camera 2D
|
||||||
|
|
||||||
|
### Orthographic Projection
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class Camera2D {
|
||||||
|
public:
|
||||||
|
Vec2 position;
|
||||||
|
float zoom = 1.0f;
|
||||||
|
|
||||||
|
Mat4 GetViewMatrix() const {
|
||||||
|
return Mat4::Translation(-position.x, -position.y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat4 GetProjectionMatrix(int width, int height) const {
|
||||||
|
float halfW = (width / zoom) * 0.5f;
|
||||||
|
float halfH = (height / zoom) * 0.5f;
|
||||||
|
return Mat4::Ortho(-halfW, halfW, -halfH, halfH, -1, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup view transform
|
||||||
|
Mat4 view = camera.GetViewMatrix();
|
||||||
|
Mat4 proj = camera.GetProjectionMatrix(screenW, screenH);
|
||||||
|
bgfx::setViewTransform(main_view, view.data, proj.data);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UI Element Rendering
|
||||||
|
|
||||||
|
### DrawRect Implementation
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void Renderer2D::DrawRect(const Rect& rect, Color color) {
|
||||||
|
ColorVertex vertices[4] = {
|
||||||
|
{rect.x, rect.y, 0, color.abgr()},
|
||||||
|
{rect.x + rect.w, rect.y, 0, color.abgr()},
|
||||||
|
{rect.x + rect.w, rect.y + rect.h, 0, color.abgr()},
|
||||||
|
{rect.x, rect.y + rect.h, 0, color.abgr()}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t indices[6] = {0, 1, 2, 0, 2, 3};
|
||||||
|
|
||||||
|
bgfx::TransientVertexBuffer tvb;
|
||||||
|
bgfx::TransientIndexBuffer tib;
|
||||||
|
|
||||||
|
bgfx::allocTransientVertexBuffer(&tvb, 4, color_layout);
|
||||||
|
bgfx::allocTransientIndexBuffer(&tib, 6);
|
||||||
|
|
||||||
|
memcpy(tvb.data, vertices, sizeof(vertices));
|
||||||
|
memcpy(tib.data, indices, sizeof(indices));
|
||||||
|
|
||||||
|
bgfx::setVertexBuffer(0, &tvb);
|
||||||
|
bgfx::setIndexBuffer(&tib);
|
||||||
|
bgfx::setState(BGFX_STATE_DEFAULT);
|
||||||
|
bgfx::submit(main_view, color_shader);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### DrawSprite Implementation (Batched)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void Renderer2D::DrawSprite(const Sprite& sprite) {
|
||||||
|
// Find or create batch for this texture
|
||||||
|
SpriteBatch* batch = GetBatchForTexture(sprite.texture);
|
||||||
|
|
||||||
|
// Add quad to batch
|
||||||
|
float x0 = sprite.pos.x;
|
||||||
|
float y0 = sprite.pos.y;
|
||||||
|
float x1 = x0 + sprite.size.x;
|
||||||
|
float y1 = y0 + sprite.size.y;
|
||||||
|
|
||||||
|
uint32_t color = sprite.tint.abgr();
|
||||||
|
|
||||||
|
batch->vertices.push_back({x0, y0, 0, 0, 0, color});
|
||||||
|
batch->vertices.push_back({x1, y0, 0, 1, 0, color});
|
||||||
|
batch->vertices.push_back({x1, y1, 0, 1, 1, color});
|
||||||
|
batch->vertices.push_back({x0, y1, 0, 0, 1, color});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer2D::Flush() {
|
||||||
|
for (auto& batch : batches) {
|
||||||
|
size_t quad_count = batch.vertices.size() / 4;
|
||||||
|
|
||||||
|
// Generate indices (0,1,2, 0,2,3 per quad)
|
||||||
|
std::vector<uint16_t> indices;
|
||||||
|
for (size_t i = 0; i < quad_count; ++i) {
|
||||||
|
uint16_t base = i * 4;
|
||||||
|
indices.push_back(base + 0);
|
||||||
|
indices.push_back(base + 1);
|
||||||
|
indices.push_back(base + 2);
|
||||||
|
indices.push_back(base + 0);
|
||||||
|
indices.push_back(base + 2);
|
||||||
|
indices.push_back(base + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit draw call
|
||||||
|
bgfx::TransientVertexBuffer tvb;
|
||||||
|
bgfx::TransientIndexBuffer tib;
|
||||||
|
|
||||||
|
bgfx::allocTransientVertexBuffer(&tvb, batch.vertices.size(), sprite_layout);
|
||||||
|
bgfx::allocTransientIndexBuffer(&tib, indices.size());
|
||||||
|
|
||||||
|
memcpy(tvb.data, batch.vertices.data(), batch.vertices.size() * sizeof(SpriteVertex));
|
||||||
|
memcpy(tib.data, indices.data(), indices.size() * sizeof(uint16_t));
|
||||||
|
|
||||||
|
bgfx::setTexture(0, sampler, batch.texture);
|
||||||
|
bgfx::setVertexBuffer(0, &tvb);
|
||||||
|
bgfx::setIndexBuffer(&tib);
|
||||||
|
bgfx::setState(BGFX_STATE_DEFAULT);
|
||||||
|
bgfx::submit(main_view, sprite_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
batches.clear();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Module
|
||||||
|
|
||||||
|
### Config File (JSON)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"module": "RenderModule",
|
||||||
|
"window": {
|
||||||
|
"width": 1280,
|
||||||
|
"height": 720,
|
||||||
|
"title": "GroveEngine - RenderModule Test",
|
||||||
|
"fullscreen": false,
|
||||||
|
"vsync": true
|
||||||
|
},
|
||||||
|
"rendering": {
|
||||||
|
"clear_color": "#303030",
|
||||||
|
"main_view_id": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Loading Config
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void RenderModule::initialize(const IDataNode& config, IIO* io) {
|
||||||
|
WindowConfig window_config;
|
||||||
|
window_config.width = config.get("window.width", 1280);
|
||||||
|
window_config.height = config.get("window.height", 720);
|
||||||
|
window_config.title = config.get("window.title", "GroveEngine");
|
||||||
|
window_config.vsync = config.get("window.vsync", true);
|
||||||
|
|
||||||
|
InitializeWindow(window_config);
|
||||||
|
InitializeBgfx(window_config);
|
||||||
|
InitializeRenderer();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap Développement
|
||||||
|
|
||||||
|
### Phase 1 - Window + Init (Semaine 1)
|
||||||
|
|
||||||
|
**Objectif** : Window SDL2 + bgfx initialized, clear screen
|
||||||
|
|
||||||
|
- [ ] Setup SDL2 window
|
||||||
|
- [ ] Initialize bgfx avec window handle
|
||||||
|
- [ ] Clear screen avec couleur
|
||||||
|
- [ ] Main loop fonctionnel
|
||||||
|
- [ ] Event handling basique (close window)
|
||||||
|
|
||||||
|
**Livrable** : Window qui affiche fond gris, ferme proprement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 2 - Primitives 2D (Semaine 2)
|
||||||
|
|
||||||
|
**Objectif** : DrawRect fonctionnel
|
||||||
|
|
||||||
|
- [ ] Vertex layouts (ColorVertex, SpriteVertex)
|
||||||
|
- [ ] Shader compilation (color shader)
|
||||||
|
- [ ] DrawRect implementation
|
||||||
|
- [ ] Camera 2D orthographic
|
||||||
|
- [ ] Afficher 1 rectangle coloré
|
||||||
|
|
||||||
|
**Livrable** : Fenêtre avec rectangle rouge affiché
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 3 - Sprite Rendering (Semaine 3)
|
||||||
|
|
||||||
|
**Objectif** : DrawSprite fonctionnel
|
||||||
|
|
||||||
|
- [ ] Texture loading (stb_image)
|
||||||
|
- [ ] Sprite shader (vertex + fragment)
|
||||||
|
- [ ] DrawSprite implementation (batched)
|
||||||
|
- [ ] Afficher 1 sprite texturé
|
||||||
|
|
||||||
|
**Livrable** : Fenêtre avec sprite test affiché
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 4 - UI Elements (Semaine 4)
|
||||||
|
|
||||||
|
**Objectif** : Text rendering + UI primitives
|
||||||
|
|
||||||
|
- [ ] Font loading (stb_truetype ou FreeType)
|
||||||
|
- [ ] DrawText implementation
|
||||||
|
- [ ] UI element base class
|
||||||
|
- [ ] UIPanel, UIText primitives
|
||||||
|
|
||||||
|
**Livrable** : Fenêtre avec panneau UI + texte
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dépendances
|
||||||
|
|
||||||
|
### Externes (Libraries)
|
||||||
|
|
||||||
|
- **SDL2** : Window + input
|
||||||
|
- **bgfx** : Rendering abstraction
|
||||||
|
- **bx** : Base library (bgfx dependency)
|
||||||
|
- **bimg** : Image loading (bgfx dependency)
|
||||||
|
- **stb_image** : Texture loading
|
||||||
|
- **stb_truetype** ou **FreeType** : Font rendering
|
||||||
|
|
||||||
|
### GroveEngine (Internes)
|
||||||
|
|
||||||
|
- `IModule` interface
|
||||||
|
- `IDataNode` (config system)
|
||||||
|
- `IIO` (inter-module communication)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Test Case - Base Avancée
|
||||||
|
|
||||||
|
### Validation Criteria
|
||||||
|
|
||||||
|
**Window + UI 2D element = base avancée validée** si :
|
||||||
|
|
||||||
|
1. ✅ Window SDL2 créée et stable
|
||||||
|
2. ✅ bgfx initialisé et rendering fonctionnel
|
||||||
|
3. ✅ DrawRect affiche rectangle coloré
|
||||||
|
4. ✅ DrawSprite affiche sprite texturé
|
||||||
|
5. ✅ DrawText affiche texte (police)
|
||||||
|
6. ✅ UI element (panel) rendu correctement
|
||||||
|
7. ✅ Module intégré dans GroveEngine (IModule interface)
|
||||||
|
|
||||||
|
### Example Test Code
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// main.cpp
|
||||||
|
int main() {
|
||||||
|
auto engine = grove::EngineFactory::CreateDebugEngine();
|
||||||
|
|
||||||
|
auto config = LoadConfig("render_module_config.json");
|
||||||
|
engine->LoadModule("RenderModule", config);
|
||||||
|
|
||||||
|
// Game loop
|
||||||
|
while (!should_quit) {
|
||||||
|
engine->Update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dans RenderModule::update()
|
||||||
|
void RenderModule::update(float dt) {
|
||||||
|
BeginFrame();
|
||||||
|
|
||||||
|
// Test: Rectangle
|
||||||
|
DrawRect({100, 100, 200, 100}, Color{255, 0, 0, 255});
|
||||||
|
|
||||||
|
// Test: Sprite
|
||||||
|
DrawSprite(test_sprite);
|
||||||
|
|
||||||
|
// Test: UI Panel
|
||||||
|
DrawRect({50, 50, 300, 200}, Color{64, 64, 64, 200});
|
||||||
|
DrawText("Base Avancée OK!", main_font, {60, 60});
|
||||||
|
|
||||||
|
EndFrame();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Questions Ouvertes
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
|
||||||
|
1. **Text rendering** : stb_truetype (simple) ou FreeType (complet) ?
|
||||||
|
2. **Asset management** : AssetManager séparé ou intégré dans RenderModule ?
|
||||||
|
3. **Multi-window** : Support futur ou single window only ?
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
4. **Sprite batching** : Sort by texture ou sort by Z-order ?
|
||||||
|
5. **Transient buffers** : OK pour MVP ou besoin persistent buffers ?
|
||||||
|
|
||||||
|
### Integration
|
||||||
|
|
||||||
|
6. **ImGui** : Garder ImGuiUI.h existant ou remplacer par custom UI ?
|
||||||
|
7. **Hot-reload** : Shader hot-reload nécessaire ou compilation statique OK ?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ressources
|
||||||
|
|
||||||
|
### Documentation bgfx
|
||||||
|
|
||||||
|
- Repo : https://github.com/bkaradzic/bgfx
|
||||||
|
- Examples : https://github.com/bkaradzic/bgfx/tree/master/examples
|
||||||
|
- API docs : https://bkaradzic.github.io/bgfx/
|
||||||
|
|
||||||
|
### Tutorials 2D avec bgfx
|
||||||
|
|
||||||
|
- bgfx example-26 (vectordisplay)
|
||||||
|
- NanoVG-bgfx : https://github.com/memononen/nanovg
|
||||||
|
|
||||||
|
### SDL2
|
||||||
|
|
||||||
|
- Wiki : https://wiki.libsdl.org/
|
||||||
|
- Lazy Foo tutorials : https://lazyfoo.net/tutorials/SDL/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Liens Projets
|
||||||
|
|
||||||
|
- **GroveEngine core** : `Projects/WIP/GroveEngine.md`
|
||||||
|
- **GroveEngine architecture** : `Projects/WIP/grove-sup.md`
|
||||||
|
- **Aissia** (utilisateur) : `Projects/WIP/AISSIA.md`
|
||||||
|
- **Pokrovsk** (utilisateur futur) : `Projects/CONCEPT/pokrovsk_last_day.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Créé** : 26 novembre 2025
|
||||||
|
**Status** : Architecture planning
|
||||||
|
**Type** : Framework module (base avancée)
|
||||||
|
**Objectif** : Window + UI 2D rendering pour GroveEngine
|
||||||
Loading…
Reference in New Issue
Block a user