8#include <glm/mat3x3.hpp>
9#include <unordered_map>
10#include <glm/gtc/type_ptr.hpp>
11#include <glm/gtx/intersect.hpp>
12#include <glm/gtx/polar_coordinates.hpp>
13#include <glm/gtc/constants.hpp>
14#include <glm/gtx/transform.hpp>
26 auto pt = state.world.province_get_port_to(p);
30 auto adj = state.world.get_province_adjacency_by_province_pair(p, pt);
32 auto id = adj.index();
33 auto& map_data = state.map_state.map_data;
34 auto& border = map_data.borders[id];
35 auto& vertex = map_data.border_vertices[border.start_index + border.count / 2];
36 glm::vec2 map_size = glm::vec2(map_data.size_x, map_data.size_y);
38 return vertex.position * map_size;
42 return prov_id.index() >= state.province_definitions.first_sea_province.index();
47 return state.world.province_get_mid_point(prov_id);
53 return state.world.province_get_mid_point(prov_id);
64 for(
auto pc : state.world.nation_get_province_control_as_nation(n))
65 list.push_back(pc.get_province());
66 for(
auto ac : state.world.nation_get_army_control_as_controller(n))
67 list.push_back(ac.get_army().get_location_from_army_location());
68 for(
auto nc : state.world.nation_get_navy_control_as_controller(n))
69 list.push_back(nc.get_navy().get_location_from_navy_location());
73 std::vector<dcon::province_id> direct_provinces;
75 for(
auto urel : state.world.nation_get_overlord_as_ruler(state.local_player_nation))
77 for(
auto rel : state.world.nation_get_diplomatic_relation(state.local_player_nation)) {
78 if(rel.get_are_allied()) {
79 auto n = rel.get_related_nations(0) == state.local_player_nation ? rel.get_related_nations(1) : rel.get_related_nations(0);
81 for(
auto urel : state.world.nation_get_overlord_as_ruler(n))
87 std::vector<uint32_t> province_fows(state.world.province_size() + 1, 0xFFFFFFFF);
89 state.map_state.visible_provinces.clear();
90 state.map_state.visible_provinces.resize(state.world.province_size() + 1,
false);
91 for(
auto p : direct_provinces) {
94 for(
auto c : state.world.province_get_province_adjacency(p)) {
95 auto pc = c.get_connected_provinces(0) == p ? c.get_connected_provinces(1) : c.get_connected_provinces(0);
102 for(
auto p : state.world.in_province)
106 state.map_state.visible_provinces.clear();
107 state.map_state.visible_provinces.resize(state.world.province_size() + 1,
true);
114 glBindBuffer(GL_ARRAY_BUFFER, vbo);
116 glBufferData(GL_ARRAY_BUFFER,
sizeof(
textured_line_vertex) * data.size(), data.data(), GL_STATIC_DRAW);
122 glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, offsetof(
textured_line_vertex, normal_direction_));
124 glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, offsetof(
textured_line_vertex, texture_coordinate_));
127 glEnableVertexAttribArray(0);
128 glEnableVertexAttribArray(1);
129 glEnableVertexAttribArray(2);
130 glEnableVertexAttribArray(3);
131 glVertexAttribBinding(0, 0);
132 glVertexAttribBinding(1, 0);
133 glVertexAttribBinding(2, 0);
134 glVertexAttribBinding(3, 0);
139 glBindBuffer(GL_ARRAY_BUFFER, vbo);
154 glEnableVertexAttribArray(0);
155 glEnableVertexAttribArray(1);
156 glEnableVertexAttribArray(2);
157 glEnableVertexAttribArray(3);
158 glEnableVertexAttribArray(4);
159 glVertexAttribBinding(0, 0);
160 glVertexAttribBinding(1, 0);
161 glVertexAttribBinding(2, 0);
162 glVertexAttribBinding(3, 0);
163 glVertexAttribBinding(4, 0);
168 glBindBuffer(GL_ARRAY_BUFFER, vbo);
178 glEnableVertexAttribArray(0);
179 glEnableVertexAttribArray(1);
180 glEnableVertexAttribArray(2);
181 glEnableVertexAttribArray(3);
182 glEnableVertexAttribArray(4);
183 glVertexAttribBinding(0, 0);
184 glVertexAttribBinding(1, 0);
185 glVertexAttribBinding(2, 0);
186 glVertexAttribBinding(3, 0);
187 glVertexAttribBinding(4, 0);
192 glBindBuffer(GL_ARRAY_BUFFER, vbo);
194 glBufferData(GL_ARRAY_BUFFER,
sizeof(
curved_line_vertex) * data.size(), data.data(), GL_STATIC_DRAW);
198 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, offsetof(
curved_line_vertex, position_));
200 glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, offsetof(
curved_line_vertex, normal_direction_));
202 glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, offsetof(
curved_line_vertex, direction_));
204 glVertexAttribFormat(3, 2, GL_FLOAT, GL_FALSE, offsetof(
curved_line_vertex, texture_coord_));
207 glEnableVertexAttribArray(0);
208 glEnableVertexAttribArray(1);
209 glEnableVertexAttribArray(2);
210 glEnableVertexAttribArray(3);
211 glEnableVertexAttribArray(4);
212 glVertexAttribBinding(0, 0);
213 glVertexAttribBinding(1, 0);
214 glVertexAttribBinding(2, 0);
215 glVertexAttribBinding(3, 0);
216 glVertexAttribBinding(4, 0);
221 glBindBuffer(GL_ARRAY_BUFFER, vbo);
225 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, offsetof(
text_line_vertex, position_));
227 glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, offsetof(
text_line_vertex, normal_direction_));
229 glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, offsetof(
text_line_vertex, direction_));
231 glVertexAttribFormat(3, 3, GL_FLOAT, GL_FALSE, offsetof(
text_line_vertex, texture_coord_));
232 glVertexAttribFormat(4, 1, GL_FLOAT, GL_FALSE, offsetof(
text_line_vertex, thickness_));
233 glEnableVertexAttribArray(0);
234 glEnableVertexAttribArray(1);
235 glEnableVertexAttribArray(2);
236 glEnableVertexAttribArray(3);
237 glEnableVertexAttribArray(4);
238 glEnableVertexAttribArray(5);
239 glVertexAttribBinding(0, 0);
240 glVertexAttribBinding(1, 0);
241 glVertexAttribBinding(2, 0);
242 glVertexAttribBinding(3, 0);
243 glVertexAttribBinding(4, 0);
244 glVertexAttribBinding(5, 0);
249 glBindBuffer(GL_ARRAY_BUFFER, vbo);
253 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, offsetof(
screen_vertex, position_));
254 glEnableVertexAttribArray(0);
255 glVertexAttribBinding(0, 0);
263 std::vector<map_vertex> land_vertices;
265 auto add_vertex = [map_size = glm::vec2(
float(
size_x),
float(
size_y))](std::vector<map_vertex>& vertices, glm::vec2 pos0) {
266 vertices.emplace_back(pos0.x, pos0.y);
269 glm::vec2 last_pos(0, 0);
272 glm::ivec2 sections(200, 200);
273 for(
int y = 0; y <= sections.y; y++) {
274 pos.y = float(y) / float(sections.y);
275 for(
int x = 0; x <= sections.x; x++) {
276 pos.x = float(x) / float(sections.x);
277 add_vertex(land_vertices, pos);
282 for(
int y = 0; y < sections.y; y++) {
283 auto top_row_start = y * (sections.x + 1);
284 auto bottom_row_start = (y + 1) * (sections.x + 1);
285 map_indices.push_back(uint16_t(bottom_row_start + 0));
286 map_indices.push_back(uint16_t(top_row_start + 0));
287 for(
int x = 0; x < sections.x; x++) {
288 map_indices.push_back(uint16_t(bottom_row_start + 1 + x));
289 map_indices.push_back(uint16_t(top_row_start + 1 + x));
291 map_indices.push_back(std::numeric_limits<uint16_t>::max());
300 glBufferData(GL_ARRAY_BUFFER,
sizeof(
map_vertex) * land_vertices.size(), land_vertices.data(), GL_STATIC_DRAW);
304 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, offsetof(
map_vertex, position_));
305 glEnableVertexAttribArray(0);
306 glVertexAttribBinding(0, 0);
337 glBindVertexArray(0);
356 for(
const auto shader :
shaders) {
358 glDeleteProgram(shader);
371 auto vshader_string = std::string_view(vshader_content.data, vshader_content.file_size);
373 auto fshader_string = std::string_view(fshader_content.data, fshader_content.file_size);
385 auto line_unit_arrow_vshader =
try_load_shader(root,
NATIVE(
"assets/shaders/glsl/line_unit_arrow_v.glsl"));
386 auto line_unit_arrow_fshader =
try_load_shader(root,
NATIVE(
"assets/shaders/glsl/line_unit_arrow_f.glsl"));
392 auto tline_width_vshader =
try_load_shader(root,
NATIVE(
"assets/shaders/glsl/textured_line_variable_width_v.glsl"));
394 auto river_fshader =
try_load_shader(root,
NATIVE(
"assets/shaders/glsl/textured_line_river_f.glsl"));
453 glEnable(GL_CULL_FACE);
457 glBindFramebuffer(GL_FRAMEBUFFER, state.open_gl.msaa_framebuffer);
458 glClearColor(1.f, 1.f, 1.f, 0.f);
459 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
462 glActiveTexture(GL_TEXTURE0);
464 glActiveTexture(GL_TEXTURE1);
466 glActiveTexture(GL_TEXTURE3);
468 glActiveTexture(GL_TEXTURE4);
470 glActiveTexture(GL_TEXTURE5);
472 glActiveTexture(GL_TEXTURE6);
474 glActiveTexture(GL_TEXTURE7);
476 glActiveTexture(GL_TEXTURE8);
478 glActiveTexture(GL_TEXTURE9);
480 glActiveTexture(GL_TEXTURE10);
482 glActiveTexture(GL_TEXTURE11);
484 glActiveTexture(GL_TEXTURE13);
486 glActiveTexture(GL_TEXTURE14);
488 glActiveTexture(GL_TEXTURE15);
492 auto load_shader = [&](GLuint program) {
493 glUseProgram(
shaders[program]);
504 glEnable(GL_PRIMITIVE_RESTART);
506 glPrimitiveRestartIndex(std::numeric_limits<uint16_t>::max());
527 GLuint fragment_subroutines = 0;
529 fragment_subroutines = 0;
531 fragment_subroutines = 1;
533 fragment_subroutines = 2;
537 glDrawElements(GL_TRIANGLE_STRIP, GLsizei(
map_indices.size() - 1), GL_UNSIGNED_SHORT,
map_indices.data());
540 glDisable(GL_PRIMITIVE_RESTART);
543 if(state.user_settings.rivers_enabled) {
544 glActiveTexture(GL_TEXTURE0);
546 glActiveTexture(GL_TEXTURE1);
548 glActiveTexture(GL_TEXTURE2);
550 glActiveTexture(GL_TEXTURE3);
567 glActiveTexture(GL_TEXTURE0);
569 glActiveTexture(GL_TEXTURE1);
584 constexpr float border_type_national = 0.f;
585 constexpr float border_type_provincial = 1.f;
586 constexpr float border_type_regional = 2.f;
587 constexpr float border_type_coastal = 3.f;
600 glActiveTexture(GL_TEXTURE0);
602 glActiveTexture(GL_TEXTURE1);
607 glActiveTexture(GL_TEXTURE2);
612 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
618 glActiveTexture(GL_TEXTURE2);
622 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
629 glActiveTexture(GL_TEXTURE2);
633 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
640 glActiveTexture(GL_TEXTURE2);
644 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
651 glActiveTexture(GL_TEXTURE2);
655 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
661 glActiveTexture(GL_TEXTURE2);
665 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
672 glActiveTexture(GL_TEXTURE2);
676 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
683 glActiveTexture(GL_TEXTURE2);
687 auto p0 = state.world.province_adjacency_get_connected_provinces(b.adj, 0);
688 auto p1 = state.world.province_adjacency_get_connected_provinces(b.adj, 1);
689 if((state.world.province_get_nation_from_province_ownership(p0) == state.local_player_nation
690 || state.world.province_get_nation_from_province_ownership(p1) == state.local_player_nation)
692 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
696 auto owner = state.world.province_get_nation_from_province_ownership(state.map_state.selected_province);
698 auto siid = state.world.province_get_state_membership(state.map_state.selected_province);
701 auto p0 = state.world.province_adjacency_get_connected_provinces(b.adj, 0);
702 auto p1 = state.world.province_adjacency_get_connected_provinces(b.adj, 1);
703 if((state.world.province_get_state_membership(p0) == siid
704 || state.world.province_get_state_membership(p1) == siid)
706 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
712 auto p0 = state.world.province_adjacency_get_connected_provinces(b.adj, 0);
713 auto p1 = state.world.province_adjacency_get_connected_provinces(b.adj, 1);
714 if(p0 == state.map_state.selected_province || p1 == state.map_state.selected_province) {
715 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
720 dcon::province_id prov{};
722 if(!state.ui_state.under_mouse && state.map_state.screen_to_map(glm::vec2(state.mouse_x_position, state.mouse_y_position), screen_size, state.map_state.current_view(state), map_pos)) {
723 map_pos *= glm::vec2(
float(state.map_state.map_data.size_x),
float(state.map_state.map_data.size_y));
724 auto idx = int32_t(state.map_state.map_data.size_y - map_pos.y) * int32_t(state.map_state.map_data.size_x) + int32_t(map_pos.x);
725 if(0 <= idx &&
size_t(idx) < state.map_state.map_data.province_id_map.size() && state.map_state.map_data.province_id_map[idx] <
province::to_map_id(state.province_definitions.first_sea_province)) {
729 glActiveTexture(GL_TEXTURE2);
731 auto owner = state.world.province_get_nation_from_province_ownership(prov);
735 auto p0 = state.world.province_adjacency_get_connected_provinces(b.adj, 0);
736 auto p1 = state.world.province_adjacency_get_connected_provinces(b.adj, 1);
737 if((state.world.province_get_nation_from_province_ownership(p0) == owner
738 || state.world.province_get_nation_from_province_ownership(p1) == owner)
740 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
744 auto siid = state.world.province_get_state_membership(prov);
747 auto p0 = state.world.province_adjacency_get_connected_provinces(b.adj, 0);
748 auto p1 = state.world.province_adjacency_get_connected_provinces(b.adj, 1);
749 if((state.world.province_get_state_membership(p0) == siid
750 || state.world.province_get_state_membership(p1) == siid)
752 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
758 auto p0 = state.world.province_adjacency_get_connected_provinces(b.adj, 0);
759 auto p1 = state.world.province_adjacency_get_connected_provinces(b.adj, 1);
760 if(p0 == prov || p1 == prov) {
761 glDrawArrays(GL_TRIANGLE_STRIP, b.start_index, b.count);
770 glActiveTexture(GL_TEXTURE2);
779 glActiveTexture(GL_TEXTURE0);
781 glActiveTexture(GL_TEXTURE3);
801 glActiveTexture(GL_TEXTURE0);
808 glActiveTexture(GL_TEXTURE0);
815 glActiveTexture(GL_TEXTURE0);
822 glActiveTexture(GL_TEXTURE0);
829 glActiveTexture(GL_TEXTURE0);
836 glActiveTexture(GL_TEXTURE0);
862 glActiveTexture(GL_TEXTURE0);
864 glDrawArrays(GL_TRIANGLES, i * 6, 6);
880 constexpr float dist_step = 1.77777f;
882 glEnable(GL_DEPTH_TEST);
883 glClear(GL_DEPTH_BUFFER_BIT);
885 glDepthFunc(GL_GREATER);
900 glActiveTexture(GL_TEXTURE0);
902 for(
uint32_t i = 0; i <
uint32_t(state.province_definitions.first_sea_province.index()); i++) {
903 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
906 auto center = state.world.province_get_mid_point(p);
907 auto pos = center + glm::vec2(-dist_step, dist_step);
920 static const model_tier nbe_tiers[] = {
925 for(
const auto& tier : nbe_tiers) {
926 glActiveTexture(GL_TEXTURE0);
928 for(
uint32_t i = 0; i <
uint32_t(state.province_definitions.first_sea_province.index()); i++) {
929 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
930 auto units = state.world.province_get_navy_location_as_location(p);
932 if(level >= tier.min && level <= tier.max && units.begin() == units.end()) {
934 auto p2 = state.world.province_get_mid_point(p);
936 auto theta = glm::atan(p2.y - p1.y, p2.x - p1.x);
944 static const model_tier nbf_tiers[] = {
949 for(
const auto& tier : nbf_tiers) {
950 glActiveTexture(GL_TEXTURE0);
952 for(
uint32_t i = 0; i <
uint32_t(state.province_definitions.first_sea_province.index()); i++) {
953 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
954 auto units = state.world.province_get_navy_location_as_location(p);
956 if(level >= tier.min && level <= tier.max && units.begin() != units.end()) {
958 auto p2 = state.world.province_get_mid_point(p);
960 auto theta = glm::atan(p2.y - p1.y, p2.x - p1.x);
968 static const model_tier fort_tiers[] = {
973 for(
const auto& tier : fort_tiers) {
974 glActiveTexture(GL_TEXTURE0);
976 for(
uint32_t i = 0; i <
uint32_t(state.province_definitions.first_sea_province.index()); i++) {
977 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
979 if(level >= tier.min && level <= tier.max) {
980 auto center = state.world.province_get_mid_point(p);
981 auto pos = center + glm::vec2(dist_step, -dist_step);
990 if(canal_id >=
uint32_t(state.province_definitions.canals.size())
991 && canal_id >=
uint32_t(state.province_definitions.canal_provinces.size()))
993 auto const adj = state.province_definitions.canals[canal_id];
996 glActiveTexture(GL_TEXTURE0);
998 glm::vec2 pos = state.world.province_get_mid_point(state.province_definitions.canal_provinces[canal_id]);
1004 render_canal(3, 0, 0.f);
1005 render_canal(4, 1, glm::pi<float>() / 2.f),
1006 render_canal(2, 2, 0.f);
1008 glActiveTexture(GL_TEXTURE0);
1010 for(
uint32_t i = 0; i <
uint32_t(state.province_definitions.first_sea_province.index()); i++) {
1011 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
1012 auto factories = state.world.province_get_factory_location_as_province(p);
1013 if(factories.begin() != factories.end()) {
1014 auto center = state.world.province_get_mid_point(p);
1015 auto pos = center + glm::vec2(-dist_step, -dist_step);
1023 glActiveTexture(GL_TEXTURE0);
1025 for(
uint32_t i = 0; i <
uint32_t(state.province_definitions.first_sea_province.index()); i++) {
1026 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
1029 auto p2 = state.world.province_get_mid_point(p);
1031 auto theta = glm::atan(p2.y - p1.y, p2.x - p1.x);
1039 glActiveTexture(GL_TEXTURE0);
1041 for(
uint32_t i = 0; i <
uint32_t(state.province_definitions.first_sea_province.index()); i++) {
1042 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
1043 auto units = state.world.province_get_army_location_as_location(p);
1045 && units.begin() != units.end()) {
1046 auto p1 = state.world.province_get_mid_point(p);
1048 bool has_unit =
false;
1049 for(
const auto unit : units) {
1050 for(
const auto sm : unit.get_army().get_army_membership()) {
1051 auto& t = state.military_definitions.unit_base_definitions[sm.get_regiment().get_type()];
1052 if(t.type == type) {
1058 if(
auto path = unit.get_army().get_path(); path.size() > 0) {
1059 p2 = state.world.province_get_mid_point(path[path.size() - 1]);
1066 auto theta = glm::atan(p2.y - p1.y, p2.x - p1.x);
1082 glActiveTexture(GL_TEXTURE0);
1084 for(
uint32_t i =
uint32_t(state.province_definitions.first_sea_province.index()); i < state.world.province_size(); i++) {
1085 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
1086 auto units = state.world.province_get_navy_location_as_location(p);
1088 && units.begin() != units.end()) {
1091 bool has_unit =
false;
1092 for(
const auto unit : units) {
1093 for(
const auto sm : unit.get_navy().get_navy_membership()) {
1094 auto& t = state.military_definitions.unit_base_definitions[sm.get_ship().get_type()];
1095 if(t.type == type && t.min_port_level <= min_port) {
1101 if(
auto path = unit.get_navy().get_path(); path.size() > 0) {
1109 auto theta = glm::atan(p2.y - p1.y, p2.x - p1.x);
1136 glActiveTexture(GL_TEXTURE0);
1138 for(
uint32_t i = 0; i < state.world.province_size(); i++) {
1139 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
1140 auto units = state.world.province_get_navy_location_as_location(p);
1142 && units.begin() != units.end()) {
1143 auto p1 = state.world.province_get_mid_point(p);
1145 auto theta = glm::atan(0.f, 0.f);
1151 glActiveTexture(GL_TEXTURE0);
1153 for(
uint32_t i = 0; i < state.world.province_size(); i++) {
1154 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(i));
1155 auto units = state.world.province_get_navy_location_as_location(p);
1157 && units.begin() != units.end()) {
1158 auto p1 = state.world.province_get_mid_point(p);
1160 auto theta = glm::atan(0.f, 0.f);
1167 for(
uint32_t i = 0; i < 3 * 3; i++) {
1168 auto index = 19 + i;
1169 glActiveTexture(GL_TEXTURE0);
1171 for(
uint32_t j = 0; j <
uint32_t(state.province_definitions.first_sea_province.index()); j++) {
1172 dcon::province_id p = dcon::province_id(dcon::province_id::value_base_t(j));
1173 if(state.world.province_get_demographics(p,
demographics::total) >=
float(i * 100000.f)) {
1177 auto center = state.world.province_get_mid_point(p);
1179 pos.x += i == 0 ? 0.f : float(i % 3) * 2.5f;
1180 pos.y += i == 0 ? 0.f : float(i / 3) * 2.5f;
1194 glDisable(GL_DEPTH_TEST);
1198 glBindVertexArray(0);
1199 glDisable(GL_CULL_FACE);
1202 glBindFramebuffer(GL_READ_FRAMEBUFFER, state.open_gl.msaa_framebuffer);
1203 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, state.open_gl.msaa_interbuffer);
1204 glBlitFramebuffer(0, 0, GLint(screen_size.x), GLint(screen_size.y), 0, 0, GLint(screen_size.x), GLint(screen_size.y), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1206 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1208 glUseProgram(state.open_gl.msaa_shader_program);
1209 glUniform1f(state.open_gl.msaa_uniform_gaussian_blur, state.user_settings.gaussianblur_level);
1210 glUniform2f(state.open_gl.msaa_uniform_screen_size, screen_size.x, screen_size.y);
1212 glActiveTexture(GL_TEXTURE0);
1213 glBindTexture(GL_TEXTURE_2D, state.open_gl.msaa_texture);
1214 glBindVertexArray(state.open_gl.msaa_vao);
1216 glDrawArrays(GL_TRIANGLES, 0, 6);
1221 GLuint texture_handle;
1222 glGenTextures(1, &texture_handle);
1223 if(texture_handle) {
1224 glBindTexture(GL_TEXTURE_2D, texture_handle);
1227 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG8, size_x, size_y);
1228 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size_x, size_y, GL_RG, GL_UNSIGNED_BYTE, &province_index[0]);
1229 glBindTexture(GL_TEXTURE_2D, 0);
1232 return texture_handle;
1237 glBindTexture(GL_TEXTURE_2D, texture_handle);
1239 glBindTexture(GL_TEXTURE_2D_ARRAY, texture_handle);
1250 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &prov_color[0]);
1253 for(
int i = 0; i < layers; i++) {
1254 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, x, y, i, width, height / layers, 1, GL_RGBA, GL_UNSIGNED_BYTE, &prov_color[i * (prov_color.size() / layers)]);
1260 width = left_on_last_row;
1265 if(left_on_last_row > 0 && layers == 1)
1266 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &prov_color[rows * 256]);
1268 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
1269 glBindTexture(GL_TEXTURE_2D, 0);
1273 std::vector<uint32_t> province_highlights(state.world.province_size() + 1, 0);
1274 state.current_scene.update_highlight_texture(state, province_highlights, prov_id);
1282void add_drag_box_line(std::vector<screen_vertex>& drag_box_vertices, glm::vec2 pos1, glm::vec2 pos2, glm::vec2 size,
bool vertical) {
1292 drag_box_vertices.emplace_back(pos1.x + size.x, pos1.y - size.y);
1293 drag_box_vertices.emplace_back(pos1.x - size.x, pos1.y + size.y);
1294 drag_box_vertices.emplace_back(pos2.x - size.x, pos2.y + size.y);
1296 drag_box_vertices.emplace_back(pos2.x - size.x, pos2.y + size.y);
1297 drag_box_vertices.emplace_back(pos2.x + size.x, pos2.y - size.y);
1298 drag_box_vertices.emplace_back(pos1.x + size.x, pos1.y - size.y);
1311 glm::vec2 size = pixel_size;
1323 glBindBuffer(GL_ARRAY_BUFFER, 0);
1326void add_arrow_to_buffer(std::vector<map::curved_line_vertex>& buffer, glm::vec2 start, glm::vec2 end, glm::vec2 prev_normal_dir, glm::vec2 next_normal_dir,
float fill_progress,
bool end_arrow,
float size_x,
float size_y) {
1327 constexpr float type_filled = 2.f;
1328 constexpr float type_unfilled = 0.f;
1329 constexpr float type_end = 3.f;
1330 glm::vec2 curr_dir = glm::normalize(end - start);
1331 start /= glm::vec2(size_x, size_y);
1332 end /= glm::vec2(size_x, size_y);
1334 if(fill_progress != 0) {
1335 if(fill_progress < 1.0f) {
1336 auto pos3 = glm::mix(start, end, fill_progress);
1337 auto midd_normal_dir = glm::vec2(-curr_dir.y, curr_dir.x);
1339 buffer.emplace_back(pos3, +midd_normal_dir, -curr_dir, glm::vec2(1.0f, 0.0f), type_filled);
1340 buffer.emplace_back(pos3, -midd_normal_dir, -curr_dir, glm::vec2(1.0f, 1.0f), type_filled);
1341 buffer.emplace_back(pos3, +midd_normal_dir, -curr_dir, glm::vec2(1.0f, 0.0f), type_unfilled);
1342 buffer.emplace_back(pos3, -midd_normal_dir, -curr_dir, glm::vec2(1.0f, 1.0f), type_unfilled);
1345 buffer.emplace_back(end, +next_normal_dir, -curr_dir, glm::vec2(1.0f, 0.0f), type_unfilled);
1346 buffer.emplace_back(end, -next_normal_dir, -curr_dir, glm::vec2(1.0f, 1.0f), type_unfilled);
1349 buffer.emplace_back(end, +next_normal_dir, -curr_dir, glm::vec2(1.0f, 0.0f), type_filled);
1350 buffer.emplace_back(end, -next_normal_dir, -curr_dir, glm::vec2(1.0f, 1.0f), type_filled);
1354 if(buffer.back().type_ == type_filled) {
1355 buffer.emplace_back(buffer[buffer.size() - 2]);
1356 buffer.emplace_back(buffer[buffer.size() - 2]);
1357 buffer[buffer.size() - 2].type_ = type_unfilled;
1358 buffer[buffer.size() - 1].type_ = type_unfilled;
1360 buffer.emplace_back(end, +next_normal_dir, -curr_dir, glm::vec2(1.0f, 0.0f), type_unfilled);
1361 buffer.emplace_back(end, -next_normal_dir, -curr_dir, glm::vec2(1.0f, 1.0f), type_unfilled);
1364 if(buffer.back().type_ == type_filled) {
1365 buffer.emplace_back(buffer[buffer.size() - 2]);
1366 buffer.emplace_back(buffer[buffer.size() - 2]);
1367 buffer[buffer.size() - 2].type_ = type_unfilled;
1368 buffer[buffer.size() - 1].type_ = type_unfilled;
1370 buffer.emplace_back(end, +next_normal_dir, -curr_dir, glm::vec2(1.0f, 0.0f), type_end);
1371 buffer.emplace_back(end, -next_normal_dir, -curr_dir, glm::vec2(1.0f, 1.0f), type_end);
1378void add_bezier_to_buffer(std::vector<map::curved_line_vertex>& buffer, glm::vec2 start, glm::vec2 end, glm::vec2 start_per, glm::vec2 end_per,
float progress,
bool last_curve,
float size_x,
float size_y,
uint32_t num_b_segments) {
1381 auto start_control_point = start_per * control_point_length + start;
1382 auto end_control_point = end_per * control_point_length + end;
1384 auto bpoint = [=](
float t) {
1387 + (u * u * u) * start
1388 + (3.0f * u * u * t) * start_control_point
1389 + (3.0f * u * t * t) * end_control_point
1390 + (t * t * t) * end;
1393 auto last_normal = glm::vec2(-start_per.y, start_per.x);
1394 glm::vec2 next_normal{ 0.0f, 0.0f };
1396 for(
uint32_t i = 0; i < num_b_segments - 1; ++i) {
1397 auto t_start = float(i) / float(num_b_segments);
1398 auto t_end = float(i + 1) / float(num_b_segments);
1399 auto t_next = float(i + 2) / float(num_b_segments);
1401 auto start_point = bpoint(t_start);
1402 auto end_point = bpoint(t_end);
1403 auto next_point = bpoint(t_next);
1405 next_normal = glm::normalize(end_point - start_point) + glm::normalize(end_point - next_point);
1406 auto temp = glm::normalize(end_point - start_point);
1407 if(glm::length(next_normal) < 0.00001f) {
1408 next_normal = glm::normalize(glm::vec2(-temp.y, temp.x));
1410 next_normal = glm::normalize(next_normal);
1411 if(glm::dot(glm::vec2(-temp.y, temp.x), next_normal) < 0) {
1412 next_normal = -next_normal;
1416 if(progress > 0.0f) {
1417 if(t_end <= progress) {
1418 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, 1.0f,
false, size_x, size_y);
1419 }
else if(progress < t_start) {
1420 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, 0.0f,
false, size_x, size_y);
1422 auto effective_progress = (progress - t_start) *
float(num_b_segments);
1423 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, effective_progress,
false, size_x, size_y);
1426 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, 0.0f,
false, size_x, size_y);
1429 last_normal = next_normal;
1432 next_normal = glm::vec2(end_per.y, -end_per.x);
1433 auto t_start = float(num_b_segments - 1) / float(num_b_segments);
1435 auto start_point = bpoint(t_start);
1436 auto end_point = bpoint(t_end);
1438 if(progress > 0.0f) {
1439 if(t_end <= progress) {
1440 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, 1.0f, last_curve, size_x, size_y);
1441 }
else if(progress < t_start) {
1442 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, 0.0f, last_curve, size_x, size_y);
1444 auto effective_progress = (progress - t_start) *
float(num_b_segments);
1445 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, effective_progress, last_curve, size_x, size_y);
1448 add_arrow_to_buffer(buffer, start_point, end_point, last_normal, next_normal, 0.0f, last_curve, size_x, size_y);
1453void add_tl_segment_buffer(std::vector<map::textured_line_vertex>& buffer, glm::vec2 start, glm::vec2 end, glm::vec2 next_normal_dir,
float size_x,
float size_y,
float& distance) {
1454 start /= glm::vec2(size_x, size_y);
1455 end /= glm::vec2(size_x, size_y);
1456 auto d = start - end;
1458 distance += 0.5f * glm::length(d);
1464 std::vector<map::textured_line_with_width_vertex>& buffer,
1467 glm::vec2 next_normal_dir,
1473 start /= glm::vec2(size_x, size_y);
1474 end /= glm::vec2(size_x, size_y);
1475 auto d = start - end;
1476 distance += glm::length(d) * width / 1000.f;
1481void add_tl_bezier_to_buffer(std::vector<map::textured_line_vertex>& buffer, glm::vec2 start, glm::vec2 end, glm::vec2 start_per, glm::vec2 end_per,
float progress,
bool last_curve,
float size_x,
float size_y,
uint32_t num_b_segments,
float& distance) {
1484 auto start_control_point = start_per * control_point_length + start;
1485 auto end_control_point = end_per * control_point_length + end;
1487 auto bpoint = [=](
float t) {
1490 + (u * u * u) * start
1491 + (3.0f * u * u * t) * start_control_point
1492 + (3.0f * u * t * t) * end_control_point
1493 + (t * t * t) * end;
1496 auto last_normal = glm::vec2(-start_per.y, start_per.x);
1497 glm::vec2 next_normal{ 0.0f, 0.0f };
1499 for(
uint32_t i = 0; i < num_b_segments - 1; ++i) {
1500 auto t_start = float(i) / float(num_b_segments);
1501 auto t_end = float(i + 1) / float(num_b_segments);
1502 auto t_next = float(i + 2) / float(num_b_segments);
1504 auto start_point = bpoint(t_start);
1505 auto end_point = bpoint(t_end);
1506 auto next_point = bpoint(t_next);
1508 next_normal = glm::normalize(end_point - start_point) + glm::normalize(end_point - next_point);
1509 auto temp = glm::normalize(end_point - start_point);
1510 if(glm::length(next_normal) < 0.00001f) {
1511 next_normal = glm::normalize(glm::vec2(-temp.y, temp.x));
1513 next_normal = glm::normalize(next_normal);
1514 if(glm::dot(glm::vec2(-temp.y, temp.x), next_normal) < 0) {
1515 next_normal = -next_normal;
1521 last_normal = next_normal;
1524 next_normal = glm::vec2(end_per.y, -end_per.x);
1525 auto t_start = float(num_b_segments - 1) / float(num_b_segments);
1527 auto start_point = bpoint(t_start);
1528 auto end_point = bpoint(t_end);
1535 std::vector<map::textured_line_with_width_vertex>& buffer,
1538 glm::vec2 start_tangent,
1539 glm::vec2 end_tangent,
1557 auto start_control_point = start_tangent * control_point_length + start;
1558 auto end_control_point = end_tangent * control_point_length + end;
1560 auto bpoint = [=](
float t) {
1563 + (u * u * u) * start
1564 + (3.0f * u * u * t) * start_control_point
1565 + (3.0f * u * t * t) * end_control_point
1566 + (t * t * t) * end;
1569 auto last_normal = glm::vec2(-start_tangent.y, start_tangent.x);
1570 glm::vec2 next_normal{ 0.0f, 0.0f };
1572 for(
uint32_t i = 0; i < num_b_segments - 1; ++i) {
1573 auto t_start = float(i) / float(num_b_segments);
1574 auto t_end = float(i + 1) / float(num_b_segments);
1575 auto t_next = float(i + 2) / float(num_b_segments);
1577 auto start_point = bpoint(t_start);
1578 auto end_point = bpoint(t_end);
1579 auto next_point = bpoint(t_next);
1581 next_normal = glm::normalize(end_point - start_point) + glm::normalize(end_point - next_point);
1582 auto temp = glm::normalize(end_point - start_point);
1583 if(glm::length(next_normal) < 0.00001f) {
1584 next_normal = glm::normalize(glm::vec2(-temp.y, temp.x));
1586 next_normal = glm::normalize(next_normal);
1587 if(glm::dot(glm::vec2(-temp.y, temp.x), next_normal) < 0) {
1588 next_normal = -next_normal;
1592 auto width = t_start * width_end + (1.f - t_start) * width_start;
1594 if(width != width_end) {
1598 add_tl_segment_buffer(buffer, start_point, end_point, next_normal, size_x, size_y, distance, width);
1600 last_normal = next_normal;
1603 next_normal = glm::vec2(end_tangent.y, -end_tangent.x);
1604 auto t_start = float(num_b_segments - 1) / float(num_b_segments);
1606 auto start_point = bpoint(t_start);
1607 auto end_point = bpoint(t_end);
1608 auto width = t_start * width_end + (1.f - t_start) * width_start;
1610 add_tl_segment_buffer(buffer, start_point, end_point, next_normal, size_x, size_y, distance, width);
1614glm::vec2
put_in_local(glm::vec2 new_point, glm::vec2 base_point,
float size_x) {
1615 auto uadjx = std::abs(new_point.x - base_point.x);
1616 auto ladjx = std::abs(new_point.x - size_x - base_point.x);
1617 auto radjx = std::abs(new_point.x + size_x - base_point.x);
1619 return uadjx < radjx ? new_point : glm::vec2{ new_point.x + size_x, new_point.y };
1621 return ladjx < radjx ? glm::vec2{ new_point.x - size_x, new_point.y } : glm::vec2{ new_point.x + size_x, new_point.y };
1625void make_navy_path(
sys::state& state, std::vector<map::curved_line_vertex>& buffer, dcon::navy_id selected_navy,
float size_x,
float size_y) {
1626 auto path = state.world.navy_get_path(selected_navy);
1627 if(
auto ps = path.size(); ps > 0) {
1632 glm::vec2 prev_perpendicular = glm::normalize(next_pos - current_pos);
1634 auto start_normal = glm::vec2(-prev_perpendicular.y, prev_perpendicular.x);
1635 auto norm_pos = current_pos / glm::vec2(size_x, size_y);
1637 buffer.emplace_back(norm_pos, +start_normal, glm::vec2{ 0,0 }, glm::vec2(0.0f, 0.0f), progress > 0.0f ? 2.0f : 0.0f);
1638 buffer.emplace_back(norm_pos, -start_normal, glm::vec2{ 0,0 }, glm::vec2(0.0f, 1.0f), progress > 0.0f ? 2.0f : 0.0f);
1639 for(
auto i = ps; i-- > 0;) {
1640 glm::vec2 next_perpendicular{ 0.0f, 0.0f };
1645 glm::vec2 a_per = glm::normalize(next_pos - current_pos);
1646 glm::vec2 b_per = glm::normalize(next_pos - next_next_pos);
1647 glm::vec2 temp = a_per + b_per;
1648 if(glm::length(temp) < 0.00001f) {
1649 next_perpendicular = -a_per;
1651 next_perpendicular = glm::normalize(glm::vec2{ -temp.y, temp.x });
1652 if(glm::dot(a_per, -next_perpendicular) < glm::dot(a_per, next_perpendicular)) {
1653 next_perpendicular *= -1.0f;
1657 next_perpendicular = glm::normalize(current_pos - next_pos);
1662 prev_perpendicular = -1.0f * next_perpendicular;
1669 auto path = state.world.navy_get_path(selected_navy);
1670 if(
auto ps = path.size(); ps > 0) {
1675 glm::vec2 prev_perpendicular = glm::normalize(next_pos - current_pos);
1677 auto start_normal = glm::vec2(-prev_perpendicular.y, prev_perpendicular.x);
1678 auto norm_pos = current_pos / glm::vec2(size_x, size_y);
1680 buffer.emplace_back(norm_pos, +start_normal, glm::vec2{ 0,0 }, glm::vec2(0.0f, 0.0f), progress > 0.0f ? 2.0f : 0.0f);
1681 buffer.emplace_back(norm_pos, -start_normal, glm::vec2{ 0,0 }, glm::vec2(0.0f, 1.0f), progress > 0.0f ? 2.0f : 0.0f);
1682 for(
auto i = ps; i-- > path.size() - 1;) {
1683 glm::vec2 next_perpendicular{ 0.0f, 0.0f };
1688 glm::vec2 a_per = glm::normalize(next_pos - current_pos);
1689 glm::vec2 b_per = glm::normalize(next_pos - next_next_pos);
1690 glm::vec2 temp = a_per + b_per;
1691 if(glm::length(temp) < 0.00001f) {
1692 next_perpendicular = -a_per;
1694 next_perpendicular = glm::normalize(glm::vec2{ -temp.y, temp.x });
1695 if(glm::dot(a_per, -next_perpendicular) < glm::dot(a_per, next_perpendicular)) {
1696 next_perpendicular *= -1.0f;
1700 next_perpendicular = glm::normalize(current_pos - next_pos);
1705 prev_perpendicular = -1.0f * next_perpendicular;
1712 std::vector<map::textured_line_with_width_vertex>& buffer,
1713 dcon::province_id origin,
1714 dcon::province_id target,
1722 float distance = 0.0f;
1724 auto shift = glm::vec2(shift_x, shift_y) / glm::vec2(size_x, size_y);
1725 if(
auto ps = path.size(); ps > 0) {
1728 glm::vec2 prev_perpendicular = glm::normalize(next_pos - current_pos);
1729 auto start_normal = glm::vec2(-prev_perpendicular.y, prev_perpendicular.x);
1730 auto norm_pos = current_pos / glm::vec2(size_x, size_y);
1747 for(
auto i = ps; i-- > 0;) {
1748 glm::vec2 next_perpendicular{ 0.0f, 0.0f };
1753 glm::vec2 a_per = glm::normalize(next_pos - current_pos);
1754 glm::vec2 b_per = glm::normalize(next_pos - next_next_pos);
1755 glm::vec2 temp = a_per + b_per;
1756 if(glm::length(temp) < 0.00001f) {
1757 next_perpendicular = -a_per;
1759 next_perpendicular = glm::normalize(glm::vec2{ -temp.y, temp.x });
1760 if(glm::dot(a_per, -next_perpendicular) < glm::dot(a_per, next_perpendicular)) {
1761 next_perpendicular *= -1.0f;
1765 next_perpendicular = glm::normalize(current_pos - next_pos);
1784 prev_perpendicular = -1.0f * next_perpendicular;
1792 std::vector<map::textured_line_with_width_vertex>& buffer,
1793 dcon::province_id origin,
1794 dcon::province_id target,
1800 float distance = 0.0f;
1801 if(
auto ps = path.size(); ps > 0) {
1804 glm::vec2 prev_tangent = glm::normalize(next_pos - current_pos);
1805 auto start_normal = glm::vec2(-prev_tangent.y, prev_tangent.x);
1806 auto norm_pos = current_pos / glm::vec2(size_x, size_y);
1823 for(
auto i = ps; i-- > 0;) {
1824 glm::vec2 next_tangent{ 0.0f, 0.0f };
1829 glm::vec2 a_per = glm::normalize(next_pos - current_pos);
1830 glm::vec2 b_per = glm::normalize(next_pos - next_next_pos);
1831 glm::vec2 temp = a_per + b_per;
1832 if(glm::length(temp) < 0.00001f) {
1833 next_tangent = -a_per;
1835 next_tangent = glm::normalize(glm::vec2{ -temp.y, temp.x });
1836 if(glm::dot(a_per, -next_tangent) < glm::dot(a_per, next_tangent)) {
1837 next_tangent *= -1.0f;
1841 next_tangent = glm::normalize(current_pos - next_pos);
1861 prev_tangent = -next_tangent;
1867void make_army_path(
sys::state& state, std::vector<map::curved_line_vertex>& buffer, dcon::army_id selected_army,
float size_x,
float size_y) {
1868 auto path = state.world.army_get_path(selected_army);
1869 if(
auto ps = path.size(); ps > 0) {
1874 glm::vec2 prev_perpendicular = glm::normalize(next_pos - current_pos);
1876 auto start_normal = glm::vec2(-prev_perpendicular.y, prev_perpendicular.x);
1877 auto norm_pos = current_pos / glm::vec2(size_x, size_y);
1879 buffer.emplace_back(norm_pos, +start_normal, glm::vec2{0,0}, glm::vec2(0.0f, 0.0f), progress > 0.0f ? 2.0f : 0.0f);
1880 buffer.emplace_back(norm_pos, -start_normal, glm::vec2{ 0,0 }, glm::vec2(0.0f, 1.0f), progress > 0.0f ? 2.0f : 0.0f);
1881 for(
auto i = ps; i-- > 0;) {
1882 glm::vec2 next_perpendicular{ 0.0f, 0.0f };
1887 glm::vec2 a_per = glm::normalize(next_pos - current_pos);
1888 glm::vec2 b_per = glm::normalize(next_pos - next_next_pos);
1889 glm::vec2 temp = a_per + b_per;
1890 if(glm::length(temp) < 0.00001f) {
1891 next_perpendicular = -a_per;
1893 next_perpendicular = glm::normalize(glm::vec2{ -temp.y, temp.x });
1894 if(glm::dot(a_per, -next_perpendicular) < glm::dot(a_per, next_perpendicular)) {
1895 next_perpendicular *= -1.0f;
1899 next_perpendicular = glm::normalize(current_pos - next_pos);
1904 prev_perpendicular = -1.0f * next_perpendicular;
1911 auto path = state.world.army_get_path(selected_army);
1912 if(
auto ps = path.size(); ps > 0) {
1917 glm::vec2 prev_perpendicular = glm::normalize(next_pos - current_pos);
1919 auto start_normal = glm::vec2(-prev_perpendicular.y, prev_perpendicular.x);
1920 auto norm_pos = current_pos / glm::vec2(size_x, size_y);
1922 buffer.emplace_back(norm_pos, +start_normal, glm::vec2{ 0,0 }, glm::vec2(0.0f, 0.0f), progress > 0.0f ? 2.0f : 0.0f);
1923 buffer.emplace_back(norm_pos, -start_normal, glm::vec2{ 0,0 }, glm::vec2(0.0f, 1.0f), progress > 0.0f ? 2.0f : 0.0f);
1924 for(
auto i = ps; i-- > path.size()-1;) {
1925 glm::vec2 next_perpendicular{ 0.0f, 0.0f };
1930 glm::vec2 a_per = glm::normalize(next_pos - current_pos);
1931 glm::vec2 b_per = glm::normalize(next_pos - next_next_pos);
1932 glm::vec2 temp = a_per + b_per;
1933 if(glm::length(temp) < 0.00001f) {
1934 next_perpendicular = -a_per;
1936 next_perpendicular = glm::normalize(glm::vec2{ -temp.y, temp.x });
1937 if(glm::dot(a_per, -next_perpendicular) < glm::dot(a_per, next_perpendicular)) {
1938 next_perpendicular *= -1.0f;
1942 next_perpendicular = glm::normalize(current_pos - next_pos);
1947 prev_perpendicular = -1.0f * next_perpendicular;
1954 auto const m1 = state.world.province_get_mid_point(p1);
1955 auto const m2 = state.world.province_get_mid_point(p2);
1956 railroad.emplace_back(m1);
1958 auto mid = ((m1 + m2) / glm::vec2(2.f, 2.f));
1959 const auto rp =
rng::get_random(state, p1.index(), p2.index() ^ p1.index());
1961 auto const perpendicular = glm::normalize(m2 - m1) * glm::vec2(rf, rf);
1962 railroad.emplace_back(mid + glm::vec2(-perpendicular.y, perpendicular.x));
1970 if(visited_prov[p.index()])
1972 visited_prov[p.index()] =
true;
1973 provinces.push_back(p);
1975 std::vector<dcon::province_adjacency_id> valid_adj;
1976 for(
const auto adj : state.world.province_get_province_adjacency_as_connected_provinces(p)) {
1977 auto const pa = adj.get_connected_provinces(adj.get_connected_provinces(0) == p ? 1 : 0);
1979 || visited_prov[pa.id.index()])
1986 valid_adj.push_back(adj.id);
1988 std::sort(valid_adj.begin(), valid_adj.end(), [&](
auto const a,
auto const b) ->
bool {
1989 auto const ad = state.world.province_adjacency_get_distance(a);
1990 auto const bd = state.world.province_adjacency_get_distance(b);
1993 for(
const auto a : valid_adj) {
1995 auto const pa = adj.get_connected_provinces(adj.get_connected_provinces(0) == p ? 1 : 0);
1997 visited_adj[adj.id.index()] =
true;
2006 std::vector<bool> visited_prov(state.world.province_size() + 1,
false);
2007 std::vector<bool> rr_ends(state.world.province_size() + 1,
false);
2008 std::vector<bool> visited_adj(state.world.province_adjacency_size() + 1,
false);
2009 std::vector<std::vector<glm::vec2>> railroads;
2010 for(
const auto p : state.world.in_province) {
2011 std::vector<dcon::province_id> provinces;
2013 if(provinces.size() > 1) {
2014 std::vector<glm::vec2> railroad;
2017 railroad.emplace_back(state.world.province_get_mid_point(provinces.back()));
2018 assert(!railroad.empty());
2019 railroads.push_back(railroad);
2020 assert(provinces.front());
2021 assert(provinces.back());
2022 rr_ends[provinces.front().index()] =
true;
2023 rr_ends[provinces.back().index()] =
true;
2030 for(
const auto p1 : state.world.in_province) {
2031 if(visited_prov[p1.id.index()]) {
2034 auto max_adj = std::max<uint32_t>(
uint32_t(admin_efficiency * 2.75f), rr_ends[p1.id.index()] ? 3 : 1);
2035 std::vector<dcon::province_adjacency_id> valid_adj;
2036 for(
const auto adj : p1.get_province_adjacency_as_connected_provinces()) {
2039 auto p2 = adj.get_connected_provinces(adj.get_connected_provinces(0) == p1.id ? 1 : 0);
2045 if(visited_adj[adj.id.index()])
2047 if(rr_ends[p1.id.index()] != rr_ends[p2.id.index()]
2048 && rr_ends[p1.id.index()] ==
false)
2050 visited_adj[adj.id.index()] =
true;
2051 valid_adj.push_back(adj.id);
2053 std::sort(valid_adj.begin(), valid_adj.end(), [&](
auto const a,
auto const b) ->
bool {
2054 auto const ad = state.world.province_adjacency_get_distance(a);
2055 auto const bd = state.world.province_adjacency_get_distance(b);
2058 for(
const auto a : valid_adj) {
2060 auto const p2 = adj.get_connected_provinces(adj.get_connected_provinces(0) == p1.id ? 1 : 0);
2062 std::vector<glm::vec2> railroad;
2064 railroad.emplace_back(state.world.province_get_mid_point(p2.id));
2065 assert(!railroad.empty());
2066 railroads.push_back(railroad);
2074 for(
const auto& railroad : railroads) {
2076 glm::vec2 current_pos = railroad.back();
2077 glm::vec2 next_pos =
put_in_local(railroad[railroad.size() - 2], current_pos,
float(
size_x));
2078 glm::vec2 prev_perpendicular = glm::normalize(next_pos - current_pos);
2079 auto start_normal = glm::vec2(-prev_perpendicular.y, prev_perpendicular.x);
2080 auto norm_pos = current_pos / glm::vec2(
size_x,
size_y);
2083 float distance = 0.0f;
2084 for(
auto i = railroad.size() - 1; i-- > 0;) {
2085 glm::vec2 next_perpendicular{ 0.0f, 0.0f };
2089 glm::vec2 a_per = glm::normalize(next_pos - current_pos);
2090 glm::vec2 b_per = glm::normalize(next_pos - next_next_pos);
2091 glm::vec2 temp = a_per + b_per;
2092 if(glm::length(temp) < 0.00001f) {
2093 next_perpendicular = -a_per;
2095 next_perpendicular = glm::normalize(glm::vec2{ -temp.y, temp.x });
2096 if(glm::dot(a_per, -next_perpendicular) < glm::dot(a_per, next_perpendicular))
2097 next_perpendicular *= -1.0f;
2100 next_perpendicular = glm::normalize(current_pos - next_pos);
2102 add_tl_bezier_to_buffer(
railroad_vertices, current_pos, next_pos, prev_perpendicular, next_perpendicular, 0.0f,
false,
float(
size_x),
float(
size_y),
default_num_b_segments, distance);
2103 prev_perpendicular = -1.0f * next_perpendicular;
2104 current_pos = railroad[i];
2114 glBindBuffer(GL_ARRAY_BUFFER, 0);
2122 const auto map_x_scaling = float(
size_x) / float(
size_y);
2125 for(
const auto& e : data) {
2127 if(!std::isfinite(e.coeff[0]) || !std::isfinite(e.coeff[1]) || !std::isfinite(e.coeff[2]) || !std::isfinite(e.coeff[3]))
2130 bool is_linear =
true;
2131 if((e.coeff[2] != 0) || (e.coeff[3] != 0)) {
2137 auto poly_fn = [&](
float x) {
2138 return e.coeff[0] + e.coeff[1] * x + e.coeff[2] * x * x + e.coeff[3] * x * x * x;
2140 auto dpoly_fn = [&](
float x) {
2143 return e.coeff[1] + 2.f * e.coeff[2] * x + 3.f * e.coeff[3] * x * x;
2153 if(e.coeff[1] > 0.01f) {
2154 left = (-e.coeff[0]) / e.coeff[1];
2155 right = (1.f - e.coeff[0]) / e.coeff[1];
2156 }
else if(e.coeff[1] < -0.01f) {
2157 left = (1.f - e.coeff[0]) / e.coeff[1];
2158 right = (- e.coeff[0]) / e.coeff[1];
2161 while(((poly_fn(left) < 0.f) || (poly_fn(left) > 1.f)) && (left < 1.f)) {
2162 left += 1.f / 300.f;
2164 while(((poly_fn(right) < 0.f) || (poly_fn(right) > 1.f)) && (right > 0.f)) {
2165 right -= 1.f / 300.f;
2170 left = std::clamp(left, 0.f, 1.f);
2171 right = std::clamp(right, 0.f, 1.f);
2178 float result_interval = right - left;
2179 float center = (right + left) / 2.f;
2181 glm::vec2 ratio = e.ratio;
2182 glm::vec2 basis = e.basis;
2184 auto effective_ratio = ratio.x * map_x_scaling / ratio.y;
2186 float text_length = f.text_extent(state, e.text, 0,
uint32_t(e.text.glyph_info.size()), 1);
2187 assert(std::isfinite(text_length) && text_length != 0.f);
2188 float x_step = (result_interval / float(e.text.glyph_info.size() * 32.f));
2189 float curve_length = 0.f;
2191 float height = poly_fn(right) - poly_fn(left);
2192 curve_length = 2.f * glm::length(glm::vec2(height * ratio.y, result_interval * ratio.x));
2193 }
else for(
float x = left; x <= right; x += x_step) {
2194 curve_length += 2.0f * glm::length(glm::vec2(x_step * ratio.x, (poly_fn(x) - poly_fn(x + x_step)) * ratio.y));
2196 float size = (curve_length / text_length) * 0.8f;
2200 float font_size_index = std::round(5.f * log(size) / log(1.618034f));
2202 if(font_size_index > 45.f) {
2203 font_size_index = 45.f;
2205 if (font_size_index > 5.f)
2206 font_size_index = 5.f * std::round(font_size_index / 5.f);
2208 size = std::pow(1.618034f, font_size_index / 5.f);
2233 auto real_text_size = size / (
size_x * 2.0f);
2235 float letter_spacing_map = std::clamp((0.8f * curve_length / text_length - size) / 2.f, 0.f, size * 2.f);
2236 if(state.world.locale_get_prevent_letterspace(state.font_collection.get_current_locale())) {
2237 letter_spacing_map = 0.f;
2240 float margin = (curve_length - text_length * (size + letter_spacing_map * 2.f) + letter_spacing_map) / 2.0f;
2242 for(
float accumulated_length = 0.f; ; x += x_step) {
2243 auto added_distance = 2.0f * glm::length(glm::vec2(x_step * ratio.x, (poly_fn(x) - poly_fn(x + x_step)) * e.ratio.y));
2244 if(accumulated_length + added_distance >= margin) {
2245 x += x_step * (margin - accumulated_length) / added_distance;
2248 accumulated_length += added_distance;
2252 unsigned int glyph_count =
static_cast<unsigned int>(e.text.glyph_info.size());
2253 for(
unsigned int i = 0; i < glyph_count; i++) {
2254 hb_codepoint_t glyphid = e.text.glyph_info[i].codepoint;
2255 auto gso = f.glyph_positions[glyphid];
2259 if(glyphid != FT_Get_Char_Index(f.font_face,
' ')) {
2261 glm::vec2 glyph_positions{ x_offset / 64.f, -y_offset / 64.f };
2263 glm::vec2 curr_dir = glm::normalize(glm::vec2(effective_ratio, dpoly_fn(x)));
2264 glm::vec2 curr_normal_dir = glm::vec2(-curr_dir.y, curr_dir.x);
2266 curr_normal_dir.x *= 0.5f;
2268 glm::vec2 shader_direction = glm::normalize(glm::vec2(ratio.x, dpoly_fn(x) * ratio.y));
2270 auto p0 = glm::vec2(x, poly_fn(x)) * ratio + basis;
2272 p0 -= (1.5f - 2.f * glyph_positions.y) * curr_normal_dir * real_text_size;
2273 p0 += (1.0f + 2.f * glyph_positions.x) * curr_dir * real_text_size;
2276 float step = 1.f / 8.f;
2277 float tx = float(gso.texture_slot & 7) * step;
2278 float ty = float((gso.texture_slot & 63) >> 3) * step;
2280 text_line_vertices.emplace_back(p0, glm::vec2(-1, 1), shader_direction, glm::vec3(tx, ty, type), real_text_size);
2281 text_line_vertices.emplace_back(p0, glm::vec2(-1, -1), shader_direction, glm::vec3(tx, ty + step, type), real_text_size);
2282 text_line_vertices.emplace_back(p0, glm::vec2(1, -1), shader_direction, glm::vec3(tx + step, ty + step, type), real_text_size);
2284 text_line_vertices.emplace_back(p0, glm::vec2(1, -1), shader_direction, glm::vec3(tx + step, ty + step, type), real_text_size);
2285 text_line_vertices.emplace_back(p0, glm::vec2(1, 1), shader_direction, glm::vec3(tx + step, ty, type), real_text_size);
2286 text_line_vertices.emplace_back(p0, glm::vec2(-1, 1), shader_direction, glm::vec3(tx, ty, type), real_text_size);
2289 float glyph_advance = x_advance * size / 64.f;
2290 for(
float glyph_length = 0.f; ; x += x_step) {
2291 auto added_distance = 2.0f * glm::length(glm::vec2(x_step * ratio.x, (poly_fn(x) - poly_fn(x + x_step)) * ratio.y));
2292 if(glyph_length + added_distance >= glyph_advance + letter_spacing_map) {
2293 x += x_step * (glyph_advance + letter_spacing_map - glyph_length) / added_distance;
2296 glyph_length += added_distance;
2303 glBindBuffer(GL_ARRAY_BUFFER, 0);
2309 const auto map_x_scaling = float(
size_x) / float(
size_y);
2312 for(
const auto& e : data) {
2314 if(!std::isfinite(e.coeff[0]) || !std::isfinite(e.coeff[1]) || !std::isfinite(e.coeff[2]) || !std::isfinite(e.coeff[3]))
2317 auto effective_ratio = e.ratio.x * map_x_scaling / e.ratio.y;
2319 float text_length = f.text_extent(state, e.text, 0,
uint32_t(e.text.glyph_info.size()), 1);
2320 assert(std::isfinite(text_length) && text_length != 0.f);
2323 auto poly_fn = [&](
float x) {
2324 return e.coeff[0] + e.coeff[1] * x + e.coeff[2] * x * x + e.coeff[3] * x * x * x;
2326 float x_step = (1.f / float(e.text.glyph_info.size() * 32.f));
2327 float curve_length = 0.f;
2328 for(
float x = 0.f; x <= 1.f; x += x_step)
2329 curve_length += 2.0f * glm::length(glm::vec2(x_step * e.ratio.x, (poly_fn(x) - poly_fn(x + x_step)) * e.ratio.y));
2331 float size = (curve_length / text_length) * 0.85f;
2333 size = 200.0f + (size - 200.0f) * 0.5f;
2335 auto real_text_size = size / (
size_x * 2.0f);
2336 float margin = (curve_length - text_length * size) / 2.0f;
2338 for(
float accumulated_length = 0.f; ; x += x_step) {
2339 auto added_distance = 2.0f * glm::length(glm::vec2(x_step * e.ratio.x, (poly_fn(x) - poly_fn(x + x_step)) * e.ratio.y));
2340 if(accumulated_length + added_distance >= margin) {
2341 x += x_step * (margin - accumulated_length) / added_distance;
2344 accumulated_length += added_distance;
2347 unsigned int glyph_count =
uint32_t(e.text.glyph_info.size());
2348 for(
unsigned int i = 0; i < glyph_count; i++) {
2349 hb_codepoint_t glyphid = e.text.glyph_info[i].codepoint;
2350 auto gso = f.glyph_positions[glyphid];
2351 float x_advance = float(gso.x_advance);
2352 float x_offset = float(e.text.glyph_info[i].x_offset) / 4.f + float(gso.x);
2353 float y_offset = float(gso.y) - float(e.text.glyph_info[i].y_offset) / 4.f;
2354 if(glyphid != FT_Get_Char_Index(f.font_face,
' ')) {
2356 glm::vec2 glyph_positions{ x_offset / 64.f, -y_offset / 64.f };
2357 auto dpoly_fn = [&](
float x) {
2360 return e.coeff[1] + 2.f * e.coeff[2] * x + 3.f * e.coeff[3] * x * x;
2362 glm::vec2 curr_dir = glm::normalize(glm::vec2(effective_ratio, dpoly_fn(x)));
2363 glm::vec2 curr_normal_dir = glm::vec2(-curr_dir.y, curr_dir.x);
2365 curr_normal_dir.x *= 0.5f;
2367 glm::vec2 shader_direction = glm::normalize(glm::vec2(e.ratio.x, dpoly_fn(x) * e.ratio.y));
2369 auto p0 = glm::vec2(x, poly_fn(x)) * e.ratio + e.basis;
2371 p0 -= (1.5f - 2.f * glyph_positions.y) * curr_normal_dir * real_text_size;
2372 p0 += (1.0f + 2.f * glyph_positions.x) * curr_dir * real_text_size;
2375 float step = 1.f / 8.f;
2376 float tx = float(gso.texture_slot & 7) * step;
2377 float ty = float((gso.texture_slot & 63) >> 3) * step;
2380 province_text_line_vertices.emplace_back(p0, glm::vec2(-1, -1), shader_direction, glm::vec3(tx, ty + step, type), real_text_size);
2381 province_text_line_vertices.emplace_back(p0, glm::vec2(1, -1), shader_direction, glm::vec3(tx + step, ty + step, type), real_text_size);
2383 province_text_line_vertices.emplace_back(p0, glm::vec2(1, -1), shader_direction, glm::vec3(tx + step, ty + step, type), real_text_size);
2387 float glyph_advance = x_advance * size / 64.f;
2388 for(
float glyph_length = 0.f; ; x += x_step) {
2389 auto added_distance = 2.0f * glm::length(glm::vec2(x_step * e.ratio.x, (poly_fn(x) - poly_fn(x + x_step)) * e.ratio.y));
2390 if(glyph_length + added_distance >= glyph_advance) {
2391 x += x_step * (glyph_advance - glyph_length) / added_distance;
2394 glyph_length += added_distance;
2401 glBindBuffer(GL_ARRAY_BUFFER, 0);
2410 OutputDebugStringA(full_message.c_str());
2412 std::fprintf(stderr,
"%s", full_message.c_str());
2423 for(
const auto& layer : mat.
layers) {
2428 for(
const auto& layer : mat.
layers) {
2429 if(strstr(layer.texture.c_str(),
"spec") == NULL) {
2433 return mat.
layers.empty()
2440 struct static_mesh_vertex {
2441 glm::vec3 position_;
2443 glm::vec2 texture_coord_;
2445 std::vector<static_mesh_vertex> static_mesh_vertices;
2446 static const std::array<native_string_view, display_data::max_static_meshes> xac_model_names = {
2447 NATIVE(
"capital_bigben"),
2448 NATIVE(
"capital_eiffeltower"),
2453 NATIVE(
"Navalbase_Late_Empty"),
2454 NATIVE(
"Navalbase_Late_Full"),
2458 NATIVE(
"generic_euro_infantry"),
2459 NATIVE(
"Generic_Frigate"),
2460 NATIVE(
"Generic_Manowar"),
2461 NATIVE(
"Generic_Transport_Ship"),
2464 NATIVE(
"Infantry_shadowblob"),
2465 NATIVE(
"Generic_Euro_Infantry2"),
2466 NATIVE(
"buildings_01_1"),
2467 NATIVE(
"buildings_01_2"),
2468 NATIVE(
"buildings_01_3"),
2469 NATIVE(
"buildings_02_1"),
2470 NATIVE(
"buildings_02_2"),
2471 NATIVE(
"buildings_02_3"),
2472 NATIVE(
"buildings_03_1"),
2473 NATIVE(
"buildings_03_2"),
2474 NATIVE(
"buildings_03_3"),
2477 NATIVE(
"Navalbase_Early_Empty"),
2478 NATIVE(
"Navalbase_Early_Full"),
2479 NATIVE(
"Navalbase_Mid_Empty"),
2480 NATIVE(
"Navalbase_Mid_Full"),
2481 NATIVE(
"Generic_Battleship"),
2482 NATIVE(
"Generic_Cruiser"),
2483 NATIVE(
"Generic_Ironclad"),
2484 NATIVE(
"Generic_Raider"),
2488 static const std::array<float, display_data::max_static_meshes> scaling_factor = {
2532 constexpr float no_elim = 9999.f + 0.1f;
2533 constexpr float quad_elim = 9999.f + 0.2f;
2534 static const std::array<float, display_data::max_static_meshes> elim_factor = {
2584 auto old_size = static_mesh_vertices.size();
2590 emfx::parse_xac(context, contents.data, contents.data + contents.file_size, err);
2593 auto& texid = state.map_state.map_data.static_mesh_textures[k];
2594 for(
auto const& node : context.nodes) {
2595 int32_t mesh_index = 0;
2596 for(
auto const& mesh : node.meshes) {
2597 bool is_collision = node.collision_mesh == mesh_index;
2598 bool is_visual = node.visual_mesh == mesh_index;
2601 for(
auto const& sub : mesh.submeshes) {
2603 static_mesh_vertex triangle_vertices[3];
2605 static_mesh_vertex smv;
2606 auto index = sub.indices[i + j] + vertex_offset;
2607 auto vv = mesh.vertices[index % mesh.vertices.size()];
2608 auto vn = mesh.normals.empty()
2610 : mesh.normals[index % mesh.normals.size()];
2611 auto vt = mesh.texcoords.empty()
2613 : mesh.texcoords[index % mesh.texcoords.size()];
2614 smv.position_ = glm::vec3(vv.x, vv.y, vv.z);
2615 smv.normal_ = glm::vec3(vn.x, vn.y, vn.z);
2616 smv.texture_coord_ = glm::vec2(vt.x, vt.y);
2617 triangle_vertices[j] = smv;
2621 bool keep = is_visual;
2622 if(elim_factor[k] == no_elim) {
2624 for(
const auto& smv : triangle_vertices) {
2625 static_mesh_vertex tmp = smv;
2626 tmp.position_ *= scaling_factor[k];
2627 static_mesh_vertices.push_back(tmp);
2630 }
else if(elim_factor[k] == quad_elim) {
2631 if(triangle_vertices[0].position_.y <= -0.1f
2632 || triangle_vertices[1].position_.y <= -0.1f
2633 || triangle_vertices[2].position_.y <= -0.1f) {
2634 for(
const auto& smv : triangle_vertices) {
2635 static_mesh_vertex tmp = smv;
2636 tmp.position_ *= scaling_factor[k];
2637 static_mesh_vertices.push_back(tmp);
2641 if(triangle_vertices[0].position_.y <= elim_factor[k]
2642 && triangle_vertices[1].position_.y <= elim_factor[k]
2643 && triangle_vertices[2].position_.y <= elim_factor[k]) {
2644 for(
const auto& smv : triangle_vertices) {
2645 static_mesh_vertex tmp = smv;
2646 tmp.position_ *= scaling_factor[k];
2647 static_mesh_vertices.push_back(tmp);
2652 vertex_offset += sub.num_vertices;
2655 auto const& mat = context.materials[sub.material_id];
2657 if(layer.texture.empty()) {
2680 state.map_state.map_data.static_mesh_starts[k] = GLint(old_size);
2681 state.map_state.map_data.static_mesh_counts[k] = GLsizei(static_mesh_vertices.size() - old_size);
2683 state.map_state.map_data.static_mesh_starts[k] = GLint(old_size);
2684 state.map_state.map_data.static_mesh_counts[k] = GLsizei(0);
2688 if(!static_mesh_vertices.empty()) {
2689 glBindBuffer(GL_ARRAY_BUFFER, state.map_state.map_data.vbo_array[state.map_state.map_data.vo_static_mesh]);
2690 glBufferData(GL_ARRAY_BUFFER,
sizeof(static_mesh_vertex) * static_mesh_vertices.size(), &static_mesh_vertices[0], GL_STATIC_DRAW);
2692 glBindVertexArray(state.map_state.map_data.vao_array[state.map_state.map_data.vo_static_mesh]);
2693 glBindVertexBuffer(0, state.map_state.map_data.vbo_array[state.map_state.map_data.vo_static_mesh], 0,
sizeof(static_mesh_vertex));
2694 glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, offsetof(static_mesh_vertex, position_));
2695 glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, offsetof(static_mesh_vertex, normal_));
2696 glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, offsetof(static_mesh_vertex, texture_coord_));
2697 glEnableVertexAttribArray(0);
2698 glEnableVertexAttribArray(1);
2699 glEnableVertexAttribArray(2);
2700 glVertexAttribBinding(0, 0);
2701 glVertexAttribBinding(1, 0);
2702 glVertexAttribBinding(2, 0);
2703 glBindVertexArray(0);
2724 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8UI,
size_x,
size_y);
2726 glBindTexture(GL_TEXTURE_2D, 0);
2734 auto texturesheet = open_file(map_terrain_dir,
NATIVE(
"texturesheet.png"));
2736 texturesheet = open_file(map_terrain_dir,
NATIVE(
"texturesheet.tga"));
2738 texturesheet = open_file(map_terrain_dir,
NATIVE(
"texturesheet.dds"));
2810 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 256, 256, 2);
2816 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2822 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2828 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2831 for(
auto p : state.world.in_province) {
2832 if(p.id.index() >= state.province_definitions.first_sea_province.index()) {
2841 glBindTexture(GL_TEXTURE_2D, 0);
2843 uint32_t province_size = state.world.province_size() + 1;
2844 province_size += 256 - province_size % 256;
2846 std::vector<uint32_t> test_highlight(province_size);
2848 for(
uint32_t i = 0; i < test_highlight.size(); ++i) {
2849 test_highlight[i] = 255;
2851 std::vector<uint32_t> test_color(province_size * 4);
2852 for(
uint32_t i = 0; i < test_color.size(); ++i) {
2853 test_color[i] = 255;
std::vector< textured_line_with_width_vertex > river_vertices
static constexpr uint32_t texture_diag_border_identifier
static constexpr uint32_t uniform_texture_sampler
void update_railroad_paths(sys::state &state)
static constexpr uint32_t uniform_colormap_water
static constexpr uint32_t shader_textured_line
std::vector< GLsizei > trade_flow_arrow_counts
static constexpr uint32_t texture_strategy_unit_arrow
std::vector< GLsizei > river_counts
void load_shaders(simple_fs::directory &root)
static constexpr uint32_t texture_array_province_color
GLuint texture_arrays[texture_array_count]
static constexpr uint32_t uniform_rotation
static constexpr uint32_t uniform_overlay
static constexpr uint32_t texture_sea_mask
static constexpr uint32_t vo_coastal
std::vector< GLsizei > coastal_counts
void update_fog_of_war(sys::state &state)
GLuint vao_array[vo_count]
static constexpr uint32_t uniform_water_normal
static constexpr uint32_t uniform_stripes_texture
static constexpr uint32_t texture_colormap_water
static constexpr uint32_t texture_coastal_border
std::vector< GLint > coastal_starts
std::vector< text_line_vertex > province_text_line_vertices
std::vector< GLsizei > static_mesh_counts
std::vector< curved_line_vertex > retreat_unit_arrow_vertices
static constexpr uint32_t shader_map_standing_object
void load_map(sys::state &state)
void set_selected_province(sys::state &state, dcon::province_id province_id)
static constexpr uint32_t shader_count
std::vector< GLuint > text_line_texture_per_quad
static constexpr uint32_t shader_text_line
std::vector< text_line_vertex > text_line_vertices
static constexpr uint32_t uniform_diag_border_identifier
static constexpr uint32_t texture_imp_border
static constexpr uint32_t vo_count
static constexpr uint32_t texture_province_fow
static constexpr uint32_t uniform_provinces_sea_mask
std::vector< GLsizei > strategy_unit_arrow_counts
static constexpr uint32_t uniform_opaque
static constexpr uint32_t texture_national_border
static constexpr uint32_t vo_land
static constexpr uint32_t vo_objective_unit_arrow
static constexpr uint32_t texture_hover_border
static constexpr uint32_t uniform_border_width
std::vector< border > borders
static constexpr uint32_t shader_line_unit_arrow
static constexpr uint32_t vo_province_text_line
std::vector< curved_line_vertex > attack_unit_arrow_vertices
static constexpr uint32_t vo_unit_arrow
std::vector< textured_line_with_width_vertex > trade_flow_vertices
std::vector< GLint > objective_unit_arrow_starts
static constexpr uint32_t shader_railroad_line
std::vector< GLint > river_starts
static constexpr uint32_t uniform_province_highlight
static constexpr uint32_t texture_unit_arrow
void set_province_text_lines(sys::state &state, std::vector< text_line_generator_data > const &data)
std::vector< uint16_t > province_id_map
static constexpr uint32_t uniform_province_color
std::vector< uint8_t > diagonal_borders
void gen_prov_color_texture(GLuint texture_handle, std::vector< uint32_t > const &prov_color, uint8_t layers=1)
std::vector< textured_line_vertex_b > border_vertices
std::vector< curved_line_vertex > other_objective_unit_arrow_vertices
std::vector< GLint > static_mesh_starts
static constexpr uint32_t texture_prov_border
std::vector< GLsizei > other_objective_unit_arrow_counts
static constexpr uint32_t texture_terrain
GLuint static_mesh_textures[max_static_meshes]
std::vector< uint16_t > map_indices
static constexpr uint32_t vo_drag_box
static constexpr uint32_t vo_border
static constexpr uint32_t texture_overlay
static constexpr uint32_t shader_trade_flow
std::vector< curved_line_vertex > unit_arrow_vertices
std::vector< GLsizei > retreat_unit_arrow_counts
std::vector< curved_line_vertex > strategy_unit_arrow_vertices
static constexpr uint32_t uniform_colormap_terrain
static constexpr uint32_t uniform_aspect_ratio
void update_borders(sys::state &state)
static constexpr uint32_t uniform_time
std::vector< textured_line_vertex_b > coastal_vertices
static constexpr uint32_t uniform_province_fow
static constexpr uint32_t uniform_offset
static constexpr uint32_t vo_attack_unit_arrow
static constexpr uint32_t vo_trade_flow
static constexpr uint32_t uniform_terrain_texture_sampler
static constexpr uint32_t vo_other_objective_unit_arrow
std::vector< GLint > retreat_unit_arrow_starts
static constexpr uint32_t uniform_zoom
static constexpr uint32_t texture_array_terrainsheet
std::vector< uint8_t > terrain_id_map
static constexpr uint32_t texture_stripes
static constexpr uint32_t uniform_width
std::vector< GLsizei > objective_unit_arrow_counts
static constexpr uint32_t texture_retreat_unit_arrow
static constexpr uint32_t uniform_is_black
static constexpr uint32_t uniform_subroutines_index_2
static constexpr uint32_t max_static_meshes
GLuint shader_uniforms[shader_count][uniform_count]
static constexpr uint32_t uniform_target_topview_fixup
static constexpr uint32_t texture_provinces
static constexpr uint32_t vo_static_mesh
static constexpr uint32_t uniform_map_size
static constexpr uint32_t texture_railroad
GLuint shaders[shader_count]
static constexpr uint32_t vo_railroad
static constexpr uint32_t texture_water_normal
std::vector< GLint > attack_unit_arrow_starts
std::vector< GLsizei > unit_arrow_counts
static constexpr uint32_t texture_other_objective_unit_arrow
static constexpr uint32_t uniform_target_facing
static constexpr uint32_t shader_borders
void render(sys::state &state, glm::vec2 screen_size, glm::vec2 offset, float zoom, map_view map_view_mode, map_mode::mode active_map_mode, glm::mat3 globe_rotation, float time_counter)
static constexpr uint32_t uniform_line_texture
static constexpr uint32_t texture_objective_unit_arrow
static constexpr uint32_t vo_retreat_unit_arrow
void set_text_lines(sys::state &state, std::vector< text_line_generator_data > const &data)
static constexpr uint32_t uniform_gamma
void create_border_ogl_objects()
static constexpr uint32_t vo_strategy_unit_arrow
static constexpr uint32_t uniform_model_offset
static constexpr uint32_t texture_attack_unit_arrow
static constexpr uint32_t texture_province_highlight
uint32_t land_vertex_count
GLuint vbo_array[vo_count]
std::vector< GLint > railroad_starts
std::vector< GLint > trade_flow_arrow_starts
std::vector< GLsizei > attack_unit_arrow_counts
std::vector< GLint > strategy_unit_arrow_starts
std::vector< GLint > unit_arrow_starts
static constexpr uint32_t texture_river_body
static constexpr uint32_t uniform_subroutines_index
std::vector< GLint > other_objective_unit_arrow_starts
static constexpr uint32_t shader_drag_box
static constexpr uint32_t uniform_colormap_political
void set_drag_box(bool draw_box, glm::vec2 pos1, glm::vec2 pos2, glm::vec2 pixel_size)
static constexpr uint32_t uniform_provinces_texture_sampler
static constexpr uint32_t texture_count
std::vector< screen_vertex > drag_box_vertices
static constexpr uint32_t vo_river
GLuint textures[texture_count]
std::vector< uint32_t > province_id_sea_mask
static constexpr uint32_t vo_text_line
static constexpr uint32_t texture_arrow
static constexpr uint32_t texture_colormap_terrain
std::vector< GLsizei > railroad_counts
std::vector< curved_line_vertex > objective_unit_arrow_vertices
void set_province_color(std::vector< uint32_t > const &prov_color)
static constexpr uint32_t shader_textured_line_with_variable_width
static constexpr uint32_t uniform_terrainsheet_texture_sampler
static constexpr uint32_t texture_colormap_political
static constexpr uint32_t texture_state_border
std::vector< textured_line_vertex > railroad_vertices
static constexpr uint32_t uniform_unit_arrow
static constexpr uint32_t shader_terrain
#define assert(condition)
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
constexpr dcon::demographics_key total(0)
glm::vec2 get_navy_location(sys::state &state, dcon::province_id prov_id)
bool is_sea_province(sys::state &state, dcon::province_id prov_id)
glm::vec2 get_army_location(sys::state &state, dcon::province_id prov_id)
glm::vec2 get_port_location(sys::state &state, dcon::province_id p)
void parse_xac(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
void finish(xac_context &context)
constexpr float zoom_close
glm::vec2 put_in_local(glm::vec2 new_point, glm::vec2 base_point, float size_x)
void create_railroad_connection(sys::state &state, std::vector< glm::vec2 > &railroad, dcon::province_id p1, dcon::province_id p2)
GLuint create_program(simple_fs::file &vshader_file, simple_fs::file &fshader_file)
void make_army_path(sys::state &state, std::vector< map::curved_line_vertex > &buffer, dcon::army_id selected_army, float size_x, float size_y)
GLuint load_dds_texture(simple_fs::directory const &dir, native_string_view file_name, int soil_flags=ogl::SOIL_FLAG_TEXTURE_REPEATS)
void load_static_meshes(sys::state &state)
void make_land_path(sys::state &state, std::vector< map::textured_line_with_width_vertex > &buffer, dcon::province_id origin, dcon::province_id target, float width, float size_x, float size_y)
void make_sea_path(sys::state &state, std::vector< map::textured_line_with_width_vertex > &buffer, dcon::province_id origin, dcon::province_id target, float width, float size_x, float size_y, float shift_x, float shift_y)
std::optional< simple_fs::file > try_load_shader(simple_fs::directory &root, native_string_view name)
emfx::xac_pp_actor_material_layer get_diffuse_layer(emfx::xac_pp_actor_material const &mat)
void add_bezier_to_buffer(std::vector< map::curved_line_vertex > &buffer, glm::vec2 start, glm::vec2 end, glm::vec2 start_per, glm::vec2 end_per, float progress, bool last_curve, float size_x, float size_y, uint32_t num_b_segments)
void create_unit_arrow_vbo(GLuint vbo, std::vector< curved_line_vertex > &data)
bool get_provinces_part_of_rr_path(sys::state &state, std::vector< bool > &visited_adj, std::vector< bool > &visited_prov, std::vector< dcon::province_id > &provinces, dcon::province_id p)
void create_drag_box_vbo(GLuint vbo)
void make_army_direction(sys::state &state, std::vector< map::curved_line_vertex > &buffer, dcon::army_id selected_army, float size_x, float size_y)
void add_nation_visible_provinces(sys::state &state, std::vector< dcon::province_id > &list, dcon::nation_id n)
constexpr uint32_t default_num_b_segments
constexpr float control_point_length_factor
void make_navy_path(sys::state &state, std::vector< map::curved_line_vertex > &buffer, dcon::navy_id selected_navy, float size_x, float size_y)
void create_text_line_vbo(GLuint vbo)
constexpr float zoom_very_close
void create_textured_line_b_vbo(GLuint vbo, std::vector< textured_line_vertex_b > &data)
void create_textured_line_vbo(GLuint vbo, std::vector< textured_line_vertex > &data)
void add_tl_segment_buffer(std::vector< map::textured_line_vertex > &buffer, glm::vec2 start, glm::vec2 end, glm::vec2 next_normal_dir, float size_x, float size_y, float &distance)
void add_arrow_to_buffer(std::vector< map::curved_line_vertex > &buffer, glm::vec2 start, glm::vec2 end, glm::vec2 prev_normal_dir, glm::vec2 next_normal_dir, float fill_progress, bool end_arrow, float size_x, float size_y)
GLuint load_province_map(std::vector< uint16_t > &province_index, uint32_t size_x, uint32_t size_y)
void make_navy_direction(sys::state &state, std::vector< map::curved_line_vertex > &buffer, dcon::navy_id selected_navy, float size_x, float size_y)
void add_drag_box_line(std::vector< screen_vertex > &drag_box_vertices, glm::vec2 pos1, glm::vec2 pos2, glm::vec2 size, bool vertical)
void add_tl_bezier_to_buffer(std::vector< map::textured_line_vertex > &buffer, glm::vec2 start, glm::vec2 end, glm::vec2 start_per, glm::vec2 end_per, float progress, bool last_curve, float size_x, float size_y, uint32_t num_b_segments, float &distance)
float fractional_distance_covered(sys::state &state, dcon::army_id a)
bool province_is_blockaded(sys::state const &state, dcon::province_id ids)
GLuint make_gl_texture(uint8_t *data, uint32_t size_x, uint32_t size_y, uint32_t channels)
bool msaa_enabled(sys::state const &state)
GLuint load_texture_array_from_file(simple_fs::file &file, int32_t tiles_x, int32_t tiles_y)
void set_gltex_parameters(GLuint texture_handle, GLuint texture_type, GLuint filter, GLuint wrap)
GLuint create_program(std::string_view vertex_shader, std::string_view fragment_shader)
GLuint SOIL_direct_load_DDS_from_memory(unsigned char const *const buffer, uint32_t buffer_length, uint32_t &width, uint32_t &height, int soil_flags)
@ SOIL_FLAG_TEXTURE_REPEATS
void notify_user_of_fatal_opengl_error(std::string message)
constexpr uint8_t impassible_bit
constexpr uint8_t non_adjacent_bit
constexpr uint8_t state_bit
constexpr uint8_t national_bit
constexpr uint8_t coastal_bit
constexpr dcon::province_id from_map_id(uint16_t id)
std::vector< dcon::province_id > make_naval_path(sys::state &state, dcon::province_id start, dcon::province_id end)
std::vector< dcon::province_id > make_unowned_land_path(sys::state &state, dcon::province_id start, dcon::province_id end)
float state_admin_efficiency(sys::state &state, dcon::state_instance_id id)
constexpr uint16_t to_map_id(dcon::province_id id)
uint32_t reduce(uint32_t value_in, uint32_t upper_bound)
uint64_t get_random(sys::state const &state, uint32_t value_in)
directory open_directory(directory const &dir, native_string_view directory_name)
native_string utf8_to_native(std::string_view data_in)
directory get_root(file_system const &fs)
native_string get_full_name(directory const &f)
std::optional< file > open_file(directory const &dir, native_string_view file_name)
std::string native_to_utf8(native_string_view data_in)
file_contents view_contents(file const &f)
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
constexpr int magnification_factor
constexpr uint32_t max_texture_layers
std::string_view native_string_view
std::string native_string
std::vector< xac_pp_actor_material_layer > layers
Holds important data about the game world, state, and other data regarding windowing,...