R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
RaylibGraphics.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** workspace
4** File description:
5** Raylib
6*/
7
8#include "RaylibGraphics.hpp"
9
10namespace Graphics {
11 // Constructor / Destructor
13
16 for (const Font &font : _fonts) {
17 ::UnloadFont(font);
18 }
19 for (const auto &[name, texture] : _textures) {
20 ::UnloadTexture(texture);
21 }
22 for (const auto &[name, sound] : _sounds) {
23 ::UnloadSound(sound);
24 }
27 }
28 }
29
30 // Window management
31 void RaylibGraphics::InitWindow(int width, int height, const char *title) {
32 if (!::IsWindowReady()) {
33 // Create new window
34 ::InitWindow(width, height, title);
35 // Disable default ESC exit behavior to allow custom window/menu handling
36 ::SetExitKey(0);
37 } else {
38 // Window already exists (from login), reconfigure it
39 ::SetWindowTitle(title);
40 ::SetWindowSize(width, height);
41 // Ensure this is set even if reused
42 ::SetExitKey(0);
43 }
44 _windowInitialized = true;
45 }
46
48 ::ClearBackground(_clearColor);
49 }
50
52 ::BeginDrawing();
53 }
54
56 ::EndDrawing();
57 }
58
62
64 return ::GetScreenWidth();
65 }
66
68 return ::GetScreenHeight();
69 }
70
77
78 void RaylibGraphics::SetWindowTitle(const char *title) {
79 ::SetWindowTitle(title);
80 }
81
82 void RaylibGraphics::SetWindowSize(int width, int height) {
83 ::SetWindowSize(width, height);
84 }
85
87 ::ToggleFullscreen();
88 }
89
91 ::SetTargetFPS(fps);
92 }
93
94 void RaylibGraphics::SetClearColor(unsigned int color) {
95 _clearColor.a = (color >> 24) & 0xFF;
96 _clearColor.r = (color >> 16) & 0xFF;
97 _clearColor.g = (color >> 8) & 0xFF;
98 _clearColor.b = color & 0xFF;
99 }
100
101 void RaylibGraphics::TakeScreenshot(const char *filepath) {
102 ::TakeScreenshot(filepath);
103 }
104
105 // Time / profiling
107 return ::GetTime();
108 }
109
111 return ::GetFrameTime();
112 }
113
114 // Basic drawing primitives
115 void RaylibGraphics::DrawRect(int x, int y, int width, int height, unsigned int color) {
116 Color clr;
117 clr.a = (color >> 24) & 0xFF;
118 clr.r = (color >> 16) & 0xFF;
119 clr.g = (color >> 8) & 0xFF;
120 clr.b = color & 0xFF;
121 ::DrawRectangleLines(x, y, width, height, clr);
122 }
123
124 void RaylibGraphics::DrawRectFilled(int x, int y, int width, int height, unsigned int color) {
125 Color clr;
126 clr.a = (color >> 24) & 0xFF;
127 clr.r = (color >> 16) & 0xFF;
128 clr.g = (color >> 8) & 0xFF;
129 clr.b = color & 0xFF;
130 ::DrawRectangle(x, y, width, height, clr);
131 }
132
133 void RaylibGraphics::DrawCircle(int x, int y, int radius, unsigned int color) {
134 Color clr;
135 clr.a = (color >> 24) & 0xFF;
136 clr.r = (color >> 16) & 0xFF;
137 clr.g = (color >> 8) & 0xFF;
138 clr.b = color & 0xFF;
139 ::DrawCircleLines(x, y, radius, clr);
140 }
141
142 void RaylibGraphics::DrawCircleFilled(int x, int y, int radius, unsigned int color) {
143 Color clr;
144 clr.a = (color >> 24) & 0xFF;
145 clr.r = (color >> 16) & 0xFF;
146 clr.g = (color >> 8) & 0xFF;
147 clr.b = color & 0xFF;
148 ::DrawCircle(x, y, radius, clr);
149 }
150 // Fonts / text
151 int RaylibGraphics::LoadFont(const char *filepath, int size) {
152 Font font = ::LoadFontEx(filepath, size, 0, 0);
153 if (font.texture.id == 0)
154 return -1;
155 _fonts.push_back(font);
156 return _fonts.size() - 1;
157 }
158
159 void RaylibGraphics::UnloadFont(int fontHandle) {
160 if (fontHandle >= 0 && static_cast<size_t>(fontHandle) < _fonts.size()) {
161 ::UnloadFont(_fonts[fontHandle]);
162 }
163 }
164
165 void RaylibGraphics::DrawText(int fontHandle, const char *text, int x, int y, int fontSize,
166 unsigned int color) {
167 Color clr;
168 clr.a = (color >> 24) & 0xFF;
169 clr.r = (color >> 16) & 0xFF;
170 clr.g = (color >> 8) & 0xFF;
171 clr.b = color & 0xFF;
172
173 if (fontHandle >= 0 && static_cast<size_t>(fontHandle) < _fonts.size()) {
174 ::DrawTextEx(_fonts[fontHandle], text, {(float)x, (float)y}, fontSize, 1.0f, clr);
175 return;
176 } else
177 ::DrawText(text, x, y, fontSize, clr);
178 }
179
180 int RaylibGraphics::GetFontHeight(int fontHandle, int fontSize) {
181 if (fontHandle >= 0 && static_cast<size_t>(fontHandle) < _fonts.size()) {
182 return _fonts[fontHandle].baseSize;
183 }
184 return fontSize;
185 }
186
187 // Textures / sprites / images
188 int RaylibGraphics::LoadTexture(const char *textureName, const char *filepath) {
189 Texture2D texture = ::LoadTexture(filepath);
190 if (texture.id == 0)
191 return -1;
192 _textures[textureName] = texture;
193 return 0;
194 }
195
196 int RaylibGraphics::CreateTextureFromMemory(const char *textureName, const void *pixels, int width,
197 int height, int format) {
198 Image img;
199 img.data = const_cast<void *>(pixels);
200 img.width = width;
201 img.height = height;
202 img.format = format;
203 img.mipmaps = 1;
204 Texture2D texture = ::LoadTextureFromImage(img);
205 if (texture.id == 0)
206 return -1;
207 _textures[textureName] = texture;
208 return 0;
209 }
210
211 void RaylibGraphics::UpdateTexture(const char *textureName, const void *pixels) {
212 auto iter = _textures.find(textureName);
213 if (iter != _textures.end()) {
214 ::UpdateTexture(iter->second, pixels);
215 }
216 }
217
218 void RaylibGraphics::UnloadTexture(const char *textureName) {
219 auto iter = _textures.find(textureName);
220 if (iter != _textures.end()) {
221 ::UnloadTexture(iter->second);
222 _textures.erase(iter);
223 }
224 }
225
226 void RaylibGraphics::DrawTexture(const char *textureName, int xPos, int yPos, unsigned int tint) {
227 auto iter = _textures.find(textureName);
228 if (iter != _textures.end()) {
229 Color clr;
230 clr.a = (tint >> 24) & 0xFF;
231 clr.r = (tint >> 16) & 0xFF;
232 clr.g = (tint >> 8) & 0xFF;
233 clr.b = tint & 0xFF;
234 ::DrawTexture(iter->second, xPos, yPos, clr);
235 }
236 }
237
238 void RaylibGraphics::DrawTextureEx(const char *textureName, int srcX, int srcY, int srcW, int srcH,
239 float destX, float destY, float rotation, float scale,
240 unsigned int tint) {
241 auto iter = _textures.find(textureName);
242 if (iter != _textures.end()) {
243 Color clr;
244 clr.a = (tint >> 24) & 0xFF;
245 clr.r = (tint >> 16) & 0xFF;
246 clr.g = (tint >> 8) & 0xFF;
247 clr.b = tint & 0xFF;
248
249 Rectangle source = {(float)srcX, (float)srcY, (float)srcW, (float)srcH};
250 Rectangle dest = {destX, destY, (float)srcW * scale, (float)srcH * scale};
251 Vector2 origin = {0, 0};
252
253 ::DrawTexturePro(iter->second, source, dest, origin, rotation, clr);
254 } else {
255 // DEBUG: Texture not found - fallback to colored rectangle
256 TraceLog(LOG_WARNING, "DrawTextureEx: Texture '%s' not found! Drawing fallback rectangle",
257 textureName);
258 ::DrawRectangle((int)destX, (int)destY, (int)(srcW * scale), (int)(srcH * scale), BLUE);
259 }
260 }
261
262 bool RaylibGraphics::GetTextureSize(const char *textureName, int &width, int &height) const {
263 auto iter = _textures.find(textureName);
264 if (iter != _textures.end()) {
265 width = iter->second.width;
266 height = iter->second.height;
267 return true;
268 }
269 return false;
270 }
271
272 void RaylibGraphics::DrawTexturePro(const char *textureName, int srcX, int srcY, int srcW, int srcH,
273 float destX, float destY, float destW, float destH,
274 unsigned int tint) {
275 auto iter = _textures.find(textureName);
276 if (iter != _textures.end()) {
277 Color clr;
278 clr.a = (tint >> 24) & 0xFF;
279 clr.r = (tint >> 16) & 0xFF;
280 clr.g = (tint >> 8) & 0xFF;
281 clr.b = tint & 0xFF;
282
283 Rectangle source = {static_cast<float>(srcX), static_cast<float>(srcY), static_cast<float>(srcW),
284 static_cast<float>(srcH)};
285 Rectangle dest = {destX, destY, destW, destH};
286 Vector2 origin = {0, 0};
287
288 ::DrawTexturePro(iter->second, source, dest, origin, 0.0f, clr);
289 }
290 }
291
292 // Input helpers
293 bool RaylibGraphics::IsKeyPressed(int key) const {
294 return ::IsKeyPressed(key);
295 }
296
297 bool RaylibGraphics::IsKeyDown(int key) const {
298 return ::IsKeyDown(key);
299 }
300
301 bool RaylibGraphics::IsKeyReleased(int key) const {
302 return ::IsKeyReleased(key);
303 }
304
305 bool RaylibGraphics::IsGamepadAvailable(int gamepad) const {
306 return ::IsGamepadAvailable(gamepad);
307 }
308
309 bool RaylibGraphics::IsGamepadButtonPressed(int gamepad, int button) const {
310 return ::IsGamepadButtonPressed(gamepad, button);
311 }
312
313 bool RaylibGraphics::IsGamepadButtonDown(int gamepad, int button) const {
314 return ::IsGamepadButtonDown(gamepad, button);
315 }
316
317 float RaylibGraphics::GetGamepadAxisMovement(int gamepad, int axis) const {
318 return ::GetGamepadAxisMovement(gamepad, axis);
319 }
320
322 return ::IsMouseButtonPressed(button);
323 }
324
325 bool RaylibGraphics::IsMouseButtonDown(int button) const {
326 return ::IsMouseButtonDown(button);
327 }
328
329 void RaylibGraphics::GetMousePosition(float &x, float &y) const {
330 Vector2 pos = ::GetMousePosition();
331 x = pos.x;
332 y = pos.y;
333 }
334
336 if (!_windowInitialized) {
337 return false;
338 }
339 return ::WindowShouldClose();
340 }
341
343 return ::GetMouseX();
344 }
345
347 return ::GetMouseY();
348 }
349
351 return ::GetCharPressed();
352 }
353
355 return ::GetScreenWidth();
356 }
357
359 return ::GetScreenHeight();
360 }
361
362 void RaylibGraphics::DrawRectangle(int x, int y, int width, int height, unsigned int color) {
363 Color clr;
364 clr.a = (color >> 24) & 0xFF;
365 clr.r = (color >> 16) & 0xFF;
366 clr.g = (color >> 8) & 0xFF;
367 clr.b = color & 0xFF;
368 ::DrawRectangle(x, y, width, height, clr);
369 }
370
371 void RaylibGraphics::DrawRectangleLines(int x, int y, int width, int height, unsigned int color) {
372 Color clr;
373 clr.a = (color >> 24) & 0xFF;
374 clr.r = (color >> 16) & 0xFF;
375 clr.g = (color >> 8) & 0xFF;
376 clr.b = color & 0xFF;
377 ::DrawRectangleLines(x, y, width, height, clr);
378 }
379
380 void RaylibGraphics::DrawText(const char *text, int x, int y, int fontSize, unsigned int color) {
381 Color clr;
382 clr.a = (color >> 24) & 0xFF;
383 clr.r = (color >> 16) & 0xFF;
384 clr.g = (color >> 8) & 0xFF;
385 clr.b = color & 0xFF;
386 ::DrawText(text, x, y, fontSize, clr);
387 }
388
389 // ========== Colorblind Filter Implementation ==========
390
393 return;
394 }
395
396 // Load shader from files
397 _colorblindShader = ::LoadShader("assets/shaders/colorblind.vs", "assets/shaders/colorblind.fs");
398
399 if (_colorblindShader.id == 0) {
400 // Shader failed to load, fall back to no filtering
401 return;
402 }
403
404 // Get uniform location for filter type
405 _filterTypeLoc = ::GetShaderLocation(_colorblindShader, "filterType");
406
407 // Create render texture for post-processing
408 int width = ::GetScreenWidth();
409 int height = ::GetScreenHeight();
410 _colorblindRenderTexture = ::LoadRenderTexture(width, height);
411
413 }
414
417 return;
418 }
419
420 ::UnloadShader(_colorblindShader);
421 ::UnloadRenderTexture(_colorblindRenderTexture);
423 }
424
426 _colorblindFilter = filter;
427
428 // Load shader if needed and filter is not NONE
431 }
432 }
433
437
440 return;
441 }
442
443 // Check if render texture needs resizing
444 int width = ::GetScreenWidth();
445 int height = ::GetScreenHeight();
446 if (_colorblindRenderTexture.texture.width != width ||
447 _colorblindRenderTexture.texture.height != height) {
448 ::UnloadRenderTexture(_colorblindRenderTexture);
449 _colorblindRenderTexture = ::LoadRenderTexture(width, height);
450 }
451
452 // Begin rendering to texture
453 ::BeginTextureMode(_colorblindRenderTexture);
454 ::ClearBackground(_clearColor);
455 }
456
459 return;
460 }
461
462 // End rendering to texture
463 ::EndTextureMode();
464
465 // Set filter type uniform
466 int filterValue = static_cast<int>(_colorblindFilter);
467 ::SetShaderValue(_colorblindShader, _filterTypeLoc, &filterValue, SHADER_UNIFORM_INT);
468
469 // Draw the render texture with shader applied
470 ::BeginShaderMode(_colorblindShader);
471
472 // Draw flipped because render textures are flipped in OpenGL
473 Rectangle sourceRec = {0.0f, 0.0f, static_cast<float>(_colorblindRenderTexture.texture.width),
474 static_cast<float>(-_colorblindRenderTexture.texture.height)};
475 Rectangle destRec = {0.0f, 0.0f, static_cast<float>(::GetScreenWidth()),
476 static_cast<float>(::GetScreenHeight())};
477 Vector2 origin = {0.0f, 0.0f};
478
479 ::DrawTexturePro(_colorblindRenderTexture.texture, sourceRec, destRec, origin, 0.0f, WHITE);
480
481 ::EndShaderMode();
482 }
483
484 // Audio management
491
493 if (_audioInitialized) {
494 for (const auto &[name, sound] : _sounds) {
495 ::UnloadSound(sound);
496 }
497 _sounds.clear();
499 _audioInitialized = false;
500 }
501 }
502
506
507 bool RaylibGraphics::LoadSound(const char *soundName, const char *filepath) {
508 if (!_audioInitialized) {
509 return false;
510 }
511 Sound sound = ::LoadSound(filepath);
512 if (sound.frameCount == 0) {
513 return false;
514 }
515 _sounds[soundName] = sound;
516 return true;
517 }
518
519 void RaylibGraphics::UnloadSound(const char *soundName) {
520 auto iter = _sounds.find(soundName);
521 if (iter != _sounds.end()) {
522 ::UnloadSound(iter->second);
523 _sounds.erase(iter);
524 }
525 }
526
527 void RaylibGraphics::PlaySound(const char *soundName) {
528 auto iter = _sounds.find(soundName);
529 if (iter != _sounds.end()) {
530 ::PlaySound(iter->second);
531 }
532 }
533
534 void RaylibGraphics::SetSoundVolume(const char *soundName, float volume) {
535 auto iter = _sounds.find(soundName);
536 if (iter != _sounds.end()) {
537 ::SetSoundVolume(iter->second, volume);
538 }
539 }
540
541 bool RaylibGraphics::IsSoundPlaying(const char *soundName) const {
542 auto iter = _sounds.find(soundName);
543 if (iter != _sounds.end()) {
544 return ::IsSoundPlaying(iter->second);
545 }
546 return false;
547 }
548} // namespace Graphics
#define LOG_WARNING(...)
Definition Logger.hpp:182
void SetClearColor(unsigned int color) override
Set the background clear color.
void DrawRectangle(int x, int y, int width, int height, unsigned int color) override
Draw a filled rectangle (alias for DrawRectFilled)
float GetDeltaTime() const override
Get the time elapsed for the last frame.
void DrawRectFilled(int x, int y, int width, int height, unsigned int color) override
Draw a filled rectangle.
int GetMouseX() const override
Get the current X position of the mouse cursor.
void DisplayWindow() override
Display the current frame to the window (end drawing and swap buffers)
void DrawTextureEx(const char *textureName, int srcX, int srcY, int srcW, int srcH, float destX, float destY, float rotation, float scale, unsigned int tint) override
Draw a texture with advanced parameters (rotation, scale, source rectangle)
bool IsKeyPressed(int key) const override
Check if a key was pressed (triggered once when key goes down)
int GetMouseY() const override
Get the current Y position of the mouse cursor.
bool IsKeyDown(int key) const override
Check if a key is currently being held down.
void DrawRect(int x, int y, int width, int height, unsigned int color) override
Draw a rectangle outline.
void DrawCircleFilled(int x, int y, int radius, unsigned int color) override
Draw a filled circle.
bool GetTextureSize(const char *textureName, int &width, int &height) const override
Get the dimensions of a loaded texture.
int LoadFont(const char *filepath, int size) override
Load a font from file.
void UnloadTexture(const char *textureName) override
Unload a previously loaded texture.
void CloseWindow() override
Close the graphics window and cleanup resources.
bool WindowShouldClose() const override
Check if the window should close.
ColorblindFilterType _colorblindFilter
void SetTargetFPS(int fps) override
Set the target frames per second for rendering.
bool IsSoundPlaying(const char *soundName) const override
Check if a sound is currently playing.
void SetSoundVolume(const char *soundName, float volume) override
Set volume for a specific sound.
std::unordered_map< std::string, Texture2D > _textures
int GetFontHeight(int fontHandle, int fontSize) override
Get the height of a font at a given size.
bool IsMouseButtonPressed(int button) const override
Check if a mouse button was pressed (triggered once when button goes down)
void BeginColorblindCapture() override
Begin capturing frame for colorblind filter processing.
int CreateTextureFromMemory(char const *textureName, const void *pixels, int width, int height, int format) override
Create a texture from raw pixel data in memory.
ColorblindFilterType GetColorblindFilter() const override
Get the current colorblind filter type.
float GetGamepadAxisMovement(int gamepad, int axis) const override
Get gamepad axis value (for analog sticks and triggers)
void DrawTexturePro(const char *textureName, int srcX, int srcY, int srcW, int srcH, float destX, float destY, float destW, float destH, unsigned int tint) override
Draw a texture with separate width/height scaling (for non-uniform scaling)
void SetWindowTitle(const char *title) override
Change the window title.
void SetColorblindFilter(ColorblindFilterType filter) override
Set the colorblind filter type.
int GetCharPressed() const override
Get the next character from the keyboard input queue.
void DrawRectangleLines(int x, int y, int width, int height, unsigned int color) override
Draw a rectangle outline (alias for DrawRect)
bool IsAudioDeviceReady() const override
Check if audio device is ready.
void StartDrawing() override
Begin drawing frame (setup canvas for drawing operations)
void ClearWindow() override
Clear the window with the current clear color.
bool IsGamepadAvailable(int gamepad) const override
Check if a gamepad is available/connected.
void SetWindowSize(int width, int height) override
Resize the window.
int GetWindowHeight() const override
Get current window height in pixels.
void UpdateTexture(const char *textureName, const void *pixels) override
Update an existing texture with new pixel data.
void DrawText(int fontHandle, const char *text, int x, int y, int fontSize, unsigned int color) override
Draw text using a loaded font.
void ToggleFullScreen() override
Toggle between fullscreen and windowed mode.
void CloseAudioDevice() override
Close the audio device and cleanup audio resources.
bool IsGamepadButtonPressed(int gamepad, int button) const override
Check if a gamepad button was pressed this frame.
bool IsMouseButtonDown(int button) const override
Check if a mouse button is currently being held down.
RaylibGraphics()
Construct a new Raylib graphics object.
std::vector< Font > _fonts
bool LoadSound(const char *soundName, const char *filepath) override
Load a sound from file.
bool IsKeyReleased(int key) const override
Check if a key was released (triggered once when key goes up)
bool IsWindowOpen() const override
Check if the window is still open.
int GetWindowWidth() const override
Get current window width in pixels.
void DrawCircle(int x, int y, int radius, unsigned int color) override
Draw a circle outline.
std::unordered_map< std::string, Sound > _sounds
void InitAudioDevice() override
Initialize the audio device.
void InitWindow(int width, int height, const char *title) override
Initialize the graphics window.
void UnloadFont(int fontHandle) override
Unload a previously loaded font.
RenderTexture2D _colorblindRenderTexture
void DrawTexture(const char *textureName, int x, int y, unsigned int tint) override
Draw a texture at the specified position.
int GetScreenWidth() const override
Get the screen width (same as window width)
void UnloadSound(const char *soundName) override
Unload a previously loaded sound.
void GetMousePosition(float &x, float &y) const override
Get the current mouse cursor position.
int GetScreenHeight() const override
Get the screen height (same as window height)
void TakeScreenshot(const char *filepath) override
Capture the current screen and save it to a file.
void EndColorblindCapture() override
End capturing and apply the colorblind filter.
float GetTime() const override
Get elapsed time since initialization.
~RaylibGraphics() override
Destroy the Raylib graphics object and cleanup resources.
bool IsGamepadButtonDown(int gamepad, int button) const override
Check if a gamepad button is currently held down.
int LoadTexture(const char *name, const char *filepath) override
Load a texture from an image file.
void PlaySound(const char *soundName) override
Play a loaded sound.
ColorblindFilterType
Colorblind filter types for accessibility.
Definition IGraphics.hpp:15
@ NONE
No filter applied.