From a30f20e853f64668404551518fa6d52f608c9c76 Mon Sep 17 00:00:00 2001 From: Marc Date: Fri, 20 Jan 2023 21:59:44 +0100 Subject: [PATCH] Renderer --- CMakeLists.txt | 5 +- src/main.c | 140 ++----------------------------------------------- src/renderer.c | 113 +++++++++++++++++++++++++++++++++++++++ src/renderer.h | 23 +++++--- 4 files changed, 137 insertions(+), 144 deletions(-) create mode 100644 src/renderer.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ba38075..578ed1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_link_options(-fsanitize=address) endif() -set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmaybe-uninitialized") +set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmaybe-uninitialized -Wno-unused-variable") set(CMAKE_C_FLAGS_DEBUG "-g -Werror -O0") set(CMAKE_C_FLAGS_RELEASE "") @@ -21,11 +21,12 @@ project(FLOPPE_FION) set(SRC src/main.c + src/renderer.c ) # add the executable add_executable(FLOPPE_FION ${SRC}) -target_link_libraries(FLOPPE_FION SDL2 SDL_image) +target_link_libraries(FLOPPE_FION SDL2 SDL_image pthread m) set_property(TARGET FLOPPE_FION PROPERTY C_STANDARD 23) diff --git a/src/main.c b/src/main.c index bfc6d5a..2f6aa36 100644 --- a/src/main.c +++ b/src/main.c @@ -1,138 +1,6 @@ -#include -#include -#include +#include "renderer.h" -int main(int argc, char *argv[]) -{ - - // returns zero on success else non-zero - if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { - printf("error initializing SDL: %s\n", SDL_GetError()); - } - SDL_Window* win = SDL_CreateWindow("GAME", // creates a window - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - 1000, 1000, 0); - - // triggers the program that controls - // your graphics hardware and sets flags - Uint32 render_flags = SDL_RENDERER_ACCELERATED; - - // creates a renderer to render our images - SDL_Renderer* rend = SDL_CreateRenderer(win, -1, render_flags); - - // creates a surface to load an image into the main memory - SDL_Surface* surface; - - // please provide a path for your image - surface = IMG_Load("path"); - - // loads image to our graphics hardware memory. - SDL_Texture* tex = SDL_CreateTextureFromSurface(rend, surface); - - // clears main-memory - SDL_FreeSurface(surface); - - // let us control our image position - // so that we can move it with our keyboard. - SDL_Rect dest; - - // connects our texture with dest to control position - SDL_QueryTexture(tex, NULL, NULL, &dest.w, &dest.h); - - // adjust height and width of our image box. - dest.w /= 6; - dest.h /= 6; - - // sets initial x-position of object - dest.x = (1000 - dest.w) / 2; - - // sets initial y-position of object - dest.y = (1000 - dest.h) / 2; - - // controls animation loop - int close = 0; - - // speed of box - int speed = 300; - - // animation loop - while (!close) { - SDL_Event event; - - // Events management - while (SDL_PollEvent(&event)) { - switch (event.type) { - - case SDL_QUIT: - // handling of close button - close = 1; - break; - - case SDL_KEYDOWN: - // keyboard API for key pressed - switch (event.key.keysym.scancode) { - case SDL_SCANCODE_W: - case SDL_SCANCODE_UP: - dest.y -= speed / 30; - break; - case SDL_SCANCODE_A: - case SDL_SCANCODE_LEFT: - dest.x -= speed / 30; - break; - case SDL_SCANCODE_S: - case SDL_SCANCODE_DOWN: - dest.y += speed / 30; - break; - case SDL_SCANCODE_D: - case SDL_SCANCODE_RIGHT: - dest.x += speed / 30; - break; - default: - break; - } - } - } - - // right boundary - if (dest.x + dest.w > 1000) - dest.x = 1000 - dest.w; - - // left boundary - if (dest.x < 0) - dest.x = 0; - - // bottom boundary - if (dest.y + dest.h > 1000) - dest.y = 1000 - dest.h; - - // upper boundary - if (dest.y < 0) - dest.y = 0; - - // clears the screen - SDL_RenderClear(rend); - SDL_RenderCopy(rend, tex, NULL, &dest); - - // triggers the double buffers - // for multiple rendering - SDL_RenderPresent(rend); - - // calculates to 60 fps - SDL_Delay(1000 / 60); - } - - // destroy texture - SDL_DestroyTexture(tex); - - // destroy renderer - SDL_DestroyRenderer(rend); - - // destroy window - SDL_DestroyWindow(win); - - // close SDL - SDL_Quit(); - - return 0; +int main(void) { + renderer_main(); + while(1); } diff --git a/src/renderer.c b/src/renderer.c new file mode 100644 index 0000000..bdc7f47 --- /dev/null +++ b/src/renderer.c @@ -0,0 +1,113 @@ +#include "renderer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct RenderItem { + RenderObject_t object; + SDL_Texture * cache; + SDL_Rect rect; + RenderId_t id; +} RenderItem_t; + +RenderItem_t * objects = NULL; +int objectCount = 0; +int objectStorageSize = 0; +MonitorSize_t monitorSize; +pthread_t thread; +SDL_Window* win; + +static int compartSort(const RenderItem_t * a, const RenderItem_t * b) { + return a->object.z - b->object.z; +} + +//int (*compar)(const void [.size], const void [.size], void *) +static void * render_thread(void *) { + SDL_GetRendererOutputSize(renderer, &monitorSize.width, &monitorSize.height); + + objectStorageSize = 1000; + objects = malloc(objectStorageSize); + + while(true) { + for(int i = 0; i < objectCount; i++) { + RenderItem_t * object = &objects[i]; + if(object->cache == NULL) { + SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, object->object.surface); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + object->cache = texture; + } + SDL_RenderCopyEx(renderer, object->cache, &object->rect, NULL, object->object.angle_degre, NULL, SDL_FLIP_NONE); + } + SDL_Delay(1000 / 400); //400fps or u a pussy + } + return NULL; +} + +void renderer_main() { + // returns zero on success else non-zero + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { + printf("error initializing SDL: %s\n", SDL_GetError()); + } + win = SDL_CreateWindow("GAME", // creates a window + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 1000, 1000, 0); + + Uint32 render_flags = SDL_RENDERER_ACCELERATED; + + // creates a renderer to render our images + renderer = SDL_CreateRenderer(win, -1, render_flags); + + pthread_create(&thread, NULL, render_thread, NULL); +} + +RenderId_t renderer_renderObject(RenderObject_t object) { + RenderId_t itemId = objectCount++; + + SDL_Rect rect = { + round(object.x * monitorSize.width), + round(object.y * monitorSize.height), + round(object.height * monitorSize.height), + round(object.width * monitorSize.width) + }; + + RenderItem_t item = { + object, + NULL, + rect, + itemId + }; + + objects[itemId] = item; + //the objects are sorted + qsort(objects, objectCount, sizeof(RenderItem_t), (__compar_fn_t)compartSort); + return itemId; +} + +void renderer_removeObject(RenderId_t id) { + bool found = false; + for(int i = 0; i < objectCount - 1; i++) { + if(objects[i].id == id) { + SDL_FreeSurface(objects[i].object.surface); + if(objects[i].cache != NULL) { + SDL_DestroyTexture(objects[i].cache); + } + } + if(found) { + objects[i] = objects[i + 1]; + } + } + objectCount--; +} + +MonitorSize_t renderer_getMonitorSize() { + return monitorSize; +} diff --git a/src/renderer.h b/src/renderer.h index 12a2fdb..a41b99f 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -1,9 +1,17 @@ -#include +#ifndef __RENDERER_H__ +#define __RENDERER_H__ -typedef int RenderItem_t; +#include +#include + +typedef int RenderId_t; +static SDL_Renderer * renderer; typedef struct RenderObject { - int x,y,z; + float x,y; + int z; + float width, height; //ratio between 0 & 1 of the monitor resolution + float angle_degre; SDL_Surface * surface; } RenderObject_t; @@ -11,7 +19,10 @@ typedef struct MonitorSize { int width, height; } MonitorSize_t; -RenderItem_t renderer_renderObject(RenderObject_t *); -void renderer_removeObject(RenderItem_t); +void renderer_main(void); +RenderId_t renderer_renderObject(RenderObject_t); +void renderer_removeObject(RenderId_t); -MonitorSize_t renderer_getMonitorSize(); +MonitorSize_t renderer_getMonitorSize(void); + +#endif