port: CMapOutdoor + PythonBackground + minimap (1:1 40250)
GameLib map/area/terrain units, PRTerrainLib Terrain/TextureSet, PythonBackground(+Module) and ColorTransitionHelper ported verbatim; pending stand-ins and background module stubs removed. Hand edits: BeginEnvironment's pointer tag via uintptr_t, LoadWaterMap reads the file's 32-bit longs. Terrain draw passes stay platform no-ops (Godot draws the terrain). RecordingDevice gains textures, buffers and render targets; orthographic draws become UI commands so CPythonMiniMap's masked tiles show through minimap_image_filter in python_ui_surface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b69116992c
commit
2ead95756e
@@ -44,6 +44,15 @@ func run_app() -> String:
|
||||
return ""
|
||||
|
||||
func _exit_tree() -> void:
|
||||
for segment in _segments:
|
||||
RenderingServer.free_rid(segment)
|
||||
_segments.clear()
|
||||
for material in _materials:
|
||||
RenderingServer.free_rid(material)
|
||||
_materials.clear()
|
||||
if _mask_shader.is_valid():
|
||||
RenderingServer.free_rid(_mask_shader)
|
||||
_mask_shader = RID()
|
||||
if _owns_app:
|
||||
_owns_app = false
|
||||
Metin2PythonHost.stop()
|
||||
@@ -90,7 +99,36 @@ func _unhandled_key_input(event: InputEvent) -> void:
|
||||
if dik != 0:
|
||||
Metin2PythonHost.ui_key(dik, event.pressed)
|
||||
|
||||
# The command stream is drawn into pooled child canvas items in order: a run of plain commands
|
||||
# shares one item; a masked image (CPythonMiniMap's terrain tiles under minimap_image_filter.dds)
|
||||
# gets its own item carrying the mask shader, since a canvas item has a single material.
|
||||
const MASK_SHADER := """
|
||||
shader_type canvas_item;
|
||||
render_mode blend_mix;
|
||||
uniform sampler2D mask_texture : repeat_disable, filter_linear;
|
||||
uniform vec4 uv_rect; // su, sv, eu, ev of the image
|
||||
uniform vec2 m0; // mask coordinates at the image's TL, TR and BL corners
|
||||
uniform vec2 m1;
|
||||
uniform vec2 m2;
|
||||
void fragment() {
|
||||
vec2 ab = (UV - uv_rect.xy) / max(uv_rect.zw - uv_rect.xy, vec2(1e-6));
|
||||
vec4 mask = texture(mask_texture, m0 + (m1 - m0) * ab.x + (m2 - m0) * ab.y);
|
||||
vec4 image = texture(TEXTURE, UV) * COLOR;
|
||||
COLOR = vec4(image.rgb * mask.rgb, mask.a * COLOR.a);
|
||||
}
|
||||
"""
|
||||
|
||||
var _segments: Array[RID] = []
|
||||
var _materials: Array[RID] = []
|
||||
var _mask_shader := RID()
|
||||
var _white: ImageTexture
|
||||
|
||||
func _draw() -> void:
|
||||
var used := 0
|
||||
var masked := 0
|
||||
var plain := false
|
||||
for segment in _segments:
|
||||
RenderingServer.canvas_item_clear(segment)
|
||||
if not Metin2PythonHost.is_running():
|
||||
return
|
||||
for command in Metin2PythonHost.ui_render_commands():
|
||||
@@ -105,17 +143,68 @@ func _draw() -> void:
|
||||
if command["kind"] == "bar":
|
||||
var visible := Rect2(p1, p2 - p1).intersection(clip)
|
||||
if visible.has_area():
|
||||
draw_rect(visible, color, true)
|
||||
if not plain:
|
||||
used = _segment(used, RID())
|
||||
plain = true
|
||||
RenderingServer.canvas_item_add_rect(_segments[used - 1], visible, color)
|
||||
elif command["kind"] == "line":
|
||||
var segment := _clip_line(p1, p2, clip)
|
||||
if segment.size() == 2:
|
||||
draw_line(segment[0], segment[1], color)
|
||||
if not plain:
|
||||
used = _segment(used, RID())
|
||||
plain = true
|
||||
RenderingServer.canvas_item_add_line(_segments[used - 1], segment[0], segment[1], color)
|
||||
elif command["kind"] == "image":
|
||||
var texture: Texture2D = _texture(command["text"])
|
||||
var mask: Texture2D = _texture(command["mask"]) if command.has("mask") else null
|
||||
if mask != null and texture == null:
|
||||
texture = _white_texture()
|
||||
if texture != null:
|
||||
var clipped := _clip_quad(command["quad"], command["uv"], clip)
|
||||
if clipped[0].size() >= 3:
|
||||
draw_polygon(clipped[0], PackedColorArray([color]), clipped[1], texture)
|
||||
if mask != null:
|
||||
used = _segment(used, _mask_material(masked, mask, command["uv"], command["mask_uv"]))
|
||||
masked += 1
|
||||
plain = false
|
||||
elif not plain:
|
||||
used = _segment(used, RID())
|
||||
plain = true
|
||||
RenderingServer.canvas_item_add_polygon(_segments[used - 1], clipped[0],
|
||||
PackedColorArray([color]), clipped[1], texture.get_rid())
|
||||
|
||||
# Opens the next pooled child item (draw order = index) with the given material; returns the count used.
|
||||
func _segment(used: int, material: RID) -> int:
|
||||
if used == _segments.size():
|
||||
var item := RenderingServer.canvas_item_create()
|
||||
RenderingServer.canvas_item_set_parent(item, get_canvas_item())
|
||||
_segments.push_back(item)
|
||||
var item := _segments[used]
|
||||
RenderingServer.canvas_item_set_draw_index(item, used)
|
||||
RenderingServer.canvas_item_set_material(item, material)
|
||||
return used + 1
|
||||
|
||||
func _mask_material(index: int, mask: Texture2D, uv: PackedVector2Array, mask_uv: PackedVector2Array) -> RID:
|
||||
if not _mask_shader.is_valid():
|
||||
_mask_shader = RenderingServer.shader_create()
|
||||
RenderingServer.shader_set_code(_mask_shader, MASK_SHADER)
|
||||
if index == _materials.size():
|
||||
var material := RenderingServer.material_create()
|
||||
RenderingServer.material_set_shader(material, _mask_shader)
|
||||
_materials.push_back(material)
|
||||
var material := _materials[index]
|
||||
RenderingServer.material_set_param(material, "mask_texture", mask.get_rid())
|
||||
RenderingServer.material_set_param(material, "uv_rect", Vector4(uv[0].x, uv[0].y, uv[3].x, uv[3].y))
|
||||
RenderingServer.material_set_param(material, "m0", mask_uv[0])
|
||||
RenderingServer.material_set_param(material, "m1", mask_uv[1])
|
||||
RenderingServer.material_set_param(material, "m2", mask_uv[2])
|
||||
return material
|
||||
|
||||
func _white_texture() -> Texture2D:
|
||||
if _white == null:
|
||||
var image := Image.create(1, 1, false, Image.FORMAT_RGBA8)
|
||||
image.fill(Color.WHITE)
|
||||
_white = ImageTexture.create_from_image(image)
|
||||
return _white
|
||||
|
||||
func _texture(name: String) -> Texture2D:
|
||||
if not name.begins_with("mem:"):
|
||||
|
||||
Reference in New Issue
Block a user