#include "Renderer.h" #include "SDL.h" #include "SDL_blendmode.h" #include "SDL_image.h" #include "SDL_platform.h" #include "SDL_rect.h" #include "SDL_render.h" #include "SDL_video.h" #include "aliases.h" #include "engine_build_config.h" #include #include #ifdef DEBUG_ENGINE #include #endif /* DEBUG_ENGINE */ struct renderer { SDL_Renderer *SDL_base_renderer; }; Renderer *create_renderer(SDL_Window *window) { Renderer *renderer = (Renderer *)malloc(sizeof(Renderer)); if (!renderer) { return NULL; } renderer->SDL_base_renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (!(renderer->SDL_base_renderer)) { destroy_renderer(&renderer); return NULL; } SDL_SetRenderDrawBlendMode(renderer->SDL_base_renderer, SDL_BLENDMODE_BLEND); return renderer; } void get_render_output_size(Renderer *renderer, i32 *w, i32 *h) { SDL_GetRendererOutputSize(renderer->SDL_base_renderer, w, h); } void set_render_draw_color(const Renderer *renderer, SDL_Color color) { SDL_SetRenderDrawColor(renderer->SDL_base_renderer, color.r, color.g, color.b, color.a); } void render_clear(const Renderer *renderer, SDL_Color color) { if (!renderer || !(renderer->SDL_base_renderer)) { return; } SDL_SetRenderDrawColor(renderer->SDL_base_renderer, color.r, color.g, color.b, color.a); SDL_RenderClear(renderer->SDL_base_renderer); } void draw_rect(const Renderer *renderer, SDL_Color color, f32 x, f32 y, f32 w, f32 h) { SDL_FRect dest = {x, y, w, h}; SDL_SetRenderDrawColor(renderer->SDL_base_renderer, color.r, color.g, color.b, color.a); SDL_RenderDrawRectF(renderer->SDL_base_renderer, &dest); } void fill_rect(const Renderer *renderer, SDL_Color color, f32 x, f32 y, f32 w, f32 h) { SDL_FRect dest = {x, y, w, h}; SDL_SetRenderDrawColor(renderer->SDL_base_renderer, color.r, color.g, color.b, color.a); SDL_RenderFillRectF(renderer->SDL_base_renderer, &dest); } void render_surface(const Renderer *renderer, SDL_Surface *surface, const RenderRect *dest) { SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer->SDL_base_renderer, surface); if (!texture) { return; } render_texture(renderer, texture, NULL, dest); SDL_DestroyTexture(texture); texture = NULL; } void render_texture(const Renderer *renderer, SDL_Texture *texture, const RenderRect *src, const RenderRect *dest) { if (!renderer || !texture || !dest) { return; } SDL_Rect src_frect; if (src) { src_frect.x = src->x; src_frect.y = src->y; src_frect.w = src->width; src_frect.h = src->height; } SDL_FRect dest_frect = {dest->x, dest->y, dest->width, dest->height}; // TODO (Abdelrahman): Look into using the SDL_RenderCopyExF instead to // support rotating the texture SDL_RenderCopyF(renderer->SDL_base_renderer, texture, src ? &src_frect : NULL, &dest_frect); } void swap_buffers(const Renderer *renderer) { if (!renderer || !(renderer->SDL_base_renderer)) { return; } SDL_RenderPresent(renderer->SDL_base_renderer); } SDL_Texture *load_texture(const Renderer *renderer, const char *path) { return IMG_LoadTexture(renderer->SDL_base_renderer, path); } void destroy_renderer(Renderer **renderer) { if (*renderer) { if ((*renderer)->SDL_base_renderer) { SDL_DestroyRenderer((*renderer)->SDL_base_renderer); (*renderer)->SDL_base_renderer = NULL; } free(*renderer); *renderer = NULL; #ifdef DEBUG_ENGINE printf("Renderer destroyed successfully\n"); #endif /* DEBUG_ENGINE */ } }