diff --git a/source/renderer/TerrainOverlay.h b/source/renderer/TerrainOverlay.h index f5f122fb94..2dc2984c26 100644 --- a/source/renderer/TerrainOverlay.h +++ b/source/renderer/TerrainOverlay.h @@ -23,6 +23,7 @@ #ifndef INCLUDED_TERRAINOVERLAY #define INCLUDED_TERRAINOVERLAY +#include "graphics/SColor.h" #include "graphics/ShaderTechniquePtr.h" #include "lib/code_annotation.h" #include "lib/posix/posix_types.h" @@ -212,6 +213,24 @@ public: */ static SColor4ub GetColor(std::size_t idx, std::uint8_t alpha); + static void OverwriteEachTile(std::uint8_t* data, const std::size_t w, const std::size_t h, + const auto generate) + { + static_assert(std::is_invocable_r_v); + + for (int i{0}; i != static_cast(h); ++i) + { + for (int j{0}; j != static_cast(w); ++j) + { + SColor4ub color{generate(i, j)}; + *data++ = color.R; + *data++ = color.G; + *data++ = color.B; + *data++ = color.A; + } + } + }; + private: void RenderAfterWater( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, int cullGroup) final; diff --git a/source/simulation2/components/CCmpPathfinder.cpp b/source/simulation2/components/CCmpPathfinder.cpp index 627038e986..2018df1670 100644 --- a/source/simulation2/components/CCmpPathfinder.cpp +++ b/source/simulation2/components/CCmpPathfinder.cpp @@ -78,28 +78,18 @@ REGISTER_COMPONENT_TYPE(Pathfinder) namespace { -void BuildTextureRGBA(const CCmpPathfinder& pathfinder, std::uint8_t* data, - std::size_t w, std::size_t h) +void BuildTextureRGBA(const CCmpPathfinder& pathfinder, std::uint8_t* data, std::size_t w, std::size_t h) { // Render navcell passability, based on the terrain-only grid - u8* p = data; - for (size_t j = 0; j < h; ++j) + TerrainTextureOverlay::OverwriteEachTile(data, w, h, [&](const int i, const int j) { - for (size_t i = 0; i < w; ++i) + if (!IS_PASSABLE(pathfinder.m_TerrainOnlyGrid->get(j, i), + pathfinder.m_OverlayPassClass)) { - SColor4ub color(0, 0, 0, 0); - if (!IS_PASSABLE(pathfinder.m_TerrainOnlyGrid->get(static_cast(i), - static_cast(j)), pathfinder.m_OverlayPassClass)) - { - color = SColor4ub(255, 0, 0, 127); - } - - *p++ = color.R; - *p++ = color.G; - *p++ = color.B; - *p++ = color.A; + return SColor4ub{255, 0, 0, 127}; } - } + return SColor4ub{0, 0, 0, 0}; + }); } } @@ -1091,3 +1081,4 @@ ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const I return ICmpObstruction::FOUNDATION_CHECK_SUCCESS; } + diff --git a/source/simulation2/components/CCmpTerritoryManager.cpp b/source/simulation2/components/CCmpTerritoryManager.cpp index a26e02eaac..8f948cc415 100644 --- a/source/simulation2/components/CCmpTerritoryManager.cpp +++ b/source/simulation2/components/CCmpTerritoryManager.cpp @@ -77,21 +77,14 @@ namespace { constexpr bool DISABLE_TERRITORY_OVERLAY{true}; -void BuildTextureRGBA(Grid*& territories, u8* data, size_t w, size_t h) +void BuildTextureRGBA(Grid*& territories, std::uint8_t* data, const int w, const int h) { - for (size_t j = 0; j < h; ++j) + TerrainTextureOverlay::OverwriteEachTile(data, w, h, [&](const int i, const int j) { - for (size_t i = 0; i < w; ++i) - { - SColor4ub color; - u8 id = (territories->get((int)i, (int)j) & ICmpTerritoryManager::TERRITORY_PLAYER_MASK); - color = TerrainTextureOverlay::GetColor(id, 64); - *data++ = color.R; - *data++ = color.G; - *data++ = color.B; - *data++ = color.A; - } - } + const u8 id{static_cast(territories->get(j, i) & + ICmpTerritoryManager::TERRITORY_PLAYER_MASK)}; + return TerrainTextureOverlay::GetColor(id, 64); + }); } } @@ -164,7 +157,7 @@ public: m_DebugOverlay = DISABLE_TERRITORY_OVERLAY? nullptr : new TerrainTextureOverlay{static_cast(Pathfinding::NAVCELLS_PER_TERRAIN_TILE) / ICmpTerritoryManager::NAVCELLS_PER_TERRITORY_TILE, - std::bind_front(BuildTextureRGBA, std::ref(this->m_Territories))}; + std::bind_front(BuildTextureRGBA, std::ref(m_Territories))}; m_BoundaryLinesDirty = true; m_TriggerEvent = true; m_EnableLineDebugOverlays = false; diff --git a/source/simulation2/helpers/HierarchicalPathfinder.cpp b/source/simulation2/helpers/HierarchicalPathfinder.cpp index fea7536a0d..84c7b400c2 100644 --- a/source/simulation2/helpers/HierarchicalPathfinder.cpp +++ b/source/simulation2/helpers/HierarchicalPathfinder.cpp @@ -53,30 +53,18 @@ void BuildTextureRGBA(HierarchicalPathfinder& pathfinderHier, std::uint8_t* data std::size_t h) { ENSURE(h <= std::numeric_limits::max() && w <= std::numeric_limits::max()); - u16 height = static_cast(h); - u16 width = static_cast(w); pass_class_t passClass = pathfinderHier.GetPassabilityClass("default"); - for (u16 j = 0; j < height; ++j) + TerrainTextureOverlay::OverwriteEachTile(data, w, h, [&](const int i, const int j) { - for (u16 i = 0; i < width; ++i) - { - SColor4ub color; - - HierarchicalPathfinder::RegionID rid = pathfinderHier.Get(i, j, passClass); - if (rid.r == 0) - color = SColor4ub(0, 0, 0, 0); - else if (rid.r == 0xFFFF) - color = SColor4ub(255, 0, 255, 255); - else - color = TerrainTextureOverlay::GetColor(rid.r + rid.ci*5 + rid.cj*7, 127); - - *data++ = color.R; - *data++ = color.G; - *data++ = color.B; - *data++ = color.A; - } - } + HierarchicalPathfinder::RegionID rid = pathfinderHier.Get(static_cast(j), + static_cast(i), passClass); + if (rid.r == 0) + return SColor4ub{0, 0, 0, 0}; + if (rid.r == 0xFFFF) + return SColor4ub{255, 0, 255, 255}; + return TerrainTextureOverlay::GetColor(rid.r + rid.ci*5 + rid.cj*7, 127); + }); } } diff --git a/source/simulation2/helpers/LongPathfinder.cpp b/source/simulation2/helpers/LongPathfinder.cpp index 3da92b4105..2fcb3532f1 100644 --- a/source/simulation2/helpers/LongPathfinder.cpp +++ b/source/simulation2/helpers/LongPathfinder.cpp @@ -48,37 +48,23 @@ void BuildTextureRGBA(LongPathfinder& pathfinder, std::uint8_t* data, std::size_ pathfinder.GetDebugData(steps, time, debugGrid); // Render navcell passability - u8* p = data; - for (size_t j = 0; j < h; ++j) + TerrainTextureOverlay::OverwriteEachTile(data, w, h, [&](const int i, const int j) { - for (size_t i = 0; i < w; ++i) + if (debugGrid.m_W && debugGrid.m_H) { - SColor4ub color(0, 0, 0, 0); - if (!IS_PASSABLE(pathfinder.m_Grid->get(static_cast(i), static_cast(j)), - pathfinder.m_Debug.PassClass)) - { - color = SColor4ub(255, 0, 0, 127); - } + if (pathfinder.m_Debug.Goal.NavcellContainsGoal(i, j)) + return SColor4ub(0, 0, 255, 127); - if (debugGrid.m_W && debugGrid.m_H) - { - u8 n = debugGrid.get((int)i, (int)j); - - if (n == 1) - color = SColor4ub(255, 255, 0, 127); - else if (n == 2) - color = SColor4ub(0, 255, 0, 127); - - if (pathfinder.m_Debug.Goal.NavcellContainsGoal(i, j)) - color = SColor4ub(0, 0, 255, 127); - } - - *p++ = color.R; - *p++ = color.G; - *p++ = color.B; - *p++ = color.A; + const u8 n{debugGrid.get(i, j)}; + if (n == 1) + return SColor4ub(255, 255, 0, 127); + if (n == 2) + return SColor4ub(0, 255, 0, 127); } - } + if (!IS_PASSABLE(pathfinder.m_Grid->get(j, i), pathfinder.m_Debug.PassClass)) + return SColor4ub(255, 0, 0, 127); + return SColor4ub{0, 0, 0, 0}; + }); // Render the most recently generated path if (pathfinder.m_Debug.Path && !pathfinder.m_Debug.Path->m_Waypoints.empty())