#include "renderer.h" #include "scene.h" #include #include #include #include #include #include #include const RenderObject_t EMPTY_RENDER_OBJECT = { 0, 0, 0, 0, NULL, "Undefined" }; static int compartSort(const SceneObject_t * a, const SceneObject_t * b) { return a->renderObj.z - b->renderObj.z; } void scene_render(const Scene_t * scene) { MonitorSize_t monitorSize = renderer_getMonitorSize(); for(int i = 0; i < scene->objectCount; i++) { printf("Rendering %d, %s\n", scene->objects[i].id, scene->objects[i].renderObj.name); const SceneObject_t * object = &scene->objects[i]; float x = (object->x - scene->x) / CAMERA_WIDTH; float y = (object->y - scene->y) / CAMERA_HEIGHT; //the object is to be rendered SDL_Rect rect = { round(x * monitorSize.width) , round(y * monitorSize.height), round(object->renderObj.width * monitorSize.width), round(object->renderObj.height * monitorSize.height) }; int error = SDL_RenderCopyEx(renderer, object->cache, NULL, &rect, object->renderObj.angle_degre, NULL, SDL_FLIP_NONE); if(error != 0) { fprintf(stderr, "Render error in object %d with error %s\n", object->id, SDL_GetError()); exit(1); } } } static void buildCache(SceneObject_t * object) { SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, object->renderObj.surface); if(texture == NULL) { fprintf(stderr, "Error while creating texture %s is_null: %d\n", SDL_GetError(), object->renderObj.surface == NULL); exit(1); } SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); object->cache = texture; } RenderId_t scene_addRenderObject(Scene_t * scene, RenderObject_t object, int x, int y) { scene->objectCount++; RenderId_t itemId = scene->lastId++; printf("adding item: %s: %d\n", object.name, itemId); if(scene->objectCount * sizeof(SceneObject_t) > scene->objectArraySize) { scene->objectArraySize = scene->objectCount * sizeof(SceneObject_t); scene->objects = realloc(scene->objects, scene->objectArraySize); if(scene->objects == NULL) { printf("Realloc failed\n"); } } SceneObject_t item = { x, y, object, NULL, itemId }; buildCache(&item); scene->objects[scene->objectCount - 1] = item; //the objects are sorted qsort(scene->objects, scene->objectCount, sizeof(SceneObject_t), (__compar_fn_t)compartSort); return itemId; } static int indexof(Scene_t * scene, RenderId_t id) { bool found = false; int index = 0; for(int i = 0; i < scene->objectCount; i++) { if(scene->objects[i].id == id){ found = true; index = i; break; } } if(!found){ printf("object %d not found\n", id); return -1; } return index; } void scene_moveRenderObject(Scene_t * scene, RenderId_t id, float x, float y) { int index = indexof(scene, id); if(index < 0) return; SceneObject_t * object = &scene->objects[index]; object->x = x; object->y = y; } void scene_removeRenderObject(Scene_t * scene, RenderId_t id) { int index = indexof(scene, id); if(index < 0) return; printf("removing item: %s: %d\n", scene->objects[index].renderObj.name, id); scene->objectCount--; for(int i = index; i < scene->objectCount; i++) { scene->objects[i] = scene->objects[i + 1]; } } void scene_free(Scene_t * scene) { for(int i = 0; i < scene->objectCount - 1; i++) { SDL_FreeSurface(scene->objects[i].renderObj.surface); if(scene->objects[i].cache != NULL) { SDL_DestroyTexture(scene->objects[i].cache); } } free(scene->objects); scene->objectArraySize = 0; scene->objectCount = 0; scene->objects = NULL; }