added buffer system and fixed rendering functions

This commit is contained in:
herbglitch 2025-04-04 03:45:53 -06:00
parent 5a9d7ca07d
commit 017629872f
9 changed files with 170 additions and 44 deletions

View file

@ -5,22 +5,21 @@
extern "C" { extern "C" {
#endif #endif
#include <stdint.h>
/** /**
* @brief predefien ARC_EngineData so as not to get circular reference * @brief predefien ARC_EngineData so as not to get circular reference
*/ */
typedef struct ARC_EngineData ARC_EngineData; 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; typedef struct ARC_RendererType ARC_Renderer;
/** /**
* @brief creates ARC_Renderer type with ARC_EngineData * @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 renderer ARC_Renderer to initialize
* @param data the engine data to create from * @param data the engine data to create from
*/ */
@ -43,12 +42,48 @@ void ARC_Renderer_Clear(ARC_Renderer *renderer);
/** /**
* @brief renders the renderer * @brief renders the renderer
* *
* @note the renderer will most likely be drawn to from ARC_EngineData * @param renderer renders all buffers and current renderer to window
*
* @param renderer the renderer to render
*/ */
void ARC_Renderer_Render(ARC_Renderer *renderer); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -2,6 +2,6 @@
#include "renderer.h" #include "renderer.h"
void ARC_Line_Render(ARC_Point point1, ARC_Point point2, ARC_Renderer *renderer, ARC_Color color){ 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_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a);
SDL_RenderLine((SDL_Renderer *)renderer, point1.x, point1.y, point2.x, point2.y); SDL_RenderLine(renderer->renderer, point1.x, point1.y, point2.x, point2.y);
} }

View file

@ -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){ 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_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a);
SDL_RenderRect((SDL_Renderer *)renderer, (SDL_FRect *)&rect); SDL_RenderRect(renderer->renderer, (SDL_FRect *)&rect);
} }
void ARC_FRect_RenderFill(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ 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_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a);
SDL_RenderFillRect((SDL_Renderer *)renderer, (SDL_FRect *)&rect); SDL_RenderFillRect(renderer->renderer, (SDL_FRect *)&rect);
} }

View file

@ -5,8 +5,22 @@
#include <stdlib.h> #include <stdlib.h>
#include "arc/engine/engine.h" #include "arc/engine/engine.h"
#include "arc/graphics/window.h" #include "arc/graphics/window.h"
#include "arc/std/bool.h"
#include "arc/std/errno.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){ void ARC_Renderer_CreateWithEngineData(ARC_Renderer **renderer, ARC_EngineData *data){
if(!data){ if(!data){
arc_errno = ARC_ERRNO_NULL; arc_errno = ARC_ERRNO_NULL;
@ -14,26 +28,93 @@ void ARC_Renderer_CreateWithEngineData(ARC_Renderer **renderer, ARC_EngineData *
return; 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_errno = ARC_ERRNO_NULL;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateRenderer(%p, NULL);", data->window); ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateRenderer(%p, NULL);", data->window);
free(renderer); 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){ 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){ void ARC_Renderer_Clear(ARC_Renderer *renderer){
SDL_SetRenderDrawColor((SDL_Renderer *)renderer, 0x1c, 0x2c, 0x3c, 0xff); SDL_SetRenderTarget(renderer->renderer, NULL);
SDL_RenderClear((SDL_Renderer *)renderer); 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){ 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);
} }

View file

@ -1,10 +1,18 @@
#ifndef ARC_SDL_RENDERER_H_ #ifndef ARC_SDL_RENDERER_H_
#define ARC_SDL_RENDERER_H_ #define ARC_SDL_RENDERER_H_
#include "arc/graphics/color.h"
#include "arc/graphics/renderer.h" #include "arc/graphics/renderer.h"
#include "arc/graphics/window.h" #include "arc/graphics/window.h"
#include "arc/std/hashtable.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
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_ #endif // !ARC_SDL_RENDERER_H_

View file

@ -1,5 +1,6 @@
#include "arc/graphics/sprite.h" #include "arc/graphics/sprite.h"
#include "renderer.h"
#include "spritesheet.h" #include "spritesheet.h"
#include "arc/math/point.h" #include "arc/math/point.h"
#include "arc/math/rectangle.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){ 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){ 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; 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){ void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){

View file

@ -28,7 +28,7 @@ void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer
//set the texture //set the texture
SDL_BlendMode tempMode; SDL_BlendMode tempMode;
SDL_GetSurfaceBlendMode(surface, &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_SetTextureBlendMode((*spritesheet)->texture, tempMode);
SDL_SetTextureScaleMode((*spritesheet)->texture, SDL_SCALEMODE_NEAREST); 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){ 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){ void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_FRect renderBounds){
ARC_FRect bounds = ARC_Rect_CastToFRect(sheetBounds); 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){ 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 //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){ ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){

View file

@ -1,6 +1,7 @@
#include "arc/graphics/text.h" #include "arc/graphics/text.h"
#include "text.h" #include "text.h"
#include "renderer.h"
#include "arc/graphics/color.h" #include "arc/graphics/color.h"
#include "arc/math/point.h" #include "arc/math/point.h"
#include "arc/math/rectangle.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){ if(text->texture){
SDL_DestroyTexture(text->texture); SDL_DestroyTexture(text->texture);
} }
text->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); text->texture = SDL_CreateTextureFromSurface(renderer->renderer, surface);
SDL_DestroySurface(surface); SDL_DestroySurface(surface);
TTF_CloseFont(ttfont); 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_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){ void ARC_Text_SetPos(ARC_Text *text, ARC_Point pos){

View file

@ -1,7 +1,7 @@
#include "arc/graphics/view.h" #include "arc/graphics/view.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include <SDL.h> #include <SDL3/SDL.h>
#include <stdlib.h> #include <stdlib.h>
void ARC_View_Create(ARC_View **view, ARC_Renderer *renderer, ARC_Rect bounds){ 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){ 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)); // int err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, (const SDL_Rect *)&(view->bounds));
if(err){ // if(err){
ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, renderFn), SDL_RenderSetViewport(...) returned: %d", 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; // return;
} // }
//
renderFn(data); // renderFn(data);
//
err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, NULL); // err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, NULL);
if(err){ // if(err){
ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, NULL), SDL_RenderSetViewport(...) returned: %d", err); // ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, NULL), SDL_RenderSetViewport(...) returned: %d", err);
return; // return;
} // }
} }
ARC_Rect ARC_View_GetBounds(ARC_View *view){ ARC_Rect ARC_View_GetBounds(ARC_View *view){
return view->bounds; return view->bounds;
} }