diff options
author | Hop311 <hop3114@gmail.com> | 2023-04-07 01:42:53 +0200 |
---|---|---|
committer | Hop311 <hop3114@gmail.com> | 2023-04-07 01:42:53 +0200 |
commit | 513a1328edb89ac695c70164158933aee4546cd7 (patch) | |
tree | 8d979d4e8c728bb80543aa13e037a328829122fd /game/src | |
parent | 14c2358c7837e644349ea37866607fcd1459d2bc (diff) |
Province index and colour lookup texture
Diffstat (limited to 'game/src')
-rw-r--r-- | game/src/GameSession/MapView.gd | 37 | ||||
-rw-r--r-- | game/src/GameSession/TerrainMap.gdshader | 46 |
2 files changed, 57 insertions, 26 deletions
diff --git a/game/src/GameSession/MapView.gd b/game/src/GameSession/MapView.gd index 4a44bce..67938f2 100644 --- a/game/src/GameSession/MapView.gd +++ b/game/src/GameSession/MapView.gd @@ -11,7 +11,8 @@ const _action_zoomout : StringName = &"map_zoomout" const _action_drag : StringName = &"map_drag" const _action_click : StringName = &"map_click" -const _shader_param_provinces : StringName = &"province_tex" +const _shader_param_province_index : StringName = &"province_index_tex" +const _shader_param_province_colour : StringName = &"province_colour_tex" const _shader_param_hover_pos : StringName = &"hover_pos" const _shader_param_selected_pos : StringName = &"selected_pos" @@ -34,7 +35,8 @@ const _shader_param_selected_pos : StringName = &"selected_pos" @export var _map_mesh_instance : MeshInstance3D var _map_mesh : MapMesh var _map_shader_material : ShaderMaterial -var _map_province_shape_image : Image +var _map_image_size : Vector2 +var _map_province_index_image : Image var _map_mesh_corner : Vector2 var _map_mesh_dims : Vector2 @@ -49,17 +51,14 @@ func _ready(): if _map_mesh_instance == null: push_error("MapView's _map_mesh variable hasn't been set!") return - _map_province_shape_image = MapSingleton.get_province_shape_image() - if _map_province_shape_image == null: - push_error("Failed to get province shape image!") - return if not _map_mesh_instance.mesh is MapMesh: push_error("Invalid map mesh class: ", _map_mesh_instance.mesh.get_class(), "(expected MapMesh)") return _map_mesh = _map_mesh_instance.mesh # Set map mesh size and get bounds - _map_mesh.aspect_ratio = float(_map_province_shape_image.get_width()) / float(_map_province_shape_image.get_height()) + _map_image_size = Vector2(Vector2i(MapSingleton.get_width(), MapSingleton.get_height())) + _map_mesh.aspect_ratio = _map_image_size.x / _map_image_size.y var map_mesh_aabb := _map_mesh.get_core_aabb() * _map_mesh_instance.transform _map_mesh_corner = Vector2( min(map_mesh_aabb.position.x, map_mesh_aabb.end.x), @@ -78,18 +77,28 @@ func _ready(): push_error("Invalid map mesh material class: ", map_material.get_class()) return _map_shader_material = map_material - var texture := ImageTexture.create_from_image(_map_province_shape_image) - _map_shader_material.set_shader_parameter(_shader_param_provinces, texture) + # Province index texture + _map_province_index_image = MapSingleton.get_province_index_image() + if _map_province_index_image == null: + push_error("Failed to get province index image!") + return + var province_index_texture := ImageTexture.create_from_image(_map_province_index_image) + _map_shader_material.set_shader_parameter(_shader_param_province_index, province_index_texture) + # Province colour texture + var province_colour_image = MapSingleton.get_province_colour_image() + if province_colour_image == null: + push_error("Failed to get province colour image!") + return + var province_colour_texture := ImageTexture.create_from_image(province_colour_image) + _map_shader_material.set_shader_parameter(_shader_param_province_colour, province_colour_texture) func _unhandled_input(event : InputEvent): if event.is_action_pressed(_action_click): # Check if the mouse is outside of bounds - var mouse_inside_flag := 0 < _mouse_pos_map.x and _mouse_pos_map.x < 1 and 0 < _mouse_pos_map.y and _mouse_pos_map.y < 1 - if mouse_inside_flag: - var mouse_pixel_pos := Vector2i(_mouse_pos_map * Vector2(_map_province_shape_image.get_size())) - var province_colour := _map_province_shape_image.get_pixelv(mouse_pixel_pos).to_argb32() & 0xFFFFFF - var province_identifier := MapSingleton.get_province_identifier_from_colour(province_colour) + if _map_mesh.is_valid_uv_coord(_mouse_pos_map): _map_shader_material.set_shader_parameter(_shader_param_selected_pos, _mouse_pos_map) + var mouse_pixel_pos := Vector2i(_mouse_pos_map * _map_image_size) + var province_identifier := MapSingleton.get_province_identifier_from_pixel_coords(mouse_pixel_pos) province_selected.emit(province_identifier) elif event is InputEventMouseMotion and Input.is_action_pressed(_action_drag): diff --git a/game/src/GameSession/TerrainMap.gdshader b/game/src/GameSession/TerrainMap.gdshader index 61b7032..be2bbe1 100644 --- a/game/src/GameSession/TerrainMap.gdshader +++ b/game/src/GameSession/TerrainMap.gdshader @@ -3,24 +3,46 @@ shader_type spatial; render_mode unshaded; // Cosmetic terrain texture -uniform sampler2D terrain_tex: source_color, repeat_enable; -// Province shape texture -uniform sampler2D province_tex: source_color, repeat_enable; +uniform sampler2D terrain_tex: source_color, repeat_enable, filter_linear; +// Province index texture +uniform sampler2D province_index_tex : repeat_enable, filter_nearest; +// Province colour texture +uniform sampler2D province_colour_tex: source_color, repeat_enable, filter_nearest; // Position of the mouse over the map mesh in UV coords uniform vec2 hover_pos; // Position in UV coords of a pixel belonging to the currently selected province uniform vec2 selected_pos; -const vec3 NULL_COLOUR = vec3(0.0); +uvec2 vec2_to_uvec2(vec2 v) { + return uvec2(v * 256.0); +} + +uint uvec2_to_uint(uvec2 v) { + return (v.y << 8u) | v.x; +} + +uvec2 read_uvec2(sampler2D tex, vec2 uv) { + return vec2_to_uvec2(texture(tex, uv).rg); +} + +uint read_uint16(sampler2D tex, vec2 uv) { + return uvec2_to_uint(read_uvec2(tex, uv)); +} void fragment() { - vec3 terrain_colour = texture(terrain_tex, UV).rgb; - vec3 prov_colour = texture(province_tex, UV).rgb; - vec3 hover_colour = texture(province_tex, hover_pos).rgb; - vec3 selected_colour = texture(province_tex, selected_pos).rgb; + uvec2 prov_idx_split = read_uvec2(province_index_tex, UV); + + uint prov_index = uvec2_to_uint(prov_idx_split); + uint hover_index = read_uint16(province_index_tex, hover_pos); + uint selected_index = read_uint16(province_index_tex, selected_pos); + // Boost prov_colour's contribution if it matches hover_colour or selected_colour - float mix_val = float(prov_colour == hover_colour) * 0.3 + float(prov_colour == selected_colour) * 0.5; - // Set to 0 if the province has NULL colour - mix_val *= 1.0 - float(prov_colour == NULL_COLOUR); - ALBEDO = mix(terrain_colour, prov_colour, mix_val); + float mix_val = float(prov_index == hover_index) * 0.3 + float(prov_index == selected_index) * 0.5; + // Don't mix if the province index is 0 + mix_val *= float(prov_index != 0u); + + vec3 terrain_colour = texture(terrain_tex, UV).rgb; + vec3 province_colour = texelFetch(province_colour_tex, ivec2(prov_idx_split), 0).rgb; + + ALBEDO = mix(terrain_colour, province_colour, mix_val); } |