#include "arc/graphics/renderer.h" #include "renderer.h" #include #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; ARC_DEBUG_LOG_ERROR("ARC_Renderer_CreateWithEngineData(**renderer, NULL)"); return; } *renderer = (ARC_Renderer *)malloc(sizeof(ARC_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((*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){ ARC_Hashtable_Destroy(renderer->buffers); SDL_DestroyRenderer(renderer->renderer); free(renderer); } void ARC_Renderer_Clear(ARC_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(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); }