diff --git a/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.cpp b/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.cpp index 8356f3c5e..99e7a161c 100644 --- a/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.cpp +++ b/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.cpp @@ -183,7 +183,7 @@ int NewIsometricTileRenderer::getTileSize() const { return images->getBlockSize() * 16 * tile_width; } -void NewIsometricTileRenderer::renderTopBlocks(const TilePos& tile_pos, boost::container::vector& tile_images) { +void NewIsometricTileRenderer::renderTopBlocks(const TilePos& tile_pos, std::vector& tile_images) { int block_size = images->getBlockSize(); mc::BlockDir dir = render_view->getRotation().rotate(mc::DIR_NORTH + mc::DIR_EAST + mc::DIR_BOTTOM); for (old::TileTopBlockIterator it(tile_pos, block_size, tile_width, render_view); !it.end(); it.next()) { diff --git a/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.h b/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.h index b660bc969..7dfccc1a7 100644 --- a/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.h +++ b/src/mapcraftercore/renderer/renderviews/isometricnew/tilerenderer.h @@ -90,7 +90,7 @@ class NewIsometricTileRenderer : public TileRenderer { virtual int getTileSize() const; protected: - virtual void renderTopBlocks(const TilePos& tile_pos, boost::container::vector& tile_images); + virtual void renderTopBlocks(const TilePos& tile_pos, std::vector& tile_images); }; } diff --git a/src/mapcraftercore/renderer/renderviews/side/tilerenderer.cpp b/src/mapcraftercore/renderer/renderviews/side/tilerenderer.cpp index 02489146a..789303839 100644 --- a/src/mapcraftercore/renderer/renderviews/side/tilerenderer.cpp +++ b/src/mapcraftercore/renderer/renderviews/side/tilerenderer.cpp @@ -63,7 +63,7 @@ int SideTileRenderer::getTileHeight() const { return block_images->getBlockHeight() * 8 * tile_width; } -void SideTileRenderer::renderTopBlocks(const TilePos& tile_pos, boost::container::vector& tile_images) { +void SideTileRenderer::renderTopBlocks(const TilePos& tile_pos, std::vector& tile_images) { int block_width = block_images->getBlockWidth(); int block_height = block_images->getBlockHeight(); for (int cx = 0; cx < tile_width; cx++) { diff --git a/src/mapcraftercore/renderer/renderviews/side/tilerenderer.h b/src/mapcraftercore/renderer/renderviews/side/tilerenderer.h index 2fba3f921..dcabf70a1 100644 --- a/src/mapcraftercore/renderer/renderviews/side/tilerenderer.h +++ b/src/mapcraftercore/renderer/renderviews/side/tilerenderer.h @@ -40,7 +40,7 @@ class SideTileRenderer : public TileRenderer { virtual int getTileHeight() const; protected: - virtual void renderTopBlocks(const TilePos& tile_pos, boost::container::vector& tile_images); + virtual void renderTopBlocks(const TilePos& tile_pos, std::vector& tile_images); }; } diff --git a/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.cpp b/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.cpp index 778e2a9d2..2abcb463a 100644 --- a/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.cpp +++ b/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.cpp @@ -53,7 +53,7 @@ int TopdownTileRenderer::getTileSize() const { return images->getBlockSize() * 16 * tile_width; } -void TopdownTileRenderer::renderTopBlocks(const TilePos& tile_pos, boost::container::vector& tile_images) { +void TopdownTileRenderer::renderTopBlocks(const TilePos& tile_pos, std::vector& tile_images) { int block_size = images->getBlockSize(); for (int cx = 0; cx < tile_width; cx++) { for (int cz = 0; cz < tile_width; cz++) { diff --git a/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.h b/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.h index ee0491e75..d8c74a2bf 100644 --- a/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.h +++ b/src/mapcraftercore/renderer/renderviews/topdown/tilerenderer.h @@ -38,7 +38,7 @@ class TopdownTileRenderer : public TileRenderer { virtual int getTileSize() const; protected: - virtual void renderTopBlocks(const TilePos& tile_pos, boost::container::vector& tile_images); + virtual void renderTopBlocks(const TilePos& tile_pos, std::vector& tile_images); }; } diff --git a/src/mapcraftercore/renderer/tilerenderer.cpp b/src/mapcraftercore/renderer/tilerenderer.cpp index b48f70c39..ff176d045 100644 --- a/src/mapcraftercore/renderer/tilerenderer.cpp +++ b/src/mapcraftercore/renderer/tilerenderer.cpp @@ -19,7 +19,10 @@ #include "tilerenderer.h" -#include +#include //std::sort() +#include +#include // std::allocator +#include #include "blockimages.h" #include "rendermode.h" @@ -30,6 +33,8 @@ #include "../mc/pos.h" #include "../util.h" +#include + namespace mapcrafter { namespace renderer { @@ -65,62 +70,82 @@ void TileRenderer::setShadowEdges(std::array shadow_edges) { this->shadow_edges = shadow_edges; } -TileRenderer::cmpBlockPos* TileRenderer::getTileComparator() const { - switch ((RenderRotation::Direction)render_view->getRotation()){ +template +static void sortTiles(IT begin, IT end, RenderRotation::Direction dir) { + switch (dir){ default: case RenderRotation::TOP_LEFT: - return [](const TileImage& a, const TileImage& b) -> bool { + std::sort(begin, end, [](const TileImage* a, const TileImage* b) -> bool { return - (a.pos.y != b.pos.y) ? (a.pos.y < b.pos.y) : ( - (a.pos.z != b.pos.z) ? (a.pos.z < b.pos.z) : ( - (a.pos.x != b.pos.x) ? (a.pos.x > b.pos.x) : ( + (a->pos.y != b->pos.y) ? (a->pos.y < b->pos.y) : ( + (a->pos.z != b->pos.z) ? (a->pos.z < b->pos.z) : ( + (a->pos.x != b->pos.x) ? (a->pos.x > b->pos.x) : ( false ))); - }; + }); break; case RenderRotation::TOP_RIGHT: - return [](const TileImage& a, const TileImage& b) -> bool { + std::sort(begin, end, [](const TileImage* a, const TileImage* b) -> bool { return - (a.pos.y != b.pos.y) ? (a.pos.y < b.pos.y) : ( - (a.pos.x != b.pos.x) ? (a.pos.x < b.pos.x) : ( - (a.pos.z != b.pos.z) ? (a.pos.z < b.pos.z) : ( + (a->pos.y != b->pos.y) ? (a->pos.y < b->pos.y) : ( + (a->pos.x != b->pos.x) ? (a->pos.x < b->pos.x) : ( + (a->pos.z != b->pos.z) ? (a->pos.z < b->pos.z) : ( false ))); - }; + }); break; case RenderRotation::BOTTOM_RIGHT: - return [](const TileImage& a, const TileImage& b) -> bool { + std::sort(begin, end, [](const TileImage* a, const TileImage* b) -> bool { return - (a.pos.y != b.pos.y) ? (a.pos.y < b.pos.y) : ( - (a.pos.z != b.pos.z) ? (a.pos.z > b.pos.z) : ( - (a.pos.x != b.pos.x) ? (a.pos.x < b.pos.x) : ( + (a->pos.y != b->pos.y) ? (a->pos.y < b->pos.y) : ( + (a->pos.z != b->pos.z) ? (a->pos.z > b->pos.z) : ( + (a->pos.x != b->pos.x) ? (a->pos.x < b->pos.x) : ( false ))); - }; + }); break; case RenderRotation::BOTTOM_LEFT: - return [](const TileImage& a, const TileImage& b) -> bool { + std::sort(begin, end, [](const TileImage* a, const TileImage* b) -> bool { return - (a.pos.y != b.pos.y) ? (a.pos.y < b.pos.y) : ( - (a.pos.x != b.pos.x) ? (a.pos.x > b.pos.x) : ( - (a.pos.z != b.pos.z) ? (a.pos.z > b.pos.z) : ( + (a->pos.y != b->pos.y) ? (a->pos.y < b->pos.y) : ( + (a->pos.x != b->pos.x) ? (a->pos.x > b->pos.x) : ( + (a->pos.z != b->pos.z) ? (a->pos.z > b->pos.z) : ( false ))); - }; + }); break; } } void TileRenderer::renderTile(const TilePos& tile_pos, RGBAImage& tile) { + static std::atomic tile_images_maxsize(64 << 10); //64Ki + tile.setSize(getTileWidth(), getTileHeight()); - boost::container::vector tile_images; + size_t tile_images_capacity_value = tile_images_maxsize; + + std::vector tile_images; + tile_images.reserve(tile_images_capacity_value * 2); renderTopBlocks(tile_pos, tile_images); + size_t count = tile_images.size(); + if (count > tile_images_capacity_value + && tile_images_maxsize.compare_exchange_strong(tile_images_capacity_value, count)) { + LOG(DEBUG) << "raised initial tile_images capacity to " << count; + } + + //get pointers to all the TileImages + std::vector>> tile_image_pointers(count); + std::transform( + tile_images.begin(), tile_images.end(), tile_image_pointers.begin(), + [](TileImage& tile_image) -> TileImage* { + return &tile_image; + }); + // Sort them in order depending of the rotation - boost::range::sort(tile_images, getTileComparator()); + sortTiles(tile_image_pointers.begin(), tile_image_pointers.end(), (RenderRotation::Direction)render_view->getRotation()); - for (auto it = tile_images.begin(); it != tile_images.end(); ++it) { + for (auto it : tile_image_pointers) { tile.alphaBlit(it->image, it->x, it->y); } } @@ -133,7 +158,7 @@ int TileRenderer::getTileHeight() const { return getTileSize(); } -void TileRenderer::renderBlocks(int x, int y, mc::BlockPos top, const mc::BlockDir& dir, boost::container::vector& tile_images) { +void TileRenderer::renderBlocks(int x, int y, mc::BlockPos top, const mc::BlockDir& dir, std::vector& tile_images) { for (; top.y >= mc::CHUNK_LOWEST*16 ; top += dir) { // get current chunk position diff --git a/src/mapcraftercore/renderer/tilerenderer.h b/src/mapcraftercore/renderer/tilerenderer.h index 57e8b0404..f2de3cced 100644 --- a/src/mapcraftercore/renderer/tilerenderer.h +++ b/src/mapcraftercore/renderer/tilerenderer.h @@ -27,7 +27,6 @@ #include #include #include -#include namespace fs = boost::filesystem; @@ -75,11 +74,8 @@ class TileRenderer { virtual int getTileHeight() const; protected: - // void sortTiles(boost::container::vector& tile_images) const; - typedef bool cmpBlockPos(const TileImage &, const TileImage &); - cmpBlockPos* getTileComparator() const; - void renderBlocks(int x, int y, mc::BlockPos top, const mc::BlockDir& dir, boost::container::vector& tile_images); - virtual void renderTopBlocks(const TilePos& tile_pos, boost::container::vector& tile_images) {} + void renderBlocks(int x, int y, mc::BlockPos top, const mc::BlockDir& dir, std::vector& tile_images); + virtual void renderTopBlocks(const TilePos& tile_pos, std::vector& tile_images) {} mc::Block getBlock(const mc::BlockPos& pos, int get = mc::GET_ID); uint32_t getBiomeColor(const mc::BlockPos& pos, const BlockImage& block, const mc::Chunk* chunk);