From 35ee11e5c1a468530bce671c797eccffc2a1c330 Mon Sep 17 00:00:00 2001 From: PaweÅ‚ Redman Date: Thu, 12 Apr 2018 22:07:38 +0200 Subject: Fix the rendering order problems. --- src/common.hpp | 19 +++++++++++--- src/game/assets.cpp | 12 ++++----- src/game/effects.cpp | 2 +- src/game/unit_nest.cpp | 2 +- src/game/unit_repl.cpp | 2 +- src/game/unit_soldier.cpp | 4 +-- src/game/unit_spider.cpp | 2 +- src/render.cpp | 63 +++++++++++++++++++++++++++++------------------ 8 files changed, 67 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/common.hpp b/src/common.hpp index 45782f7..1cd1921 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -68,7 +68,19 @@ namespace procgen { }; } -namespace render { class state_t; } +namespace render { + class state_t; + + enum { + LAYER_FLAT, + LAYER_NORMAL, + LAYER_TOP, + LAYER_COUNT + }; + + // Apparently you can't increment an enum type... + typedef int layer_t; +} namespace world { #define SECTOR_SIZE 8 @@ -186,7 +198,7 @@ namespace world { int type; cmodel_t cmodel; rectf_t render_bounds; - int render_layer = 0; + render::layer_t render_layer = render::LAYER_NORMAL; entity_t(int type_); virtual ~entity_t(void) = 0; @@ -397,7 +409,7 @@ namespace render { ALIGN_CENTER_BOTTOM } text_align_t; - void register_tile(uint8_t type, const char *top, const char *side, float height); + void register_tile(uint8_t type, const char *top, const char *side, float height, layer_t layer); bool rendering_order(const world::entity_t *x, const world::entity_t *y); bool visibility_order(const world::entity_t *x, const world::entity_t *y); @@ -405,6 +417,7 @@ namespace render { sf::RenderWindow *window; void render_tile(world::world_t *world, v2f_t tx, world::tile_t *tile); + void render_layer(game::state_t *game, rect_t §ors, std::list &ents, layer_t layer); void drender_text(rectf_t rect, std::string str); void drender_entity(world::entity_t *ent); public: diff --git a/src/game/assets.cpp b/src/game/assets.cpp index f38b6ef..553cafd 100644 --- a/src/game/assets.cpp +++ b/src/game/assets.cpp @@ -79,17 +79,17 @@ void load(void) aim_marker.load("assets/units/aim_marker_", 5); world::register_tile(TILE_DIRT, 0); - render::register_tile(TILE_DIRT, "assets/tiles/dirt.png", NULL, 0.0f); + render::register_tile(TILE_DIRT, "assets/tiles/dirt.png", NULL, 0.0f, render::LAYER_FLAT); world::register_tile(TILE_DIRT_RED, 0); - render::register_tile(TILE_DIRT_RED, "assets/tiles/dirt_red.png", NULL, 0.0f); + render::register_tile(TILE_DIRT_RED, "assets/tiles/dirt_red.png", NULL, 0.0f, render::LAYER_FLAT); world::register_tile(TILE_STONE, CF_SOLID); - render::register_tile(TILE_STONE, "assets/tiles/stone.png", "assets/tiles/stone_side.png", 1.0f); + render::register_tile(TILE_STONE, "assets/tiles/stone.png", "assets/tiles/stone_side.png", 1.0f, render::LAYER_NORMAL); world::register_tile(TILE_STONE_RED, CF_SOLID); - render::register_tile(TILE_STONE_RED, "assets/tiles/stone_red.png", "assets/tiles/stone_red_side.png", 1.4f); + render::register_tile(TILE_STONE_RED, "assets/tiles/stone_red.png", "assets/tiles/stone_red_side.png", 1.4f, render::LAYER_NORMAL); world::register_tile(TILE_WATER, CF_WATER); - render::register_tile(TILE_WATER, "assets/tiles/water.png", NULL, 0.0f); + render::register_tile(TILE_WATER, "assets/tiles/water.png", NULL, 0.0f, render::LAYER_FLAT); world::register_tile(TILE_GRAVEL, 0); - render::register_tile(TILE_GRAVEL, "assets/tiles/gravel.png", NULL, 0.0f); + render::register_tile(TILE_GRAVEL, "assets/tiles/gravel.png", NULL, 0.0f, render::LAYER_FLAT); ambients[AMBIENT_NEXUS].load("assets/ambience/nexus.ogg"); ambients[AMBIENT_CHASM].load("assets/ambience/chasm.ogg"); diff --git a/src/game/effects.cpp b/src/game/effects.cpp index f56c065..a398527 100644 --- a/src/game/effects.cpp +++ b/src/game/effects.cpp @@ -143,7 +143,7 @@ fx_aim_marker_t::fx_aim_marker_t(state_t *game_, v2f_t x_) : effect_t(game_) x = x_; render_bounds[0] = x + v2f_t(-0.2, -0.2); render_bounds[1] = x + v2f_t(0.2, 0.2); - render_layer = 100; + render_layer = render::LAYER_TOP; cmodel.bounds = render_bounds; cmodel.cflags = 0; diff --git a/src/game/unit_nest.cpp b/src/game/unit_nest.cpp index a46aa79..ffa551b 100644 --- a/src/game/unit_nest.cpp +++ b/src/game/unit_nest.cpp @@ -79,7 +79,7 @@ void unit_nest_t::on_spawn(void) void unit_nest_t::on_death(void) { - render_layer = -1; + render_layer = render::LAYER_FLAT; cmodel.cflags = CF_BACKGROUND; } diff --git a/src/game/unit_repl.cpp b/src/game/unit_repl.cpp index fbefcd2..8bfd835 100644 --- a/src/game/unit_repl.cpp +++ b/src/game/unit_repl.cpp @@ -24,7 +24,7 @@ unit_repl_t::unit_repl_t(game::state_t *game_) : unit_t(game_, UNIT_REPL) size[0] = {-0.4f, -0.2f}; size[1] = {+0.4f, +0.6f}; render_size = size; - render_layer = -2; + render_layer = render::LAYER_FLAT; cmodel.cflags = CF_BACKGROUND; name = text::get(text::UNIT_NAME_REPL); diff --git a/src/game/unit_soldier.cpp b/src/game/unit_soldier.cpp index 7dca7ff..351970e 100644 --- a/src/game/unit_soldier.cpp +++ b/src/game/unit_soldier.cpp @@ -131,7 +131,7 @@ void unit_soldier_t::target_and_attack(void) last_target_time = game->now; last_target_x = target->x; - + skip_targetting: aim_marker = std::make_unique(game, aim); @@ -165,7 +165,7 @@ void unit_soldier_t::on_death(void) assets::soldier.gib_sound.play_3d(x); } - render_layer = -1; + render_layer = render::LAYER_FLAT; cmodel.cflags = CF_BACKGROUND; place(world, x); controllable = false; diff --git a/src/game/unit_spider.cpp b/src/game/unit_spider.cpp index 0eea8eb..fd69305 100644 --- a/src/game/unit_spider.cpp +++ b/src/game/unit_spider.cpp @@ -80,7 +80,7 @@ void unit_spider_t::on_wake(void) void unit_spider_t::on_death(void) { - render_layer = -1; + render_layer = render::LAYER_FLAT; cmodel.cflags = CF_BACKGROUND; } diff --git a/src/render.cpp b/src/render.cpp index beda97b..9056d9c 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -33,10 +33,11 @@ state_t::state_t(sf::RenderWindow *window_) typedef struct { sf::Texture *top, *side; float height; + layer_t layer; } tiledata_t; static tiledata_t tiledata[256] = {0}; -void register_tile(uint8_t type, const char *top, const char *side, float height) +void register_tile(uint8_t type, const char *top, const char *side, float height, layer_t layer) { tiledata_t *tile = tiledata + type; @@ -52,6 +53,8 @@ void register_tile(uint8_t type, const char *top, const char *side, float height tile->side->loadFromFile(side); tile->side->setRepeated(true); } + + tile->layer = layer; } @@ -202,32 +205,23 @@ rectf_t state_t::window_in_world_space(void) bool rendering_order(const world::entity_t *x, const world::entity_t *y) { - if (x->render_layer < y->render_layer) - return true; - else if (x->render_layer > y->render_layer) - return false; - else - return x->render_bounds[1][1] < y->render_bounds[1][1]; + return x->render_bounds[1][1] < y->render_bounds[1][1]; } bool visibility_order(const world::entity_t *x, const world::entity_t *y) { - return !rendering_order(x, y); + if (x->render_layer < y->render_layer) + return false; + else if (x->render_layer > y->render_layer) + return true; + else + return x->render_bounds[1][1] > y->render_bounds[1][1]; } -void state_t::render(game::state_t *game) +void state_t::render_layer(game::state_t *game, rect_t §ors, + std::list &ents, layer_t layer) { - rectf_t bounds; - std::list ents; std::list::iterator ent; - rect_t sectors; - - bounds = window_bounds(window); - sectors[0] = world::sector_index_at(bounds[0]); - sectors[1] = world::sector_index_at(bounds[1]); - - ents = game->world.get_render_entities(bounds); - ents.sort(rendering_order); ent = ents.begin(); for (world::coord_t sy = sectors[0][1]; sy <= sectors[1][1]; sy++) @@ -240,8 +234,11 @@ void state_t::render(game::state_t *game) while (ent != ents.end() && (*ent)->render_bounds[1][1] < sy * SECTOR_SIZE + ty) { - (*ent)->render_to(this); - stats.entities++; + if ((*ent)->render_layer == layer) { + (*ent)->render_to(this); + stats.entities++; + } + ent++; } @@ -253,14 +250,32 @@ void state_t::render(game::state_t *game) world::tile_index_t(tx, ty); tile = sector->tiles + ty * SECTOR_SIZE + tx; + if (tiledata[tile->type].layer != layer) + continue; + render_tile(&game->world, index, tile); } - stats.sectors++; + if (layer == LAYER_COUNT - 1) + stats.sectors++; } +} + +void state_t::render(game::state_t *game) +{ + rectf_t bounds; + std::list ents; + rect_t sectors; + + bounds = window_bounds(window); + sectors[0] = world::sector_index_at(bounds[0]); + sectors[1] = world::sector_index_at(bounds[1]); + + ents = game->world.get_render_entities(bounds); + ents.sort(rendering_order); - // Every sector is iterated SECTOR_SIZE times. - stats.sectors /= SECTOR_SIZE; + for (layer_t layer = LAYER_FLAT; layer < LAYER_COUNT; layer++) + render_layer(game, sectors, ents, layer); if (debug_draw_tile_coords) { for (world::sector_t *sector : game->world.get_sectors(bounds, world::SECTOR_FULL)) -- cgit