diff --git a/include/arc/graphics/renderer.h b/include/arc/graphics/renderer.h index e5f7ab4..c7b6f21 100644 --- a/include/arc/graphics/renderer.h +++ b/include/arc/graphics/renderer.h @@ -5,22 +5,21 @@ extern "C" { #endif +#include + /** * @brief predefien ARC_EngineData so as not to get circular reference */ typedef struct ARC_EngineData ARC_EngineData; /** - * @note ARC_RendererType is determined by which window library you are using + * @note ARC_RendererType is determined by which window backend you are using */ typedef struct ARC_RendererType ARC_Renderer; /** * @brief creates ARC_Renderer type with ARC_EngineData * - * @note the parameter data is determined by which graphics library you are using - * please refer to the graphics library section to see what needs to be passed - * * @param renderer ARC_Renderer to initialize * @param data the engine data to create from */ @@ -43,12 +42,48 @@ void ARC_Renderer_Clear(ARC_Renderer *renderer); /** * @brief renders the renderer * - * @note the renderer will most likely be drawn to from ARC_EngineData - * - * @param renderer the renderer to render + * @param renderer renders all buffers and current renderer to window */ void ARC_Renderer_Render(ARC_Renderer *renderer); +/** + * @brief + * + * @param renderer + * @param zIndex +*/ +void ARC_Renderer_InitBuffer(ARC_Renderer *renderer, uint32_t zIndex); + +/** + * @brief + * + * @param renderer + * @param zIndex +*/ +void ARC_Renderer_RemoveBuffer(ARC_Renderer *renderer, uint32_t zIndex); + +/** + * @brief + * + * @param renderer +*/ +void ARC_Renderer_ClearBuffers(ARC_Renderer *renderer); + +/** + * @brief + * + * @param renderer + * @param zIndex +*/ +void ARC_Renderer_SetCurrentBuffer(ARC_Renderer *renderer, uint32_t zIndex); + +/** + * @brief + * + * @param renderer +*/ +void ARC_Renderer_UnsetBuffer(ARC_Renderer *renderer); + #ifdef __cplusplus } #endif diff --git a/packages/graphics/sdl3/line.c b/packages/graphics/sdl3/line.c index 6035a4c..12ea67e 100644 --- a/packages/graphics/sdl3/line.c +++ b/packages/graphics/sdl3/line.c @@ -2,6 +2,6 @@ #include "renderer.h" void ARC_Line_Render(ARC_Point point1, ARC_Point point2, ARC_Renderer *renderer, ARC_Color color){ - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); - SDL_RenderLine((SDL_Renderer *)renderer, point1.x, point1.y, point2.x, point2.y); + SDL_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a); + SDL_RenderLine(renderer->renderer, point1.x, point1.y, point2.x, point2.y); } diff --git a/packages/graphics/sdl3/rectangle.c b/packages/graphics/sdl3/rectangle.c index cc51480..2837483 100644 --- a/packages/graphics/sdl3/rectangle.c +++ b/packages/graphics/sdl3/rectangle.c @@ -13,11 +13,11 @@ void ARC_Rect_RenderFill(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color) } void ARC_FRect_Render(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); - SDL_RenderRect((SDL_Renderer *)renderer, (SDL_FRect *)&rect); + SDL_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a); + SDL_RenderRect(renderer->renderer, (SDL_FRect *)&rect); } void ARC_FRect_RenderFill(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); - SDL_RenderFillRect((SDL_Renderer *)renderer, (SDL_FRect *)&rect); + SDL_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a); + SDL_RenderFillRect(renderer->renderer, (SDL_FRect *)&rect); } diff --git a/packages/graphics/sdl3/renderer.c b/packages/graphics/sdl3/renderer.c index a4d6e2c..01f7005 100644 --- a/packages/graphics/sdl3/renderer.c +++ b/packages/graphics/sdl3/renderer.c @@ -5,8 +5,22 @@ #include #include "arc/engine/engine.h" #include "arc/graphics/window.h" +#include "arc/std/bool.h" #include "arc/std/errno.h" +uint32_t ARC_Renderer_BuffersHashtableHashFn(void *key){ + return *(uint32_t *)key; +} + +ARC_Bool ARC_Renderer_BuffersHashtableKeyCompareFn(void *key1, void *key2){ + return (ARC_Bool)(*(uint32_t *)key1 == *(uint32_t *)key2); +} + +void ARC_Renderer_BuffersHashtableDestroy(void *key, void *value){ + free((uint32_t *)key); + SDL_DestroyTexture(value); +} + void ARC_Renderer_CreateWithEngineData(ARC_Renderer **renderer, ARC_EngineData *data){ if(!data){ arc_errno = ARC_ERRNO_NULL; @@ -14,26 +28,93 @@ void ARC_Renderer_CreateWithEngineData(ARC_Renderer **renderer, ARC_EngineData * return; } - *renderer = (ARC_Renderer *)SDL_CreateRenderer((SDL_Window *)(data->window), NULL); + *renderer = (ARC_Renderer *)malloc(sizeof(ARC_Renderer)); - if(!*renderer){ + /* ~ Renderer ~ */ + (*renderer)->renderer = SDL_CreateRenderer((SDL_Window *)(data->window), NULL); + + if((*renderer)->renderer == NULL){ arc_errno = ARC_ERRNO_NULL; ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateRenderer(%p, NULL);", data->window); free(renderer); + return; } - SDL_SetRenderDrawBlendMode((SDL_Renderer *)*renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawBlendMode((*renderer)->renderer, SDL_BLENDMODE_BLEND); + + /* ~ Buffers ~ */ + ARC_Hashtable_HashFn hashFn = ARC_Renderer_BuffersHashtableHashFn; + ARC_Hashtable_KeyCompareFn keyCompareFn = ARC_Renderer_BuffersHashtableKeyCompareFn; + ARC_Hashtable_DestroyKeyValueFn destroyKeyValueFn = ARC_Renderer_BuffersHashtableDestroy; + ARC_Hashtable_Create(&((*renderer)->buffers), &hashFn, &keyCompareFn, &destroyKeyValueFn); + + /* ~ Clear Color ~ */ + (*renderer)->clearColor = (ARC_Color){ 0x1c, 0x2c, 0x3c, 0xff }; } void ARC_Renderer_Destroy(ARC_Renderer *renderer){ - SDL_DestroyRenderer((SDL_Renderer *) renderer); + ARC_Hashtable_Destroy(renderer->buffers); + SDL_DestroyRenderer(renderer->renderer); + free(renderer); } void ARC_Renderer_Clear(ARC_Renderer *renderer){ - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, 0x1c, 0x2c, 0x3c, 0xff); - SDL_RenderClear((SDL_Renderer *)renderer); + SDL_SetRenderTarget(renderer->renderer, NULL); + SDL_SetRenderDrawColor(renderer->renderer, renderer->clearColor.r, renderer->clearColor.g, renderer->clearColor.b, renderer->clearColor.a); + SDL_RenderClear(renderer->renderer); } void ARC_Renderer_Render(ARC_Renderer *renderer){ - SDL_RenderPresent((SDL_Renderer *)renderer); + SDL_RenderPresent(renderer->renderer); +} + +void ARC_Renderer_InitBuffer(ARC_Renderer *renderer, uint32_t zIndex){ + SDL_Texture *buffer = (SDL_Texture *)ARC_Hashtable_Get(renderer->buffers, &zIndex); + if(buffer != NULL){ + //buffer was already created, do nothing + return; + } + + SDL_Rect viewPort = { 0, 0, 0, 0 }; + + SDL_GetRenderViewport(renderer->renderer, &viewPort); + + buffer = SDL_CreateTexture(renderer->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, viewPort.w - viewPort.x, viewPort.h - viewPort.y); + + uint32_t *index = (uint32_t *)malloc(sizeof(uint32_t)); + *index = zIndex; + ARC_Hashtable_Add(renderer->buffers, index, buffer); +} + +void ARC_Renderer_RemoveBuffer(ARC_Renderer *renderer, uint32_t zIndex){ + ARC_Hashtable_Remove(renderer->buffers, &zIndex); +} + +//private function to iterate and clear each available buffer +void ARC_Renderer_BuffersHashtableClearIteratorFn(void *key, void *value, void *userData){ + ARC_Renderer *renderer = (ARC_Renderer *)userData; + + SDL_Texture *buffer = (SDL_Texture *)value; + + SDL_SetRenderTarget(renderer->renderer, buffer); + SDL_SetRenderDrawColor(renderer->renderer, 0x00, 0x00, 0x00, 0x00); + SDL_RenderClear(renderer->renderer); +} + +void ARC_Renderer_ClearBuffers(ARC_Renderer *renderer){ + ARC_Hashtable_RunIteration(renderer->buffers, ARC_Renderer_BuffersHashtableClearIteratorFn, (void *)renderer); +} + +void ARC_Renderer_SetCurrentBuffer(ARC_Renderer *renderer, uint32_t zIndex){ + SDL_Texture *buffer = (SDL_Texture *)ARC_Hashtable_Get(renderer->buffers, &zIndex); + SDL_SetRenderTarget(renderer->renderer, buffer); + + if(buffer != NULL){ + //TODO: probs throw an error + return; + } +} + +void ARC_Renderer_UnsetBuffer(ARC_Renderer *renderer){ + SDL_SetRenderTarget(renderer->renderer, NULL); } diff --git a/packages/graphics/sdl3/renderer.h b/packages/graphics/sdl3/renderer.h index 2609e6b..423f931 100644 --- a/packages/graphics/sdl3/renderer.h +++ b/packages/graphics/sdl3/renderer.h @@ -1,10 +1,18 @@ #ifndef ARC_SDL_RENDERER_H_ #define ARC_SDL_RENDERER_H_ +#include "arc/graphics/color.h" #include "arc/graphics/renderer.h" #include "arc/graphics/window.h" +#include "arc/std/hashtable.h" #include -typedef SDL_Renderer ARC_RendererType; +typedef struct ARC_RendererType { + SDL_Renderer *renderer; + + ARC_Hashtable *buffers; + + ARC_Color clearColor; +} ARC_RendererType; #endif // !ARC_SDL_RENDERER_H_ diff --git a/packages/graphics/sdl3/sprite.c b/packages/graphics/sdl3/sprite.c index 397de3a..c07a4b7 100644 --- a/packages/graphics/sdl3/sprite.c +++ b/packages/graphics/sdl3/sprite.c @@ -1,5 +1,6 @@ #include "arc/graphics/sprite.h" +#include "renderer.h" #include "spritesheet.h" #include "arc/math/point.h" #include "arc/math/rectangle.h" @@ -41,7 +42,7 @@ void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite){ } void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FRect renderBounds){ - SDL_RenderTexture((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)(sprite->frames.data + sprite->frameIndex), (SDL_FRect *)&renderBounds); + SDL_RenderTexture(renderer->renderer, sprite->spritesheet->texture, (SDL_FRect *)(sprite->frames.data + sprite->frameIndex), (SDL_FRect *)&renderBounds); } void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint point, double scale){ @@ -64,7 +65,7 @@ void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint flip |= SDL_FLIP_VERTICAL; } - SDL_RenderTextureRotated((SDL_Renderer *)renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, sprite->angle, (SDL_FPoint *)&(sprite->origin), flip); + SDL_RenderTextureRotated(renderer->renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, sprite->angle, (SDL_FPoint *)&(sprite->origin), flip); } void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ diff --git a/packages/graphics/sdl3/spritesheet.c b/packages/graphics/sdl3/spritesheet.c index 6bca7ac..82e005e 100644 --- a/packages/graphics/sdl3/spritesheet.c +++ b/packages/graphics/sdl3/spritesheet.c @@ -28,7 +28,7 @@ void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer //set the texture SDL_BlendMode tempMode; SDL_GetSurfaceBlendMode(surface, &tempMode); - (*spritesheet)->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); + (*spritesheet)->texture = SDL_CreateTextureFromSurface(renderer->renderer, surface); SDL_SetTextureBlendMode((*spritesheet)->texture, tempMode); SDL_SetTextureScaleMode((*spritesheet)->texture, SDL_SCALEMODE_NEAREST); @@ -45,12 +45,12 @@ void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ } void ARC_Spritesheet_Render(ARC_Spritesheet *spritesheet, ARC_Renderer *renderer, ARC_FRect renderBounds){ - SDL_RenderTexture((SDL_Renderer *)renderer, spritesheet->texture, NULL, (SDL_FRect *)&renderBounds); + SDL_RenderTexture(renderer->renderer, spritesheet->texture, NULL, (SDL_FRect *)&renderBounds); } void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_FRect renderBounds){ ARC_FRect bounds = ARC_Rect_CastToFRect(sheetBounds); - SDL_RenderTexture((SDL_Renderer *)renderer, spritesheet->texture, (SDL_FRect *)&bounds, (SDL_FRect *)&renderBounds); + SDL_RenderTexture(renderer->renderer, spritesheet->texture, (SDL_FRect *)&bounds, (SDL_FRect *)&renderBounds); } void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_FRect renderBounds){ @@ -70,7 +70,7 @@ void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosi }; //render the bounds - SDL_RenderTexture((SDL_Renderer *)renderer, spritesheet->texture, (SDL_FRect *)&sheetBounds, (SDL_FRect *)&renderBounds); + SDL_RenderTexture(renderer->renderer, spritesheet->texture, (SDL_FRect *)&sheetBounds, (SDL_FRect *)&renderBounds); } ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ diff --git a/packages/graphics/sdl3/text.c b/packages/graphics/sdl3/text.c index d87ed08..39fdf16 100644 --- a/packages/graphics/sdl3/text.c +++ b/packages/graphics/sdl3/text.c @@ -1,6 +1,7 @@ #include "arc/graphics/text.h" #include "text.h" +#include "renderer.h" #include "arc/graphics/color.h" #include "arc/math/point.h" #include "arc/math/rectangle.h" @@ -45,7 +46,7 @@ void ARC_Text_SetString(ARC_Text *text, ARC_Renderer *renderer, ARC_String *stri if(text->texture){ SDL_DestroyTexture(text->texture); } - text->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); + text->texture = SDL_CreateTextureFromSurface(renderer->renderer, surface); SDL_DestroySurface(surface); TTF_CloseFont(ttfont); @@ -57,7 +58,7 @@ void ARC_Text_Render(ARC_Text *text, ARC_Renderer *renderer){ } SDL_FRect bounds = (SDL_FRect){ text->bounds.x, text->bounds.y, text->bounds.w, text->bounds.h }; - SDL_RenderTexture((SDL_Renderer *)renderer, text->texture, NULL, &bounds); + SDL_RenderTexture(renderer->renderer, text->texture, NULL, &bounds); } void ARC_Text_SetPos(ARC_Text *text, ARC_Point pos){ diff --git a/packages/graphics/sdl3/view.c b/packages/graphics/sdl3/view.c index b581e10..135b125 100644 --- a/packages/graphics/sdl3/view.c +++ b/packages/graphics/sdl3/view.c @@ -1,7 +1,7 @@ #include "arc/graphics/view.h" #include "arc/std/errno.h" -#include +#include #include void ARC_View_Create(ARC_View **view, ARC_Renderer *renderer, ARC_Rect bounds){ @@ -15,21 +15,21 @@ void ARC_View_Destroy(ARC_View *view){ } void ARC_View_Render(ARC_View *view, ARC_View_RenderFn renderFn, void *data){ - int err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, (const SDL_Rect *)&(view->bounds)); - if(err){ - ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, renderFn), SDL_RenderSetViewport(...) returned: %d", err); - return; - } - - renderFn(data); - - err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, NULL); - if(err){ - ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, NULL), SDL_RenderSetViewport(...) returned: %d", err); - return; - } +// int err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, (const SDL_Rect *)&(view->bounds)); +// if(err){ +// ARC_DEBUG_LOG_ERROR(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, renderFn), SDL_RenderSetViewport(...) returned: %d", err); +// return; +// } +// +// renderFn(data); +// +// err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, NULL); +// if(err){ +// ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, NULL), SDL_RenderSetViewport(...) returned: %d", err); +// return; +// } } ARC_Rect ARC_View_GetBounds(ARC_View *view){ return view->bounds; -} \ No newline at end of file +}