From 7ec5e2122e7a28b13fca55aa4bf84435495a6f57 Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Fri, 29 Dec 2023 10:02:13 +0100 Subject: [PATCH] Use built-in qsort instead of flecs (better perf) --- engine/breeze/util/array.h | 10 +++++----- game/game_state.h | 9 +++++++++ game/main.c | 38 ++++++++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/engine/breeze/util/array.h b/engine/breeze/util/array.h index 521b71b..8694d67 100644 --- a/engine/breeze/util/array.h +++ b/engine/breeze/util/array.h @@ -38,17 +38,17 @@ i32 _bzArrayPop(void *arr); #define bzArrayDel(arr, idx) _bzArrayDelN(arr, idx, 1) #define bzArrayDelN(arr, idx, n) _bzArrayDelN(arr, idx, n) -#define bzArrayPush(arr, e) \ +#define bzArrayPush(arr, ...) \ do { \ (arr) = bzArrayEnsureCapacity(arr, bzArraySize(arr) + 1); \ - (arr)[_bzArrayPush(arr)] = (e); \ + (arr)[_bzArrayPush(arr)] = (__VA_ARGS__); \ } while (0) -#define bzArrayIns(arr, idx, e) \ +#define bzArrayIns(arr, idx, ...) \ do { \ (arr) = bzArrayEnsureCapacity(arr, bzArraySize(arr) + 1); \ - (arr)[_bzArrayIns(arr, idx)] = (e); \ + (arr)[_bzArrayIns(arr, idx)] = (__VA_ARGS__); \ } while (0) -#define bzArraySet(arr, idx, e) (arr)[_bzArraySet(arr, idx)] = e +#define bzArraySet(arr, idx, ...) (arr)[_bzArraySet(arr, idx)] = (__VA_ARGS__) #define bzArrayPop(arr) (arr)[_bzArrayPop(arr)] #define bzArrayFor(arr, it) for (i32 it = 0; it < bzArraySize(arr); it++) diff --git a/game/game_state.h b/game/game_state.h index 2da072f..22d94cd 100644 --- a/game/game_state.h +++ b/game/game_state.h @@ -10,6 +10,14 @@ typedef enum GameScreen { SCREEN_SETTINGS, } GameScreen; +typedef struct DrawData { + Texture tex; + Rectangle src; + Rectangle dst; + Vector2 origin; + f32 rotation; +} DrawData; + typedef struct Game { GameScreen screen; Camera2D camera; @@ -41,6 +49,7 @@ typedef struct Game { f32 elapsed; ecs_query_t *drawQuery; + DrawData *drawData; } Game; extern ecs_world_t *ECS; diff --git a/game/main.c b/game/main.c index 873322d..62ae331 100644 --- a/game/main.c +++ b/game/main.c @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include "systems.h" #include "components.h" @@ -15,8 +18,6 @@ #include "pathfinding.h" -#include -#include ECS_COMPONENT_DECLARE(Game); ECS_COMPONENT_DECLARE(InputState); @@ -148,12 +149,11 @@ ECS_DTOR(Path, path, { } }) -int cmpPos(ecs_entity_t e1, const void *v1, ecs_entity_t e2, const void *v2) { - const Position *pos1 = v1; - const Position *pos2 = v2; +int cmpDrawData(const void *a, const void *b) { + const DrawData *lhs = (DrawData *) a; + const DrawData *rhs = (DrawData *) b; - // NOTE: entities with lower Y are in front - f32 dif = pos2->y - pos1->y; + f32 dif = (rhs->dst.y) - (lhs->dst.y); int cmpVal = 0; if (dif < 0) cmpVal = 1; else if (dif > 0) cmpVal = -1; @@ -179,6 +179,7 @@ bool init(void *userData) { Game *game = ecs_singleton_get_mut(ECS, Game); game->screen = SCREEN_MAIN_MENU; game->font = LoadFontEx("assets/fonts/CompassPro.ttf", 92, NULL, 0); + game->drawData = bzArrayCreate(DrawData, 1000); game->drawQuery = ecs_query(ECS, { .filter.terms = { { ecs_id(Position) }, @@ -186,8 +187,6 @@ bool init(void *userData) { { ecs_id(Rotation) }, { ecs_id(TextureRegion) } }, - .order_by_component = ecs_id(Position), - .order_by = cmpPos }); ECS_COMPONENT_DEFINE(ECS, InputState); @@ -250,10 +249,6 @@ bool init(void *userData) { ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path); - //ECS_SYSTEM(ECS, renderTerrain, EcsOnUpdate, Position, Size, Rotation, TextureRegion, TextureTerrain); - //ECS_SYSTEM(ECS, renderBuildings, EcsOnUpdate, Position, Size, Rotation, TextureRegion, TextureBuildings); - //ECS_SYSTEM(ECS, renderEntities, EcsOnUpdate, Position, Size, Rotation, TextureRegion, TextureEntities); - ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, Size); ECS_SYSTEM(ECS, renderRotationDirection, EcsOnUpdate, Position, Rotation); @@ -294,6 +289,8 @@ void deinit(void *userData) { bzObjectPoolDestroy(game->pools.pathData); bzObjectPoolDestroy(game->pools.actions); + bzArrayDestroy(game->drawData); + bzUIDestroy(UI); UI = NULL; @@ -342,6 +339,7 @@ static void renderGame(Game *game, float dt) { // Ground UI drawPlayerInputUIGround(); // Entities + bzArrayClear(game->drawData); ecs_iter_t it = ecs_query_iter(ECS, game->drawQuery); while (ecs_iter_next(&it)) { Position *p = ecs_field(&it, Position, 1); @@ -354,9 +352,21 @@ static void renderGame(Game *game, float dt) { Rectangle src = t[i].rec; if (t[i].flipX) src.width *= -1.0f; if (t[i].flipY) src.height *= -1.0f; - DrawTexturePro(t[i].texture, src, dst, origin, t[i].rotation, WHITE); + bzArrayPush(game->drawData, (DrawData) { + .tex = t[i].texture, + .src = src, + .dst = dst, + .origin = origin, + .rotation = t[i].rotation + }); } } + qsort(game->drawData, bzArraySize(game->drawData), sizeof(*game->drawData), cmpDrawData); + + for (i32 i = 0; i < bzArraySize(game->drawData); i++) { + DrawData draw = game->drawData[i]; + DrawTexturePro(draw.tex, draw.src, draw.dst, draw.origin, draw.rotation, WHITE); + } ecs_progress(ECS, dt); ecs_enable(ECS, renderDebugPathSystem, game->debugDraw.path);