137 lines
3.6 KiB
C
137 lines
3.6 KiB
C
#include "renderer.h"
|
|
#include "scene.h"
|
|
#include <SDL2/SDL_blendmode.h>
|
|
#include <SDL2/SDL_error.h>
|
|
#include <SDL2/SDL_image.h>
|
|
#include <SDL2/SDL_render.h>
|
|
#include <SDL2/SDL_surface.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
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;
|
|
}
|