mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 03:00:06 +00:00 
			
		
		
		
	Load placefile icons into texture atlas cache
This commit is contained in:
		
							parent
							
								
									1f2d5227c4
								
							
						
					
					
						commit
						0f9fbdbf63
					
				
					 12 changed files with 237 additions and 44 deletions
				
			
		|  | @ -46,7 +46,8 @@ set(HDR_CONFIG source/scwx/qt/config/county_database.hpp | ||||||
|                source/scwx/qt/config/radar_site.hpp) |                source/scwx/qt/config/radar_site.hpp) | ||||||
| set(SRC_CONFIG source/scwx/qt/config/county_database.cpp | set(SRC_CONFIG source/scwx/qt/config/county_database.cpp | ||||||
|                source/scwx/qt/config/radar_site.cpp) |                source/scwx/qt/config/radar_site.cpp) | ||||||
| set(SRC_EXTERNAL source/scwx/qt/external/stb_rect_pack.cpp) | set(SRC_EXTERNAL source/scwx/qt/external/stb_image.cpp | ||||||
|  |                  source/scwx/qt/external/stb_rect_pack.cpp) | ||||||
| set(HDR_GL source/scwx/qt/gl/gl.hpp | set(HDR_GL source/scwx/qt/gl/gl.hpp | ||||||
|            source/scwx/qt/gl/gl_context.hpp |            source/scwx/qt/gl/gl_context.hpp | ||||||
|            source/scwx/qt/gl/shader_program.hpp |            source/scwx/qt/gl/shader_program.hpp | ||||||
|  | @ -203,6 +204,7 @@ set(HDR_UTIL source/scwx/qt/util/color.hpp | ||||||
|              source/scwx/qt/util/geographic_lib.hpp |              source/scwx/qt/util/geographic_lib.hpp | ||||||
|              source/scwx/qt/util/json.hpp |              source/scwx/qt/util/json.hpp | ||||||
|              source/scwx/qt/util/maplibre.hpp |              source/scwx/qt/util/maplibre.hpp | ||||||
|  |              source/scwx/qt/util/network.hpp | ||||||
|              source/scwx/qt/util/streams.hpp |              source/scwx/qt/util/streams.hpp | ||||||
|              source/scwx/qt/util/texture_atlas.hpp |              source/scwx/qt/util/texture_atlas.hpp | ||||||
|              source/scwx/qt/util/q_file_buffer.hpp |              source/scwx/qt/util/q_file_buffer.hpp | ||||||
|  | @ -215,6 +217,7 @@ set(SRC_UTIL source/scwx/qt/util/color.cpp | ||||||
|              source/scwx/qt/util/geographic_lib.cpp |              source/scwx/qt/util/geographic_lib.cpp | ||||||
|              source/scwx/qt/util/json.cpp |              source/scwx/qt/util/json.cpp | ||||||
|              source/scwx/qt/util/maplibre.cpp |              source/scwx/qt/util/maplibre.cpp | ||||||
|  |              source/scwx/qt/util/network.cpp | ||||||
|              source/scwx/qt/util/texture_atlas.cpp |              source/scwx/qt/util/texture_atlas.cpp | ||||||
|              source/scwx/qt/util/q_file_buffer.cpp |              source/scwx/qt/util/q_file_buffer.cpp | ||||||
|              source/scwx/qt/util/q_file_input_stream.cpp |              source/scwx/qt/util/q_file_input_stream.cpp | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								scwx-qt/source/scwx/qt/external/stb_image.cpp
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								scwx-qt/source/scwx/qt/external/stb_image.cpp
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | #define STB_IMAGE_IMPLEMENTATION | ||||||
|  | #define STBI_ASSERT(x) | ||||||
|  | #define STBI_FAILURE_USERMSG | ||||||
|  | #include <stb_image.h> | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <aws/core/Aws.h> | #include <aws/core/Aws.h> | ||||||
| #include <boost/asio.hpp> | #include <boost/asio.hpp> | ||||||
|  | #include <fmt/format.h> | ||||||
| #include <spdlog/spdlog.h> | #include <spdlog/spdlog.h> | ||||||
| #include <QApplication> | #include <QApplication> | ||||||
| #include <QTranslator> | #include <QTranslator> | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| #include <scwx/qt/manager/placefile_manager.hpp> | #include <scwx/qt/manager/placefile_manager.hpp> | ||||||
|  | #include <scwx/qt/manager/resource_manager.hpp> | ||||||
|  | #include <scwx/qt/util/network.hpp> | ||||||
| #include <scwx/gr/placefile.hpp> | #include <scwx/gr/placefile.hpp> | ||||||
| #include <scwx/network/cpr.hpp> | #include <scwx/network/cpr.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
|  | @ -35,7 +37,7 @@ public: | ||||||
|    explicit Impl(PlacefileManager* self) : self_ {self} {} |    explicit Impl(PlacefileManager* self) : self_ {self} {} | ||||||
|    ~Impl() {} |    ~Impl() {} | ||||||
| 
 | 
 | ||||||
|    static std::string NormalizeUrl(const std::string& urlString); |    static void LoadResources(const std::shared_ptr<gr::Placefile>& placefile); | ||||||
| 
 | 
 | ||||||
|    boost::asio::thread_pool threadPool_ {1u}; |    boost::asio::thread_pool threadPool_ {1u}; | ||||||
| 
 | 
 | ||||||
|  | @ -67,7 +69,7 @@ public: | ||||||
| 
 | 
 | ||||||
|    void Update(); |    void Update(); | ||||||
|    void UpdateAsync(); |    void UpdateAsync(); | ||||||
|    void UpdatePlacefile(std::shared_ptr<gr::Placefile> placefile); |    void UpdatePlacefile(const std::shared_ptr<gr::Placefile>& placefile); | ||||||
| 
 | 
 | ||||||
|    Impl* p; |    Impl* p; | ||||||
| 
 | 
 | ||||||
|  | @ -78,10 +80,6 @@ public: | ||||||
|    boost::asio::thread_pool       threadPool_ {1u}; |    boost::asio::thread_pool       threadPool_ {1u}; | ||||||
|    boost::asio::steady_timer      refreshTimer_ {threadPool_}; |    boost::asio::steady_timer      refreshTimer_ {threadPool_}; | ||||||
|    std::mutex                     refreshMutex_ {}; |    std::mutex                     refreshMutex_ {}; | ||||||
| 
 |  | ||||||
| signals: |  | ||||||
|    void Updated(const std::string&             name, |  | ||||||
|                 std::shared_ptr<gr::Placefile> placefile); |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this)) {} | PlacefileManager::PlacefileManager() : p(std::make_unique<Impl>(this)) {} | ||||||
|  | @ -167,7 +165,7 @@ void PlacefileManager::set_placefile_thresholded(const std::string& name, | ||||||
| void PlacefileManager::set_placefile_url(const std::string& name, | void PlacefileManager::set_placefile_url(const std::string& name, | ||||||
|                                          const std::string& newUrl) |                                          const std::string& newUrl) | ||||||
| { | { | ||||||
|    std::string normalizedUrl = Impl::NormalizeUrl(newUrl); |    std::string normalizedUrl = util::network::NormalizeUrl(newUrl); | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock(p->placefileRecordLock_); |    std::unique_lock lock(p->placefileRecordLock_); | ||||||
| 
 | 
 | ||||||
|  | @ -235,7 +233,7 @@ PlacefileManager::GetActivePlacefiles() | ||||||
| 
 | 
 | ||||||
| void PlacefileManager::AddUrl(const std::string& urlString) | void PlacefileManager::AddUrl(const std::string& urlString) | ||||||
| { | { | ||||||
|    std::string normalizedUrl = Impl::NormalizeUrl(urlString); |    std::string normalizedUrl = util::network::NormalizeUrl(urlString); | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock(p->placefileRecordLock_); |    std::unique_lock lock(p->placefileRecordLock_); | ||||||
| 
 | 
 | ||||||
|  | @ -318,6 +316,8 @@ void PlacefileManager::LoadFile(const std::string& filename) | ||||||
| 
 | 
 | ||||||
| void PlacefileManager::Impl::PlacefileRecord::Update() | void PlacefileManager::Impl::PlacefileRecord::Update() | ||||||
| { | { | ||||||
|  |    logger_->debug("Update: {}", name_); | ||||||
|  | 
 | ||||||
|    // Make a copy of name in the event it changes.
 |    // Make a copy of name in the event it changes.
 | ||||||
|    const std::string name {name_}; |    const std::string name {name_}; | ||||||
| 
 | 
 | ||||||
|  | @ -399,6 +399,9 @@ void PlacefileManager::Impl::PlacefileRecord::Update() | ||||||
| 
 | 
 | ||||||
|    if (updatedPlacefile != nullptr) |    if (updatedPlacefile != nullptr) | ||||||
|    { |    { | ||||||
|  |       // Load placefile resources
 | ||||||
|  |       Impl::LoadResources(updatedPlacefile); | ||||||
|  | 
 | ||||||
|       // Check the name matches, in case the name updated
 |       // Check the name matches, in case the name updated
 | ||||||
|       if (name_ == name) |       if (name_ == name) | ||||||
|       { |       { | ||||||
|  | @ -421,7 +424,7 @@ void PlacefileManager::Impl::PlacefileRecord::UpdateAsync() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileManager::Impl::PlacefileRecord::UpdatePlacefile( | void PlacefileManager::Impl::PlacefileRecord::UpdatePlacefile( | ||||||
|    std::shared_ptr<gr::Placefile> placefile) |    const std::shared_ptr<gr::Placefile>& placefile) | ||||||
| { | { | ||||||
|    // Update placefile
 |    // Update placefile
 | ||||||
|    placefile_ = placefile; |    placefile_ = placefile; | ||||||
|  | @ -448,22 +451,22 @@ std::shared_ptr<PlacefileManager> PlacefileManager::Instance() | ||||||
|    return placefileManager; |    return placefileManager; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string PlacefileManager::Impl::NormalizeUrl(const std::string& urlString) | void PlacefileManager::Impl::LoadResources( | ||||||
|  |    const std::shared_ptr<gr::Placefile>& placefile) | ||||||
| { | { | ||||||
|    std::string normalizedUrl; |    const auto iconFiles = placefile->icon_files(); | ||||||
| 
 | 
 | ||||||
|    // Normalize URL string
 |    const QUrl baseUrl = | ||||||
|    QUrl url = QUrl::fromUserInput(QString::fromStdString(urlString)); |       QUrl::fromUserInput(QString::fromStdString(placefile->name())); | ||||||
|    if (url.isLocalFile()) |  | ||||||
|    { |  | ||||||
|       normalizedUrl = QDir::toNativeSeparators(url.toLocalFile()).toStdString(); |  | ||||||
|    } |  | ||||||
|    else |  | ||||||
|    { |  | ||||||
|       normalizedUrl = urlString; |  | ||||||
|    } |  | ||||||
| 
 | 
 | ||||||
|    return normalizedUrl; |    // TODO: Parallelize
 | ||||||
|  |    for (auto& iconFile : iconFiles) | ||||||
|  |    { | ||||||
|  |       QUrl fileUrl     = QUrl(QString::fromStdString(iconFile->filename_)); | ||||||
|  |       QUrl resolvedUrl = baseUrl.resolved(fileUrl); | ||||||
|  | 
 | ||||||
|  |       ResourceManager::LoadImageResource(resolvedUrl.toString().toStdString()); | ||||||
|  |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace manager
 | } // namespace manager
 | ||||||
|  |  | ||||||
|  | @ -5,9 +5,8 @@ | ||||||
| #include <scwx/qt/util/texture_atlas.hpp> | #include <scwx/qt/util/texture_atlas.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
| #include <imgui.h> |  | ||||||
| 
 |  | ||||||
| #include <QFontDatabase> | #include <QFontDatabase> | ||||||
|  | #include <imgui.h> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -62,6 +61,12 @@ std::shared_ptr<util::Font> Font(types::Font font) | ||||||
|    return nullptr; |    return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void LoadImageResource(const std::string& urlString) | ||||||
|  | { | ||||||
|  |    util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); | ||||||
|  |    textureAtlas.CacheTexture(urlString, urlString); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void LoadFonts() | static void LoadFonts() | ||||||
| { | { | ||||||
|    for (auto& fontName : fontNames_) |    for (auto& fontName : fontNames_) | ||||||
|  |  | ||||||
|  | @ -18,6 +18,8 @@ void Shutdown(); | ||||||
| int                         FontId(types::Font font); | int                         FontId(types::Font font); | ||||||
| std::shared_ptr<util::Font> Font(types::Font font); | std::shared_ptr<util::Font> Font(types::Font font); | ||||||
| 
 | 
 | ||||||
|  | void LoadImageResource(const std::string& urlString); | ||||||
|  | 
 | ||||||
| } // namespace ResourceManager
 | } // namespace ResourceManager
 | ||||||
| } // namespace manager
 | } // namespace manager
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								scwx-qt/source/scwx/qt/util/network.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								scwx-qt/source/scwx/qt/util/network.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | #include <scwx/qt/util/network.hpp> | ||||||
|  | 
 | ||||||
|  | #include <QDir> | ||||||
|  | #include <QUrl> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace util | ||||||
|  | { | ||||||
|  | namespace network | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | std::string NormalizeUrl(const std::string& urlString) | ||||||
|  | { | ||||||
|  |    std::string normalizedUrl; | ||||||
|  | 
 | ||||||
|  |    // Normalize URL string
 | ||||||
|  |    QUrl url = QUrl::fromUserInput(QString::fromStdString(urlString)); | ||||||
|  |    if (url.isLocalFile()) | ||||||
|  |    { | ||||||
|  |       normalizedUrl = QDir::toNativeSeparators(url.toLocalFile()).toStdString(); | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       normalizedUrl = urlString; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return normalizedUrl; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace network
 | ||||||
|  | } // namespace util
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										26
									
								
								scwx-qt/source/scwx/qt/util/network.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								scwx-qt/source/scwx/qt/util/network.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace util | ||||||
|  | { | ||||||
|  | namespace network | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Converts a local or remote URL to a consistent format. | ||||||
|  |  * | ||||||
|  |  * @param [in] urlString URL to normalize | ||||||
|  |  * | ||||||
|  |  * @return Normalized URL string | ||||||
|  |  */ | ||||||
|  | std::string NormalizeUrl(const std::string& urlString); | ||||||
|  | 
 | ||||||
|  | } // namespace network
 | ||||||
|  | } // namespace util
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include <scwx/qt/util/texture_atlas.hpp> | #include <scwx/qt/util/texture_atlas.hpp> | ||||||
| #include <scwx/qt/util/streams.hpp> | #include <scwx/qt/util/streams.hpp> | ||||||
|  | #include <scwx/network/cpr.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
| #include <shared_mutex> | #include <shared_mutex> | ||||||
|  | @ -13,8 +14,11 @@ | ||||||
| 
 | 
 | ||||||
| #include <boost/gil/extension/io/png.hpp> | #include <boost/gil/extension/io/png.hpp> | ||||||
| #include <boost/iostreams/stream.hpp> | #include <boost/iostreams/stream.hpp> | ||||||
|  | #include <cpr/cpr.h> | ||||||
|  | #include <stb_image.h> | ||||||
| #include <stb_rect_pack.h> | #include <stb_rect_pack.h> | ||||||
| #include <QFile> | #include <QFile> | ||||||
|  | #include <QUrl> | ||||||
| 
 | 
 | ||||||
| #if defined(_MSC_VER) | #if defined(_MSC_VER) | ||||||
| #   pragma warning(pop) | #   pragma warning(pop) | ||||||
|  | @ -48,6 +52,9 @@ public: | ||||||
|    std::unordered_map<std::string, std::string> texturePathMap_; |    std::unordered_map<std::string, std::string> texturePathMap_; | ||||||
|    std::shared_mutex                            texturePathMutex_; |    std::shared_mutex                            texturePathMutex_; | ||||||
| 
 | 
 | ||||||
|  |    std::shared_mutex textureCacheMutex_; | ||||||
|  |    std::unordered_map<std::string, boost::gil::rgba8_image_t> textureCache_; | ||||||
|  | 
 | ||||||
|    boost::gil::rgba8_image_t                          atlas_; |    boost::gil::rgba8_image_t                          atlas_; | ||||||
|    std::unordered_map<std::string, TextureAttributes> atlasMap_; |    std::unordered_map<std::string, TextureAttributes> atlasMap_; | ||||||
|    std::shared_mutex                                  atlasMutex_; |    std::shared_mutex                                  atlasMutex_; | ||||||
|  | @ -66,6 +73,34 @@ void TextureAtlas::RegisterTexture(const std::string& name, | ||||||
|    p->texturePathMap_.insert_or_assign(name, path); |    p->texturePathMap_.insert_or_assign(name, path); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool TextureAtlas::CacheTexture(const std::string& name, | ||||||
|  |                                 const std::string& path) | ||||||
|  | { | ||||||
|  |    // If the image is already loaded, we don't need to load it again
 | ||||||
|  |    { | ||||||
|  |       std::shared_lock lock(p->textureCacheMutex_); | ||||||
|  | 
 | ||||||
|  |       if (p->textureCache_.contains(path)) | ||||||
|  |       { | ||||||
|  |          return false; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Attempt to load the image
 | ||||||
|  |    boost::gil::rgba8_image_t image = TextureAtlas::Impl::LoadImage(path); | ||||||
|  | 
 | ||||||
|  |    // If the image is valid
 | ||||||
|  |    if (image.width() > 0 && image.height() > 0) | ||||||
|  |    { | ||||||
|  |       // Store it in the texture cache
 | ||||||
|  |       std::unique_lock lock(p->textureCacheMutex_); | ||||||
|  | 
 | ||||||
|  |       p->textureCache_.emplace(name, std::move(image)); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void TextureAtlas::BuildAtlas(size_t width, size_t height) | void TextureAtlas::BuildAtlas(size_t width, size_t height) | ||||||
| { | { | ||||||
|    logger_->debug("Building {}x{} texture atlas", width, height); |    logger_->debug("Building {}x{} texture atlas", width, height); | ||||||
|  | @ -110,6 +145,11 @@ void TextureAtlas::BuildAtlas(size_t width, size_t height) | ||||||
|                     }); |                     }); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // TODO: Cached images
 | ||||||
|  |    { | ||||||
|  | 
 | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|    // Pack images
 |    // Pack images
 | ||||||
|    { |    { | ||||||
|       logger_->trace("Packing {} images", images.size()); |       logger_->trace("Packing {} images", images.size()); | ||||||
|  | @ -260,29 +300,86 @@ TextureAtlas::Impl::LoadImage(const std::string& imagePath) | ||||||
| 
 | 
 | ||||||
|    boost::gil::rgba8_image_t image; |    boost::gil::rgba8_image_t image; | ||||||
| 
 | 
 | ||||||
|    QFile imageFile(imagePath.c_str()); |    QUrl url = QUrl::fromUserInput(QString::fromStdString(imagePath)); | ||||||
| 
 | 
 | ||||||
|    imageFile.open(QIODevice::ReadOnly); |    if (url.isLocalFile()) | ||||||
| 
 |  | ||||||
|    if (!imageFile.isOpen()) |  | ||||||
|    { |    { | ||||||
|       logger_->error("Could not open image: {}", imagePath); |       QFile imageFile(imagePath.c_str()); | ||||||
|       return image; | 
 | ||||||
|  |       imageFile.open(QIODevice::ReadOnly); | ||||||
|  | 
 | ||||||
|  |       if (!imageFile.isOpen()) | ||||||
|  |       { | ||||||
|  |          logger_->error("Could not open image: {}", imagePath); | ||||||
|  |          return image; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       boost::iostreams::stream<util::IoDeviceSource> dataStream(imageFile); | ||||||
|  | 
 | ||||||
|  |       try | ||||||
|  |       { | ||||||
|  |          boost::gil::read_and_convert_image( | ||||||
|  |             dataStream, image, boost::gil::png_tag()); | ||||||
|  |       } | ||||||
|  |       catch (const std::exception& ex) | ||||||
|  |       { | ||||||
|  |          logger_->error("Error reading image: {}", ex.what()); | ||||||
|  |          return image; | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 |    else | ||||||
|    boost::iostreams::stream<util::IoDeviceSource> dataStream(imageFile); |  | ||||||
| 
 |  | ||||||
|    boost::gil::image<boost::gil::rgba8_pixel_t, false> x; |  | ||||||
| 
 |  | ||||||
|    try |  | ||||||
|    { |    { | ||||||
|       boost::gil::read_and_convert_image( |       auto response = cpr::Get(cpr::Url {imagePath}, network::cpr::GetHeader()); | ||||||
|          dataStream, image, boost::gil::png_tag()); | 
 | ||||||
|    } |       if (cpr::status::is_success(response.status_code)) | ||||||
|    catch (const std::exception& ex) |       { | ||||||
|    { |          // Use stbi, since we can only guess the image format
 | ||||||
|       logger_->error("Error reading image: {}", ex.what()); |          static constexpr int desiredChannels = 4; | ||||||
|       return image; | 
 | ||||||
|  |          int width; | ||||||
|  |          int height; | ||||||
|  |          int numChannels; | ||||||
|  | 
 | ||||||
|  |          unsigned char* pixelData = stbi_load_from_memory( | ||||||
|  |             reinterpret_cast<const unsigned char*>(response.text.data()), | ||||||
|  |             static_cast<int>( | ||||||
|  |                std::clamp<std::size_t>(response.text.size(), 0, INT32_MAX)), | ||||||
|  |             &width, | ||||||
|  |             &height, | ||||||
|  |             &numChannels, | ||||||
|  |             desiredChannels); | ||||||
|  | 
 | ||||||
|  |          if (pixelData == nullptr) | ||||||
|  |          { | ||||||
|  |             logger_->error("Error loading image: {}", stbi_failure_reason()); | ||||||
|  |             return image; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          // Create a view pointing to the STB image data
 | ||||||
|  |          auto imageView = boost::gil::interleaved_view( | ||||||
|  |             width, | ||||||
|  |             height, | ||||||
|  |             reinterpret_cast<boost::gil::rgba8_pixel_t*>(pixelData), | ||||||
|  |             width * desiredChannels); | ||||||
|  | 
 | ||||||
|  |          // Copy the view to the destination image
 | ||||||
|  |          image = boost::gil::rgba8_image_t(imageView); | ||||||
|  | 
 | ||||||
|  |          if (numChannels == 3) | ||||||
|  |          { | ||||||
|  |             // TODO: If no alpha channel, replace black with transparent
 | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          stbi_image_free(pixelData); | ||||||
|  |       } | ||||||
|  |       else if (response.status_code == 0) | ||||||
|  |       { | ||||||
|  |          logger_->error("Error loading image: {}", response.error.message); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          logger_->error("Error loading image: {}", response.status_line); | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return image; |    return image; | ||||||
|  |  | ||||||
|  | @ -67,6 +67,7 @@ public: | ||||||
|    static TextureAtlas& Instance(); |    static TextureAtlas& Instance(); | ||||||
| 
 | 
 | ||||||
|    void   RegisterTexture(const std::string& name, const std::string& path); |    void   RegisterTexture(const std::string& name, const std::string& path); | ||||||
|  |    bool   CacheTexture(const std::string& name, const std::string& path); | ||||||
|    void   BuildAtlas(size_t width, size_t height); |    void   BuildAtlas(size_t width, size_t height); | ||||||
|    GLuint BufferAtlas(gl::OpenGLFunctions& gl); |    GLuint BufferAtlas(gl::OpenGLFunctions& gl); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -109,6 +109,8 @@ public: | ||||||
|     */ |     */ | ||||||
|    std::vector<std::shared_ptr<DrawItem>> GetDrawItems(); |    std::vector<std::shared_ptr<DrawItem>> GetDrawItems(); | ||||||
| 
 | 
 | ||||||
|  |    std::vector<std::shared_ptr<const IconFile>> icon_files(); | ||||||
|  | 
 | ||||||
|    std::string                                            name() const; |    std::string                                            name() const; | ||||||
|    std::string                                            title() const; |    std::string                                            title() const; | ||||||
|    std::unordered_map<std::size_t, std::shared_ptr<Font>> fonts(); |    std::unordered_map<std::size_t, std::shared_ptr<Font>> fonts(); | ||||||
|  |  | ||||||
|  | @ -86,6 +86,19 @@ std::vector<std::shared_ptr<Placefile::DrawItem>> Placefile::GetDrawItems() | ||||||
|    return p->drawItems_; |    return p->drawItems_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::vector<std::shared_ptr<const Placefile::IconFile>> Placefile::icon_files() | ||||||
|  | { | ||||||
|  |    std::vector<std::shared_ptr<const Placefile::IconFile>> iconFiles {}; | ||||||
|  |    iconFiles.reserve(p->iconFiles_.size()); | ||||||
|  | 
 | ||||||
|  |    std::transform(p->iconFiles_.begin(), | ||||||
|  |                   p->iconFiles_.end(), | ||||||
|  |                   std::back_inserter(iconFiles), | ||||||
|  |                   [](auto& iconFile) { return iconFile.second; }); | ||||||
|  | 
 | ||||||
|  |    return iconFiles; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::string Placefile::name() const | std::string Placefile::name() const | ||||||
| { | { | ||||||
|    return p->name_; |    return p->name_; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat