2025-03-22 23:25:21 -06:00
|
|
|
#include "arc/graphics/renderer.h"
|
|
|
|
|
#include "renderer.h"
|
|
|
|
|
|
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include "arc/engine/engine.h"
|
|
|
|
|
#include "arc/graphics/window.h"
|
2025-04-04 03:45:53 -06:00
|
|
|
#include "arc/std/bool.h"
|
2025-03-22 23:25:21 -06:00
|
|
|
#include "arc/std/errno.h"
|
|
|
|
|
|
2025-04-04 03:45:53 -06:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-22 23:25:21 -06:00
|
|
|
void ARC_Renderer_CreateWithEngineData(ARC_Renderer **renderer, ARC_EngineData *data){
|
|
|
|
|
if(!data){
|
|
|
|
|
arc_errno = ARC_ERRNO_NULL;
|
|
|
|
|
ARC_DEBUG_LOG_ERROR("ARC_Renderer_CreateWithEngineData(**renderer, NULL)");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-04 03:45:53 -06:00
|
|
|
*renderer = (ARC_Renderer *)malloc(sizeof(ARC_Renderer));
|
|
|
|
|
|
|
|
|
|
/* ~ Renderer ~ */
|
|
|
|
|
(*renderer)->renderer = SDL_CreateRenderer((SDL_Window *)(data->window), NULL);
|
2025-03-22 23:25:21 -06:00
|
|
|
|
2025-04-04 03:45:53 -06:00
|
|
|
if((*renderer)->renderer == NULL){
|
2025-03-22 23:25:21 -06:00
|
|
|
arc_errno = ARC_ERRNO_NULL;
|
|
|
|
|
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateRenderer(%p, NULL);", data->window);
|
|
|
|
|
free(renderer);
|
2025-04-04 03:45:53 -06:00
|
|
|
return;
|
2025-03-22 23:25:21 -06:00
|
|
|
}
|
|
|
|
|
|
2025-04-04 03:45:53 -06:00
|
|
|
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 };
|
2025-03-22 23:25:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ARC_Renderer_Destroy(ARC_Renderer *renderer){
|
2025-04-04 03:45:53 -06:00
|
|
|
ARC_Hashtable_Destroy(renderer->buffers);
|
|
|
|
|
SDL_DestroyRenderer(renderer->renderer);
|
|
|
|
|
free(renderer);
|
2025-03-22 23:25:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ARC_Renderer_Clear(ARC_Renderer *renderer){
|
2025-04-04 03:45:53 -06:00
|
|
|
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);
|
2025-03-22 23:25:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ARC_Renderer_Render(ARC_Renderer *renderer){
|
2025-04-04 03:45:53 -06:00
|
|
|
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);
|
2025-03-22 23:25:21 -06:00
|
|
|
}
|