diff options
author | Hop311 <hop3114@gmail.com> | 2023-09-24 23:45:37 +0200 |
---|---|---|
committer | Hop311 <hop3114@gmail.com> | 2023-09-27 15:14:46 +0200 |
commit | de2017128313b9a322eb59c40a4180099d9c18b7 (patch) | |
tree | a8aa710f9f2024e863d489f1ab553dccb4398315 /extension/src | |
parent | fadabd3e19605a7f30ee7e3dd1453f21384dd662 (diff) |
DDS load + moved terrain (type) loading to sim
Diffstat (limited to 'extension/src')
-rw-r--r-- | extension/src/openvic-extension/GameSingleton.cpp | 11 | ||||
-rw-r--r-- | extension/src/openvic-extension/GameSingleton.hpp | 9 | ||||
-rw-r--r-- | extension/src/openvic-extension/LoadGameCompatibility.cpp | 19 | ||||
-rw-r--r-- | extension/src/openvic-extension/LoadGameOpenVic.cpp | 49 | ||||
-rw-r--r-- | extension/src/openvic-extension/Utilities.cpp | 38 |
5 files changed, 56 insertions, 70 deletions
diff --git a/extension/src/openvic-extension/GameSingleton.cpp b/extension/src/openvic-extension/GameSingleton.cpp index 2d6f784..cdba44c 100644 --- a/extension/src/openvic-extension/GameSingleton.cpp +++ b/extension/src/openvic-extension/GameSingleton.cpp @@ -9,10 +9,8 @@ using namespace godot; using namespace OpenVic; -TerrainVariant::TerrainVariant(const std::string_view new_identfier, - colour_t new_colour, Ref<Image> const& new_image) - : HasIdentifierAndColour { new_identfier, new_colour, true, false }, - image { new_image } {} +TerrainVariant::TerrainVariant(const std::string_view new_identfier, Ref<Image> const& new_image) + : HasIdentifier { new_identfier }, image { new_image } {} Ref<Image> TerrainVariant::get_image() const { return image; @@ -81,6 +79,7 @@ void GameSingleton::_bind_methods() { "shadow_displacement", "shadow_tightness", "shadow_radius", "shadow_thickness", "trim_colour", "trim_size", "gradient_falloff", "gradient_base", "donut", "donut_inner_trim", "donut_inner_radius"), &GameSingleton::draw_pie_chart); + ClassDB::bind_static_method("GameSingleton", D_METHOD("load_image", "path"), &GameSingleton::load_image); } void GameSingleton::draw_pie_chart(Ref<Image> image, @@ -94,6 +93,10 @@ void GameSingleton::draw_pie_chart(Ref<Image> image, donut, donut_inner_trim, donut_inner_radius); } +Ref<Image> GameSingleton::load_image(String const& path) { + return load_godot_image(path); +} + GameSingleton* GameSingleton::get_singleton() { return singleton; } diff --git a/extension/src/openvic-extension/GameSingleton.hpp b/extension/src/openvic-extension/GameSingleton.hpp index 4d9e912..2a72e2f 100644 --- a/extension/src/openvic-extension/GameSingleton.hpp +++ b/extension/src/openvic-extension/GameSingleton.hpp @@ -8,17 +8,16 @@ namespace OpenVic { - struct TerrainVariant : HasIdentifierAndColour { + struct TerrainVariant : HasIdentifier { friend class GameSingleton; private: const godot::Ref<godot::Image> image; - TerrainVariant(const std::string_view new_identfier, colour_t new_colour, - godot::Ref<godot::Image> const& new_image); + TerrainVariant(const std::string_view new_identfier, godot::Ref<godot::Image> const& new_image); public: - static constexpr size_t MAX_TERRIN_VARIANT_COUNT = 1 << (8 * sizeof(Map::terrain_t)); + static constexpr size_t MAX_TERRIN_VARIANT_COUNT = 1 << (8 * sizeof(TerrainTypeMapping::index_t)); TerrainVariant(TerrainVariant&&) = default; @@ -39,7 +38,6 @@ namespace OpenVic { godot::Ref<godot::ImageTexture> province_colour_texture; Mapmode::index_t mapmode_index = 0; IdentifierRegistry<TerrainVariant> terrain_variants; - Map::terrain_variant_map_t terrain_variant_map; godot::Ref<godot::Texture2DArray> terrain_texture; godot::Error _generate_terrain_texture_array(); @@ -63,6 +61,7 @@ namespace OpenVic { godot::Vector2 shadow_displacement, float shadow_tightness, float shadow_radius, float shadow_thickness, godot::Color trim_colour, float trim_size, float gradient_falloff, float gradient_base, bool donut, bool donut_inner_trim, float donut_inner_radius); + static godot::Ref<godot::Image> load_image(godot::String const& path); static GameSingleton* get_singleton(); diff --git a/extension/src/openvic-extension/LoadGameCompatibility.cpp b/extension/src/openvic-extension/LoadGameCompatibility.cpp index b696315..0a6cb33 100644 --- a/extension/src/openvic-extension/LoadGameCompatibility.cpp +++ b/extension/src/openvic-extension/LoadGameCompatibility.cpp @@ -12,18 +12,7 @@ using namespace godot; using namespace OpenVic; Error GameSingleton::_load_terrain_variants_compatibility_mode(String const& terrain_image_path, String const& terrain_texturesheet_path) { - // Read BMP's palette to determine terrain variant colours which texture they're associated with - BMP bmp; - if (!(bmp.open(godot_to_std_string(terrain_image_path).c_str()) && bmp.read_header() && bmp.read_palette())) { - UtilityFunctions::push_error("Failed to read BMP palette from compatibility mode terrain image: ", terrain_image_path); - return FAILED; - } - std::vector<colour_t> const& palette = bmp.get_palette(); - static constexpr int32_t SHEET_DIMS = 8, PALETTE_SIZE = SHEET_DIMS * SHEET_DIMS; - if (palette.size() == 0 || palette.size() < PALETTE_SIZE) { - UtilityFunctions::push_error("Invalid BMP palette size for terrain image: ", static_cast<uint64_t>(palette.size()), " (expected ", PALETTE_SIZE, ")"); - return FAILED; - } + static constexpr int32_t SHEET_DIMS = 8, SHEET_SIZE = SHEET_DIMS * SHEET_DIMS; // Load the terrain texture sheet and prepare to slice it up Ref<Image> terrain_sheet = load_godot_image(terrain_texturesheet_path); @@ -44,10 +33,10 @@ Error GameSingleton::_load_terrain_variants_compatibility_mode(String const& ter Ref<Image> water_image = Image::create(slice_size, slice_size, false, terrain_sheet->get_format()); ERR_FAIL_NULL_V_EDMSG(water_image, FAILED, "Failed to create water terrain image"); water_image->fill({ 0.1f, 0.1f, 0.5f }); - terrain_variants.add_item({ "terrain_water", TERRAIN_WATER_INDEX_COLOUR, water_image }); + terrain_variants.add_item({ "terrain_water", water_image }); } Error err = OK; - for (int32_t idx = 0; idx < PALETTE_SIZE; ++idx) { + for (int32_t idx = 0; idx < SHEET_SIZE; ++idx) { const Rect2i slice { (idx % SHEET_DIMS) * slice_size, (7 - (idx / SHEET_DIMS)) * slice_size, slice_size, slice_size }; const Ref<Image> terrain_image = terrain_sheet->get_region(slice); if (terrain_image.is_null() || terrain_image->is_empty()) { @@ -55,7 +44,7 @@ Error GameSingleton::_load_terrain_variants_compatibility_mode(String const& ter err = FAILED; continue; } - if (!terrain_variants.add_item({ "terrain_" + std::to_string(idx), palette[idx], terrain_image })) err = FAILED; + if (!terrain_variants.add_item({ "terrain_" + std::to_string(idx), terrain_image })) err = FAILED; } terrain_variants.lock(); if (_generate_terrain_texture_array() != OK) return FAILED; diff --git a/extension/src/openvic-extension/LoadGameOpenVic.cpp b/extension/src/openvic-extension/LoadGameOpenVic.cpp index c34411c..b118f87 100644 --- a/extension/src/openvic-extension/LoadGameOpenVic.cpp +++ b/extension/src/openvic-extension/LoadGameOpenVic.cpp @@ -25,7 +25,6 @@ Error GameSingleton::_generate_terrain_texture_array() { Array terrain_images; for (size_t i = 0; i < terrain_variants.size() && i < TerrainVariant::MAX_TERRIN_VARIANT_COUNT; ++i) { TerrainVariant const& var = *terrain_variants.get_item_by_index(i); - terrain_variant_map[var.get_colour()] = i; terrain_images.append(var.get_image()); } @@ -43,53 +42,11 @@ Error GameSingleton::_load_map_images(String const& province_image_path, String return FAILED; } - // Load images - Ref<Image> province_image = load_godot_image(province_image_path); - if (province_image.is_null()) { - UtilityFunctions::push_error("Failed to load province image: ", province_image_path); - return FAILED; - } - Ref<Image> terrain_image = load_godot_image(terrain_image_path); - if (terrain_image.is_null()) { - UtilityFunctions::push_error("Failed to load terrain image: ", terrain_image_path); - return FAILED; - } - - if (flip_vertical) { - province_image->flip_y(); - terrain_image->flip_y(); - } - - // Validate dimensions and format Error err = OK; - const Vector2i province_dims = province_image->get_size(), terrain_dims = terrain_image->get_size(); - if (province_dims.x < 1 || province_dims.y < 1) { - UtilityFunctions::push_error("Invalid dimensions (", province_dims.x, "x", province_dims.y, ") for province image: ", province_image_path); - err = FAILED; - } - if (province_dims != terrain_dims) { - UtilityFunctions::push_error("Invalid dimensions (", terrain_dims.x, "x", terrain_dims.y, ") for terrain image: ", - terrain_image_path, " (must match province image: (", province_dims.x, "x", province_dims.x, "))"); - err = FAILED; - } - static constexpr Image::Format expected_format = Image::FORMAT_RGB8; - if (province_image->get_format() == Image::FORMAT_RGBA8) province_image->convert(expected_format); - if (terrain_image->get_format() == Image::FORMAT_RGBA8) terrain_image->convert(expected_format); - if (province_image->get_format() != expected_format) { - UtilityFunctions::push_error("Invalid format (", province_image->get_format(), ", should be ", expected_format, ") for province image: ", province_image_path); - err = FAILED; - } - if (terrain_image->get_format() != expected_format) { - UtilityFunctions::push_error("Invalid format (", terrain_image->get_format(), ", should be ", expected_format, ") for terrain image: ", terrain_image_path); - err = FAILED; - } - if (err != OK) return err; - // Generate interleaved province and terrain ID image - if (!game_manager.get_map().generate_province_shape_image(province_dims.x, province_dims.y, - province_image->get_data().ptr(), terrain_image->get_data().ptr(), terrain_variant_map, - false /* <-- whether to print detailed map errors or not (specific missing/unrecognised colours) */ - )) err = FAILED; + const Vector2i province_dims { + static_cast<int32_t>(game_manager.get_map().get_width()), + static_cast<int32_t>(game_manager.get_map().get_height()) }; static constexpr int32_t GPU_DIM_LIMIT = 0x3FFF; // For each dimension of the image, this finds the small number of equal subdivisions required get the individual texture dims under GPU_DIM_LIMIT diff --git a/extension/src/openvic-extension/Utilities.cpp b/extension/src/openvic-extension/Utilities.cpp index 4ca6855..649550f 100644 --- a/extension/src/openvic-extension/Utilities.cpp +++ b/extension/src/openvic-extension/Utilities.cpp @@ -2,17 +2,55 @@ #include <numbers> +#include <godot_cpp/classes/file_access.hpp> #include <godot_cpp/classes/resource_loader.hpp> #include <godot_cpp/variant/utility_functions.hpp> +#include <gli/convert.hpp> +#include <gli/load_dds.hpp> + using namespace godot; using namespace OpenVic; +static Ref<Image> load_dds_image(String const& path) { + gli::texture2d texture { gli::load_dds(godot_to_std_string(path)) }; + if (texture.empty()) { + UtilityFunctions::push_error("Failed to load DDS file: ", path); + return {}; + } + + static constexpr gli::format expected_format = gli::FORMAT_BGRA8_UNORM_PACK8; + const bool needs_bgr_to_rgb = texture.format() == expected_format; + if (!needs_bgr_to_rgb) { + texture = gli::convert(texture, expected_format); + if (texture.empty()) { + UtilityFunctions::push_error("Failed to convert DDS file: ", path); + return {}; + } + } + + PackedByteArray pixels; + pixels.resize(texture.size()); + memcpy(pixels.ptrw(), texture.data(), pixels.size()); + UtilityFunctions::print("needs_bgr_to_rgb = ", needs_bgr_to_rgb); + if (needs_bgr_to_rgb) { + for (size_t i = 0; i < pixels.size(); i += 4) { + std::swap(pixels[i], pixels[i+2]); + } + } + + const gli::texture2d::extent_type extent { texture.extent() }; + return Image::create_from_data(extent.x, extent.y, false, Image::FORMAT_RGBA8, pixels); +} + Ref<Image> OpenVic::load_godot_image(String const& path) { if (path.begins_with("res://")) { ResourceLoader* loader = ResourceLoader::get_singleton(); return loader ? loader->load(path) : nullptr; } else { + if (path.ends_with(".dds")) { + return load_dds_image(path); + } return Image::load_from_file(path); } } |