aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hop311 <hop3114@gmail.com>2023-04-26 13:06:19 +0200
committer Hop311 <hop3114@gmail.com>2023-04-26 13:06:19 +0200
commit2455806f52f0133e5bd5e4997589c5ce4fe99b2c (patch)
treea1882d8d3a4e836ec305dd0893b6eda5ec3dd230
parent10053cf259c55ee45803268a844edf1011d8a16b (diff)
Vertical subdivision + calculation for both dims
-rw-r--r--extension/src/GameSingleton.cpp58
-rw-r--r--extension/src/GameSingleton.hpp6
-rw-r--r--extension/src/MapMesh.cpp18
-rw-r--r--extension/src/MapMesh.hpp10
-rw-r--r--game/src/GameSession/MapView.gd5
-rw-r--r--game/src/GameSession/TerrainMap.gdshader8
6 files changed, 62 insertions, 43 deletions
diff --git a/extension/src/GameSingleton.cpp b/extension/src/GameSingleton.cpp
index 3811dea..3545928 100644
--- a/extension/src/GameSingleton.cpp
+++ b/extension/src/GameSingleton.cpp
@@ -24,6 +24,7 @@ void GameSingleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_province_info_from_index", "index"), &GameSingleton::get_province_info_from_index);
ClassDB::bind_method(D_METHOD("get_width"), &GameSingleton::get_width);
ClassDB::bind_method(D_METHOD("get_height"), &GameSingleton::get_height);
+ ClassDB::bind_method(D_METHOD("get_province_index_image_subdivisions"), &GameSingleton::get_province_index_image_subdivisions);
ClassDB::bind_method(D_METHOD("get_province_index_images"), &GameSingleton::get_province_index_images);
ClassDB::bind_method(D_METHOD("get_province_colour_image"), &GameSingleton::get_province_colour_image);
@@ -231,7 +232,7 @@ Error GameSingleton::load_region_file(String const& file_path) {
}
Error GameSingleton::load_province_shape_file(String const& file_path) {
- if (province_index_image[0].is_valid()) {
+ if (!province_index_images.empty()) {
UtilityFunctions::push_error("Province shape file has already been loaded, cannot load: ", file_path);
return FAILED;
}
@@ -242,16 +243,15 @@ Error GameSingleton::load_province_shape_file(String const& file_path) {
UtilityFunctions::push_error("Failed to load province shape file: ", file_path);
return err;
}
- const int32_t width = province_shape_image->get_width();
- const int32_t height = province_shape_image->get_height();
- if (width < 1 || height < 1) {
- UtilityFunctions::push_error("Invalid dimensions (", width, "x", height, ") for province shape file: ", file_path);
- err = FAILED;
- }
- if (width % image_width_divide != 0) {
- UtilityFunctions::push_error("Invalid width ", width, " (must be divisible by ", image_width_divide, ") for province shape file: ", file_path);
+ const Vector2i image_dims = province_shape_image->get_size();
+ if (image_dims.x < 1 || image_dims.y < 1) {
+ UtilityFunctions::push_error("Invalid dimensions (", image_dims.x, "x", image_dims.y, ") for province shape file: ", file_path);
err = FAILED;
}
+ 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
+ for (int i = 0; i < 2; ++i) for (image_subdivisions[i] = 1;
+ image_dims[i] / image_subdivisions[i] > GPU_DIM_LIMIT || image_dims[i] % image_subdivisions[i] != 0; ++image_subdivisions[i]);
static constexpr Image::Format expected_format = Image::FORMAT_RGB8;
const Image::Format format = province_shape_image->get_format();
if (format != expected_format) {
@@ -259,21 +259,27 @@ Error GameSingleton::load_province_shape_file(String const& file_path) {
err = FAILED;
}
if (err != OK) return err;
- err = ERR(game_manager.map.generate_province_index_image(width, height, province_shape_image->get_data().ptr()));
+ err = ERR(game_manager.map.generate_province_index_image(image_dims.x, image_dims.y, province_shape_image->get_data().ptr()));
std::vector<Province::index_t> const& province_index_data = game_manager.map.get_province_index_image();
- const int32_t divided_width = width / image_width_divide;
- for (int32_t i = 0; i < image_width_divide; ++i) {
- PackedByteArray index_data_array;
- index_data_array.resize(divided_width * height * sizeof(Province::index_t));
- for (int32_t y = 0; y < height; ++y)
- memcpy(index_data_array.ptrw() + y * divided_width * sizeof(Province::index_t),
- province_index_data.data() + y * width + i * divided_width,
- divided_width * sizeof(Province::index_t));
- province_index_image[i] = Image::create_from_data(divided_width, height, false, Image::FORMAT_RG8, index_data_array);
- if (province_index_image[i].is_null()) {
- UtilityFunctions::push_error("Failed to create province ID image #", i);
- err = FAILED;
+ const Vector2i divided_dims = image_dims / image_subdivisions;
+ province_index_images.resize(image_subdivisions.x * image_subdivisions.y);
+ for (int32_t v = 0; v < image_subdivisions.y; ++v) {
+ for (int32_t u = 0; u < image_subdivisions.x; ++u) {
+ PackedByteArray index_data_array;
+ index_data_array.resize(divided_dims.x * divided_dims.y * sizeof(Province::index_t));
+
+ for (int32_t y = 0; y < divided_dims.y; ++y)
+ memcpy(index_data_array.ptrw() + y * divided_dims.x * sizeof(Province::index_t),
+ province_index_data.data() + (v * divided_dims.y + y) * image_dims.x + u * divided_dims.x,
+ divided_dims.x * sizeof(Province::index_t));
+
+ const int32_t idx = u + v * image_subdivisions.x;
+ province_index_images[idx] = Image::create_from_data(divided_dims.x, divided_dims.y, false, Image::FORMAT_RG8, index_data_array);
+ if (province_index_images[idx].is_null()) {
+ UtilityFunctions::push_error("Failed to create province index image (", u, ", ", v, ")");
+ err = FAILED;
+ }
}
}
@@ -366,10 +372,14 @@ int32_t GameSingleton::get_height() const {
return game_manager.map.get_height();
}
+Vector2i GameSingleton::get_province_index_image_subdivisions() const {
+ return image_subdivisions;
+}
+
Array GameSingleton::get_province_index_images() const {
Array ret;
- for (int i = 0; i < image_width_divide; ++i)
- ret.append(province_index_image[i]);
+ for (Ref<Image> const& image : province_index_images)
+ ret.append(image);
return ret;
}
diff --git a/extension/src/GameSingleton.hpp b/extension/src/GameSingleton.hpp
index d9879ef..35aec19 100644
--- a/extension/src/GameSingleton.hpp
+++ b/extension/src/GameSingleton.hpp
@@ -14,8 +14,9 @@ namespace OpenVic2 {
GameManager game_manager;
- static constexpr int image_width_divide = 2;
- godot::Ref<godot::Image> province_index_image[image_width_divide], province_colour_image;
+ godot::Vector2i image_subdivisions;
+ std::vector<godot::Ref<godot::Image>> province_index_images;
+ godot::Ref<godot::Image> province_colour_image;
Mapmode::index_t mapmode_index = 0;
godot::Error _parse_province_identifier_entry(godot::String const& identifier, godot::Variant const& entry);
@@ -40,6 +41,7 @@ namespace OpenVic2 {
godot::Dictionary get_province_info_from_index(int32_t index) const;
int32_t get_width() const;
int32_t get_height() const;
+ godot::Vector2i get_province_index_image_subdivisions() const;
godot::Array get_province_index_images() const;
godot::Ref<godot::Image> get_province_colour_image() const;
diff --git a/extension/src/MapMesh.cpp b/extension/src/MapMesh.cpp
index 91c7611..6d94973 100644
--- a/extension/src/MapMesh.cpp
+++ b/extension/src/MapMesh.cpp
@@ -50,21 +50,21 @@ float MapMesh::get_repeat_proportion() const {
return repeat_proportion;
}
-void MapMesh::set_subdivide_width(const int divisions) {
+void MapMesh::set_subdivide_width(const int32_t divisions) {
subdivide_w = divisions > 0 ? divisions : 0;
_request_update();
}
-int MapMesh::get_subdivide_width() const {
+int32_t MapMesh::get_subdivide_width() const {
return subdivide_w;
}
-void MapMesh::set_subdivide_depth(const int divisions) {
+void MapMesh::set_subdivide_depth(const int32_t divisions) {
subdivide_d = divisions > 0 ? divisions : 0;
_request_update();
}
-int MapMesh::get_subdivide_depth() const {
+int32_t MapMesh::get_subdivide_depth() const {
return subdivide_d;
}
@@ -81,8 +81,8 @@ Array MapMesh::_create_mesh_array() const {
Array arr;
arr.resize(Mesh::ARRAY_MAX);
- const int vertex_count = (subdivide_w + 2) * (subdivide_d + 2);
- const int indice_count = (subdivide_w + 1) * (subdivide_d + 1) * 6;
+ const int32_t vertex_count = (subdivide_w + 2) * (subdivide_d + 2);
+ const int32_t indice_count = (subdivide_w + 1) * (subdivide_d + 1) * 6;
PackedVector3Array points;
PackedVector3Array normals;
@@ -100,17 +100,17 @@ Array MapMesh::_create_mesh_array() const {
const Size2 uv_size{ 1.0f + 2.0f * repeat_proportion, 1.0f };
const Size2 size{ aspect_ratio * uv_size.x, uv_size.y }, start_pos = size * -0.5f;
- int point_index = 0, thisrow = 0, prevrow = 0, indice_index = 0;
+ int32_t point_index = 0, thisrow = 0, prevrow = 0, indice_index = 0;
Vector2 subdivide_step{ 1.0f / (subdivide_w + 1.0f) , 1.0f / (subdivide_d + 1.0f) };
Vector3 point{ 0.0f, 0.0f, start_pos.y };
Vector2 point_step = subdivide_step * size;
Vector2 uv{}, uv_step = subdivide_step * uv_size;
- for (int j = 0; j <= subdivide_d + 1; ++j) {
+ for (int32_t j = 0; j <= subdivide_d + 1; ++j) {
point.x = start_pos.x;
uv.x = -repeat_proportion;
- for (int i = 0; i <= subdivide_w + 1; ++i) {
+ for (int32_t i = 0; i <= subdivide_w + 1; ++i) {
points[point_index] = point;
normals[point_index] = normal;
tangents[point_index * 4 + 0] = 1.0f;
diff --git a/extension/src/MapMesh.hpp b/extension/src/MapMesh.hpp
index d8727cf..89c0147 100644
--- a/extension/src/MapMesh.hpp
+++ b/extension/src/MapMesh.hpp
@@ -7,7 +7,7 @@ namespace OpenVic2 {
GDCLASS(MapMesh, godot::PrimitiveMesh)
float aspect_ratio = 2.0f, repeat_proportion = 0.5f;
- int subdivide_w = 0, subdivide_d = 0;
+ int32_t subdivide_w = 0, subdivide_d = 0;
protected:
static void _bind_methods();
@@ -20,11 +20,11 @@ namespace OpenVic2 {
void set_repeat_proportion(const float proportion);
float get_repeat_proportion() const;
- void set_subdivide_width(const int divisions);
- int get_subdivide_width() const;
+ void set_subdivide_width(const int32_t divisions);
+ int32_t get_subdivide_width() const;
- void set_subdivide_depth(const int divisions);
- int get_subdivide_depth() const;
+ void set_subdivide_depth(const int32_t divisions);
+ int32_t get_subdivide_depth() const;
godot::AABB get_core_aabb() const;
bool is_valid_uv_coord(godot::Vector2 const& uv) const;
diff --git a/game/src/GameSession/MapView.gd b/game/src/GameSession/MapView.gd
index e74ea59..1b04097 100644
--- a/game/src/GameSession/MapView.gd
+++ b/game/src/GameSession/MapView.gd
@@ -13,6 +13,7 @@ const _action_drag : StringName = &"map_drag"
const _action_click : StringName = &"map_click"
const _shader_param_province_index : StringName = &"province_index_tex"
+const _shader_param_province_index_subdivisions : StringName = &"province_index_subdivisions"
const _shader_param_province_colour : StringName = &"province_colour_tex"
const _shader_param_hover_index : StringName = &"hover_index"
const _shader_param_selected_index : StringName = &"selected_index"
@@ -86,6 +87,10 @@ func _ready():
push_error("Failed to generate province index texture array!")
return
_map_shader_material.set_shader_parameter(_shader_param_province_index, province_index_texture)
+ var subdivisions := GameSingleton.get_province_index_image_subdivisions()
+ if subdivisions.x < 1 or subdivisions.y < 1:
+ push_error("Invalid province index image subdivision: ", subdivisions.x, "x", subdivisions.y)
+ _map_shader_material.set_shader_parameter(_shader_param_province_index_subdivisions, Vector2(subdivisions))
# Province colour texture
_map_province_colour_image = GameSingleton.get_province_colour_image()
diff --git a/game/src/GameSession/TerrainMap.gdshader b/game/src/GameSession/TerrainMap.gdshader
index 305a34b..f80d6bd 100644
--- a/game/src/GameSession/TerrainMap.gdshader
+++ b/game/src/GameSession/TerrainMap.gdshader
@@ -6,6 +6,8 @@ render_mode unshaded;
uniform sampler2D farmlands_tex: source_color, repeat_enable, filter_linear;
// Province index texture
uniform sampler2DArray province_index_tex : source_color, repeat_enable, filter_nearest;
+// Province index subdivisions
+uniform vec2 province_index_subdivisions;
// Province colour texture
uniform sampler2D province_colour_tex: source_color, repeat_enable, filter_nearest;
// Index of the mouse over the map mesh
@@ -19,9 +21,9 @@ uvec2 vec2_to_uvec2(vec2 v) {
return uvec2(v * 255.0);
}
uvec2 read_uvec2(vec2 uv) {
- float width_divisions = float(textureSize(province_index_tex, 0).z);
- uv.x *= width_divisions;
- float idx = mod(floor(uv.x), width_divisions);
+ uv *= province_index_subdivisions;
+ vec2 subdivision_coords = mod(floor(uv), province_index_subdivisions);
+ float idx = subdivision_coords.x + subdivision_coords.y * province_index_subdivisions.x;
return vec2_to_uvec2(texture(province_index_tex, vec3(uv, idx)).rg);
}
uint uvec2_to_uint(uvec2 v) {