diff --git a/assets/shaders/glsl/_geometry.glsl b/assets/shaders/glsl/_geometry.glsl index f64c7a1e6..0598fcc14 100644 --- a/assets/shaders/glsl/_geometry.glsl +++ b/assets/shaders/glsl/_geometry.glsl @@ -11,6 +11,11 @@ Functions in this file are shader versions of functions from projections.cpp #define M_PI 3.1415926535897932384626433832795 #define PI 3.1415926535897932384626433832795 +float smootherstep(float x) { + x = clamp(x, 0.f, 1.f); + return x * x * x * (x * (6.0f * x - 15.0f) + 10.0f); +} + struct square_tangent {vec2 base; vec2 tangent;}; struct rectangle_tangent {vec2 base; vec2 tangent;}; struct sphere_tangent { vec3 base; vec3 tangent; }; diff --git a/assets/shaders/glsl/map_f.glsl b/assets/shaders/glsl/map_f.glsl index 9a4fa0e06..4c5802de3 100644 --- a/assets/shaders/glsl/map_f.glsl +++ b/assets/shaders/glsl/map_f.glsl @@ -24,6 +24,7 @@ uniform uint graphics_mode; // location 0 : offset // location 1 : zoom // location 2 : screen_size +uniform float zoom; uniform vec2 map_size; uniform vec2 screen_size; uniform float time; @@ -188,6 +189,88 @@ vec4 get_land_terrain() { return get_terrain_mix(); } +// if we display data, ignore pretty effects +vec4 get_land_data_modern() { + vec4 terrain = get_terrain_mix(); + float is_land = terrain.a; + vec4 province_sample = texture(provinces_texture_sampler, gl_FragCoord.xy / screen_size); + vec2 prov_id = province_sample.xy; + return vec4(texture(province_color, vec3(prov_id, 0.)).rgb * 0.8f, is_land); +} + +vec4 get_land_political_modern() { + vec4 terrain = get_terrain_mix(); + float is_land = terrain.a; + const vec3 GREYIFY = vec3( 0.212671, 0.715160, 0.072169 ); + float grey = dot( terrain.rgb, GREYIFY ); + + vec4 province_sample = texture(provinces_texture_sampler, gl_FragCoord.xy / screen_size); + vec2 prov_id = province_sample.xy; + vec4 prov_color = texture(province_color, vec3(prov_id, 0.)); + + float to_national_border = smootherstep(sqrt(province_sample.z)); + + vec4 stripe_color = texture(province_color, vec3(prov_id, 1.)); + vec2 stripe_coord = tex_coord * vec2(512., 512. * map_size.y / map_size.x); + + float stripeFactor = texture(stripes_texture, stripe_coord).a; + float prov_highlight = texture(province_highlight, prov_id).r * (abs(cos(time * 3.f)) + 1.f); + vec3 political = clamp(mix(prov_color, stripe_color, stripeFactor) + vec4(prov_highlight), 0.0, 1.0).rgb; + + vec4 OutColor = vec4(0.5f, 0.5f, 0.5f, is_land); + + float sum_of_prov_colors = dot(prov_color, vec4(1.f, 1.f, 1.f, 0.f)); + bool is_colonised = true; + if (sum_of_prov_colors > 2.99f) { + is_colonised = false; + } + + if (is_colonised) { + OutColor.rgb = mix((grey + terrain.rgb) / 2.f, political, 0.3f + 0.5f / zoom + (1.f - to_national_border) * 0.7f); + OutColor.rgb -= (1.f - to_national_border) * 0.1f; + } else { + OutColor.rgb = (grey * 2.f + terrain.rgb) / 3.f + 0.2f; + } + + OutColor.rgb *= texture(province_fow, prov_id).rgb * (to_national_border * 0.3f + 0.7f); + + return OutColor; +} + + +vec4 get_land_political_paper() { + vec2 uv = tex_coord * 300.f; + + vec4 province_sample = texture(provinces_texture_sampler, gl_FragCoord.xy / screen_size); + vec2 prov_id = province_sample.xy; + float to_national_border = province_sample.z; + vec4 hatching = texture(hatching, uv / 2.f); + + vec4 prov_highlight = vec4(1.f, 1.f, 1.f, 1.f); + float highlight = texture(province_highlight, prov_id).r; + + if (highlight > 0.f) { + prov_highlight = vec4(hatching.rgb * 0.2f * (hatching.a) + 0.5f * (1.f - hatching.a), 1.f); + } + + vec4 prov_color = texture(province_color, vec3(prov_id, 0.)); + + vec4 base_color = vec4(1.f, 247.f / 255.f, 240.f / 255.f, 1.f); + float wc_base = texture(watercolor, uv).b; + float gradient = 1.f; + if (int(graphics_mode) == 2) { + gradient = (0.7f + sqrt(to_national_border) * 0.3f); + } + float wc_texture = max(0.f, wc_base * wc_base * wc_base) * gradient; + vec4 mixed_color = prov_color * (1.f - wc_texture) + base_color * wc_texture; + + vec4 terrain = get_terrain_mix(); + const vec3 GREYIFY = vec3( 0.212671, 0.715160, 0.072169 ); + float grey = dot( terrain.rgb, GREYIFY ) * 2.f; + float is_land = terrain.a; + return mixed_color * prov_highlight * is_land + texture(watercolor, uv) * gradient * (1 - is_land); +} + vec4 get_land_political_close() { vec4 terrain = get_terrain_mix(); float is_land = terrain.a; @@ -229,37 +312,10 @@ vec4 get_land_political_close() { political *= texture(province_fow, prov_id).rgb; political = political - 0.7; - // vec4 OverlayColor = texture(overlay, tex_coord * vec2(11., 11.*map_size.y/map_size.x)); - vec3 OutColor; - OutColor.r = 0.5; - OutColor.g = 0.5; - OutColor.b = 0.5; - - vec3 background = texture(colormap_political, get_corrected_coords(tex_coord)).rgb; - // Mix together the terrain and map mode color - if (int(graphics_mode) == 2) { - // if we display data, ignore pretty effects - if (map_mode_is_data == 0) { - terrain.rgb = mix(terrain.rgb, political, 0.2f + (1.f - to_national_border) * 0.3f); - if (is_colonised) { - OutColor.rgb = mix((grey + terrain.rgb) / 2.f, political + 0.5, 0.2f + (1.f - to_national_border) * 0.4f); - OutColor.rgb *= 1.05; - } else { - OutColor.rgb = (grey * 2.f + terrain.rgb) / 3.f + 0.1f; - } - terrain.rgb = OutColor.rgb; - } else { - vec3 province_raw = clamp(mix(prov_color, stripe_color, stripeFactor) + vec4(prov_highlight), 0.0, 1.0).rgb; - terrain.rgb = (province_raw * 0.9f) * 0.85f + grey * 0.15f; - } - } else { - terrain.rgb = mix(vec3(grey), political, 0.3f); - terrain.rgb *= 1.5; - } + terrain.rgb = mix(vec3(grey), political, 0.3f); + terrain.rgb *= 1.5; - //terrain.rgb += vec3((test * 255) == id); - //terrain.r += ((abs(rel_coord.y) + abs(rel_coord.x)) > 0.5 ? 6 : 0) * 0.3; return terrain; } @@ -306,10 +362,10 @@ vec4 get_land_political_far() { if (int(graphics_mode) == 2) { if (map_mode_is_data == 0) { if (is_colonised) { - OutColor.rgb = mix((grey + terrain.rgb) / 2.f, political + 0.5, 0.2f + (1.f - to_national_border) * 0.4f); + OutColor.rgb = mix((grey + terrain.rgb) / 2.f, political + 0.7, 0.5f + (1.f - to_national_border) * 0.5f); OutColor.rgb *= 1.05; } else { - OutColor.rgb = (grey * 2.f + terrain.rgb) / 3.f + 0.1f; + OutColor.rgb = (grey * 2.f + terrain.rgb) / 3.f + 0.2f; } } else { vec3 political_raw = clamp(mix(prov_color, stripe_color, stripeFactor) + vec4(prov_highlight), 0.0, 1.0).rgb; @@ -326,37 +382,18 @@ vec4 get_land_political_far() { } vec4 get_land() { - /* - - vec2 uv = tex_coord * 300.f; - - vec4 province_sample = texture(provinces_texture_sampler, gl_FragCoord.xy / screen_size); - vec2 prov_id = province_sample.xy; - float to_national_border = province_sample.z; - vec4 hatching = texture(hatching, uv / 2.f); - - vec4 prov_highlight = vec4(1.f, 1.f, 1.f, 1.f); - float highlight = texture(province_highlight, prov_id).r; - - if (highlight > 0.f) { - prov_highlight = vec4(hatching.rgb * 0.2f * (hatching.a) + 0.5f * (1.f - hatching.a), 1.f); + if(subroutines_index_2 == 0) { + return get_land_terrain(); } - vec4 prov_color = texture(province_color, vec3(prov_id, 0.)); - - vec4 base_color = vec4(1.f, 247.f / 255.f, 240.f / 255.f, 1.f); - float wc_base = texture(watercolor, uv).b; - float gradient = (0.7f + sqrt(to_national_border) * 0.3f); - float wc_texture = max(0.f, wc_base * wc_base * wc_base) * gradient; - vec4 mixed_color = prov_color * (1.f - wc_texture) + base_color * wc_texture; - - vec4 terrain = get_terrain_mix(); - const vec3 GREYIFY = vec3( 0.212671, 0.715160, 0.072169 ); - float grey = dot( terrain.rgb, GREYIFY ) * 2.f; - float is_land = terrain.a; - return mixed_color * prov_highlight * is_land + texture(watercolor, uv) * gradient * (1 - is_land); - - */ + if (int(graphics_mode) == 2) { + if (map_mode_is_data == 0) { + return get_land_political_modern(); + } else { + return get_land_data_modern(); + } + return get_land_political_far(); + } if (int(graphics_mode) == 0) { return get_land_political_far(); diff --git a/assets/shaders/glsl/map_triangle_f.glsl b/assets/shaders/glsl/map_triangle_f.glsl index a92976704..e83d348ba 100644 --- a/assets/shaders/glsl/map_triangle_f.glsl +++ b/assets/shaders/glsl/map_triangle_f.glsl @@ -11,20 +11,33 @@ vec4 gamma_correct(vec4 colour) { } void main() { + if (length(tex_coord) > 1.f) { + discard; + } vec4 out_color = texture(texture_sampler, tex_coord / 10.f); vec3 inner_color = vec3(0.6f, 0.2, 0.2f); + + float darkness = max(0.f, -dot(light_direction, space_coords) + 0.2f); + + float light = 0.f; + if (ignore_light == 0.f) { - float darkness = max(0.f, -dot(light_direction, space_coords) + 0.2f); - inner_color *= 5.f * out_color.a * out_color.rgb * darkness; + light = smootherstep(1.f - length(tex_coord)) * darkness; + //inner_color *= 5.f * out_color.a * out_color.rgb * darkness * ; } - if (length(tex_coord) > 0.75f) { - frag_color = vec4(0.f, 0.f, 0.f, texture(texture_sampler, tex_coord)); + if (length(tex_coord) > 0.5f) { + if (ignore_light != 0.f) { + discard; + } + frag_color = vec4(light, light, light, 0.f); + } else if (length(tex_coord) > 0.25f) { + frag_color = vec4(light, light, light, texture(texture_sampler, tex_coord)); } else { frag_color = vec4(inner_color, texture(texture_sampler, tex_coord)); } - frag_color = gamma_correct(frag_color); + frag_color = gamma_correct(frag_color) + vec4(inner_color, 0.f) * light; } diff --git a/assets/shaders/glsl/textured_line_b_f.glsl b/assets/shaders/glsl/textured_line_b_f.glsl index 9070ac5ac..ed3ec7cd0 100644 --- a/assets/shaders/glsl/textured_line_b_f.glsl +++ b/assets/shaders/glsl/textured_line_b_f.glsl @@ -3,6 +3,7 @@ in float o_dist; in vec2 map_coord; in vec2 space_coord; out vec4 frag_color; +in float border_width_coord; uniform float gamma; uniform vec2 screen_size; @@ -22,8 +23,8 @@ void main() { // return; - vec4 out_color = texture(line_texture, vec2(o_dist, tex_coord)); - out_color.a *= texture(printbrush, map_coord * 300.f).r; + vec4 out_color = texture(line_texture, vec2(o_dist, border_width_coord)); + out_color.a *= texture(printbrush, vec2(o_dist * 10.f, tex_coord) / 10.f).r; //vec2 prov_id = texture(provinces_texture_sampler, gl_FragCoord.xy / screen_size).xy; //out_color.rgb *= texture(province_fow, prov_id).rgb; diff --git a/assets/shaders/glsl/textured_line_b_v.glsl b/assets/shaders/glsl/textured_line_b_v.glsl index 9f8d4f3cc..ad9cb9f42 100644 --- a/assets/shaders/glsl/textured_line_b_v.glsl +++ b/assets/shaders/glsl/textured_line_b_v.glsl @@ -7,6 +7,7 @@ layout (location = 4) in float texture_coord; layout (location = 5) in float distance; out float tex_coord; +out float border_width_coord; out float o_dist; out vec2 map_coord; out vec2 space_coord; @@ -73,13 +74,14 @@ void main() { } // pass data to frag shader - tex_coord = abs(texture_coord); + tex_coord = texture_coord; + border_width_coord = abs(texture_coord); o_dist = distance / (2.0f * width); map_coord = vertex_position + corner_shift; space_coord = gl_Position.xy; frag_province_index = province_index; if (is_national_border > 0.5f) { - distance_to_national_border = tex_coord; + distance_to_national_border = abs(tex_coord); gl_Position.z -= 0.001f; } else { distance_to_national_border = 1.f; diff --git a/src/map/map.cpp b/src/map/map.cpp index b40a6f245..888d57984 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -777,8 +777,8 @@ void display_data::render( if(state.map_state.light_rotate) { state.map_state.light_direction.x = 0.f ; - state.map_state.light_direction.y = sin(-time_counter); - state.map_state.light_direction.z = cos(-time_counter); + state.map_state.light_direction.y = sin(time_counter); + state.map_state.light_direction.z = cos(time_counter); state.map_state.light_direction = state.map_state.light_direction * axial_rotation; } @@ -804,6 +804,9 @@ void display_data::render( float pixel_size = (screen_size.y) / float(size_y) * zoom; + auto scale_borders = std::clamp(2.f / pixel_size, 1.f, 4.f); + + // BORDERS TO FIX HUGE PIXELS if(state.user_settings.graphics_mode != sys::graphics_mode::ugly && pixel_size > 2.f) { load_shader(shader_borders_provinces); @@ -1079,7 +1082,7 @@ void display_data::render( } // impassible borders { - glUniform1f(shader_uniforms[shader_borders][uniform_width], 0.0002f); // width + glUniform1f(shader_uniforms[shader_borders][uniform_width], 0.0006f); // width glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textures[texture_imp_border]); for(auto b : borders) { @@ -1093,7 +1096,7 @@ void display_data::render( } // national borders { - glUniform1f(shader_uniforms[shader_borders][uniform_width], 0.0001f); // width + glUniform1f(shader_uniforms[shader_borders][uniform_width], 0.00015f * scale_borders); // width glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textures[texture_national_border]); for(auto b : borders) { @@ -1134,7 +1137,7 @@ void display_data::render( } // national borders { - glUniform1f(shader_uniforms[shader_borders][uniform_width], 0.0003f); // width + glUniform1f(shader_uniforms[shader_borders][uniform_width], 0.00015f * scale_borders); // width glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textures[texture_state_border]); for(auto b : borders) { @@ -2711,7 +2714,7 @@ void display_data::update_sprawl(sys::state& state) { connectors.resize(state.world.province_size()); //auto minimal_population_per_visible_settlement = 2500.f; - auto population_per_km2 = 20000.f; + auto population_per_km2 = 5000.f; auto minimal_size_per_visible_settlement_km2 = 20.f; // Populate paths with railroads - only account provinces that have been visited @@ -2756,7 +2759,7 @@ void display_data::update_sprawl(sys::state& state) { std::vector> weighted_settlements; - auto km2_per_potential_settlement = 20000.f; + auto km2_per_potential_settlement = 5000.f; int potential_settlement_slots = std::min( (int)7, std::min( @@ -3082,8 +3085,13 @@ void display_data::set_text_lines(sys::state& state) { } } - left = std::clamp(left, 0.f, 1.f); - right = std::clamp(right, 0.f, 1.f); + if(!is_spherical) { + left = std::clamp(left, e.offset_left, 1.f); + right = std::clamp(right, 0.f, e.offset_right); + } else { + left = std::clamp(left, 0.f, 1.f); + right = std::clamp(right, 0.f, 1.f); + } if(right <= left) continue; @@ -3156,6 +3164,7 @@ void display_data::set_text_lines(sys::state& state) { assert(std::isfinite(text_length) && text_length != 0.f); float size = (curve_length / text_length) * 0.8f; + if(!is_spherical) size /= 2.f; float font_size_index = std::round(5.f * log(size) / log(1.618034f)); if(font_size_index > 45.f) font_size_index = 45.f; @@ -3163,11 +3172,10 @@ void display_data::set_text_lines(sys::state& state) { size = std::pow(1.618034f, font_size_index / 5.f); auto real_text_half_size = size / size_x / 2.f; - if(!is_spherical) real_text_half_size /= 2.f; float letter_spacing_map = 0.f; if(!state.world.locale_get_prevent_letterspace(state.font_collection.get_current_locale()) && e.text.glyph_info.size() > 1) { - letter_spacing_map = std::clamp((0.8f * curve_length - text_length * size) / (e.text.glyph_info.size() - 1) / 2.f, 0.f, size * 2.f); + //letter_spacing_map = std::clamp((0.8f * curve_length - text_length * size) / (e.text.glyph_info.size() - 1) / 2.f, 0.f, size * 2.f); } float margin = (curve_length - text_length * size - (e.text.glyph_info.size() - 1) * letter_spacing_map) / 2.0f; @@ -3272,10 +3280,27 @@ void display_data::set_text_lines(sys::state& state) { auto new_tangent_square = sphere_R3::to_square(new_tangent); final_direction = new_tangent_square.data * (float)size_x; } else { - glm::vec2 forward_raw = glm::vec2(ratio.x / (float)size_x, ratio.y / (float)size_y * dpoly_fn(cur_x)); - float norm = sqrt(equirectangular::dot({ {{0.f,0.f}}, forward_raw }, { {{0.f,0.f}}, forward_raw }, (float)size_x, (float)size_y)); + // rectangle + equirectangular::tangent forward_rect { { { 0.f, 0.f } } , { ratio.x, ratio.y * dpoly_fn(cur_x) } }; + square::tangent forward = equirectangular::to_square(forward_rect, (float)size_x, (float)size_y); + float norm = sqrt(equirectangular::dot(forward, forward, (float)size_x, (float)size_y)); if(norm <= 0.f) norm = 1.f; - auto forward = forward_raw / norm * (float)size_x; + forward.data /= norm; + square::tangent up = equirectangular::rotate_left(forward, (float)size_x, (float)size_y); + + equirectangular::point center_rect { glm::vec2(cur_x, poly_fn(cur_x)) * ratio + basis }; + square::point center = equirectangular::to_square(center_rect, (float)size_x, (float)size_y); + + actual_center = center.data; + actual_center -= up.data / 2.f * size / 64.f * glyph_height; + actual_center -= up.data / 2.f * size / 64.f * max_glyph_height; + actual_center += up.data / 1.f * size / 64.f * y_bearing; + actual_center += up.data / 1.f * size / 64.f * y_offset; + actual_center += forward.data * size / 64.f * glyph_width / 2.f; + + final_direction = forward.data * (float)size_x; + + /* glm::vec2 up = equirectangular::rotate_left({ {{0.f,0.f}}, forward }, (float)size_x, (float)size_y).data; auto raw_center = glm::vec2(cur_x, poly_fn(cur_x)) * ratio + basis; auto center = raw_center / glm::vec2(size_x, size_y); @@ -3283,6 +3308,7 @@ void display_data::set_text_lines(sys::state& state) { + (-0.5f * max_glyph_height + 0.5f * glyph_height + y_offset - (glyph_height - y_bearing)) * up * real_text_half_size / 64.f + (glyph_width + x_offset) * forward * real_text_half_size / 64.f; final_direction = forward; + */ } float u0 = float(gi.ft_x_bearing) / (64.0f * text::dr_size); diff --git a/src/map/map.hpp b/src/map/map.hpp index e0ac6980f..51e535fae 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -117,11 +117,13 @@ struct text_line_vertex { struct text_line_generator_data { text_line_generator_data() { }; - text_line_generator_data(text::stored_glyphs&& text_, glm::vec4 coeff_, glm::vec2 basis_, glm::vec2 ratio_) : text(std::move(text_)), coeff{ coeff_ }, basis{ basis_ }, ratio{ ratio_ } { }; + text_line_generator_data(text::stored_glyphs&& text_, glm::vec4 coeff_, glm::vec2 basis_, glm::vec2 ratio_, float l_, float r_) : text(std::move(text_)), coeff{ coeff_ }, basis{ basis_ }, ratio{ ratio_ }, offset_left (l_), offset_right (r_) { }; text::stored_glyphs text; glm::vec4 coeff{0.f}; glm::vec2 basis{0.f}; glm::vec2 ratio{0.f}; + float offset_left = 0.f; + float offset_right = 0.f; }; struct border { diff --git a/src/map/map_state.cpp b/src/map/map_state.cpp index f8017db99..d336caea9 100644 --- a/src/map/map_state.cpp +++ b/src/map/map_state.cpp @@ -1060,7 +1060,7 @@ void draw_small_square(sys::state& state, display_data& map_data, square::point map_data.arbitrary_map_triangles.push_back(bottom_right); map_data.arbitrary_map_triangles_counts.push_back( - GLsizei(map_data.arbitrary_map_triangles.size() - current_size) + int(map_data.arbitrary_map_triangles.size() - current_size) ); map_data.new_arbitrary_map_triangle = true; @@ -1613,15 +1613,32 @@ void update_text_lines(sys::state& state, display_data& map_data) { float best_y_length_real = 0.f; float best_y_left_x = 0.f; - auto check_point = [&](float x, float y) { - if(x < 0.f) return 0.f; - if(y < 0.f) return 0.f; - if((uint32_t)x >= map_data.size_x) return 0.f; - if((uint32_t)y >= map_data.size_y) return 0.f; + auto sample_province = [&](float x, float y) { + while (x < 0.f) { + x += (float)map_data.size_x; + } + while (x >= map_data.size_x) { + x -= (float)map_data.size_x; + } + if(y < 0.f) return dcon::province_id{}; + if((uint32_t)y >= map_data.size_y) return dcon::province_id{}; glm::vec2 candidate = { x, y }; auto idx = int32_t(y) * int32_t(map_data.size_x) + int32_t(x); - if(!(0 <= idx && size_t(idx) < map_data.province_id_map.size())) return 0.f; + if(!(0 <= idx && size_t(idx) < map_data.province_id_map.size())) return dcon::province_id{}; auto pid = province::from_map_id(map_data.province_id_map[idx]); + return pid; + }; + + auto sample_nation = [&](float x, float y) { + auto pid = sample_province(x, y); + if(!pid) { + return dcon::nation_id {}; + } + return state.world.province_get_nation_from_province_ownership(pid); + }; + + auto check_point = [&](float x, float y) { + auto pid = sample_province(x, y); if(!pid) { return 0.f; } @@ -1641,14 +1658,7 @@ void update_text_lines(sys::state& state, display_data& map_data) { }; auto weight_decay = [&](float x, float y) { - if(x < 0.f) return 0.f; - if(y < 0.f) return 0.f; - if((uint32_t)x >= map_data.size_x) return 0.f; - if((uint32_t)y >= map_data.size_y) return 0.f; - glm::vec2 candidate = { x, y }; - auto idx = int32_t(y) * int32_t(map_data.size_x) + int32_t(x); - if(!(0 <= idx && size_t(idx) < map_data.province_id_map.size())) return 0.f; - auto pid = province::from_map_id(map_data.province_id_map[idx]); + auto pid = sample_province(x, y); if(!pid) { return 0.7f; } @@ -1932,6 +1942,7 @@ void update_text_lines(sys::state& state, display_data& map_data) { auto coord = glm::vec2{ point.x, point.y }; average_weight += point.z; sum_points += coord; + //draw_small_square(state, state.map_state.map_data, { { point.x / (float)map_data.size_x, point.y / (float)map_data.size_y } }, 0.0001f); } average_weight /= (float)(points.size()); @@ -2004,10 +2015,26 @@ void update_text_lines(sys::state& state, display_data& map_data) { bottom = current.y; } } - key_points.push_back(center + glm::vec2(left, 0)); - key_points.push_back(center + glm::vec2(0, bottom - local_step.y)); - key_points.push_back(center + glm::vec2(right, 0)); - key_points.push_back(center + glm::vec2(0, top + local_step.y)); + + { + auto result = center + glm::vec2(left, 0); + key_points.push_back(result); + } + + { + auto result = center + glm::vec2(0, bottom - local_step.y); + key_points.push_back(result); + } + + { + auto result = center + glm::vec2(right, 0); + key_points.push_back(result); + } + + { + auto result = center + glm::vec2(0, top + local_step.y); + key_points.push_back(result); + } } std::array key_provs{ @@ -2070,7 +2097,7 @@ void update_text_lines(sys::state& state, display_data& map_data) { for (auto point : centroids) { auto e = point; - //draw_small_square(state, state.map_state.map_data, { { point.x / (float)map_data.size_x, point.y / (float)map_data.size_y } }, 0.002f); + //draw_small_square(state, state.map_state.map_data, { { point.x / (float)map_data.size_x, point.y / (float)map_data.size_y } }, 0.0005f); if(e.x < basis.x) { continue; @@ -2149,6 +2176,8 @@ void update_text_lines(sys::state& state, display_data& map_data) { }; float xstep = (1.f / float(name_extent * 2.f)); + + for(float x = 0.f; x <= 1.f; x += xstep) { float y = poly_fn(x); if(y < 0.f || y > 1.f) { @@ -2163,8 +2192,39 @@ void update_text_lines(sys::state& state, display_data& map_data) { } } - if(!use_quadratic) - text_data.emplace_back(std::move(prepared_name), mo, basis, ratio); + if(!use_quadratic) { + xstep = 1 / 32.f; + + float offset_left = 0.f; + for(float x = 0.f; x <= 1.f; x += xstep) { + float y = poly_fn(x); + auto map_point = glm::vec2{x, y} * ratio + basis; + auto nation = sample_nation(map_point.x, map_point.y); + if(nation && nation != n) { + offset_left = x; + } + if(nation == n) { + break; + } + } + float offset_right = 1.f; + for(float x = 1.f; x >= 0.f; x -= xstep) { + float y = poly_fn(x); + auto map_point = glm::vec2{x, y} * ratio + basis; + auto nation = sample_nation(map_point.x, map_point.y); + if(nation && nation != n) { + offset_right = x; + } + if(nation == n) { + break; + } + } + if(offset_left > offset_right) { + use_quadratic = true; + } else { + text_data.emplace_back(std::move(prepared_name), mo, basis, ratio, offset_left, offset_right); + } + } } bool use_linear = false; @@ -2208,16 +2268,46 @@ void update_text_lines(sys::state& state, display_data& map_data) { break; } } - if(!use_linear) - text_data.emplace_back(std::move(prepared_name), glm::vec4(mo, 0.f), basis, ratio); + if(!use_linear) { + xstep = 1 / 32.f; + float offset_left = 0.f; + for(float x = 0.f; x <= 1.f; x += xstep) { + float y = poly_fn(x); + auto map_point = glm::vec2{x, y} * ratio + basis; + auto nation = sample_nation(map_point.x, map_point.y); + if(nation && nation != n) { + offset_left = x; + } + if(nation == n) { + break; + } + } + float offset_right = 1.f; + for(float x = 1.f; x >= 0.f; x -= xstep) { + float y = poly_fn(x); + auto map_point = glm::vec2{x, y} * ratio + basis; + auto nation = sample_nation(map_point.x, map_point.y); + if(nation && nation != n) { + offset_right = x; + } + if(nation == n) { + break; + } + } + if(offset_left > offset_right) { + use_linear = true; + } else { + text_data.emplace_back(std::move(prepared_name), glm::vec4{mo.x, mo.y, mo.z, 0.f}, basis, ratio, offset_left, offset_right); + } + } } if(state.user_settings.map_label == sys::map_label_mode::spherical) { if(in_x[0][1] < in_x[1][1]) { - text_data.emplace_back(std::move(prepared_name), glm::vec4(in_x[0][1], in_y[0][1], in_x[1][1], in_y[1][1]), basis, ratio); + text_data.emplace_back(std::move(prepared_name), glm::vec4(in_x[0][1], in_y[0][1], in_x[1][1], in_y[1][1]), basis, ratio, 0.f, 1.f); } else { - text_data.emplace_back(std::move(prepared_name), glm::vec4(in_x[1][1], in_y[1][1], in_x[0][1], in_y[0][1]), basis, ratio); + text_data.emplace_back(std::move(prepared_name), glm::vec4(in_x[1][1], in_y[1][1], in_x[0][1], in_y[0][1]), basis, ratio, 0.f, 1.f); } } @@ -2249,8 +2339,38 @@ void update_text_lines(sys::state& state, display_data& map_data) { if(abs(mo[1]) <= 0.05) mo[1] = 0.f; - if(ratio.x <= map_size.x * 0.75f && ratio.y <= map_size.y * 0.75f) - text_data.emplace_back(std::move(prepared_name), glm::vec4(mo, 0.f, 0.f), basis, ratio); + if(ratio.x <= map_size.x * 1.f && ratio.y <= map_size.y * 1.f) { + float xstep = 1.f / 32.f; + + float offset_left = 0.f; + for(float x = 0.f; x <= 1.f; x += xstep) { + float y = poly_fn(x); + auto map_point = glm::vec2{x, y} * ratio + basis; + auto nation = sample_nation(map_point.x, map_point.y); + if(nation && nation != n) { + offset_left = x; + } + if(nation == n) { + break; + } + } + float offset_right = 1.f; + for(float x = 1.f; x >= 0.f; x -= xstep) { + float y = poly_fn(x); + auto map_point = glm::vec2{x, y} * ratio + basis; + auto nation = sample_nation(map_point.x, map_point.y); + if(nation && nation != n) { + offset_right = x; + } + if(nation == n) { + break; + } + } + if(offset_left < offset_right) { + glm::vec4 coeffs = { mo.x, mo.y, 0.f, 0.f }; + text_data.emplace_back(std::move(prepared_name), coeffs, basis, ratio, offset_left, offset_right); + } + } } } @@ -2261,7 +2381,7 @@ void update_text_lines(sys::state& state, display_data& map_data) { std::string name = text::produce_simple_string(state, p.get_name()); text::stored_glyphs temp; state.font_collection.mfont.remake_map_cache(state, temp, name); - p_text_data.emplace_back(std::move(temp), glm::vec4(0.f, 0.f, 0.f, 0.f), p.get_mid_point() - glm::vec2(5.f, 0.f), glm::vec2(10.f, 10.f)); + p_text_data.emplace_back(std::move(temp), glm::vec4(0.f, 0.f, 0.f, 0.f), p.get_mid_point() - glm::vec2(5.f, 0.f), glm::vec2(10.f, 10.f), 0.f, 1.f); } } map_data.set_province_text_lines(state, p_text_data); diff --git a/src/map/map_state.hpp b/src/map/map_state.hpp index 66e6bbe3e..5f35242e5 100644 --- a/src/map/map_state.hpp +++ b/src/map/map_state.hpp @@ -96,7 +96,7 @@ class map_state { bool border_indices_ready = false; // lighting - glm::vec3 light_direction {1.f, 0.f, -0.3f}; + glm::vec3 light_direction {0.f, 1.f, -0.3f}; bool light_on = false; bool light_rotate = false;