aboutsummaryrefslogtreecommitdiff
path: root/extension/src
diff options
context:
space:
mode:
author Hop311 <hop3114@gmail.com>2023-09-24 23:45:37 +0200
committer Hop311 <hop3114@gmail.com>2023-09-27 15:14:46 +0200
commitde2017128313b9a322eb59c40a4180099d9c18b7 (patch)
treea8aa710f9f2024e863d489f1ab553dccb4398315 /extension/src
parentfadabd3e19605a7f30ee7e3dd1453f21384dd662 (diff)
DDS load + moved terrain (type) loading to sim
Diffstat (limited to 'extension/src')
-rw-r--r--extension/src/openvic-extension/GameSingleton.cpp11
-rw-r--r--extension/src/openvic-extension/GameSingleton.hpp9
-rw-r--r--extension/src/openvic-extension/LoadGameCompatibility.cpp19
-rw-r--r--extension/src/openvic-extension/LoadGameOpenVic.cpp49
-rw-r--r--extension/src/openvic-extension/Utilities.cpp38
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);
}
}